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

C++ の例外が WndProc の「外部」に伝播されないようにする必要があるため、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 を配置し、各メッセージの「エラーの場合」の戻り値を決定する必要があります。

もう 1 つのオプションは、エラーが発生した場合にメッセージをデフォルトのハンドラーに渡すことです。ただし、一部のメッセージでは問題になる可能性があります。

于 2012-04-24T13:50:39.080 に答える
1

非POD構造の関数レベルの静的は、関数が初めて呼び出されたときに初期化され、コードブロックをラップして、try and catch通常のケースと同様に例外をキャッチできます

于 2012-04-24T13:45:12.740 に答える
0

NULL に初期化された静的ポインターを使用し、WM_CREATE が呼び出されたときにクラス インスタンスを作成します。

もちろん、WM_CREATE 以外のメッセージについては、インスタンスを使用する場合は、ポインターが NULL でないことを再確認する必要があります。

于 2012-04-27T00:33:58.710 に答える