11

私は現在、純粋な WinAPI をクラスにラップする独自のミニ ビジュアル フレームワークを作成しています。

現在、メッセージを分析するプロセスは次のようになっています。

  • staticApplication::Runにはメッセージ ループがあります。新しいメッセージを取得し、適切な WndProc にディスパッチします。

  • 私が作成するすべてのウィンドウは (WinAPI に関して) 同じクラスから作成されるため、同じWndProcものが呼び出されます。実際には、これは静的FormAPI::WndProcメソッドです。これは、メッセージがどのウィンドウを参照し、その を呼び出すかをチェックしますWndProc

  • Form::WndProcメッセージを分析するメソッドが呼び出されます。だとしWM_MOUSEMOVEます。そして を呼び出しProcessMouseMoveますDefWindowProc。この点を [1] として覚えておいてください。

  • privateForm::ProcessMouseMoveはメッセージから実際のデータ (x、y、シフト状態など) を取得し、それを使用可能なデータに変換して protected を呼び出しますForm::OnMouseMove

  • 最後に、protectedOnMouseMoveは、イベント ハンドラーが設定されているかどうか (つまり、std::function<void(Form *, int, int, ShiftState)>) をチェックし、設定されている場合は、ハンドラーを呼び出します。それ以外の場合は何もしません。

私の懸念は、電話についてDefWindowProcです。単に「デフォルトの動作を実行する」ように見えるかもしれませんが、実際にはいくつかの重要なことを実行することがあります。たとえば、WM_LBTNDOWN呼び出さないことで無効にDefWindowProcすると、[X] ボタンをクリックしてウィンドウを閉じることができなくなります。

一方で、電話したくない場合もありますDefWindowProc。たとえば、もしWM_CLOSE来たら、アプリケーションを閉じないことにするかもしれません。DefWindowProcこの場合、 を呼び出しますDestroyWindow

私の質問は次のとおりです。に電話するDefWindowProc必要がありますか? もしそうなら、いつもですか、それとも時々ですか?

4

2 に答える 2

16

メッセージの処理方法を決定する際には、次の 3 つの選択肢があります。

  • DefWindowProc() を呼び出していません。メッセージの処理方法を完全にカスタマイズし、デフォルトの実装を望まない場合に適しています。WM_COMMAND と WM_PAINT は典型的な例です。

  • 何かカスタムを行ってから、DefWindowProc() を呼び出します。デフォルトの実装が好きな場合、または必要な場合に適しています。WM_CLOSE は典型的な例です。

  • 最初に DefWindowProc() を呼び出し、次に必要に応じて結果を変更します。典型的な例は WM_NCHITTEST です

適切な選択肢を選択するための黄金律はありません。特定のメッセージとウィンドウの特定のデフォルト処理に大きく依存します。ウィンドウをサブクラス化する場合、これは文書化されたデフォルトの処理ではない可能性があることに注意してください。ただし、間違っている場合は、一般的に簡単に診断できます。

于 2013-01-24T14:25:11.617 に答える
2

質問するだけで、私の質問に答えたようです。次の 2 つのケースを提示しました。

  • WM_LBTNDOWNDefWindowProc 呼び出す必要がある場合- そうしないと、ウィンドウが正しく機能しません。
  • WM_CLOSE、 when - イベント ハンドラーによっては -を呼び出してDefWindowProc はなりません- そうしないと、フレームワークのロジックが壊れます。

答えは次のとおりです。メッセージの種類によって異なります。どのような場合でも DefWindowProc がどのように機能するかを注意深く読み、適切に行動する必要があります。

于 2013-01-24T11:45:44.263 に答える