开发者

Is there a way to disable message boxes in MFC?

I have an MFC application (using a legacy library that I can't change). When the application starts, it loads a couple of drivers and shows message boxes if some drivers couldn't be loaded. The loading of the drivers and the showing of the message boxes is done by a method inside the library that can't be changed (let's call this method Init). I would like to disable those message boxes (preventing them from "popping"). Is t开发者_开发知识库here something I could call before calling Init to disable Message Boxes temporarily and then re-enable them after?

(Note that if it is impossible to re-enable them after, I can very well live with that, I mostly want to disable them)

Thanks to all,

Note: If someone wonders about why I would like to do that, it is because my application exposes a COM interface and will be used by other applications. The only reason it is an application is that the library I use is much more easy to use when creating an MFC application (and not a dll). When it is called by my other applications, I don't want the message boxes to show, I just want to get the errors if something goes wrong.


I am not sure whether this could work. I use it for subclassing some messageboxes not to preven them to popup and they are not from a dll.

I set a hook to capture message boxes before poping up:

HHOK hMessageBoxHook_ = SetWindowsHookEx(WH_CBT, 
                                         &CbtHookProc, 
                                         ::GetModuleHandle(NULL), 
                                         GetCurrentThreadId());

The new hook procedure (CbtHookProc) would be like this:

LRESULT CALLBACK CbtHookProc(   int nCode, 
                                            WPARAM wParam, 
                                            LPARAM lParam)
{
    if(nCode < 0)
    {
        return ::CallNextHookEx(    hMessageBoxHook_, 
                                    nCode, 
                                    wParam, 
                                    lParam); 
    }

    switch(nCode)
    {
        case HCBT_CREATEWND: // a window is about to be created
            return -1;
    }

    return ::CallNextHookEx(    hMessageBoxHook_, 
                                nCode, 
                                wParam, 
                                lParam); 
}

From microsoft documentation for HCBT_CREATEWND:

If the hook procedure returns a nonzero value, the system destroys the window

Then after calling Init you can remove the hook and message boxes will pop up again:

            ::UnhookWindowsHookEx(hMessageBoxHook_);
            hMessageBoxHook_ = 0;

As I told you I can't assure it works but give it a try.


One way to do this would be to hook/unhook the calls to MessageBox/MessageBoxEx/etc. and just do nothing when these calls are made. Check this guide for details on hooking API calls. In your case, I would specifically look at Import Address Table method, which is quite easy to implement and allows you to achieve the functionality you want.

You may also want to check Microsoft's own Detours library, but I'm not sure on whether it supports replacing API calls functionality.

Hope it helps.


I had the same problem when using ODBC with MFC. Everytime there was an error, a message box would pop up showing the error, which was fine if I wanted one.

However, if I didn't, I only needed to surround it with:

TRY
{
    // Call error-prone method
} 
CATCH ( CException, pEx )
{
    // Free resources
}
END_CATCH

The message box comes from the framework not knowing how to handle the exception. Simply catch it and do as you wish with it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜