C++ 如何使用PostThreadMessage()(意外结果)

C++ 如何使用PostThreadMessage()(意外结果),c++,multithreading,winapi,C++,Multithreading,Winapi,首先,我是多线程新手。因此,如果有比我的方法更好的方法,我想听听 我正在将代码注入另一个进程。我创建了一个CBT钩子,以便在创建新窗口时得到通知。当我的目标窗口被创建时,我通过CBT钩子得到通知并创建一个线程,最后这个线程调用PostThreadMessage()函数将数据/通知发送给我的另一个线程(也在同一个/目标应用程序中) 但这并不像预期的那样有效。我的接收线程在我第一次发送之前收到了4次该消息。然后在我发送之后,这次它没有收到。 让我们来看看代码 这就是我创建接收方线程的方式 #defi

首先,我是多线程新手。因此,如果有比我的方法更好的方法,我想听听

我正在将代码注入另一个进程。我创建了一个CBT钩子,以便在创建新窗口时得到通知。当我的目标窗口被创建时,我通过CBT钩子得到通知并创建一个线程,最后这个线程调用PostThreadMessage()函数将数据/通知发送给我的另一个线程(也在同一个/目标应用程序中)

但这并不像预期的那样有效。我的接收线程在我第一次发送之前收到了4次该消息。然后在我发送之后,这次它没有收到。 让我们来看看代码

这就是我创建接收方线程的方式

#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