SendNotifyMessage 不发送正确的消息

Posted

技术标签:

【中文标题】SendNotifyMessage 不发送正确的消息【英文标题】:SendNotifyMessage do not send correct messages 【发布时间】:2017-01-30 12:32:42 【问题描述】:

我从一个线程将消息发送到窗口过程中的主线程。 但它不成功。当我从同一个线程发送消息时 - 一切正常

include "stdafx.h"
#include <Windows.h>
#include <atlbase.h>


#define MAX_THREADS 1

HWND m_wnd;

enum

    EVENT_CALL = (WM_APP + 0x30),
;


static LRESULT CALLBACK function_call()

    //some code
    int test = 0;
    return 0;


static LRESULT CALLBACK http_message_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

        switch (uMsg)
        
        case EVENT_CALL:
            function_call();
            return 0;
        
    return ::DefWindowProc(hWnd, uMsg, wParam, lParam);


void CreateNotifyWnd()

    WNDCLASSEX   w =  0 ;
    w.cbSize = sizeof(w);
    w.hInstance = (HINSTANCE)&__ImageBase;
    w.lpszClassName = L"uistone_http_event_wnd";
    w.lpfnWndProc = http_message_proc;
    ::RegisterClassEx(&w);
    int error = GetLastError();
    m_wnd = ::CreateWindowEx(0, w.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, w.hInstance, 0);
    error = GetLastError();



DWORD WINAPI SendThread(void* request_param)

    ::SendNotifyMessage(m_wnd, EVENT_CALL, 11, 12);
    int error = GetLastError();
    return 0;



int main()

    CreateNotifyWnd();
    HANDLE  hThreadArray[MAX_THREADS];

    hThreadArray[0] = CreateThread(nullptr, 0, SendThread, nullptr, 0, nullptr);
    //::SendNotifyMessage(m_wnd, EVENT_CALL, 11, 12);

    WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);

    return 0;

为什么我不能从另一个线程捕获消息? 谢谢。

【问题讨论】:

你好像没有消息循环...en.wikipedia.org/wiki/Message_loop_in_Microsoft_Windows 1) 您的消息循环在哪里? 2)你如何验证你的代码捕捉到或没有捕捉到消息? http_message_proc 是程序中循环的函数 我想在我的线程完成后有一个信号。 我通过 MSVS2015 http_message_proc 中的断点检查它 - 消息循环 【参考方案1】:

这是记录在案的行为。这是SendNotifyMessage 文档中的相关部分:

如果窗口是由调用线程创建的,SendNotifyMessage 会为该窗口调用窗口过程并且在窗口过程处理完消息之前不会返回。 如果窗口是由不同的线程创建的,SendNotifyMessage 将消息传递给窗口过程并立即返回;它不会等待窗口过程完成对消息的处理。

当与在同一线程上创建的窗口一起使用时,这似乎可以工作,因为当您调用SendNotifyMessage 时,该函数会在返回之前同步调用与目标窗口关联的窗口过程。

另一方面,如果调用跨线程,则您必须运行一个消息循环以使 - 现在已排队 - 消息被拾取并传递给窗口过程1)。您的应用程序不会运行消息循环,它会在消息到达目标窗口之前退出。

要解决此问题,您必须运行消息循环。这可能是也可能不是解决您的问题的正确方法。由于我们不知道您要解决什么问题,因此我们无法建议潜在的更好的方法和解决方案。


1)见About Messages and Message Queues: Message Routing。

【讨论】:

我为CreateNotifyWnd中的窗口创建了消息循环 @MartinJuin:不在您发布的代码中。您注册了window procedure,但没有循环耗尽消息队列或分派消息。 好的,我明白了 - 这是我的错误 - 没有循环。但是我是否必须编写这个循环以及如何编写? @MartinJuin:如果您想问其他问题,请单击本页顶部的 链接。 @MartinJuin 在您的示例中,创建窗口并启动线程后,您需要在main() 中进行消息循环。你可以使用MsgWaitForMultipleObjects()同时等待线程和消息队列,它会告诉你哪个满足等待。如果它是一条消息,则检索它并发送它,以便窗口可以处理它。

以上是关于SendNotifyMessage 不发送正确的消息的主要内容,如果未能解决你的问题,请参考以下文章

用SendNotifyMessage代替PostMessage避免消息丢失(WIN7下消息队列的默认长度是10000,队列满后消息将被丢弃)

读取从 c++ 发送到 C# 的 lParam 作为字符串

RabbitMQ之发布订阅

当我多次进入聊天室时,让服务器不给我发送相同的消息?

在Python中使用select()方法进行客户端/服务器聊天

51单片机数据管的消影问题