There are several problems with your code:
-
ProcessThread()
is declared all wrong forCreateThread()
, and the compiler would normally scream at you for that, but you are using an erroneous type-cast to quiet the compiler instead of fixing the error. As such,ProcessThread()
will not be able to receive thevector
correctly at runtime. TheProcessThread()
would need to look more like this instead:DWORD WINAPI ProcessThread(LPVOID lpParam) { std::vector<HWND> *Windows = static_cast<std::vector<HWND>*>(lpParam); ... return 0; } ... HANDLE hThread = CreateThread(..., &ProcessThread, &Windows, ...);
-
your thread’s message loop is all wrong. Call
GetMessage()
ONCE per loop iteration, and do not specify any filteringHWND
at all (see The dangers of filtering window messages). It will pull the next available message from the message queue, which you can then pass toDispatchMessage()
to send the message along to the appropriateWndProc
for further processing.DWORD WINAPI ProcessThread(LPVOID lpParam) { std::vector<HWND> *Windows = static_cast<std::vector<HWND>*>(lpParam); MSG Msg; while (GetMessageW(&Msg, 0, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessageW(&Msg); } return 0; }
-
You are creating a worker thread just to wait for it to terminate, without doing anything else in parallel. That makes the worker thread completely useless. You need to get rid of that thread, especially given that…
-
… you are running your message loop in a separate thread than the one that creates the windows. You can’t do that at all! A window has thread affinity.
(Get|Peek)Message()
receives messages only for windows associated with the calling thread, so only the thread that creates a window can receive messages for that window.
You are over-thinking your code design. You can greatly simplify it to this:
std::vector<HWND> Windows = { lpScreen.m_WindowHandle, lpPopup.m_WindowHandle };
MSG Msg;
while (GetMessageW(&Msg, 0, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
If lpScreen.m_WindowHandle
and lpPopup.m_WindowHandle
are the only windows available in the calling thread, then you don’t even need the vector
at all!
However, if you are interested in processing messages only for specific windows, this does present an issue. The code above will receive messages for ALL windows in the calling thread. If that is not what you want, then you COULD (but shouldn’t!) filter for specific windows in the vector
, eg:
std::vector<HWND> Windows = { lpScreen.m_WindowHandle, lpPopup.m_WindowHandle };
MSG Msg;
for(auto h : Windows)
{
while (PeekMessageW(&Msg, h, 0, 0, PM_REMOVE))
{
TranslateMessage(&Msg);
DispatchMessageW(&Msg);
}
}
But that can lead to message starvation for other windows, if you are not careful.
Otherwise, you would just have to use a separate thread to CREATE AND PROCESS just the windows you are interested in.
solved How to handle messages from multiple windows