内部异常处理程序,MessageBox()成功返回IDOK,但从未显示

Inside exception handler, MessageBox() successfully returns IDOK but never shows

本文关键字:IDOK 显示 返回 成功 异常处理程序 MessageBox 内部      更新时间:2023-10-16

我使用的是一个名为windows_error的自写异常类,该类从std :: runtime_error继承,我用它来正确处理Windows API函数的意外错误。

一直位于呼叫扇区的底部,在我的Winmain功能的末尾,我捕获了尚未处理的所有Windows_Error例外。我打算通过在程序终止之前显示错误消息来处理它们,例如:

int WINAPI wWinMain(HINSTANCE inst, HINSTANCE prev, wchar_t *cmdline, int winshow)
{
    // Initialize result to EXIT_FAILURE in case the program terminates due to
    // an exception.
    int result = EXIT_FAILURE;
    try {
        result = sIRC()();
    }
    catch (windows_error &e) {
        e.basicHandler();
    }
    return result;
}

Basichandler成员函数看起来像这样:

void windows_error::basicHandler() const
{
    std::wostringstream ss;
    ss << L"An unexpected error has occurred in a Windows function.nn" 
          L"Function " << m_api << L" was called by " << m_caller << L" in " << m_srcFile << L" at line " << m_srcLine << L". " 
          L"It returned error " << m_error << L":nn" << m_errorMessage;
#ifdef _CONSOLE
    std::wcout << L"n" << ss.str();
#else
    auto result = MessageBox(HWND_DESKTOP, ss.str().c_str(), L"Windows error!", MB_ICONERROR);
    result = result; // I added this line so I can put a breakpoint in the debugger
#endif // _CONSOLE
}

当我从正在进行的程序开始时,这效果很好。但是现在该计划开始增长。在尝试新代码时,我注意到该程序似乎意外终止。通过在Visual C 2010调试器中运行它,我注意到Windows_Error异常正在抛出。通过逐步浏览Basichandler函数,我可以看到MessageBox函数返回1(IDOK)而没有实际显示消息框...

什么可能导致这种行为?

我知道我的描述有点模糊,但是我不知道还有什么要添加...我在MSDN上找不到任何暗示这种行为甚至可能的东西。我没有父母的窗口句柄可以将其传递给MessageBox,因为它们在堆叠期间都被破坏了。我也很肯定,堆栈不会通过窗口过程或任何其他Windows回调解开。

所有提示都将不胜感激。

雷蒙德(Raymond)提供了我在评论我的问题中需要的提示。在堆栈中,请在窗口句柄上放出我的User_interface类呼叫销毁窗口的破坏窗口,因为此时仍然有效。我不知道的是,该消息框解释了由此产生的WM_QUIT消息以关闭自身。我以为一个消息框有自己的内部消息队列?

我能够通过修改User_interface类的击路仪来解决我的问题。

是:

if (_wnd)
    DestroyWindow(_wnd);

我将其更改为:

if (_wnd) {
    DestroyWindow(_wnd);
    MSG msg = MSG();
    while (msg.message != WM_QUIT) {
        GetMessage(&msg, 0, 0, 0);
    }
}

这起作用,但似乎有些丑陋。有任何改进的建议吗?