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;
若定義的結構體不滿足上面的定義,在接收端無法正確獲取lParam參數指向的數據。
另外,WM_COPYDATA消息的標識符為0x004A。