How could I pass the id of a std::thread
thread as the id into PostThreadMessage
?
Like suppose, I have a thread:
// Worker Thread
auto thread_func = [](){
while(true) {
MSG msg;
if(GetMessage(&msg, NULL, 0, 0)) {
// Do appropriate stuff depending on the message
}
}
};
std::thread thread_not_main = std::thread(thread_func);
And then I want to send a message from my main thread to the above thread so that I can handle the message in a non-expensive way. So as to not interrupt the main thread.
Like:
// Main Thread
while(true) {
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
if(msg.message == WM_PAINT) {
PostThreadMessage(); // How do I pass the thread id into the function?
} else {
DispatchMessage(&msg);
}
}
}
The summary of the problem is that
PostThreadMessage
requires a thread-id to be passed in as a parameter,
now std::thread::get_id
doesn't provide it in a "DWORD
convertible format". So then I can't pass the thread's id as a parameter.
My question is: How would I pass the thread id as a parameter to PostThreadMessage
?
CodePudding user response:
You can get the underlying, "Windows-style" thread handle for a std::thread
object by calling its native_handle()
member function. From that, you can retrieve the thread's ID by calling the GetThreadId
WinAPI function, and passing that native handle as its argument.
Here's a short code snippet that may be what you'd want in the case you've outlined:
auto tHandle = thread_not_main.native_handle(); // Gets a "HANDLE"
auto tID = GetThreadId(tHandle); // Gets a DWORD ID
if (msg.message == WM_PAINT) {
PostThreadMessage(tID, msg, wParam, lParam);
}
else {
DispatchMessage(&msg);
}
//...
CodePudding user response:
std::thread
does not expose the Win32 Thread ID that PostThreadMessage()
wants.
The best way to handle this issue is to call GetCurrentThreadId()
inside of your thread function itself, saving the result to a variable that you can then use with PostThreadMessage()
when needed.
For example:
struct threadInfo
{
DWORD id;
std::condition_variable hasId;
};
auto thread_func = [](threadInfo &info){
info.id = GetCurrentThreadId();
info.hasId.notify_one();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
// Do appropriate stuff depending on the message
}
};
...
threadInfo info;
std::thread thread_not_main(thread_func, std::ref(info));
info.hasId.wait();
...
PostThreadMessage(info.id, ...);
CodePudding user response:
Solution:
You can use the native_handle()
member function to get the underlying platform-specific handle of the thread, and then pass that to PostThreadMessage()
:
std::thread thread_not_main = std::thread(thread_func);
...
PostThreadMessage(thread_not_main.native_handle(), WM_PAINT, 0, 0);