「Win」窗口退出 之 PostQuitMessage(0) 和 SendMessage(WM_CLOSE)

「Win」窗口退出 之 PostQuitMessage(0) 和 SendMessage(WM_CLOSE)

✨博客主页
何曾参静谧的博客(✅关注、👍点赞、⭐收藏、🎠转发)
📚全部专栏(专栏会有变化,以最新发布为准)
「Win」Windows程序设计 「IDE」集成开发环境 「定制」定制开发集合
「C/C++」C/C++程序设计 「DSA」数据结构与算法 「UG/NX」NX二次开发
「QT」QT5程序设计 「File」数据文件格式 「UG/NX」BlockUI集合
「Py」Python程序设计 「Math」探秘数学世界 「PK」Parasolid函数说明
「Web」前后端全栈开发 「En」英语从零到一 👍占位符
「AI」人工智能大模型 「书」书籍阅读笔记

目录

功能区别1. `PostQuitMessage(0)` – 退出消息循环2. `SendMessage(WM_CLOSE)` – 关闭窗口
工作流程对比`PostQuitMessage` 的工作流程`SendMessage(WM_CLOSE)` 的工作流程
使用场景使用 `PostQuitMessage(0)` 的情况使用 `SendMessage(WM_CLOSE)` 的情况
重要区别正确的退出流程常见错误用法错误1:混淆使用错误2:直接退出
总结

这两个函数有本质的区别,它们在不同的层面和场景下使用。让我详细解释:

功能区别

1.
PostQuitMessage(0)
– 退出消息循环


// 向消息队列投递一个WM_QUIT消息
// 参数是退出代码,通常为0
PostQuitMessage(0);

作用:

当前线程的消息队列投递一个
WM_QUIT
消息当消息循环收到
WM_QUIT
时,会退出循环不直接关闭窗口,只是告诉程序应该退出了

2.
SendMessage(WM_CLOSE)
– 关闭窗口


// 向指定窗口发送WM_CLOSE消息
// 这会触发窗口的关闭流程
SendMessage(hWnd, WM_CLOSE, 0, 0);

作用:

指定窗口发送
WM_CLOSE
消息触发窗口的关闭序列窗口可以处理这个消息(比如弹出保存对话框)

工作流程对比


PostQuitMessage
的工作流程


// 1. 投递退出消息
PostQuitMessage(0);

// 2. 消息循环中
while (GetMessage(&msg, NULL, 0, 0)) {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    
    // 当收到WM_QUIT时,GetMessage返回0,循环退出
}

// 3. 程序退出
return (int)msg.wParam;


SendMessage(WM_CLOSE)
的工作流程


// 1. 发送关闭消息
SendMessage(hWnd, WM_CLOSE, 0, 0);

// 2. 窗口过程处理
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_CLOSE:
        // 可以在这里询问是否保存等
        if (MessageBox(hWnd, "确定要退出吗?", "确认", MB_YESNO) == IDYES) {
            DestroyWindow(hWnd);  // 真正销毁窗口
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);  // 在这里退出消息循环
        break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

使用场景

使用
PostQuitMessage(0)
的情况


// 在窗口的WM_DESTROY消息中
case WM_DESTROY:
    PostQuitMessage(0);  // 正确的退出方式
    break;

// 或者当需要强制退出程序时
void ForceExit() {
    PostQuitMessage(0);  // 优雅退出
}

使用
SendMessage(WM_CLOSE)
的情况


// 1. 点击关闭按钮时
// 2. 通过菜单命令关闭窗口
void OnFileExit() {
    SendMessage(hMainWnd, WM_CLOSE, 0, 0);  // 模拟点击关闭按钮
}

// 3. 关闭其他窗口
void CloseChildWindow() {
    SendMessage(hChildWnd, WM_CLOSE, 0, 0);
}

重要区别

特性
PostQuitMessage(0)

SendMessage(WM_CLOSE)
目标 当前线程的消息队列 特定窗口
作用 退出消息循环 关闭窗口
消息类型
WM_QUIT

WM_CLOSE
是否阻塞 非阻塞(投递) 阻塞(发送)
使用场景 程序退出 窗口关闭

正确的退出流程


// 标准的Windows程序退出流程
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message) {
    case WM_CLOSE:
        // 可以在这里进行保存确认等
        if (NeedToSave()) {
            if (MessageBox(hWnd, "保存更改?", "确认", MB_YESNOCANCEL) == IDYES) {
                SaveDocument();
                DestroyWindow(hWnd);
            } else if (result == IDNO) {
                DestroyWindow(hWnd);
            }
            // IDCANCEL: 什么都不做
        } else {
            DestroyWindow(hWnd);
        }
        break;
        
    case WM_DESTROY:
        PostQuitMessage(0);  // 这才是退出消息循环的地方
        break;
        
    case WM_QUIT:
        // 通常不在窗口过程中处理WM_QUIT
        break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

常见错误用法

错误1:混淆使用


// 错误:在WM_CLOSE中调用PostQuitMessage
case WM_CLOSE:
    PostQuitMessage(0);  // 错误!应该用DestroyWindow
    break;

错误2:直接退出


// 错误:绕过正常关闭流程
void ForceExit() {
    exit(0);  // 非常粗暴的方式,不要这样做!
}

总结


PostQuitMessage(0)
:用于退出消息循环,通常在
WM_DESTROY
中调用
SendMessage(WM_CLOSE)
:用于关闭窗口,触发正常的关闭流程

正确的关系:

SendMessage(WM_CLOSE)

DestroyWindow()

WM_DESTROY

PostQuitMessage(0)
→ 退出消息循环

所以你的两个调用:


PostQuitMessage(0)
– 直接退出程序
SendMessage(WM_CLOSE)
– 请求关闭窗口(可能被取消)

根据你的需求选择合适的方法。

何曾参静谧的博客(✅关注、👍点赞、⭐收藏、🎠转发)


「Win」窗口退出 之 PostQuitMessage(0) 和 SendMessage(WM_CLOSE)

© 版权声明

相关文章

暂无评论

none
暂无评论...