コンポーネントのイベント発生を取得するには?

解決


DBOX  2003-09-03 20:31:05  No: 4575

https://www.petitmonte.com/bbs/answers?question_id=337
と同じ質問です。
WindowProcプロパティを見てその例を試してみようとしたのですが
---------------------------
エラー
---------------------------
TMyListBoxDescendant クラスの 識別子 が必要ですが On が見つかりました.
---------------------------
OK   
---------------------------
このエラーが出てしまいます。
またWindowProcの使い方もよく分かりません。
簡単な例を示していただければ幸いです。


Halbow  2003-09-04 02:08:56  No: 4576

Halbow です。

WindowProc  を入れ替えてサブクラス化する例ですね。
ListBox1 をサブクラス化してメッセージを受け取る例を
示しておきます。

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    OriginalProc:TWndMethod;
    procedure SubclassProc(var Msg:TMessage);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  OriginalProc := ListBox1.WindowProc;//元の値をとっておく
  ListBox1.WindowProc := SubclassProc;//入れ替える
end;

procedure TForm1.SubclassProc(var Msg: TMessage);
begin
  OriginalProc(Msg);//元のプロシージャを実行
  case Msg.Msg of
    WM_APP+33:ShowMessage('メッセージ受け取ったよー');
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ListBox1.Perform(WM_APP+33,0,0);//テスト
end;


DOX  2003-09-04 02:56:30  No: 4577

毎回毎回お世話になります。
Perform で流した WM_APP+33 のユーザー定義メッセージを
SubclassProc の case文 で受け取るわけですね。
ヘルプよりも断然わかり易いです。

自分がやろうとしていたのは〔Ctrl〕+〔Space〕のコード補完機能で、
THintWindowからその親のMemoなどを参照するには
上にあるように ListBox1.WindowProc := SubclassProc;//入れ替える
を使えばできます。
しかしせっかくですからカプセル化してコンポーネントにしようと
考えました。この場合ではフックなどを使うことになり少々難しそうなので
TCustomMemoからイベントを取って作ることにします。
大変勉強になりました。


Halbow  2003-09-04 03:54:28  No: 4578

Halbow です。

> しかしせっかくですからカプセル化してコンポーネントにしようと

例に示した機能をカプセル化したコンポーネントをつくりました。

http://halbow.cool.ne.jp/Notes/N004.html

参考にしてください。


Halbow  2003-09-04 04:53:13  No: 4579

Halbow です。

> TCustomMemoからイベントを取って作ることにします。

あぁ、前の返信はちょっと的はずれでした。継承で派生クラスを
つくるなら、

procedure WndProc(var Message: TMessage); override;

のように WndProc をオーバーライドするだけで、同じ事ができます。
inherited; が前のメソッドを呼び出すことに相当します。


DBOX  2003-09-04 08:22:04  No: 4580

TkkHintWindow = class(THintWindow)
ではメッセージは受け取れませんでした。
Formから離れているからメッセージが届かないのでしょうか。

TkkHintMemo = class(TCustomMemo)
では
procedure TkkHintMemo.WndProc(var Message: TMessage);
begin
  inherited;
  case Message.Msg of
      WM_KEYDOWN: ShowMessage('Key was hit.');
  end;
end;
上手く受け取れました。いいかんじです。
メッセージはこれで処理すれば良いのですね。

蛇足です。
ちょうど今、動的に作成したMemoでFormを親にできなくて
困っていたのですが
https://www.petitmonte.com/bbs/answers?question_id=303
Parent  := AOwner as TWinControl;//←この1行を追加
SenderやSelfではなくAOwnerはTComponentで as 使うとは
まだまだ自分は勉強不足だと痛感します。


DBOX  2003-09-04 19:42:33  No: 4581

追記
また勘違いしていたようです。
TCustomMemoにはイベントはないですが継承を見るとその上には
TWinControlでONKEY関連のイベントが定義されています。
これをoverrideすればWndProcでわざわざ振り分ける必要はないですね。
お騒がせしました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加