原文地址:http://blog.csdn.net/morewindows/article/details/6804157
进程间通信最简单的方式就是发送WM_COPYDATA消息。本文提供C++及C#程序相互通信的二种实现方式。这样消息的接收端可以用C++实现,发送端可以用C++或C#实现。
发送WM_COPYDATA消息:
SendMessage(接收窗口句柄, WM_COPYDATA, (WPARAM)发送窗口句柄, (LPARAM)&CopyData);
其中的CopyData为COPYDATASTRUCT结构类型,该结构定义如下:
typedef struct tagCOPYDATASTRUCT {
DWORD dwData; // Specifies data to be passed to the receiving application.
DWORD cbData; //Specifies the size, in bytes, of the data pointed to by the lpData member.
PVOID lpData; // Pointer to data to be passed to the receiving application. can be NULL.
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
注 意:该消息只能由SendMessage()来发送,而不能使用PostMessage()。因为系统必须管理用以传递数据的缓冲区的生命期,如果使用了 PostMessage(),数据缓冲区会在接收方(线程)有机会处理该数据之前,就被系统清除和回收。此外如果lpData指向一个带有指针或某一拥有 虚函数的对象时,也要小心处理。
如果传入的句柄不是一个有效的窗口或当接收方进程意外终止时,SendMessage()会立即返回,因此发送方在这种情况下不会陷入一个无穷的等待状态中。
返回值问题,MSDN上说如果接收方处理了,返回TRUE,否则返回FALSE,但是本人在实验时,都是返回0(接收方已经处理)。
接收WM_COPYDATA消息:
只要用COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam;就可以了。接收方应认为这些数据是只读的。
由于发送方在接收方处理WM_COPYDATA消息完毕前都是处于等待中,所以接收方应当尽快处理WM_COPYDATA消息。
以一个简单的例子来说明如何使用WM_COPYDATA消息,有二个程序,一个用来发送表示当前时间信息的字符串,另一个接收数据后显示到编辑框中。例子中有几点要注意:
1.如何得到当前控制台窗口句柄?VS2008下可以直接使用HWND GetConsoleWindow(void);函数。
2.使用char *ctime(const time_t *timer);将一个time_t类型转化成一个字符串时,函数会在字符串末尾加下' ',因为发送前要将这个' '去掉。
发送消息的程序代码(VS2008下编译通过):
#include <windows.h> #include <time.h> #include <conio.h> #include <stdio.h> int main() { const char szDlgTitle[] = "RecvMessage"; HWND hSendWindow = GetConsoleWindow (); if (hSendWindow == NULL) return -1; HWND hRecvWindow = FindWindow(NULL, szDlgTitle); if (hRecvWindow == NULL) return -1; char szSendBuf[100]; time_t timenow; COPYDATASTRUCT CopyData; for (int i = 0; i < 10; i++) { time(&timenow); sprintf(szSendBuf, "%s", ctime(&timenow));//注意,ctime()返回的字符串后面带了' ' CopyData.dwData = i; CopyData.cbData = strlen(szSendBuf); szSendBuf[CopyData.cbData - 1] = '