How do I get command line parameters for specific button clicks in an application?
You can use a program like AutoIt , which is designed to automate GUI applications. For example, AutoIt can launch a program, wait for that program window to end, and then simulate a button click in that window.
This is far from ideal - command line or COM Interop options are much more reliable, but they work.
AutoIt is also available as a COM or DLL version, so you can use it directly from your Delphi application.
source to share
Remote control of another application is possible, however with later versions of Windows (Vista / Win7) it will ONLY work if the program you control and your program are running at the same process level. (both apps don't work as administrator, for example). What you want to do is find the window handle of the button using the FindWindow api and then send the appropriate mouse messages to the handle you located. Since different applications behave differently, it will take some experimentation to get your messaging properly configured. I believe that WM_MOUSEDOWN and WM_MOUSEUP are usually what you want to send.
source to share
I wrote a block below for parsing command line arguments. Feel free to use it. I have included a use case after the block (scroll down).
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.
Using example:
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;
source to share
What you need to know is how the program receives the information about the button press. You can use WinSight that ships with Delphi or (much better) Spy ++ for this. You launch the program, start listening to messages using one of these tools, click a button and see what happens. You will most likely be interested in the WM_COMMAND message (you can filter out all other messages to reduce the amount of information in Spy ++). Check what happens when you click the button, what values ββare stored in wParam and lParam of the WM_COMMAND message. Read the class and / or program window name from Spy ++ and use that in FindWindow in your application. Then use SendMessage to send the detected message and its parameters to the received window handle and from you .:) Sometimes the message is not WM_COMMAND but something else, in which case you need to check more to find the correct one
source to share
Delphi provides two global variables for selecting parameters: ParamCount and ParamStr.
ParamStr (0) is always the full path and name of the executable file.
From now on, everything depends on your parameters. So if you want this parameter to be called "clickbutton" then do something like this before Application.Run in your .dpr file:
var
i: Integer;
for i := 0 to ParamCount Do
if (Lowercase(ParamStr(i)) = 'clickbutton') then
Form1.Button1.Click;
So, if your project is called from the command line:
project1.exe clickbutton
then Button1 will be clicked on Form1.
source to share
Check AutoHotKey . It allows you to program keystrokes. It's free, open source, lightweight, and programmable. It enjoys significant support from its user community and comes with several useful utilities. There are several examples of what you can do with it on the Lifehacker website .
source to share