Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在异常处理程序中,MessageBox()成功返回IDOK,但从未显示_C++_Windows_Winapi_Exception Handling - Fatal编程技术网

C++ 在异常处理程序中,MessageBox()成功返回IDOK,但从未显示

C++ 在异常处理程序中,MessageBox()成功返回IDOK,但从未显示,c++,windows,winapi,exception-handling,C++,Windows,Winapi,Exception Handling,我正在使用一个名为windows_error的自写异常类,该类继承自std::runtime_error,用于正确处理windows API函数中的意外错误 在调用堆栈的底部,在WinMain函数的末尾,我捕获了所有尚未处理的windows_错误异常。我打算在程序终止之前显示一条错误消息来处理它们,如下所示: int WINAPI wWinMain(HINSTANCE inst, HINSTANCE prev, wchar_t *cmdline, int winshow) { // In

我正在使用一个名为windows_error的自写异常类,该类继承自std::runtime_error,用于正确处理windows API函数中的意外错误

在调用堆栈的底部,在WinMain函数的末尾,我捕获了所有尚未处理的windows_错误异常。我打算在程序终止之前显示一条错误消息来处理它们,如下所示:

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
}
void windows\u错误::basicHandler()常量
{
标准:WOSS;

在对我的问题的评论中,Raymond提供了我需要的提示。在堆栈展开过程中,我的user\u interface类的析构函数调用窗口句柄上的DestroyWindow,因为它在该点上仍然有效。我不知道的是MessageBox会解释生成的WM\u QUIT消息以关闭自己。我认为MessageBox有它自己的own内部消息队列

我可以通过修改我的用户界面类的析构函数来修复我的问题

它是:

if (_wnd)
    DestroyWindow(_wnd);
我把它改成:

if (_wnd) {
    DestroyWindow(_wnd);

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

这是可行的,但看起来有点难看。有什么改进的建议吗?

队列中还会有一条离群的退出消息吗?哇,Raymond Chen回答了我的问题!我非常震惊。:-)嗯,在堆栈展开过程中,我的用户界面类的析构函数会调用主窗口句柄上的DestroyWindow,这是由窗口进程处理的我想MessageBox会创建它自己的消息队列吗?函数没有消息队列。线程有消息队列。你正处于这种情况,@RaymondChen谢谢,我现在很清楚了。你愿意评论一下我在回答中提出的修复方法吗?它看起来有点笨拙,但它是bes我对Windows API的理解是有限的。消息框有自己的消息循环,但每个线程只有一个队列。我想你可以启动一个单独的线程来显示消息框。@Harry,这似乎有点过分。:)谢谢你的评论。嗯,如果你在析构函数中这样做,那么你就可以即使在正常(无例外)的情况下,您也会丢弃消息,如果其他人想要其中一条消息,这不是一个好主意。(例如,用户执行了typeahead,在您的消息被销毁后将转到其他窗口。)此外,发布退出消息并立即删除它似乎毫无意义。wnd变量表示我的程序UI中的主窗口。没有其他窗口可供任何提前键入的文本访问。在正常、非异常情况下,运行析构函数时,\ wnd甚至不再是有效的窗口句柄。它将设置为NULL,即s它已在用户请求时被销毁。WM_QUIT将已被正常处理。我明白您所说的在异常情况下发布WM_QUIT是毫无意义的,但窗口过程被设置为调用PostQuitMessage()在处理WM_DESTROY时,我希望保持这种方式。没有任何有价值的东西会丢失。@RaymondChen:根据MSDN,DESTROY窗口会刷新线程的消息队列,所以可能只剩下退出消息了?或者我缺少了一个微妙的地方?