问题描述
这些天我正在学习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。 如果
lpTimerFunc
为NULL
,则系统将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
指向一个函数而不是窗口过程被调用。