我正在尝试使用Win32 API创建一个非常基本的窗口,自从我完成此操作已经有很长一段时间了.
我认为我的消息循环没问题,但是当我关闭打开的窗口时,应用程序仍在运行.看起来消息循环永远不会得到WM_QUIT消息.但是,我正在打电话PostQuitMessage,一个消息框确认我打电话给它.
这个极简主义代码有什么问题?
#include <Windows.h>
LRESULT CALLBACK window_proc(HWND hwnd, UINT msg,
WPARAM w_param, LPARAM l_param) {
switch (msg) {
case WM_DESTROY:
MessageBox(NULL, L"destroy", L"info", MB_OK);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, w_param, l_param);
}
return 0;
}
int CALLBACK WinMain(HINSTANCE h_instance, HINSTANCE h_prev_instance,
LPSTR cmd_line, int n_cmd_show) {
WNDCLASS wnd_class;
HWND hwnd;
MSG msg;
BOOL ret;
wnd_class.cbClsExtra = 0;
wnd_class.cbWndExtra = 0;
wnd_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
wnd_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd_class.hInstance = h_instance;
wnd_class.lpfnWndProc = window_proc;
wnd_class.lpszClassName = L"MyWindowClass";
wnd_class.lpszMenuName = NULL;
wnd_class.style = 0;
if (!RegisterClass(&wnd_class)) {
MessageBox(NULL, L"cannot register window class",
L"error", MB_OK | MB_ICONERROR);
}
hwnd = CreateWindow(
L"MyWindowClass",
L"",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
h_instance,
NULL
);
while ((ret = GetMessage(&msg, hwnd, 0, 0)) != 0) {
if (ret == -1) {
MessageBox(NULL, L"error", L"", MB_OK);
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
MessageBox(NULL, L"quitting now", L"info", MB_OK);
return msg.wParam;
}
Run Code Online (Sandbox Code Playgroud)
该GetMessage医生说,当读到一个函数返回0 WM_QUIT的消息.如何PostQuitMessage调用,GetMessage永不返回0?
谢谢你,Win32大师.
它是你的GetMessage()循环.
您将窗口句柄传递给该循环,从而过滤掉所有应用程序线程消息,并仅接收到该窗口的消息..
改变这个:
while ((ret = GetMessage(&msg, hwnd, 0, 0)) != 0)
// Note window handle =========^
Run Code Online (Sandbox Code Playgroud)
对此:
while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
// Note no handle =============^
Run Code Online (Sandbox Code Playgroud)
现在应该由GetMessage()循环监视您的应用程序线程队列.
原因: GetMessage()可以调整调用以监视特定窗口句柄的消息队列.应用程序WM_QUIT未发布到窗口句柄队列; 它被发布到线程消息队列,它只能通过使用GetMessage()(也许PeekMessage()是,但它已经太长时间让我记住)从队列中拉出消息而没有专门监视的目标窗口句柄.
| 归档时间: |
|
| 查看次数: |
1400 次 |
| 最近记录: |