0

我正在使用一个名为 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.\n\n" \
          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":\n\n" << 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 回调展开。

任何提示都将不胜感激。

4

1 回答 1

0

雷蒙德在他对我的问题的评论中提供了我需要的提示。在堆栈展开期间,我的 user_interface 类的析构函数在窗口句柄上调用 DestroyWindow,因为它在那时仍然有效。我不知道的是 MessageBox 将生成的 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);
    }
}

这有效,但似乎有点难看。有什么建议可以改进吗?

于 2012-11-05T02:03:24.597 回答