windows编程用WM

xiaoxiao2021-03-01  13

现在有个需求需要在两进程间大量传递数据,而在windows程序下两个进程间进行通信 可以有多个方法:

1、管道(未命名管道、命名管道)

2、共享内存

3、消息队列

不过上述实现起来比较麻烦,现在我们来讲解如何使用sendMessage来传输大量数据。

LRESULT SendMessage( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );

sendmessage如上所述,可以知道其中wParam 以及lParam两个参数可以传递少量数据,要用来传递大量数据,我们只需要把Msg变量指定为WM_COPYDATA就可以了。

其中WM_COPYDATA传递的是一个结构体数据为:

typedef struct tagCOPYDATASTRUCT { ULONG_PTR dwData;//一个整数,可以用来充当标识 DWORD cbData;//lpData大小 PVOID lpData;//要传输的数据 } COPYDATASTRUCT, *PCOPYDATASTRUCT;

为了我们可以在接收端容易处理传递的大量数据。我们可以传输一个规范化的结构体,然后再赋值给lpData成员变量。

例如我们可以定义一个一般的结构体数据(主要要规划好结构体的成员变量):

typedef struct __MessageContent { DWORD dwAttribute; BOOL bDisplay; BOOL bTrim; TCHAR lpszText[MAX_PATH]; TCHAR lpszDescribe[MAX_PATH]; TCHAR lpszUrl[MAX_PATH]; TCHAR lpszImage[MAX_PATH]; } MessageContent;

信息接收方一般要先于信息发送方存在,否则信息发送方无法找到需要发送数据的对象。

信息接收方代码 示例:

/* 信息接收方,并处理数据 */ #include<windows.h> #include<tchar.h> LPCTSTR g_szWindowClassName = __TEXT("ExampleDemo"); LPCTSTR g_szWindowClassTitle = __TEXT("Hello"); typedef struct __MessageContent { DWORD dwAttribute; BOOL bDisplay; BOOL bTrim; TCHAR lpszText[MAX_PATH]; TCHAR lpszDescribe[MAX_PATH]; TCHAR lpszUrl[MAX_PATH]; TCHAR lpszImage[MAX_PATH]; } MessageContent; MessageContent* g_mcMessageContent = NULL; LRESULT CALLBACK HiddenWindowProcess(__in HWND hwnd, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam); /** * @brief 应用程序主函数 * @param hInstance 模块 * @param cmdLineArgs 命令行参数 */ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLineArgs, _In_ int) { WNDCLASS wcWindowClass = { 0 }; wcWindowClass.style = CS_HREDRAW | CS_VREDRAW; wcWindowClass.lpfnWndProc = HiddenWindowProcess; wcWindowClass.cbClsExtra = 0; wcWindowClass.cbWndExtra = 0; wcWindowClass.hInstance = hInstance; wcWindowClass.hIcon = NULL; wcWindowClass.hCursor = ::LoadCursor(NULL, IDC_ARROW); wcWindowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcWindowClass.lpszMenuName = NULL; wcWindowClass.lpszClassName = g_szWindowClassName; if (::RegisterClass(&wcWindowClass) == 0) return -1; ::CreateWindow(g_szWindowClassName, g_szWindowClassTitle, WS_OVERLAPPED, 0, 0, 1, 1, NULL, NULL, hInstance, NULL); MSG msg = { 0 }; while (::GetMessage(&msg, NULL, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } return -1; } /** * @brief 处理通知窗口消息 * @param uMsg包含发送的消息 */ LRESULT CALLBACK HiddenWindowProcess(__in HWND hwnd, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam) { switch (uMsg) { case WM_COPYDATA: { COPYDATASTRUCT * cdsMessageDataStruct = (COPYDATASTRUCT*)lParam; if (!cdsMessageDataStruct || sizeof(cdsMessageDataStruct) == 0) return E_FAIL; g_mcMessageContent = (MessageContent *)cdsMessageDataStruct->lpData; MessageBox(NULL, sizeof(*g_mcMessageContent) > 0 ? L"TRUE":L"FALSE",L"Title",MB_OK); // //现在可以处理传过来的数据或者调用写好的函数进行处理。 } break; default: return ::DefWindowProc(hwnd, uMsg, wParam, lParam); } return S_OK; }

信息发送方代码示例:

/* 信息发送方 */ #include<windows.h> #include<tchar.h> typedef struct __MessageContent { DWORD dwAttribute; BOOL bDisplay; BOOL bTrim; TCHAR lpszText[MAX_PATH]; TCHAR lpszDescribe[MAX_PATH]; TCHAR lpszUrl[MAX_PATH]; TCHAR lpszImage[MAX_PATH]; } MessageContent; int WINAPI wWinMain(_In_ HINSTANCE hInstance , _In_opt_ HINSTANCE , _In_ LPWSTR cmdLineArgs , _In_ int) { //测试用例,可以从服务端获取 DWORD dwAttribute = 10; BOOL isDisplay =FALSE; BOOL isTrim = FALSE; LPCTSTR lpszText = _T("热点"); LPCTSTR lpszDescribe = _T("实时新闻"); LPCTSTR lpszUrl = _T("http://www.baidu.com"); LPCTSTR lpszImage = _T("http://www.nipic.com/topic/show_27085_1.html"); MessageContent messageContent = { 0 }; messageContent.dwAttribute = 10; messageContent.bDisplay = isDisplay; messageContent.bTrim = isTrim; _tcscpy_s(messageContent.lpszText,MAX_PATH,lpszText); _tcscpy_s(messageContent.lpszDescribe,MAX_PATH,lpszDescribe); _tcscpy_s(messageContent.lpszUrl,MAX_PATH,lpszUrl); _tcscpy_s(messageContent.lpszImage,MAX_PATH,lpszImage); COPYDATASTRUCT toastContentMessage = { 0 }; toastContentMessage.lpData = (PVOID)&messageContent; toastContentMessage.cbData = sizeof(messageContent); //需要确定对方(信息接收方)的窗口名称与标题 HWND hToastWin = ::FindWindow(__TEXT("ExampleDemo") , __TEXT("Hello")); if (hToastWin == NULL) { return false; } ::SendMessage(hToastWin , WM_COPYDATA , 0 , (LPARAM)&toastContentMessage); return 0; }

使用结构体不仅扩大了传送数据的量,而且还解决了传输数据处理的问题,规范化了传输数据的格式。

转载请注明原文地址: https://www.6miu.com/read-3450230.html

最新回复(0)