コンポーネント上のボタンが押されたとき

解決


おやじ  2010-05-25 01:49:37  No: 38526

TPanelから派生したコンポーネントを作り、その上に
AButton:=TBotann.create(self);
BButton:=TButton.create(self);
としてボタンを配置します.このコンポーネントをアプリケーションのフォームに貼付け、これらのボタンを押したとき、コンポーネント内で何がしか、の処理をしたいと考えています.ボタンを押した時のイベントの発生のさせ方及びその処理方法が全く分からず困っています.ヒントをお持ちの方がおられればご教示ください.
環境はWindows7 Home premium/TuboDelphiです.なお、同じことをlazarusの上でもやっています.


ぽむぽむ  2010-05-25 02:12:11  No: 38527

こんなの?

type
  TMyPanel=class(TPanel)
  protected
    FButtonA,
    FButtonB: TButton;

    FButtonAClick,
    FButtonBClick: TNotifyEvent;
  public
    constructor Create(AOwner: TComponent); override;
  protected
    procedure ButtonAClickEvent(Sender: TComponent);
    procedure ButtonBClickEvent(Sender: TComponent);

  published
   property ButtonAClick: TNotifyEvent read FButtonAClick write FButtonAClick
   property ButtonBClick: TNotifyEvent read FButtonBClick write FButtonBClick
  end;

constructor TMyPanel.Create(AOwner: TComponent);
begin
  inherited Craete(AOwner);
  FButtonA := TButton.Create(Self);
  FButtonA.OnClick := ButtonAClickEvent;
  FButtonB := TButton.Create(Self);
  FButtonB.OnClick := ButtonBClickEvent;
end;

procedure TMyPanel.ButtonAClickEvent(Sender: TComponent);
begin
  if Assigned(FButtonAClick) then FButtonAClick(Self{or Sender});
end;
procedure TMyPanel.ButtonBClickEvent(Sender: TComponent);
begin
  if Assigned(FButtonBClick) then FButtonBClick(Self{or Sender});
end;

コンポーネントとして、ボタンクリックイベント出さなくていいのかな?


おやじ  2010-05-25 02:23:47  No: 38528

「ぽむぽむ」さん、早速の回答ありがとうございます.早速やってみます.コンポーネントから出すボタンクリックイベントも実は必要なのですが、それに近いことはなんとか自力で実現はしています.全体を組み合わせ、不安定な動きをするようでしたらご報告いたします.


おやじ  2010-05-25 03:11:11  No: 38529

早速やってみました.
  FButtonA := TButton.Create(Self);
  FButtonA.OnClick := ButtonAClickEvent;//この行と
  FButtonB := TButton.Create(Self);
  FButtonB.OnClick := ButtonBClickEvent;;//この行
上の2行のところで、パラメータの数が不正であるとのコメントが出てエラーストップします.コードの意味が良くわかっていないので、とりあえずの報告しかできません.


Mr.XRAY  2010-05-25 03:28:51  No: 38530

こんにちは.Mr.XRAYです.

残念ですが,TuboDelphiは手元にないので確認はできませんが,Delphi 2010での動作確認です.
「これらのボタンを押したとき」というは,マウスのボタンをクリックしたと解釈します.
http://www.hyuki.com/writing/techask.html#procedure

コンポーネントの内部でイベント類を処理するには,その動作に応じたメソッドを
オーバライド(override)して定義して,そこに書きます.
以下,マウスのクリックの場合です.

TPanelはTControlから派生しています.TFromもTControlから派生していますので,
TFormで動作のテストができます.
以下の手順を試してみてください.

(1) 新規のプロジェクトを作成
(2) interface部のどこか(public部でもよい)に入力位置(カーソル位置)を移動
(3) [Ctrl] + [Space]を押す
      コード補完のリストが表示される
(4) それを表示したままキー[C],[l](エル)とタイプし,Clickを選択する
      protected部が作成され,以下のコードが追加される
      
         procedure Click; override;
      
(6) [Ctrl]+[Shit]を押したまま[C]のキーを押すと
      implementation部に以下のコードができるので,//*の部分を追加
      
         procedure TForm1.Click;
         begin
           inherited;
           ShowMessage('AAA');     //*
         end;
   
      http://mrxray.on.coocan.jp/Delphi/Others/A_IDETechnique.htm#07
   
(7) コンパイルして実行.From1のどこかをマウスでクリックするとダイアログが現れる

これは,Form1のマウスクリックのイベントを作成しなくとも,内部でイベントが
発生したのと同じことになります.
これと同じコードをコンポーネントのコードに追加すれば同じ機能を実現できます.
もちろん,コードを手でタイプしてもいいのですが,上の方法はスペルの間違いを防げます.
もっとも,この例では引数が全くないので,自分でタイプしもいいかも知れませんね.

参考図書
中村拓男著  Delphiコンポーネント設計&開発完全解説
Amazonにあります.

ではがんばってください.


Mr.XRAY  2010-05-25 03:41:41  No: 38531

参考まで,いくつかの他のイベントの場合の例があります.
リスト12のコメント(緑色の文字)が参考になるかも知れません.

内部コンポーネントのイベント処理
http://mrxray.on.coocan.jp/Delphi/plSamples/160_CreateComponent.htm#111


おやじ  2010-05-25 03:46:04  No: 38532

「Mr.XRAY 」様、ありがとうございます.コンポーネント(パネルから派生)をクリックした時の処理は今のところ実現出来ています.問題はコンポーネントの上のボタンを押した時の処理なので、問題はもう少し複雑そうです.参考図書のご紹介、ありがとうございます.


Mr.XRAY  2010-05-25 04:17:04  No: 38533

失礼しました.全くの勘違いでした.
もしかしたら,実行時に生成したボタンのイベントの作成方法のことでしょうか?
そのボタンがどこに配置しているかとは関係なく,イベントは作成できますが...
う〜む.ちがうのかな?

http://mrxray.on.coocan.jp/Delphi/plSamples/160_CreateComponent.htm#101

ここのリスト1のようなことですか?
そんな簡単な問題じゃないんですよね.
これ以上は,状況が理解できないので.申し訳ありませんね.


おやじ  2010-05-25 06:25:03  No: 38534

「Mr.XRAY」さんのご指摘通り、実行時に生成したボタンのイベントに関わっています.
作成したコンポーネントに対し、最初にアプリケーションから初期化の指示'NewPanel1.Initialize();'が出ます.コンポーネント側ではその中で
procedure NewPanel.initialize();
....
Button1:=TButton.Create(self);
.....
などしてボタンを生成します.
問題は、このボタンをクリックした時のコンポーネント内部での処理方法です.すみません、こういう問題を説明するのは難しいですね.


ぽむぽむ  2010-05-25 06:39:38  No: 38535

私のコードは、端折りまくりです(^^ゞ

それと、引数間違ってました
誤)procedure ButtonAClickEvent(Sender: TComponent);
正)procedure ButtonAClickEvent(Sender: TObject);

Mr.XRAY さんが提示されたページ
http://mrxray.on.coocan.jp/Delphi/plSamples/160_CreateComponent.htm#101
ここのButton1Clickの説明を読んでください。

動的にボタンを作成して、そのボタンにクリックイベントを割り当てる。
これが、やりたいことではないのでしょうか?

今回の場合、クリックイベントの記述は、TPanelを継承したコンポーネントで記述します。
というイメージを、最初のレスでしたつもりでした。


おやじ  2010-05-25 21:07:52  No: 38536

「ぽむぽむ」さんと「Mr.XRAY」さん、ありがとうございました.Delphi6,TurboDelphiではうまく行ったのですが、Lazarusでは
  FButtonA.OnClick := ButtonAClickEvent
  ・・・・・
  FButtonB.OnClick := ButtonBClickEvent
でエラーが出てうまくいきませんでした.苦肉の策としてDelphiエミュレーションモードのまじないのつもりで、
unit Dosc;
//{$mode objfpc}{$H+}//これを
{$MODE Delphi}       //こう変えたら
interface
すんなりと通り、期待通りの動作をしました.
ちなみに、制作中のコンポーネントはデジタルオシロライクのデザインで、計算結果を波形として表示する表示用コンポーネントです.問題のボタンは、画面消しと画面設定用コンポーネントを起動するためのものです.


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

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






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