[Windows进程间通信]拷贝数据 WM_COPYDATA
使用WM_COPYDATA进行进程间通信必须依赖Windows的消息机制,不过此方法可以传输大量数据,而且实现简单。
以下示例修改自Windows官方文档。
首先创建2个Windows桌面程序,为了示例的简单,将字符类型修改为多字节(默认为unicode)。
发送端:
#define MYDISPLAY 1 typedef struct tagMyRec { char s1[64]; char s2[64]; DWORD n; } MYREC; VOID CopyData(HWND hWnd) { COPYDATASTRUCT myCDS = {0}; MYREC myRec = {0}; // Put data into data structure auto hResult = StringCbCopy(myRec.s1, sizeof(myRec.s1), "Claude"); if (hResult != S_OK) { return ; } hResult = StringCbCopy(myRec.s2, sizeof(myRec.s2), "Bell"); if (hResult != S_OK) { return ; } myRec.n = 99; // Fill COPYDATA structure myCDS.dwData = MYDISPLAY; myCDS.cbData = sizeof(myRec); myCDS.lpData = &myRec; auto hwDispatch = FindWindow("RECEIVER", "r"); if (hwDispatch != NULL) { SendMessage(hwDispatch, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)(LPVOID)&myCDS); } else { MessageBox(hWnd, "Can't send WM_COPYDATA", "MyApp", MB_OK); } } //////////////////////// LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: //DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); CopyData(hWnd);
出于示例的简化目的,直接使用IDM_ABOUT触发拷贝数据消息.
接收端:
#define MYDISPLAY 1 typedef struct tagMyRec { char s1[64]; char s2[64]; DWORD n; } MYREC; VOID HandleCopyData(HWND hWnd, WPARAM wparam, LPARAM lparam) { auto pCDS = (PCOPYDATASTRUCT)lparam; switch (pCDS->dwData) { case MYDISPLAY: { auto myRec = (MYREC*)pCDS->lpData; MessageBox(hWnd, myRec->s1, myRec->s2, MB_OK); break; } } } /////////////////////////////// LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COPYDATA: HandleCopyData(hWnd, wParam, lParam); break;
接收端只要在消息处理函数中直接收一下数据就行了。