C#中使用SendMessage在进程间传递数据的实例

新建解决方案SendMessageExample

在解决方案下面新建三个项目:CopyDataStructReceiverSender

其中,CopyDataStruct项目的输出类型为“类库”,ReceiverSender项目的输出类型为“Windows 应用程序”。

整个实例程序的结构如下图所示。

 

2 CopyDataStruct项目实现

定义结构体COPYDATASTRUCT代码如下所示。 

[csharp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Runtime.InteropServices;  
  3.    
  4. namespace CopyDataStruct  
  5. {  
  6.     public struct COPYDATASTRUCT  
  7.     {  
  8.         public IntPtr dwData;  
  9.         public int cbData;  
  10.         [MarshalAs(UnmanagedType.LPStr)]  
  11.         public string lpData;  
  12.     }  
  13. }  

编译CopyDataStruct项目生成dll,再ReceiverSender项目中添加对此dll的引用。


3 Sender项目实现

Sender项目仅包含一个名称为“消息发送者”的窗体,如下图所示。

 

编写窗体后端代码,如下所示。

[csharp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Runtime.InteropServices;  
  3. using System.Windows.Forms;  
  4. using CopyDataStruct;  
  5.    
  6. namespace Sender  
  7. {  
  8.     public partial class frmSender : Form  
  9.     {  
  10.         //Win32 API函数  
  11.         [DllImport("User32.dll", EntryPoint = "SendMessage")]  
  12.         private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);  
  13.    
  14.         [DllImport("User32.dll", EntryPoint = "FindWindow")]  
  15.         private static extern int FindWindow(string lpClassName, string lpWindowName);  
  16.    
  17.         const int WM_COPYDATA = 0x004A;  
  18.    
  19.         public frmSender()  
  20.         {  
  21.             InitializeComponent();  
  22.         }  
  23.    
  24.         private void btnSend_Click(object sender, EventArgs e)  
  25.         {  
  26.             int hWnd = FindWindow(null, @"消息接受者");  
  27.             if (hWnd == 0)  
  28.             {  
  29.                 MessageBox.Show("555,未找到消息接受者!");  
  30.             }  
  31.             else  
  32.             {  
  33.                 byte[] sarr = System.Text.Encoding.Default.GetBytes(txtString.Text);  
  34.                 int len = sarr.Length;  
  35.                 COPYDATASTRUCT cds;  
  36.                 cds.dwData = (IntPtr)Convert.ToInt16(txtInt.Text);//可以是任意值  
  37.                 cds.cbData = len + 1;//指定lpData内存区域的字节数  
  38.                 cds.lpData = txtString.Text;//发送给目标窗口所在进程的数据  
  39.                 SendMessage(hWnd, WM_COPYDATA, 0, ref cds);  
  40.             }  
  41.         }  
  42.     }  
  43. }  

4  Receiver项目实现

Receiver项目仅包含一个名称为“消息接受者”的窗体,如下图所示。

 

编写窗体的后端代码,如下所示。

[csharp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Windows.Forms;  
  3. using CopyDataStruct;  
  4.    
  5. namespace Receiver  
  6. {  
  7.     public partial class frmReceiver : Form  
  8.     {  
  9.         const int WM_COPYDATA = 0x004A;  
  10.         public frmReceiver()  
  11.         {  
  12.             InitializeComponent();  
  13.         }  
  14.    
  15.         protected override void DefWndProc(ref Message m)  
  16.         {  
  17.             switch (m.Msg)  
  18.             {  
  19.                 case WM_COPYDATA:  
  20.                     COPYDATASTRUCT cds = new COPYDATASTRUCT();  
  21.                     Type t = cds.GetType();  
  22.                     cds = (COPYDATASTRUCT)m.GetLParam(t);  
  23.                     string strResult = cds.dwData.ToString() + ":" +cds.lpData;    
  24.                     lsvMsgList.Items.Add(strResult);  
  25.                     break;  
  26.                 default:  
  27.                     base.DefWndProc(ref m);  
  28.                     break;  
  29.             }  
  30.         }  
  31.     }  
  32. }  

5 运行结果

运行消息发送和消息接收程序(Sender.exe和Receiver.exe),效果如下图所示。

 

 

实例说明

6.1 SendMessage方法参数说明

  • hWnd:接收消息的窗口的句柄
  • Msg:消息标识符
  • wParam:32位的特定附加信息,具体取决于消息
  • lParam:32位特定附加信息,具体取决于消息

6.2 WM_COPYDATA消息说明

使用WM_COPYDATA消息,lParam参数可以指向一个 COPYDATASTRUCT结构体类型的变量

[csharp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. typedef struct COPYDATASTRUCT{  
  2.   ULONG_PTR dwData;  //可以是任意值  
  3.   DWORD cb_data;  //指定lpData内存区域的字节数  
  4.   PVOID lpData;  //发送给目录窗口所在进程的数据  
  5. }COPYDATASTRUCT;  
若定义的结构体不满足上面的定义,在接收端无法正确获取 lParam参数指向的数据。

另外,WM_COPYDATA消息的标识符为0x004A。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值