WinDjView对AfxMessageBox的定制

本文探讨了MFC框架中通过重载CWinApp::DoMessageBox函数实现对话框定制的方法,并提出了疑问:为何需要两个DoMessageBox函数及不直接定制对话框的原因。

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

Overridden DoMessageBox() sample
// 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();
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值