■Bricscad V17 Ctrl (文字列取得、送信) 2016/12/13

 ※Delphi XE5 でのサンプルです。Bricscad V17 32bit 版で動作確認をしています。
 ・メインウィンドウ、コマンド履歴ウィンドウ、コマンドラインウィンドウの取得
 ・ウィンドウの文字列取得、ウィンドウへの文字列送信



unit BcadV17TestUnit;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,  Vcl.StdCtrls;

type
  TForm3 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

//******************************************
// 他のプロセス内のコントロールの文字列を得る
//******************************************
function GetWindowString(h : HWND) : string;
var
  p : PChar;
  len : LongInt;
begin
  result := '';
  //ウィンドウの文字列のバイト数を取得
  //終端のNULL文字を含まない文字列の長さ(バイト数)
  len := SendMessage(h, WM_GETTEXTLENGTH, 0, 0);

  if len > 0 then begin
    //終端のNULL文字を含むサイズを確保
    GetMem(p, (len + 1) * 2);
    //格納するバッファの最大サイズ(終端のNULL文字を含む長さ)
    //文字列バッファ
    SendMessage(h, WM_GETTEXT, (len + 1) * 2, LongInt(p));
    //文字列がバッファサイズより長いとき、後部がカットされる
    result := string(p);
    FreeMem(p);
  end;
end;

// アクティブに
procedure TForm3.Button1Click(Sender: TObject);
var
  h : HWND;
begin
  h := FindWindow('BricscadMainWindow', nil);
  if IsWindow(h) then
    SetForegroundWindow(h);
end;

// コマンドライン文字列取得・送信
procedure TForm3.Button2Click(Sender: TObject);
var
  h, hMain : HWND;
  hCmdBar  : HWND;
  hCmdLine : HWND;
  hCmdHist : HWND;
  i : integer;
  cmd : string;
begin
  Edit1.Text := '';
  Memo1.Lines.Clear;

  hMain := FindWindow('BricscadMainWindow', nil);

  // 子ウィンドウを探す
  hCmdBar := FindWindowEx(hMain, 0, nil, 'コマンドライン');

  h := hCmdBar;
  for i := 1 to 4 do h := GetWindow(h, GW_CHILD);
  // コマンド履歴
  hCmdHist := h;

  // コマンドライン
  hCmdLine := GetWindow(h, GW_HWNDNEXT);
  if hCmdLine = 0 then begin
    // トップレベルのウィンドウを探す
    hCmdBar := FindWindow(nil, 'コマンドライン');
    h := hCmdBar;
    for i := 1 to 5 do h := GetWindow(h, GW_CHILD);
    // コマンド履歴
    hCmdHist := h;
    // コマンドライン
    hCmdLine := GetWindow(h, GW_HWNDNEXT);
  end;
  if hCmdLine <> 0 then begin
    // コマンドライン
    Edit1.Text := GetWindowString(hCmdLine);
    // コマンド履歴
    Memo1.Lines.Add(GetWindowString(hCmdHist));
    // 文字列を送信
      { コマンド送信例
        #27:[ESC] キャンセル
        #13:[Enter] }
    cmd := #27#27 + 'ZOOM ALL' + #13;
    for i := 1 to Length(cmd) do
      SendMessage(hCmdLine, WM_CHAR, Word(cmd[i]), 0);
  end;
end;

end.