一個進程的線程窗口(window1)如何在不知道另外一個進程的線程窗口(window2)的狀況下接收到window2發送的自定義消息呢?ios
Windows系統除了預約義一些系統的消息外,還爲用戶預留了自定義消息的範圍(WM_USER~0x7FFF)。經過RegisterWindowMessage函數,咱們能夠註冊一個系統惟一的新消息。兩個不一樣的進程註冊了相同的消息字符串,這些應用將會返回相同的消息。直到整個消息會話結束。windows
SendMessage或PostMessage函數能夠向指定的窗口句柄發送窗口消息。若是窗口句柄是HWND_BOARDCAST,就會向系統全部頂層窗口發生該廣播消息。api
廣播消息的代碼:函數
1 #include <iostream> 2 #include <Windows.h> 3 4 int main() 5 { 6 // 註冊窗口消息 7 UINT seewoDesktopProxyMsg = ::RegisterWindowMessageW(L"Seewo_Desktop_Proxy_Message"); 8 9 if (0 == seewoDesktopProxyMsg) 10 { 11 std::cout << "RegisterWindowMessageW fail. error code:" << ::GetLastError(); 12 return 1; 13 } 14 15 // 廣播消息 16 HWND hDesktop = GetDesktopWindow(); 17 std::cout << "desktop window:" << hDesktop << std::endl; 18 ::PostMessageW(HWND_BROADCAST, seewoDesktopProxyMsg, reinterpret_cast<WPARAM>(hDesktop), 0); 19 system("pause"); 20 21 std::cout << "Hello World!\n"; 22 }
接收廣播消息:spa
#include <iostream> #include <thread> #include <Windows.h> UINT seewoDesktopProxyMsg = 0; void ListenRegistryWindowMessage() { WNDCLASSEX wndClass; wndClass.cbSize = sizeof(WNDCLASSEX); wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.hInstance = reinterpret_cast<HINSTANCE>(GetModuleHandle(0)); wndClass.lpfnWndProc = reinterpret_cast<WNDPROC>(DefWindowProc); wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hIcon = NULL; wndClass.hbrBackground = NULL; wndClass.hCursor = LoadCursor(0, IDC_ARROW); std::wstring className(L"SeewoDesktopProxy_recevie"); wndClass.lpszClassName = className.c_str(); wndClass.lpszMenuName = NULL; wndClass.hIconSm = NULL; if (!RegisterClassEx(&wndClass)) { std::cout << "RegisterClassEx err:" << GetLastError() << std::endl; } HWND proxyHwnd = CreateWindowEx(WS_EX_NOACTIVATE, className.c_str(), NULL, WS_POPUP, 0, 0, 0, 0, NULL, NULL, 0, NULL); if (proxyHwnd == NULL) { std::cout << "CreateWindowEx err:" << GetLastError() << std::endl; } std::cout << "create proxy windows success hWnd :" << proxyHwnd << std::endl; MSG msg; while (GetMessage(&msg, nullptr, 0, 0)) { if (msg.message == seewoDesktopProxyMsg) { std::cout << "receive registry window message." << (HWND)(msg.wParam) << std::endl; } TranslateMessage(&msg); DispatchMessage(&msg); } } int main() { // 註冊窗口消息 seewoDesktopProxyMsg = ::RegisterWindowMessageW(L"Seewo_Desktop_Proxy_Message"); if (0 == seewoDesktopProxyMsg) { std::cout << "RegisterWindowMessageW fail. error code:" << ::GetLastError(); return 1; } // 接收消息的窗口 std::thread listen(ListenRegistryWindowMessage); listen.join(); std::cout << "Hello World!\n"; }
運行效果:線程
若是使用Spy++監控窗口消息會更加詳細:code
接收方必須在發送方發送廣播消息窗口消息隊列建立完成,不然建立前的全部廣播消息都沒法正常接收到。blog
參考地址:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerwindowmessagea隊列