2 Stimmen

Wie erhalte ich die Befehlszeilenparameter für bestimmte Schaltflächenklicks in einer Anwendung?

Ich möchte ein Programm starten mit Delphi Code und "befehlen" ihm, eine Aktion auszuführen, in diesem Fall einen Tastenklick.

Ich weiß, dass man ein Programm über die Befehlszeile starten kann, aber ich bräuchte die richtigen Parameter für den Tastenklick. Wie oder wo kann ich sie finden?

9voto

Josh Kelley Punkte 52169

Sie könnten ein Programm verwenden wie AutoIt das für die Automatisierung von GUI-Anwendungen konzipiert ist. AutoIt kann zum Beispiel ein Programm ausführen, warten, bis das Programmfenster fertig geladen ist, und dann einen Tastenklick in diesem Fenster simulieren.

Diese Situation ist bei weitem nicht ideal - Befehlszeilenparameter oder COM Interop sind viel zuverlässiger - aber es funktioniert.

AutoIt ist auch als COM- oder DLL-Version verfügbar, so dass Sie es direkt in Ihrer Delphi-Anwendung verwenden können.

3voto

skamradt Punkte 15128

Die Fernsteuerung einer anderen Anwendung ist möglich, aber bei den neueren Versionen von Windows (Vista/Win7) funktioniert sie NUR, wenn das Programm, das Sie steuern, und Ihr Programm auf derselben Prozessebene ausgeführt werden. (z. B. wenn beide Anwendungen NICHT als Administrator laufen). Sie müssen das Windows-Handle der Schaltfläche mit der API FindWindow finden und dann entsprechende Mausnachrichten an das Handle senden, das Sie gefunden haben. Da sich verschiedene Anwendungen unterschiedlich verhalten, müssen Sie etwas experimentieren, um die richtigen Nachrichten zu erhalten. Ich glaube, dass WM_MOUSEDOWN und WM_MOUSEUP im Allgemeinen das sind, was Sie senden möchten.

3voto

JosephStyons Punkte 55410

Ich habe die unten stehende Unit geschrieben, um Befehlszeilenargumente auf eine robustere Art und Weise zu parsen. Sie können sie gerne verwenden. Ich habe ein Anwendungsbeispiel nach der Unit eingefügt (scrollen Sie nach unten).

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.

Beispiel für die Verwendung:

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;

2voto

gcvt Punkte 1472

Sie müssen herausfinden, wie das Programm über den Klick auf die Schaltfläche informiert wird. Dafür können Sie WinSight verwenden, das mit Delphi geliefert wird, oder (viel besser) Spy++. Starten Sie das Programm, lauschen Sie mit einem dieser Tools auf Nachrichten, klicken Sie auf die Schaltfläche und sehen Sie, was passiert. Höchstwahrscheinlich sind Sie an der WM_COMMAND-Meldung interessiert (Sie können alle anderen Meldungen herausfiltern, um die Menge der Informationen in Spy++ zu reduzieren). Untersuchen Sie, was passiert, wenn Sie auf die Schaltfläche klicken, welche Werte in wParam und lParam der WM_COMMAND-Nachricht gespeichert sind. Lesen Sie die Klasse und/oder den Titel des Programmfensters aus Spy++ und verwenden Sie diese in FindWindow in Ihrer Anwendung. Dann verwenden Sie SendMessage, um die erkannte Nachricht und ihre Parameter an das erhaltene Fensterhandle zu senden, und los geht's :) Manchmal ist die Nachricht nicht WM_COMMAND, sondern etwas anderes. In diesem Fall müssen Sie mehr untersuchen, um die richtige Nachricht zu finden

1voto

J__ Punkte 3667

Delphi bietet 2 globale Variablen für die Aufnahme von Parametern: ParamCount und ParamStr.

ParamStr(0) ist immer der vollständige Pfad und Dateiname der ausführbaren Datei, die gerade ausgeführt wird.

Von da an hängt es von Ihnen ab, wie die Parameter aussehen. Wenn Sie also möchten, dass der Parameter "clickbutton" heißt, müssen Sie vor Application.Run in der .dpr-Datei etwas wie folgt eingeben:

var
  i: Integer;

for i := 0 to ParamCount Do
 if (Lowercase(ParamStr(i)) = 'clickbutton') then
  Form1.Button1.Click;

Wenn Ihr Projekt also mit der Befehlszeile aufgerufen wird:

 project1.exe clickbutton

dann wird die Schaltfläche1 im Formular1 angeklickt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X