进程通信之一使用WM_COPYDATA
2012-02-14 01:51
417 查看
/article/6980900.html
进程间通信最简单的方式就是发送WM_COPYDATA消息。
发送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类型转化成一个字符串时,函数会在字符串末尾加下'\n',因为发送前要将这个'\n'去掉。
发送消息的程序代码(VS2008下编译通过):
接收消息程序代码(VC6.0下编译通过):
程序中的IDC_EDIT_RECVMESSAGE为编辑框的ID。
运行结果如下:
/article/6980900.html
进程间通信最简单的方式就是发送WM_COPYDATA消息。
发送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类型转化成一个字符串时,函数会在字符串末尾加下'\n',因为发送前要将这个'\n'去掉。
发送消息的程序代码(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()返回的字符串后面带了'\n' CopyData.dwData = i; CopyData.cbData = strlen(szSendBuf); szSendBuf[CopyData.cbData - 1] = '\0'; CopyData.lpData = szSendBuf; SendMessage(hRecvWindow, WM_COPYDATA, (WPARAM)hSendWindow, (LPARAM)&CopyData); printf("%s\n", szSendBuf); Sleep(1000); } return 0; }
接收消息程序代码(VC6.0下编译通过):
程序中的IDC_EDIT_RECVMESSAGE为编辑框的ID。
#include "stdafx.h" #include "resource.h" #include <stdio.h> BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc); return 0; } BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { const char szDlgTitle[] = "RecvMessage"; static HWND s_hEditShowRecv; switch (message) { case WM_INITDIALOG: SetWindowText(hDlg, szDlgTitle); s_hEditShowRecv = GetDlgItem(hDlg, IDC_EDIT_RECVMESSAGE); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; case WM_COPYDATA: { COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam; char szBuffer[300]; memset(szBuffer, 0, sizeof(szBuffer)); sprintf(szBuffer, "dwData:%d cbData:%d\r\nlpData:0x%08x = %s\r\n\r\n", pCopyData->dwData, pCopyData->cbData, (PVOID)pCopyData->lpData, (char*)pCopyData->lpData); //在编辑框中追加数据 SendMessage(s_hEditShowRecv, EM_SETSEL, (WPARAM)-1, (LPARAM)-1); // (0, -1)表示全选, (-1,任意)表示全不选 SendMessage(s_hEditShowRecv, EM_REPLACESEL, FALSE, (LPARAM)szBuffer); SendMessage(s_hEditShowRecv, EM_SCROLLCARET, 0, 0); } return TRUE; } return FALSE; }
运行结果如下:
/article/6980900.html
相关文章推荐
- 进程通信之一使用WM_COPYDATA
- 进程通信之一 使用WM_COPYDATA C++及C#实现
- 用WM_COPYDATA实现进程通信
- WM_COPYDATA实现进程间数据通信
- [转载]用WM_COPYDATA实现进程通信
- 进程通信——使用WM_COPYDATA消息通信
- 发送WM_COPYDATA消息实现进程间的通信
- 进程通信之一 使用WM_COPYDATA C++及C#实现
- 进程通信之一 使用WM_COPYDATA C++及C#实现
- 进程通信——使用WM_COPYDATA消息通信
- 用WM_COPYDATA实现进程通信
- 使用 WM_COPYDATA 在进程间共享数据
- 使用 WM_COPYDATA 在进程间共享数据
- 进程间通信 2 -- 使用WM_COPYDATA消息进行通信
- 用WM_COPYDATA实现进程通信
- 转载资料-使用 WM_COPYDATA 在进程间共享数据(见关联的文章)
- 跨进程通信之WM_COPYDATA
- 进程通信——使用WM_COPYDATA消息通信
- 进程通信之一 使用WM_COPYDATA C++及C#实现 z
- 进程通信 WM_COPYDATA与HWND_BROADCAST