1 新建解决方案SendMessageExample
在解决方案下面新建三个项目:CopyDataStruct,Receiver和Sender。
其中,CopyDataStruct项目的输出类型为“类库”,Receiver和Sender项目的输出类型为“Windows 应用程序”。
整个实例程序的结构如下图所示。
2 CopyDataStruct项目实现
定义结构体COPYDATASTRUCT,代码如下所示。
- using System;
- using System.Runtime.InteropServices;
- namespace CopyDataStruct
- {
- public struct COPYDATASTRUCT
- {
- public IntPtr dwData;
- public int cbData;
- [MarshalAs(UnmanagedType.LPStr)]
- public string lpData;
- }
- }
编译CopyDataStruct项目生成dll,再在Receiver和Sender项目中添加对此dll的引用。
3 Sender项目实现
Sender项目仅包含一个名称为“消息发送者”的窗体,如下图所示。
编写窗体后端代码,如下所示。
- using System;
- using System.Runtime.InteropServices;
- using System.Windows.Forms;
- using CopyDataStruct;
- namespace Sender
- {
- public partial class frmSender : Form
- {
- //Win32 API函数
- [DllImport("User32.dll", EntryPoint = "SendMessage")]
- private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
- [DllImport("User32.dll", EntryPoint = "FindWindow")]
- private static extern int FindWindow(string lpClassName, string lpWindowName);
- const int WM_COPYDATA = 0x004A;
- public frmSender()
- {
- InitializeComponent();
- }
- private void btnSend_Click(object sender, EventArgs e)
- {
- int hWnd = FindWindow(null, @"消息接受者");
- if (hWnd == 0)
- {
- MessageBox.Show("555,未找到消息接受者!");
- }
- else
- {
- byte[] sarr = System.Text.Encoding.Default.GetBytes(txtString.Text);
- int len = sarr.Length;
- COPYDATASTRUCT cds;
- cds.dwData = (IntPtr)Convert.ToInt16(txtInt.Text);//可以是任意值
- cds.cbData = len + 1;//指定lpData内存区域的字节数
- cds.lpData = txtString.Text;//发送给目标窗口所在进程的数据
- SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
- }
- }
- }
- }
4 Receiver项目实现
Receiver项目仅包含一个名称为“消息接受者”的窗体,如下图所示。
编写窗体的后端代码,如下所示。
- using System;
- using System.Windows.Forms;
- using CopyDataStruct;
- namespace Receiver
- {
- public partial class frmReceiver : Form
- {
- const int WM_COPYDATA = 0x004A;
- public frmReceiver()
- {
- InitializeComponent();
- }
- protected override void DefWndProc(ref Message m)
- {
- switch (m.Msg)
- {
- case WM_COPYDATA:
- COPYDATASTRUCT cds = new COPYDATASTRUCT();
- Type t = cds.GetType();
- cds = (COPYDATASTRUCT)m.GetLParam(t);
- string strResult = cds.dwData.ToString() + ":" +cds.lpData;
- lsvMsgList.Items.Add(strResult);
- break;
- default:
- base.DefWndProc(ref m);
- break;
- }
- }
- }
- }
5 运行结果
运行消息发送和消息接收程序(Sender.exe和Receiver.exe),效果如下图所示。
6 实例说明
6.1 SendMessage方法参数说明
- hWnd:接收消息的窗口的句柄
- Msg:消息标识符
- wParam:32位的特定附加信息,具体取决于消息
- lParam:32位特定附加信息,具体取决于消息
6.2 WM_COPYDATA消息说明
使用WM_COPYDATA消息,lParam参数可以指向一个 COPYDATASTRUCT结构体类型的变量。
- typedef struct COPYDATASTRUCT{
- ULONG_PTR dwData; //可以是任意值
- DWORD cb_data; //指定lpData内存区域的字节数
- PVOID lpData; //发送给目录窗口所在进程的数据
- }COPYDATASTRUCT;
另外,WM_COPYDATA消息的标识符为0x004A。