更新: @JonathanPotter在评论中解决了我的问题(见下文)。显然我应该在
DefWindowProc
上致电WndProc
。如果我将其称为虚拟printf
,那么一切正常。但是我会保持这个问题的开放,因为我仍然很想知道为什么printf
本身也让它起作用。
我正在编写一个程序,可以在打开/关闭笔记本电脑盖时执行某些操作。有一个不可见的窗口,可以监视WM_POWERBROADCAST
个消息并正确处理它们。还有一个控制台(用于调试目的)。
该程序在Windows 10上运行正常,然后我在另一台运行Windows 8.1的计算机上进行测试,但该程序未捕获WM_POWERBROADCAST
消息。
奇怪的是:
printf
添加到WndProc
的开头,会收到消息。我准备了一个MCVE,以防有人想尝试重现它(下面)。请注意,printf
的开头有WndProc
评论。
printf
行仍然被评论如果我在Windows 10上运行程序,这就是我运行时得到的结果(无需关闭盖子,只需运行程序):
Power broadcast message received
但如果我在Windows 8.1上运行它,我什么也得不到(即使我关闭/打开盖子)。
printf
行未注释这就是我两者 Windows 10和8.1:
MSG: 36
MSG: 129
MSG: 131
MSG: 1
MSG: 799
MSG: 536
Power broadcast message received
MSG: 49273
(MSG: 49273
除外,它没有出现在Windows 8.1上,但似乎没有相关性。)
为什么会这样?
更多信息:
以下是MCVE:
#include <windows.h>
#include <stdio.h>
int WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
//printf("MSG: %d\n", message);
if (message == WM_POWERBROADCAST)
{
printf("Power broadcast message received\n");
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.lpszClassName = L"Test";
RegisterClass(&wc);
HWND hWnd = CreateWindow(wc.lpszClassName, NULL,
0, 0, 0, 0, 0, NULL, NULL,
hInstance, NULL);
RegisterPowerSettingNotification(hWnd, &GUID_LIDSWITCH_STATE_CHANGE, 0);
ShowWindow(hWnd, SW_HIDE);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
提前致谢。
答案 0 :(得分:4)
问题是WndProc返回了一些东西而你没有返回任何东西。虚拟printf的奇怪行为是由于你的printf返回的伪像在eax寄存器中遗留下来,导致它成为函数返回。
当添加默认值:return DefWindowProc(...)时,这会满足大多数消息的返回值,所以WM_POWERBROADCAST突然开始工作。
失败的最可能解释是你的unilitialized返回变成了WM_NCCREATE或WM_CREATE的失败代码,因此窗口没有被创建。