3

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;
}
4

3 回答 3

1

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

于 2012-04-24T13:45:12.740 回答
1

您需要在 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 也可能对某些消息有问题。

于 2012-04-24T13:50:39.080 回答
0

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

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

于 2012-04-27T00:33:58.710 回答