CWinApp::DoMessageBox
这是MFC框架内部调用的函数, 不要直接调用这个函数。
重载这个函数可以定制AfxMessageBox的处理。
WinDjView通过定制这个函数,为对话框添加checkbox等功能。
大致的流程是这样的:
1. 重载DoMessageBox函数,在其中调用另外一个自定义的DoMessageBox函数(参数列表不同)
2. 在自定义的DoMessageBox中,先使用SetWindowsHookEx设置一个WH_CBT类型的hook,用于监控之后的对话框创建过程。
3. 调用CWinApp::DoMessageBox创建对话框
4. 调用UnhookWindowsHookEx取消刚才的hook
其中,上述第3步,系统创建对话框的时候,会调用WH_CBT的回调函数,在回调函数中才开始真正的定制工作。
流程是基本知道了,但是不明白以下两个问题:
1. 为什么要有两个DoMessageBox函数?直接在第一个函数中完成任务不是一样的吗?
2. 为什么不像下面的例子那样直接定制一个对话框,然后显示呢?需要通过设置hook的方法来绕弯子定制对话框呢?
WinDjView代码中是这样使用的:
if (m_appSettings.bWarnNotDefaultViewer && RegisterShellFileTypes(true))
{
MessageBoxOptions mbo;
mbo.strCheckBox = LoadString(IDS_WARN_NOT_DEFAULT_VIEWER);
mbo.pCheckValue = &m_appSettings.bWarnNotDefaultViewer;
if (DoMessageBox(LoadString(IDS_PROMPT_MAKE_DEFAULT_VIEWER),
MB_ICONEXCLAMATION | MB_YESNO, 0, mbo) == IDYES
&& !RegisterShellFileTypesElevate(pMainFrame))
{
AfxMessageBox(IDS_MAKE_DEFAULT_FAILED, MB_ICONERROR | MB_OK);
}
}
看来作者在需要的时候是直接调用自定义的DoMessageBox函数的,而平时又是直接使用AfxMessageBox的。
这样看来就更古怪了,完全可以在需要的时候,使用自定义的对话框,而在平时使用AfxMessageBox函数。
可能还有没有看明白的地方,或者是存在什么历史原因了。
以下例子摘自MSDN
// Method for changing the application-wide behavior of AfxMessageBox().
//
// Overridden DoMessageBox() method of our application's main CWinApp class.
//
// If you want, that every call of AfxMessageBox() in your application is
// replaced by the new message box dialog, simply use the following code.
// All codes of AfxMessageBox will call this method and use the new message
// boxes.
//
int MyApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt)
{
// Create a handle to store the parent window of the message box.
CWnd* pParentWnd = CWnd::GetActiveWindow();
// Check whether an active window was retrieved successfully.
if ( pParentWnd == NULL )
{
// retrieve a handle to the last active popup
pParentWnd = GetMainWnd()->GetLastActivePopup();
}
// Create our message box dialog
CMessageBoxDialog dlgMessage(pParentWnd, lpszPrompt, _T("title"), nType, nIDPrompt);
// Display our message box dialog (instead of the system's message box)
// and return the result.
// return CWinApp::DoMessageBox(lpszPrompt, nType, nIDPrompt);
return (int)dlgMessage.DoModal();
}
本文探讨了MFC框架中通过重载CWinApp::DoMessageBox函数实现对话框定制的方法,并提出了疑问:为何需要两个DoMessageBox函数及不直接定制对话框的原因。
578

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



