C++ 如何使用PostThreadMessage()(意外结果)
首先,我是多线程新手。因此,如果有比我的方法更好的方法,我想听听 我正在将代码注入另一个进程。我创建了一个CBT钩子,以便在创建新窗口时得到通知。当我的目标窗口被创建时,我通过CBT钩子得到通知并创建一个线程,最后这个线程调用PostThreadMessage()函数将数据/通知发送给我的另一个线程(也在同一个/目标应用程序中) 但这并不像预期的那样有效。我的接收线程在我第一次发送之前收到了4次该消息。然后在我发送之后,这次它没有收到。 让我们来看看代码 这就是我创建接收方线程的方式C++ 如何使用PostThreadMessage()(意外结果),c++,multithreading,winapi,C++,Multithreading,Winapi,首先,我是多线程新手。因此,如果有比我的方法更好的方法,我想听听 我正在将代码注入另一个进程。我创建了一个CBT钩子,以便在创建新窗口时得到通知。当我的目标窗口被创建时,我通过CBT钩子得到通知并创建一个线程,最后这个线程调用PostThreadMessage()函数将数据/通知发送给我的另一个线程(也在同一个/目标应用程序中) 但这并不像预期的那样有效。我的接收线程在我第一次发送之前收到了4次该消息。然后在我发送之后,这次它没有收到。 让我们来看看代码 这就是我创建接收方线程的方式 #defi
#define MM_MY_MESSAGE (WM_APP)
// Also tried with different macros
// #define MM_MY_MESSAGE (WM_APP + 999)
// #define MM_MY_MESSAGE (WM_USER)
// #define MM_MY_MESSAGE (WM_USER + 999)
gReceiverThreadHandle = CreateThread(NULL, 0, ThreadReceiver, NULL, 0, &gReceiverThreadId);
// global variables
这是我的接收器线程,它也使用WM_COPYDATA消息
DWORD WINAPI ThreadReceiver(LPVOID lpParam) {
MSG msg;
HWND hwndReceiver = CreateReceiverWindow();
// If necessary I can post this function later
// This window is created for WM_COPYDATA messages
// Not important for PostThreadMessage()
if (!hwndReceiver) {
std::cout << "Receiver window can not be created!" << std::endl;
return 0;
}
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
这显然不是我想要的。这里出了什么问题?
PostThreadMessage()
将消息发布到线程,而不是窗口。您可以直接在GetMessage()
循环中处理线程消息,而不是在窗口过程中。但是,在UI为的线程上使用PostThreadMessage()
有一些微妙之处。解决方案很简单:使用PostMessage()
将消息发布到您的窗口PostMessage()
将自动将消息发送到正确的线程。如何使用PostThreadMessage?不要这样做。输出很容易解释,因为您要在之后才能输出。发送方线程在完成(甚至开始)调用cout
之前进入睡眠状态。重复的信息更难解释。“不清楚你是否遵循了所有概述的指导原则,特别是在备注部分,”帕迪·MSDN说;它在不等待线程处理消息的情况下返回。是的,但这意味着它在另一个线程收到消息之前不会阻塞。i、 e.您不能保证通过消息传递的任何堆栈数据在接收端有效。在执行cout
调用之前,它不会停止操作系统暂停线程和/或以任何其他方式服务接收线程。PostThreadMessage()
将消息发布到线程,而不是窗口。您可以直接在GetMessage()
循环中处理线程消息,而不是在窗口过程中。但是,在UI为的线程上使用PostThreadMessage()
有一些微妙之处。解决方案很简单:使用PostMessage()
将消息发布到您的窗口PostMessage()
将自动将消息发送到正确的线程。如何使用PostThreadMessage?不要这样做。输出很容易解释,因为您要在之后才能输出。发送方线程在完成(甚至开始)调用cout
之前进入睡眠状态。重复的信息更难解释。“不清楚你是否遵循了所有概述的指导原则,特别是在备注部分,”帕迪·MSDN说;它在不等待线程处理消息的情况下返回。是的,但这意味着它在另一个线程收到消息之前不会阻塞。i、 e.您不能保证通过消息传递的任何堆栈数据在接收端有效。在执行cout
调用之前,它不会停止操作系统暂停线程和/或以任何其他方式为接收线程提供服务。
LRESULT CALLBACK ReceiverWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch(message) {
case WM_COPYDATA:
// do something
break;
case MM_MY_MESSAGE:
std::cout << "PostThreadMessage received" << std::endl;
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
DWORD WINAPI AnotherThread(LPVOID lpParam) {
// This thread gets created inside CBT hook which is unrelated
// etc.
PostThreadMessage(gReceiverThreadId, MM_MY_MESSAGE, NULL, NULL);
std::cout << "PostThreadMessage send" << std::endl;
// etc
return 0;
}
PostThreadMessage received
PostThreadMessage received
PostThreadMessage received
PostThreadMessage received
PostThreadMessage send