如何捕获 WndProc() 函数中定义的静态对象的异常

How to catch an exception for a static object defined in a WndProc() function?

本文关键字:定义 静态 对象 异常 函数 何捕获 WndProc      更新时间:2023-10-16

如何捕获下面的伪代码中a的静态对象引发的异常,其中WndProc()是Win32 API中的标准消息处理函数?

class A
{
    public:
    class Exception{};
    A() throw(Exception) { ... }
};
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, UINT wParam, LONG lParam)
{
    static A a;
    switch( message )
    {
        case WM_CREATE:
        ...
        break;
        ...
        default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

非 POD 结构的函数级静态在第一次调用函数时被初始化 您可以将代码块包装在try and catch中,并像任何正常情况一样捕获异常

您需要

在WndProc中捕获它,因为您不应该让C++异常"从"WndProc传播。 (这适用于所有 Windows 回调)

如果 WndProc 代码不"在您的控制之下",则可以改为提供包装器 WndProc。

您需要为以后的处理实施报告机制,例如

LRESULT CALLBACK WndProcNoX(....)
{
   try
   {
      static A a;
      ...
   }
   catch(Exception const & x)
   {
      // What do you want to happen?
      // e.g.: add x to a log, or a list of "unhandled" exceptions 
      // that you process e.g. in an Idle or OnTimer handle,
      // or make otherwise accessible.

      return 0; // (*)
   }
}

(*) 是次要问题:虽然 0 对于大多数消息来说是一个"相当安全"的返回值,但这可能会导致问题,例如,当调用方请求他们需要传递给另一条消息的缓冲区的长度时。繁荣!

为了防止这种情况,您必须在所有单独的处理程序周围放置一个 try/catch,并决定每条消息的"万一出错"返回值。

另一种选择是在发生错误时将消息传递给默认处理程序,btu 也可能对某些消息有问题。

使用初始化为 NULL 的静态指针,并在调用 WM_CREATE 时创建类实例。

当然,对于除WM_CREATE以外的任何消息,如果您将使用该实例,则应仔细检查指针是否为 NULL - 以防万一您以意外的顺序收到消息。