当用户关闭窗口时,该操作会触发一系列窗口消息。
用户可以通过单击“ 关闭 ”按钮或使用 Alt+F4 等键盘快捷方式来关闭应用程序窗口。 任何这些操作都会导致窗口接收 WM_CLOSE 消息。
WM_CLOSE消息
WM_CLOSE消息使你有机会在关闭窗口之前提示用户。 如果确实想要关闭窗口,请调用 DestroyWindow 函数。 否则,只需从 WM_CLOSE 消息中返回零,操作系统将忽略该消息,不会销毁窗口。
下面是程序如何处理 WM_CLOSE的示例。
case WM_CLOSE:
if (MessageBox(hwnd, TEXT("确定退出程序?"), TEXT("My application"), MB_OKCANCEL) == IDOK)
{
DestroyWindow(hwnd);
}
//若选择取消,则不进行操作
return 0;
在此示例中, MessageBox 函数显示包含 “确定” 和“ 取消 ”按钮的模式对话框。 如果用户单击“ 确定”,程序将调用 DestroyWindow。 否则,如果用户单击“ 取消”,则会跳过对 DestroyWindow 的调用,并且窗口保持打开状态。 在任一情况下,都返回零以指示你处理了消息。效果如下:

Windows 应用程序处理 WM_CLOSE 消息时,如果不对其进行显式处理,DefWindowProc 函数会默认调用 DestroyWindow 来关闭窗口。这意味着,如果忽略 switch 语句中的WM_CLOSE消息,则默认情况下会销毁窗口。当窗口即将被销毁时,它会收到 WM_DESTROY 消息。 此消息在从屏幕中删除窗口之后,但在销毁发生之前, (特别是在) 销毁任何子窗口之前发送。在main应用程序窗口中,通常会通过调用 PostQuitMessage 来响应WM_DESTROY。
case WM_DESTROY:
PostQuitMessage(0);
return 0;
我们在 “窗口消息 ”部分看到, PostQuitMessage 将 WM_QUIT 消息置于消息队列中,导致消息循环结束。
下面是一个流程图,其中显示了处理 WM_CLOSE 和 WM_DESTROY 消息的典型方法:

最后代码
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0); // 发送退出消息
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// All painting occurs here, between BeginPaint and EndPaint.
FillRect(hdc, &ps.rcPaint, (HBRUSH)(COLOR_WINDOW + 4));
// 绘制文本
TextOut(hdc, 10, 10,TEXT("Hello, World!"), 13);
EndPaint(hwnd, &ps);
return 0;
}
case WM_CLOSE:
if (MessageBox(hwnd, TEXT("确定退出程序?"), TEXT("My application"), MB_OKCANCEL) == IDOK)
{
DestroyWindow(hwnd);
}
// Else: User canceled. Do nothing.
return 0;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam); // 默认消息处理
}
}
int WINAPI wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PWSTR pCmdLine,
int nCmdShow)
{
//注册窗口类
const wchar_t CLASS_NAME[] = L"WolvenChan's Window Class";
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
RegisterClass(&wc);
//创建窗口
HWND hwnd = CreateWindowEx(
0,
CLASS_NAME,
TEXT("Hello Wolven"),
WS_OVERLAPPEDWINDOW,
//坐标、窗口长、高
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL
);
if (hwnd == NULL) {
MessageBox(NULL, L"Failed to create window!", L"Error", MB_ICONERROR);
return 0;
}
ShowWindow(hwnd, nCmdShow);
//消息循环
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); // 翻译消息
DispatchMessage(&msg); // 分发消息
}
return (int)msg.wParam;
return 0;
}

8239

被折叠的 条评论
为什么被折叠?



