完成进程间通信最简单的方式就是发送WM_COPYDATA消息。

(1)发送WM_COPYDATA消息



SendMessage(接收窗口句柄, WM_COPYDATA, (WPARAM)发送窗口句柄, (LPARAM)&copyData);



其中的copyData是要发送的数据,类型为COPYDATASTRUCT结构体:



typedef struct tagCOPYDATASTRUCT

{

DWORD dwData;

DWORD cbData;

PVOID lpData;

} COPYDATASTRUCT;


dwData : Specifies up to 32 bits of data to be passed to the receiving application.

cbData : Specifies the size, in bytes, of the data pointed to by the lpData member.

lpData : Long pointer to data to be passed to the receiving application. This member can be NULL.



该消息只能由SendMessage()发送,而不能使用PostMessage()。因为系统必须管理用以传递数据的缓冲区的生命期,如果使用了PostMessage(),数据缓冲区会在接收方(线程)有机会处理该数据之前,就被系统清除和回收。

如果传入的接收窗口句柄无效或者当接收方进程意外终止时,SendMessage()会立即返回,发送方不会陷入一个无穷等待的状态中。

此外还需注意:

The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data.(所发送的数据不能包含数据接收方无法访问的指针或对象引用)

While this message is being sent, the referenced data must not be changed by another thread of the sending process.(消息发送后,要保证lpData所引用数据不能被其它线程修改(直到SendMessage函数返回))

示例代码片段(MFC):

通过WM_COPYDATA消息完成进程间通信(转载)_示例代码

HWND receiveWindow = ::FindWindow(NULL, "CopyDataReceiver");   if (receiveWindow == NULL)       return;   CString sendData; GetDlgItemText(IDC_EDIT_SEND, sendData);  COPYDATASTRUCT copyData = { 0 }; copyData.lpData = sendData.GetBuffer(); copyData.cbData = sendData.GetLength();  ::SendMessage(receiveWindow, WM_COPYDATA, (WPARAM)GetSafeHwnd(), (LPARAM)&copyData);  sendData.ReleaseBuffer();

通过WM_COPYDATA消息完成进程间通信(转载)_示例代码

(2)接收WM_COPYDATA消息:



WM_COPYDATA

wParam = (WPARAM)(HWND) hwnd;

lParam = (LPARAM)(PCOPYDATASTRUCT) pcds;


hwnd: Handle to the window passing the data. (数据发送方的句柄,接收方可以通过此句柄向发送方反馈数据)

pcds: Pointer to a COPYDATASTRUCT structure that contains the data to be passed.


Return Values

If the receiving application processes this message, it should return TRUE; otherwise, it should return FALSE.



lParam包含了接收到的数据,在处理之前需要将类型换为COPYDATASTRUCT结构体。接收方应认为这些数据是只读的,并且只在处理该消息的过程中有效。如果想修改这些数据,应该把它们复制到本地buffer。(The receiving application should consider the data read-only. The pcds parameter is valid only during the processing of the message. The receiving application should not free the memory referenced by pcds. If the receiving application must access the data after SendMessage returns, it must copy the data into a local buffer. )

由于发送方在接收方处理WM_COPYDATA消息完毕前都是处于等待(SendMessage阻塞)中,所以接收方应当尽快处理WM_COPYDATA消息。

示例代码片段(MFC):

通过WM_COPYDATA消息完成进程间通信(转载)_示例代码

BOOL CCopyDataReceiverDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) {     if (pCopyDataStruct->cbData > 0)     {         char recvData[256] = {0} ;         strncpy(recvData, (char *)pCopyDataStruct->lpData, pCopyDataStruct->cbData);         SetDlgItemText(IDC_EDIT_RECEIVE, (char *)recvData);          Feedback(pWnd);     }          return CDialog::OnCopyData(pWnd, pCopyDataStruct); }

通过WM_COPYDATA消息完成进程间通信(转载)_示例代码

通过WM_COPYDATA消息完成进程间通信(转载)_sed_05

参考资料:

[1] msdn