PostMessage时dispatchmessage函数未执行WM_TIMER消息

问题描述

这些天我正在学习win32 并使用PostMessage函数。

我发现的奇怪之处是,将WM_TIMER消息发布到窗口消息队列中时,窗口没有收到任何消息。 如果仅当我将lparam设置为0时接收,否则根本不起作用 这里的代码。 而且我用sendmessage进行了测试,无论哪种方式都很好。
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
    switch (msg)
    {
        case WM_CREATE:
        {
            //PostMessage(hWnd,WM_TIMER,0); // receive msg
            PostMessage(hWnd,1); // not receiving
        }
        return 0;
        case WM_TIMER:
        {
            switch (wparam)
            {
                case 0:
                {
                    HDC dc = GetDC(hWnd);

                    Ellipse(dc,70,120,120);
                    ReleaseDC(hWnd,dc);
                }
                break;
            }
            return 0;
        }
    }
    return DefWindowProc(hWnd,msg,wparam,lparam);
}

如果有人解释为什么会发生,这将是惊人的。 只是希望我缺少Windows处理系统的一些基本概念。

解决方法

根据WM_TIMER文档:

lParam [输入]

一个指向应用程序定义的回调函数的指针,该指针在安装计时器时传递给SetTimer函数。

因此,当您使用PostMessage(hWnd,WM_TIMER,0)时,会将0(作为空指针)传递给lParam

根据SetTimer文档:

当超时值过去时,指向要通知的功能的指针。有关该函数的更多信息,请参见TimerProc。 如果lpTimerFuncNULL,则系统将WM_TIMER消息发布到应用程序队列。消息的hwnd结构的MSG成员包含该值hWnd参数。

这意味着当DispatchMessage()看到WM_TIMER设置为0的lParam消息时,它将简单地按原样将消息传递到{所指定的窗口的窗口消息过程中{1}}。

但是,当您改用hWnd时,您将传递1作为PostMessage(hWnd,1);,因此它被视为指向计时器回调函数的指针。这意味着当lParam看到DispatchMessage()设置为非零的WM_TIMER消息时,它不会将消息传递到lParam的窗口消息过程中,而是尝试实际调用hWnd指向的函数,在这种情况下,这显然是非法的。系统无法通过此无效的指针调用函数。

根据DispatchMessage()文档:

lParam结构必须包含有效的消息值。如果MSG参数指向一条lpmsg消息,而WM_TIMER消息的lParam参数不是WM_TIMER,则NULL指向一个函数而不是窗口过程被调用。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...