在MFC应用程序中,使用 AfxGetMainWnd()->SendMessage(WM_CLOSE); 通常可以正常退出程序,但具体行为取决于主窗口的消息处理逻辑。以下是详细分析:
基本原理
AfxGetMainWnd():获取应用程序主窗口的指针(通常是 CFrameWnd 或其派生类)。
WM_CLOSE 消息:向主窗口发送关闭请求,触发窗口的关闭流程。默认行为
默认处理流程:
主窗口收到 WM_CLOSE 后,MFC 默认调用 CFrameWnd::OnClose()。
OnClose() 会尝试销毁窗口(DestroyWindow())。
主窗口销毁后,MFC 的 CWinApp::Run() 检测到没有活动的主窗口,退出消息循环,触发程序终止。
- 可能的问题
自定义 OnClose():
如果主窗口重写了 OnClose() 方法(例如添加了保存确认对话框),可能导致未真正销毁窗口。
此时需确保自定义逻辑最终调用 DestroyWindow() 或基类的 CFrameWnd::OnClose()。
其他窗口的存在:
若存在未关闭的非模态窗口或子窗口(如MDI子窗口),程序可能不会立即退出。
MFC 默认在单文档(SDI)或多文档(MDI)应用中,关闭主窗口会退出程序,但需检查 CWinApp::m_pMainWnd 是否指向正确的主框架。
- 替代方法
直接退出应用程序:
1 | AfxGetApp()->ExitInstance(); // 直接调用应用程序退出 |
注意:此方法会跳过窗口关闭的清理流程(如 OnClose() 或 OnDestroy())。
异步关闭(推荐):
1 | AfxGetMainWnd()->PostMessage(WM_CLOSE); // 异步发送,避免潜在死锁 |
- 验证与安全性
空指针检查:
1 | if (CWnd* pMainWnd = AfxGetMainWnd()) { |
确保主窗口未被提前销毁。
- 结论
标准情况下:AfxGetMainWnd()->SendMessage(WM_CLOSE); 能正确退出程序,前提是主窗口未拦截或修改默认关闭逻辑。
需注意:在复杂场景(如自定义窗口关闭行为、多窗口共存)中,需额外验证主窗口销毁是否触发程序终止。
附:流程图
1 | 发送 WM_CLOSE → 触发 OnClose() → DestroyWindow() → 主窗口销毁 → CWinApp 检测无主窗口 → 退出消息循环 → 程序终止 |
附:关闭AfxBeginThread线程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 3. 等待线程安全退出
if (m_Thread_FTDI != NULL)
{
// 等待线程结束,增加超时时间
DWORD dwRet = WaitForSingleObject(m_Thread_FTDI->m_hThread, 3000); // 等待3秒
if (dwRet == WAIT_TIMEOUT)
{
// 如果等待超时,强制终止线程
TerminateThread(m_Thread_FTDI->m_hThread, 0);
}
if (dwRet == WAIT_OBJECT_0)
{
AfxMessageBox(TEXT("线程正常退出"));
}
m_Thread_FTDI = NULL;
}