WindowProc中的异常

时间:2013-02-01 09:01:09

标签: c++ winapi exception-handling seh

是否有可能在WindowProc回调中捕获错误? try / catch无效。看起来像__try __except以及硬件异常(例如AV)也不起作用。


更新

我发现确实可以在WindowProc回调中抛出异常,并在catch之外的WindowProc块中捕获它。经过测试并适用于Windows XP x86。我找到了相关的问题64bit exceptions in WndProc silently fail这个问题似乎只出现在Windows 7 x64上(根据其他x64 Windows版本的问题)。

所以问题是,有可能以某种方式在WindowProc中抛出异常,并在catch之外的WindowProc块中捕获它吗?我安装了microsoft修补程序,在注册表中将DisableUserModeCallbackFilter设置为1,我得到的最好是FATAL_USER_CALLBACK_EXCEPTION,而不是我的例外。

2 个答案:

答案 0 :(得分:4)

MSDN documentation for WindowProc有关于从WindowProc抛出/传播的异常的详细信息。似乎异常只在32位版本的Windows中传播。

但是,您的原始问题与更新中的问题不同。第一个是关于WindowProc中的捕获异常,并且总能正常工作。第二个是关于来自WindowProc的抛出异常。

我不确定第二个的用处/必要性。窗口过程通常由以下结果调用:

  1. 在消息循环中调用DispatchMessage。在这种情况下不需要抛出异常,因为这样做只会导致应用程序退出。如果遇到导致应用程序退出的错误,请调用PostQuitMessage(0)
  2. 调用SendMessage。在这种情况下,您并不真的想抛出异常,因为窗口过程将在UI线程中执行,如果调用线程与UI线程不同,则调用线程无论如何都不会获得异常
  3. 直接调用窗口过程。在这种情况下,例外情况会正常。

答案 1 :(得分:0)

使用C ++ 11,您可以通过手动转发任何异常来处理您的情况,

#include <exception>
std::exception_ptr windowProcException = nullptr;

LRESULT windowProc(){
  try {
    yourcode();
  catch(...){
    windowProcException = std::current_exception();
  }   
}

然后您可以像这样在主循环中重新抛出异常:

windowProcException = nullptr;
DispatchMessage();
if (windowProcException)
  std::rethrow_exception(windowProcException);