[英]WINAPI application closes when I press either ALT, why?
我之前练习过 winapi 应用程序,但从未遇到过这个问题。
我尝试制作自定义 WindowProc 来覆盖 WM_QUIT/WM_CLOSE/WM_DESTROY 消息的默认行为以不执行任何操作,但是当我按下 ALT 时 window 仍然关闭!
这是整个代码:
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
const LPCSTR className = "Class name";
WNDCLASS wc = {};
wc.style = 0;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandle(nullptr);
wc.hIcon = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = className;
RegisterClass(&wc);
HWND window = CreateWindow(className, "Title", WS_OVERLAPPEDWINDOW, 200, 200, 600, 400, nullptr, nullptr, nullptr, nullptr);
ShowWindow(window, SW_SHOW);
MSG msg = {};
while (msg.wParam != WM_QUIT)
{
while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
我相信当我按下 ALT 时 window 不应该关闭,但确实如此。
您正在将message
字段与wParam
字段混合:
while (msg.wParam != WM_QUIT)
当您按下 ALT 时,window 会收到一条WM_KEYDOWN
消息,其wParam
是虚拟键码。 碰巧 ALT 与WM_QUIT
(0x12) 的常量具有相同的 VK 代码。
此外,您还在退出前翻译和调度WM_QUIT
。 您可以通过使用适当的检查进行单级缩进来处理这两种情况:
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) && msg.message != WM_QUIT)
正如评论中所指出的,这更干净GetMessage
:
while (GetMessage(&msg, nullptr, 0, 0) > 0)
您的代码存在一些问题。
首先,您应该使用GetMessage()
而不是PeekMessage()
。 根本区别在于PeekMessage()
是非阻塞的,因此您的程序将使用 100% 的 CPU 运行该循环。
此外,由于内部循环可能会或可能不会连续遍历多条消息,因此像您正在做的那样检查外部循环上的内容将是命中或未命中,并且不会检查所有消息。 您应该检查内部循环中的每条消息。
但在这种情况下,没有必要,因为如果 Window 无论如何关闭,这个循环就会结束。 你做的这个检查是没有意义的。
您的代码还有其他一些不一致之处, wc.hInstance
应该是hInstance
,这是您在WinMain()
中作为参数收到的那个。 无需 go 使用 API 查找此信息。
CreateWindow()
也应该再次接收hInstance
,因为它是倒数第二个参数,而不是nullptr
。
最后,正如克里斯的回答所指出的那样,您应该在msg.message
而不是在msg.wParam
中寻找消息类型。
除此之外,这里没有做“自定义 WindowProc”的地方。 如果你想做一个自定义的 WndProc,那么你应该将wc.lpfnWndProc
设置为你自己的 function 而不是DefWindowProc
,你可以在那里为你的 Window 定义自定义行为。
例如:
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
case WM_DESTROY:
// do nothing
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
请注意,无需测试WM_QUIT
,因为此消息仅在您的应用程序调用PostQuitMessage()
时才会发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.