I’m using a self written exception class called windows_error that inherits from std::runtime_error, which I use to, well, properly handle unexpected errors from Windows API functions.
All the way on the bottom of the callstack, at the end of my WinMain function, I catch all windows_error exceptions that haven’t been dealt with yet. I intend to handle them by display an error message right before the program terminates, like so:
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;
}
The basicHandler member function looks like this:
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
}
When I started out with the program I’m working on, this worked beautifully. But now the program is starting to grow. While trying out new code I noticed the program seemed to terminate unexpectedly. By running it in the Visual C++ 2010 debugger, I noticed a windows_error exception being thrown. By stepping through the basicHandler function, I could see that the MessageBox function returns 1 (IDOK) without actually showing the message box…
What could cause this behavior?
I know my description is a little vague, but I have no idea what else to add… I couldn’t find anything on MSDN that would suggest this behavior is even possible. There is no parent window handle I could pass to MessageBox, since they’re all being destroyed during stack unwinding. I’m also positive that the stack is not unwound through a window procedure or any other Windows callback.
Any hint at all would be appreciated.
Raymond provided the hint I needed in his comment to my question. During stack unwinding the destructor of my user_interface class calls DestroyWindow on the window handle because it is still valid at that point. What I didn’t know was that MessageBox interprets the resulting WM_QUIT message to close itself. I thought a message box had its own internal message queue?
I was able to fix my issue by modifying the destructor of my user_interface class.
It was:
I changed it to:
This works, but seems a little ugly. Any suggestions to improve this?