开发中有时需要进程间传递数据,比如对于只允许单实例运行的程序,当已有实例运行时,再次打开程序,可能需要向当前运行的实例传递信息进行特殊处理。对于传递少量数据的情况,最简单的就是用SendMessage发送WM_COPYDATA消息,所带参数wParam和lParam可以携带相关数据。由于SendMessage是阻塞的,在接收数据进程处理完数据之前不会返回,发送方不会删除或修改数据,因此这种方法是简单且安全的,不过数据量不能太大,否则会由于处理时间过长造成阻塞假死。
用SendMessage发送WM_COPYDATA的方法如下:
lResult = SendMessage((HWND) hWndControl,
(UINT) WM_COPYDATA, // message ID
(WPARAM) wParam, // = (WPARAM) () wParam;
(LPARAM) lParam // = (LPARAM) () lParam;
);
其中,hWndControl为接收数据方的窗口句柄,wParam为发送数据方的窗口句柄,lParam为指向一个COPYDATASTRUCT类型结构体的指针
在用MFC AppWizard(exe)创建接收数据的对话框程序后,生成对话框类CDataRecvDlg。在这个类中,首先要定义接收WM_COPYDATA消息的映射,可以用ClassWizard工具来增加,也可以手动增加,但手动增加需要修改三个地方:①在消息映射表中增加ON_WM_COPYDATA();②增加成员函数BOOL CDataRecvDlg::OnCopyData();③在CDataRecvDlg类中增加WM_COPYDATA消息映射函数的定义。
消息作用: 在进程间共享数据(内部通过创建内存映射文件) 消息介绍: 需要用到的数据结构/类型: typedef struct tagCOPYDATASTRUCT { ULONG_PTR dwData; DWORD cbData; PVOID lpData; } COPYDATASTRUCT, *PCOPYDATASTRUCT; 结构体参数说明: dwData(ULONG) 保存一个数值, 可以用来作标志等 lpData(void*) 待发送的数据的起始地址(可以为NULL) cbData(DWORD) 待发送的数据的长度 消息的参数: hWnd: 接收数据的窗口的句柄 wParam: 传送该数据的窗口句柄(NULL也无所谓) lParam: COPYDATASTRUCT类型变量的地址 使用示例: COPYDATASTRUCT cds; char msg[] = "女孩不哭"; cds.dwData = 0; cds.lpData = msg; cds.cbData = strlen(msg)+1; //字符串请记得把' '加上, 不然就错了, 这里是ANSI字符串 SendMessage(FindWindow("nbsg_class", NULL), WM_COPYDATA, 0, (LPARAM)&cds); 接收端对该消息的一种可能处理: case WM_COPYDATA: { //这里的消息应该是以 ' ' 结尾的字符串 COPYDATASTRUCT* pCDS = (COPYDATASTRUCT*)lParam; MessageBox(hWnd, pCDS->lpData, "", MB_OK); return TRUE; } 说明: 发送的数据可以是任意的, 我上面只是为了用MessageBox做测试, 所以发送的是以'