【发布时间】:2010-11-13 05:32:39
【问题描述】:
我正在编写一个使用单个对话框的 (C++) 应用程序。
设置消息泵和处理程序后,我开始想知道如何将 C++ 异常传播到我的原始代码(例如,调用 CreateDialogParam 的代码)。
这是我的意思的一个骨架示例:
BOOL CALLBACK DialogProc(HWND, UINT msg, WPARAM, LPARAM)
{
if(msg == WM_INITDIALOG) //Or some other message
{
/*
Load some critical resource(s) here. For instnace:
const HANDLE someResource = LoadImage(...);
if(someResource == NULL)
{
---> throw std::runtime_error("Exception 1"); <--- The exception handler in WinMain will never see this!
Maybe PostMessage(MY_CUSTOM_ERROR_MSG)?
}
*/
return TRUE;
}
return FALSE;
}
//======================
void RunApp()
{
const HWND dlg = CreateDialog(...); //Using DialogProc
if(dlg == NULL)
{
throw std::runtime_error("Exception 2"); //Ok, WinMain will see this.
}
MSG msg = {};
BOOL result = 0;
while((result = GetMessage(&msg, ...)) != 0)
{
if(result == -1)
{
throw std::runtime_error("Exception 3"); //Ok, WinMain will see this.
}
//Maybe check msg.message == MY_CUSTOM_ERROR_MSG and throw from here?
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//======================
int WINAPI WinMain(...)
{
try
{
RunApp();
//Some other init routines go here as well.
}
catch(const std::exception& e)
{
//log the error
return 1;
}
catch(...)
{
//log the error
return 1;
}
return 0;
}
如您所见,WinMain 将处理“异常 2”和“3”,但不会处理“异常 1”。
我的基本问题很简单;将这些错误传播到原始“调用”代码的优雅方法是什么?
我想过可能使用自定义消息并将实际的 throw-statements 移到消息泵(在 RunApp() 中),但我不确定这将如何工作,因为我对 Windows 的经验相对较少一般。
也许我对这种情况的看法完全错了。当您在消息处理程序中遇到致命的事情(即获取关键资源失败,并且没有恢复的机会)时,您通常如何摆脱困境?
【问题讨论】:
标签: c++ winapi exception message-queue