我想使用Delphi代码启动一个程序,然后“命令”它来执行一个动作,在这种情况下是一个按钮点击。
我知道你可以使用命令行启动一个程序,但我需要正确的参数来点击按钮。我如何或在哪里可以找到它?
答案 0 :(得分:9)
您可以使用专为自动化GUI应用程序而设计的AutoIt程序。例如,AutoIt可以运行程序,等待该程序的窗口完成加载,然后在该窗口中模拟按钮单击。
这远非理想情况 - 命令行参数或COM Interop更可靠 - 但它确实有效。
AutoIt也可以作为COM或DLL版本使用,以便您可以直接在Delphi应用程序中使用它。
答案 1 :(得分:3)
远程控制另一个应用程序是可能的,但是对于Windows的更高版本(Vista / Win7),只有在您控制的程序和程序在相同的进程级别运行时,它才会起作用。 (例如,两个应用程序都不以管理员身份运行)。你想要做的是使用FindWindow api找到按钮的窗口句柄,然后将适当的鼠标消息发送到你找到的句柄。由于不同的应用程序行为不同,因此需要进行一些实验才能使消息传递正确。我相信WM_MOUSEDOWN和WM_MOUSEUP通常都是您要发送的内容。
答案 2 :(得分:3)
我编写了下面的单元来以更健壮的方式解析命令行参数。随意使用它。我在单元后面添加了一个示例用法(滚动到底部)。
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;
答案 3 :(得分:2)
您需要了解的是程序如何获得按钮点击的通知。为此,您可以使用Delphi附带的WinSight或(更好)Spy ++。您运行该程序,使用这些工具之一开始侦听消息,单击按钮,看看会发生什么。最有可能的是,您对WM_COMMAND消息感兴趣(您可以过滤掉所有其他消息,以减少Spy ++中的信息量)。检查单击按钮时会发生什么,哪些值存储在WM_COMMAND消息的wParam和lParam中。从Spy ++中读取程序窗口的类和/或标题,并在应用程序的FindWindow中使用它。然后,使用SendMessage将检测到的消息及其参数发送到获取的窗口句柄,然后关闭:) 有时,消息不是WM_COMMAND,而是其他内容,在这种情况下,您需要检查更多以找到正确的消息
答案 4 :(得分:1)
Delphi为您提供2个全局变量来获取参数:ParamCount和ParamStr。
ParamStr(0)始终是正在运行的可执行文件的完整路径和文件名。
从那时起,由您决定参数是什么。因此,如果您希望将参数称为“clickbutton”,那么在.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。
答案 5 :(得分:1)
Automise可能是适合您的工具。也可以对其进行编码,但只需按一下按钮就可能太复杂了。
答案 6 :(得分:0)
结帐AutoHotKey。它允许您编程关键点击。它是免费的,开源的,重量轻且可编程的。它得到了用户社区的大力支持,并且有一些有用的实用程序。在Lifehacker web site上有一些可以用它做什么的例子。