Delphiコードを使用してプログラムを開始し、アクション (この場合はボタン クリック) を実行するように「命令」したいと考えています。
コマンドラインを使用してプログラムを起動できることは知っていますが、ボタンのクリックには適切なパラメーターが必要です。どのように、またはどこで見つけることができますか?
Delphiコードを使用してプログラムを開始し、アクション (この場合はボタン クリック) を実行するように「命令」したいと考えています。
コマンドラインを使用してプログラムを起動できることは知っていますが、ボタンのクリックには適切なパラメーターが必要です。どのように、またはどこで見つけることができますか?
GUI アプリケーションを自動化するために設計されたAutoItのようなプログラムを使用できます。たとえば、AutoIt はプログラムを実行し、そのプログラムのウィンドウの読み込みが完了するのを待ってから、そのウィンドウでボタンのクリックをシミュレートできます。
これは理想的な状況とはほど遠いものです。コマンド ライン パラメータや COM 相互運用機能の方がはるかに信頼性が高くなりますが、機能します。
AutoIt は、Delphi アプリから直接使用できるように、COM または DLL バージョンとしても利用できます。
別のアプリケーションをリモート制御することは可能ですが、それ以降のバージョンのWindows(Vista / Win7)では、制御しているプログラムとプログラムが同じプロセスレベルで実行されている場合にのみ機能します。(たとえば、両方のアプリが管理者として実行されていません)。あなたがしたいことは、FindWindow apiを使用してボタンのウィンドウハンドルを見つけて、あなたが見つけたハンドルに適切なマウスメッセージを送ることです。アプリケーションが異なれば動作も異なるため、メッセージングを正しく行うにはある程度の実験が必要になります。WM_MOUSEDOWNとWM_MOUSEUPは、一般的にあなたが送信しようとしているものだと思います。
コマンドライン引数をより堅牢な方法で解析するために、以下のユニットを作成しました。お気軽にご利用ください。ユニットの後に使用例を含めました (一番下までスクロール)。
unit CLArgParser;
//this class makes it easier to parse command line arguments
interface
uses
Classes;
type
strarr = array of string;
type
TCLArgParser = class
private
FPermitTags : array of string;
FTrimAll: boolean;
public
function IsArg(argtag : string) : boolean;
function GetArg(argtag : string) : string;
function GetDelimtedArg(argtag, delimiter : string) : TStringList;
constructor Create(ArgTags : array of string); overload;
constructor Create; overload;
property TrimAll: boolean read FTrimAll write FTrimAll;
end;
implementation
uses
SysUtils;
const
cDefaultTags : array[0..1] of string = ('-','/');
constructor TCLArgParser.Create(ArgTags : array of string);
var i : integer;
begin
try
SetLength(FPermitTags,High(ArgTags)+1);
for i := 0 to High(ArgTags) do begin
FPermitTags[i] := ArgTags[i];
end; //for i
except on e : exception do
raise;
end; //try-except
end;
constructor TCLArgParser.Create;
begin
FTrimAll := False; //default value
inherited Create;
Create(cDefaultTags);
end;
function TCLArgParser.GetArg(argtag: string): string;
var i,j,n : integer;
begin
try
Result := '';
n := High(FPermitTags);
for i := 1 to ParamCount do
for j := 0 to n do
if Uppercase(ParamStr(i)) = (FPermitTags[j] + Uppercase(argtag)) then
Result := ParamStr(i+1);
if FTrimAll then begin
Result := Trim(Result);
end;
except on e : exception do
raise;
end; //try-except
end;
function TCLArgParser.GetDelimtedArg(argtag, delimiter: string): TStringList;
var i : integer;
argval, tmp : string;
begin
try
Result := TStringList.Create;
argval := GetArg(argtag);
for i := 1 to Length(argval) do begin
if ((i = Length(argval)) or ((argval[i] = delimiter) and (tmp <> '')))
then begin
if i = Length(argval) then begin
tmp := tmp + argval[i];
if FTrimAll then begin
tmp := Trim(tmp);
end;
end;
Result.Add(tmp);
tmp := '';
end //if we found a delimted value
else begin
tmp := tmp + argval[i];
end; //else we just keep looking
end; //for ea. character
except on e : exception do
raise;
end; //try-except
end;
function TCLArgParser.IsArg(argtag: string): boolean;
var i,j,n : integer;
begin
try
Result := False;
n := High(FPermitTags);
for i := 1 to ParamCount do begin
for j := 0 to n do begin
if Uppercase(ParamStr(i)) = (FPermitTags[j] + Uppercase(argtag))
then begin
Result := True;
Exit;
end; //if we found it
end; //for j
end; //for i
except on e : exception do
raise;
end; //try-except
end;
end.
使用例:
procedure DefineParameters;
var
clarg: TCLArgParser;
begin
//assign command line arguments to various global variables
clarg := TCLArgParser.Create;
try
wantshelp := clarg.IsArg('?') or clArg.IsArg('help');
dbuser := clarg.GetArg('u');
dbpwd := clarg.GetArg('p');
dbserver := clarg.GetArg('d');
localfilename := clarg.GetArg('localfile');
ftpuser := clarg.GetArg('ftu');
ftppwd := clarg.GetArg('ftp');
ftpipaddr := clarg.GetArg('fti');
emailfromacct := clarg.GetArg('efrom');
emailtoacct := clarg.GetArg('eto');
archivefolder := clarg.GetArg('archive');
if archivefolder <> '' then begin
if archivefolder[Length(archivefolder)] <> '\' then begin
archivefolder := archivefolder + '\';
end;
end;
//figure out the (optional) verbosity code.
//if they didn't specify, assume the default value
verbosity := c_VerbosityDefault;
if clArg.IsArg('v') then begin
if not(TryStrToInt(clarg.GetArg('v'),verbosity)) then begin
WriteLn('Invalid verbosity code- using default of ' +
IntToStr(c_VerbosityDefault) + '.');
end; //if their specified verbosity was invalid
end; //if they specified the verbosity
if not(TryStrToInt(clarg.GetArg('maxtime'),maxtime)) then begin
maxtime := 9999999;
end;
finally
FreeAndNil(clarg);
end; //try-finally
end;
調べる必要があるのは、プログラムがボタンのクリックをどのように通知されるかです。そのためには、Delphi または (はるかに優れた) Spy++ に付属の WinSight を使用できます。プログラムを実行し、これらのツールのいずれかを使用してメッセージのリッスンを開始し、ボタンをクリックして何が起こるかを確認します。ほとんどの場合、WM_COMMAND メッセージに関心があるでしょう (Spy++ の情報量を減らすために、他のすべてのメッセージを除外できます)。ボタンをクリックすると何が起こるかを調べます。値は WM_COMMAND メッセージの wParam と lParam に保存されます。Spy++ からプログラムのウィンドウのクラスやタイトルを読み取り、それをアプリの FindWindow で使用します。次に、SendMessage を使用して、検出されたメッセージとそのパラメーターを取得したウィンドウ ハンドルに送信します。
Delphiには、パラメータを取得するための2つのグローバル変数ParamCountとParamStrが用意されています。
ParamStr(0)は常に、実行中の実行可能ファイルのフルパスとファイル名です。
それ以降、パラメータが何であるかはあなた次第です。したがって、パラメータを「クリックボタン」と呼びたい場合は、.dprファイルのApplication.Runの前に次のようにします。
var
i: Integer;
for i := 0 to ParamCount Do
if (Lowercase(ParamStr(i)) = 'clickbutton') then
Form1.Button1.Click;
したがって、プロジェクトがコマンドラインで呼び出された場合:
project1.exe clickbutton
次に、Form1でButton1をクリックします。
Automiseはあなたにぴったりのツールかもしれません。それをコーディングすることもできますが、ボタンを 1 回クリックするだけでは複雑すぎる可能性があります。
AutoHotKeyをチェックしてください。キークリックをプログラムすることができます。無料、オープン ソース、軽量、プログラム可能です。ユーザーコミュニティからかなりの支持を得ており、それを使用して作成されたいくつかの便利なユーティリティがあります。Lifehackerの Web サイトには、これを使ってできることの例がいくつかあります。