使用PostMessage显示关联对话框的模态消息框问题
解决方案
1. 添加窗口状态标记变量
在CChristianLifeMinistryEditorDlg类的头文件中添加成员变量,用于标记窗口是否处于活跃状态:
private: bool m_bIsWindowActive; // 标记窗口是否未被销毁
2. 初始化与清理状态变量
在对话框的OnInitDialog方法中初始化变量:
BOOL CChristianLifeMinistryEditorDlg::OnInitDialog() { CDialogEx::OnInitDialog(); m_bIsWindowActive = true; // 原有的初始化代码... if (ReadReportFromFile() && IsModified()) { ::PostMessage(GetSafeHwnd(), theApp.UWM_REFRESHED_SPECIAL_EVENTS_MSG, NULL, NULL); } return TRUE; }
在对话框的OnDestroy方法中更新状态,标记窗口已销毁:
void CChristianLifeMinistryEditorDlg::OnDestroy() { CDialogEx::OnDestroy(); m_bIsWindowActive = false; }
3. 修改消息处理函数
修改OnUwmRefreshedSpecialEvents函数,先检查窗口状态,再使用对话框自身作为父窗口显示消息框:
afx_msg LRESULT CChristianLifeMinistryEditorDlg::OnUwmRefreshedSpecialEvents(WPARAM wParam, LPARAM lParam) { // 检查窗口是否仍处于活跃状态,避免窗口销毁后显示消息框 if (!m_bIsWindowActive || !IsWindow(GetSafeHwnd())) { return 0; } CString strMessage; strMessage.LoadString(IDS_STR_NEW_SPECIAL_EVENTS_ADDED); for (const auto& sEvent : m_listNewSpecialEvents) { strMessage.AppendFormat(_T("%s: %s\n"), (LPCTSTR)sEvent.datEvent.Format(VAR_DATEVALUEONLY), (LPCTSTR)sEvent.strEvent); } // 使用对话框自身作为父窗口,替代AfxMessageBox,确保消息框与对话框模态关联 MessageBox(strMessage, _T("提示"), MB_OK | MB_ICONINFORMATION); return 0; }
关键说明
- 状态标记:通过
m_bIsWindowActive变量确保只有窗口未销毁时才处理消息,避免窗口关闭后消息框仍弹出。 - 指定父窗口:使用
MessageBox而非AfxMessageBox,并以对话框自身作为父窗口,让消息框与对话框形成模态关联,不会依附到主窗口,同时避免影响主窗口的Web浏览器控件。 - 异步消息安全:
PostMessage是异步消息,窗口可能在消息处理前销毁,状态检查是必要的防护措施。
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

