Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2012年05月03日] [更新 2012年05月03日] Delphi サンプルプログラム集
677_他のアプリの TToobar のボタンをクリック
動作確認等 Windows XP(SP3) + Delphi XE Pro
Windows 7 U64(SP1) + Delphi XE Pro
677_ToobarButtonClick.zip [1,157 KB] 2012年05月03日版 (EXE 同梱)







他のアプリの TToobar のボタンをクリック


他のアプリの TToolbar のボタンを,自アプリ側でクリックするサンプルです.
ウィンドウハンドルを持つコントロールであれば,そのコントロールのウィンドウハンドルを取得して,BM_CLICK や他のマウス操作メッセージで操作できますが,TToolbar のボタンはウィンドウハンドルがありません.そこで共有メモリを使用してコントロールの情報を取得します.
共有メモリの操作に,Halbow 資料館の [共有メモリクラス] を使用しています.この共有メモリクラスの簡単な使用例とも言えるサンプルとなっています.
  • (1) クリックしたいボタンの座標値を決めるために,ボタンの矩形領域を取得
  • (2) その矩形領域内の座標に,マウスクリックのメッセージを送る
という手順になっています.
ボタンの矩形領域を取得するには,ボタンの番号を指定して,TB_GETITEMRECT メッセージを,対象ツールバーのハンドルに対して送ります.このツールバーは他のアプリのものです.直接 TRect レコード型の値として取得できません.共有メモリで取得した後,共有メモリから取出します.

このサンプルでは,確認のため,他のアプリ側では,Toolbar のボタンクリックイベントでクリックされたボタン番号を TMemo に表示するようにしています.

ボタンの矩形領域を取得する TB_GETITEMRECT メッセージは,結果が戻ってからでないと,ボタンクリックの時の座標値が決められません.したがって,SendMessage で送っています.
ボタンクリック用の WM_LBUTTONDOWN と WM_LBUTTONUP メッセージは,PostMessage で送ります.


図1
設計時画面
  • 右が自アプリ
  • 左が他のアプリ
図2
実行例
  • スピンエディトの値と同じ番号のボタンを自アプリからクリック
  • 他のアプリの表示は確認用

リスト1
他のアプリの Toolbar の指定ボタンをクリックするサンプル
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Spin;

type
  TForm1 = class(TForm)
    Button1: TButton;
    SpinEdit1: TSpinEdit;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses CommCtrl, CommonMemoryUnit;

{$R *.dfm}

//=============================================================================
//  [ツールバーのボタンクリック]
//
//  TB_GETITEMRECTの使用には,usesにCommCtrlが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  hTargetWnd : HWND;
  hToolBar   : HWND;
  r          : TRect;
  ALeft      : WORD;
  ATop       : WORD;
  ComMem     : TCommMemNT;
  ASize      : Integer;
begin
  //他のアプリのTToolbarのハンドルを取得
  hTargetWnd := FindWindow('TTargetForm', nil);
  if hTargetWnd = 0 then exit;

  //ツールバーのハンドルを取得
  hToolBar := FindWindowEx(hTargetWnd, 0, 'TToolbar', nil);
  if hToolBar = 0 then exit;

  //TToolbarのボタンのTRect構造体の値を,共有メモリを介して取得
  //ボタンの番号はSpinEdit1の値
  ASize  := SizeOf(r);
  ComMem := TCommMemNT.Create(hToolBar, ASize);
  try
    SendMessage(hToolBar, TB_GETITEMRECT, SpinEdit1.Value, LPARAM(ComMem.MemPtr));
    ComMem.Read(0, @r, ASize);
  finally
    ComMem.Free;
  end;

  //矩形領域r(TToolbarのSpinEdit1.Value番目)のボタンをクリック
  ALeft := r.Left + 2;
  ATop  := r.Top  + 2;
  PostMessage(hToolBar,WM_LBUTTONDOWN, 0, MakeLParam(ALeft, ATop));
  PostMessage(hToolBar,WM_LBUTTONUP,   0, MakeLParam(ALeft, ATop));
end;

//=============================================================================
//  [結果の表示をクリア]
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
  hTargetWnd : HWND;
  hMemo      : HWND;
begin
  hTargetWnd := FindWindow('TTargetForm', nil);
  if hTargetWnd = 0 then exit;

  hMemo := FindWindowEx(hTargetWnd, 0, 'TMemo', nil);
  if hMemo = 0 then exit;

  SendMessage(hMemo, WM_SETTEXT, 0, LPARAM(nil));
end;

end.


リスト2
他のアプリのコード
クリックされたボタン確認のために,ボタンの番号を TMemo に表示 (番号は 0 ベース)
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ToolWin, ImgList;

type
  TTargetForm = class(TForm)
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    ToolButton6: TToolButton;
    ImageList1: TImageList;
    ToolButton7: TToolButton;
    Memo1: TMemo;
    procedure ToolButton1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  TargetForm: TTargetForm;

implementation

{$R *.dfm}

//=============================================================================
//  ツールバーのボタンクリックイベント
//=============================================================================
procedure TTargetForm.ToolButton1Click(Sender: TObject);
var
  AIndex : Integer;
begin
  AIndex := TToolButton(Sender).Index;
  Memo1.Lines.Add('Clicked No  ' + IntToStr(AIndex));
end;

end.