首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WindowProc中的异常

WindowProc中的异常
EN

Stack Overflow用户
提问于 2013-02-01 09:01:09
回答 3查看 2.7K关注 0票数 5

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

更新:

我发现,这确实可以在WindowProc回调中抛出异常,并在WindowProc之外的catch块中捕获它。测试并在Windows XP x86上工作。我发现了相关的问题WndProc中的64位异常无声失败,这个问题似乎只存在于Windows 7 x64上(根据其他x64 Windows版本也存在这个问题)。

所以问题是,在WindowProc中抛出异常并在WindowProc之外用catch块捕获它是可能的吗?我安装了microsoft,在注册表中将DisableUserModeCallbackFilter设置为1,最好是FATAL_USER_CALLBACK_EXCEPTION,而不是我的例外。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-08 11:33:26

用于WindowProc的MSDN文档提供了有关从WindowProc引发/传播的异常的详细信息。异常似乎只在32位版本的Windows中传播。

但是,您的原始问题与更新中的问题不同。第一个是关于在WindowProc中捕获异常,这将始终正常工作。第二个问题是关于从WindowProc抛出异常。

我不确定第二次考试是否有用/必要。通常调用窗口过程的原因是:

  1. 在消息循环中调用DispatchMessage。在这种情况下没有必要抛出异常,因为这样做只会导致应用程序退出。如果遇到导致应用程序退出的错误,只需调用PostQuitMessage(0)即可。
  2. 打给SendMessage。在这种情况下,您实际上不想抛出异常,因为窗口过程将在UI线程中执行,而且如果调用线程与UI线程不同,则调用线程无论如何也不会得到异常。
  3. 直接调用窗口过程。在这种情况下,异常可以正常工作。
票数 4
EN

Stack Overflow用户

发布于 2019-02-22 02:34:03

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

代码语言:javascript
运行
复制
#include <exception>
std::exception_ptr windowProcException = nullptr;

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

然后,可以在主循环中重新抛出异常,如下所示:

代码语言:javascript
运行
复制
windowProcException = nullptr;
DispatchMessage();
if (windowProcException)
  std::rethrow_exception(windowProcException);
票数 3
EN

Stack Overflow用户

发布于 2021-10-19 05:25:12

Chronial给出了最好的答案。我会给出我认为是有用的改进。

Chronial的概念是允许在窗口过程中使用cpp抛出机制,但不要让它在窗口过程之外传播;它在C库中调用,导致64位窗口上的未定义行为,即64位win 7或windows 8。相反,捕获窗口过程中的异常,并将其保存在全局变量中,然后将其重新抛入cpp主函数并使用。有关代码示例,请参见Chronial的答案。

这个概念很简单,但需要一些细节才能得到100%的正确。

  • 一个要避免的陷阱是不要摧毁你扔出的窗户。您的代码将清除try块中声明的所有对象,但您创建的窗口对象仍将处于活动状态并处理消息。即使您不再发送消息。如果在窗口过程中使用指针,则当代码处于catch块中时,这些指针可能是无效的,而windows仍在向未销毁的窗口中发送消息。
  • 每个窗口过程都需要有这个尝试捕获,保存异常技术。如果您的顶层窗口已经准备好,它就不能工作,但是在它的子窗口的过程中会抛出异常。
  • 如果前两个是超明显的,那么这个就稍微不明显了。对于顶级窗口的过程;除了尝试捕获整个开关语句之外,还应该尝试捕获WM_CREATE消息,如果发现异常,则返回-1。这将防止创建窗口及其子窗口;并避免在重新抛出异常时必须销毁该窗口。
  • 最后,在顶级窗口的WM_CREATE消息中,在运行创建子窗口的代码之后,检查这些子窗口是否设置了全局windowProcException变量。创建子窗口将运行自己的windowProcedure,在这些窗口过程中捕获的异常将不会自动与顶级窗口的过程相对应。如果子窗口过程中出现异常,则从顶层窗口返回-1将取消所有窗口的创建。除非,您认为特定的子窗口并不是非常重要的。 空洞createChildWindows(); windowProcedure(hwnd,msg,wparam,lparam) { try { if(msg == WM_CREATE) { createChildWindows();返回windowProcException?-1 : 0;}catch(.){ windowProcException = std::current_exception();返回-1;} 返回DefWindowProc(hwnd,msg,wparam,lparam);} windowProcException (.){windowProcException= std::current_exception();//明as不会抱怨如果您不返回值;//MSVC可能//就我而言,我们正在抛出//因此任何返回的值都是未定义的//我们必须小心使用WM_CREATE,因为返回代码//指示是否继续创建窗口} }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14642722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档