18

クラス(TObject)で私は持っています:

private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage); message TH_MYMESSAGE;

どこTH_MYMESSAGE = WM_USER + 1

クラスコンストラクターで:

FHwnd := AllocateHWND(HandleMyMessage);

への参照を受け取る唯一のオブジェクトFHwndは、プライベート カスタム TThread (このクラス内で作成された) であり、投稿される唯一のメッセージは ですTH_MYMESSAGE。私の理解ではmessage、プロシージャ宣言のディレクティブは、その処理を のみに制限していますTH_MYMESSAGE

これはテストでは問題なく機能していましたが、より大きなアプリケーションに統合するとHandleMyMessage、他のメッセージに対しても同様に発火するフィードバックが得られます (明らかに望ましくない結果が得られます)。

if Message.Msg <> TH_MYMESSAGE then Exit;これは、 を追加することで簡単に修正できましたHandleMyMessage。私の質問は:なぜこれが起こっているのですか?

私の最良の推測は、ディレクティブがあるにもかかわらず、 a と同等のものをAllocateHWND作成したことです。私が見逃しているこれを実装する正しい方法はありますか?HandleMyMessageDefWndProcmessage

4

1 に答える 1

13

ええ、もちろんです。作成されたウィンドウのウィンドウ プロシージャとして機能するAllocateHWnda を受け入れます。混乱は、コンパイラがディレクティブTWndMethodを受け入れることが原因であると思います。messsageそれを入れないでください:

private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage);

..

procedure TMyClass.HandleMyMessage(var Message: TMessage);
begin
  case Message.Msg of
    TH_MYMESSAGE: //
  end;
  Message.Result := DefWindowProc(FHWnd, Message.Msg, Message.WParam, Message.LParam);
end;


編集:(コメントへの応答)。ユーティリティ ウィンドウを作成したクラスでメッセージを処理するには、AllocateHWnd が作成するウィンドウからクラスにメッセージをルーティングします。

private
  FHwnd : HWND;
  procedure HandleMyMessage(var Message : TMessage);
  procedure THMyMessage(var Message: TMessage); message TH_MYMESSAGE;

..

procedure TMyClass.HandleMyMessage(var Message: TMessage);
begin
  case Message.Msg of
    TH_MYMESSAGE: Dispatch(Message);
  end;
  Message.Result := DefWindowProc(FHWnd, Message.Msg, Message.WParam, Message.LParam);
end;

procedure TMyClass.THMyMessage(var Message: TMessage);
begin
  //
end;
于 2012-06-06T12:36:07.407 に答える