AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

ShellExcecute/FindWindow/MoveWindow

Ein Thema von geldis · begonnen am 8. Jun 2025 · letzter Beitrag vom 9. Jun 2025
Antwort Antwort
geldis

Registriert seit: 19. Jan 2022
46 Beiträge
 
#1

ShellExcecute/FindWindow/MoveWindow

  Alt Gestern, 07:56
Ich starte mit folgender Prozedur (hier aus dem Forum) ein Programm (C) das eine Anwendung mit Fenster
öffnet:

Delphi-Quellcode:
procedure RunAndWaitShell(Executable, Parameter: STRING; ShowParameter: INTEGER);
var
  Info: TShellExecuteInfo;
  pInfo: PShellExecuteInfo;
  exitCode: DWord;
  HANDLE : THANDLE;
begin
  {Pointer to Info}
  pInfo := @Info;
  {Fill info}
  with Info do
  begin
    cbSize := SizeOf(Info);
    fMask := SEE_MASK_NOCLOSEPROCESS;
    wnd := application.Handle;
    lpVerb := NIL;
    lpFile := PChar(Executable); // emperormapper.exe
    {Parametros al ejecutable}
    {Executable parameters}
    lpParameters := PChar(Parameter + #0);
    lpDirectory := NIL;
    nShow := ShowParameter;
    hInstApp := 0;
  end;
  {Execute}
  ShellExecuteEx(pInfo);
  {Wait to finish}
  repeat
    exitCode := WaitForSingleObject(Info.hProcess, 500);
    Application.ProcessMessages;
  until (exitCode <> WAIT_TIMEOUT);
end;
Die Anwendung /das Fenster taucht planmäßig im Task auf.


Dann möchte ich das Fenster der Anwendung verschieben:

Delphi-Quellcode:
   HANDLE := FindWindow(Nil,'EmperorMapper');
   MoveWindow(HANDLE, 600, 600, 400, 400, True);
Geht nicht. Fehlt was?

geldis
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.001 Beiträge
 
Delphi 12 Athens
 
#2

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Gestern, 08:38
Wird denn das Handle gefunden? Hast du den Wert nach dem Aufruf von FindWindow geprüft?
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von gubbe
gubbe

Registriert seit: 8. Okt 2005
Ort: Schleswig-Holstein
157 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Gestern, 09:38
Du rufst das Programm auf und wartest auf Beendigung. An welcher Stelle willst du jetzt das Fenster verschieben?

Es könnte schon funktionieren, aber Du musst warten, bis das Programm das Fenster geöffnet hat. Schau Dir mal die API-Funktion WaitForInputIdle an.

Wenn das Programm ein Fenster anzeigt und sich nicht direkt wieder beendet, würde ich auch möglichst nicht auf Beendigung des Programms warten. Das ProcessMessages, um Dein Programm nicht einfrieren zu lassen, ist eher schlechter Stil.
  Mit Zitat antworten Zitat
geldis

Registriert seit: 19. Jan 2022
46 Beiträge
 
#4

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Gestern, 10:02
Tja,

das Programm startet, hat den Focus, der Anwender muss eine Datei laden, die wird bearbeitet, dann muss der Anwender sie woandes speichern.
Ergo benutze ich das Fenster.

Wenn ich jetzt prüfe ob das Fenster bereits vorhanden ist via WaitforInputIdle muss ich das Handle der Anwendung haben. Oder? Gut:



Delphi-Quellcode:
function processExists(exeFileName: string): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeFileName))) then
    begin
      Result := True;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;
Delphi-Quellcode:
  RunAndWaitShell(XMLPAth + 'emperormapper.exe','',1);
  If ProcessExists('emperormapper.exe') then
  begin
   WaitforInputIdle(FSnapshotHandle,10000);
   HANDLE := FindWindow(Nil,'EmperorMapper');
   MoveWindow(HANDLE, 600, 600, 400, 400, True);
  end;

Ich werde jetzt nicht ganz schlau aus dem ProcessExists. Wird da geprüft ob der Process existiert bis er existiert?

Jedenfalls geht es so auch nicht.


geldis
  Mit Zitat antworten Zitat
Benutzerbild von gubbe
gubbe

Registriert seit: 8. Okt 2005
Ort: Schleswig-Holstein
157 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Gestern, 10:13
Natürlich geht das nicht. Wenn RunAndWaitShell auf Beendigung des Programms wartet, wird Dein weiterer Code erst danach ausgeführt.
Du musst die Funktion RunAndWaitShell ändern und dort nicht auf Beendigung, sondern auf "Input Idle" warten. Das Process-Handle hast Du dort auch bereits und musst es nicht später umständlich mit ProcessExists wieder ermitteln.

Aber mal ganz von vorne: Hast Du probiert mit einem kleinen Testprogramm das Fenster der zuvor manuell gestarteten "EmpororMapper.exe" zu verschieben? Wenn das nicht geht, kannst Du Dir den Rest sparen.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.001 Beiträge
 
Delphi 12 Athens
 
#6

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Gestern, 12:32
Ich werde jetzt nicht ganz schlau aus dem ProcessExists. Wird da geprüft ob der Process existiert bis er existiert?
Ich hatte gehofft, dass du auf den Debugger verwendest. Wenn du einen Haltepunkt auf die Zeile mit dem FindWindow setzt, stellst du einerseits fest, wann dein Programm dort ankommt. Andererseits kannst du dann mit F8 einen Schritt weiter debuggen und den Rückgabewert prüfen, indem du die Maus über deine Variable Handle hältst.

Aber vermutlich wirst du dort gar nicht zur richtigen Zeit ankommen. Das wurde ja schon gesagt. Um das zu prüfen, ist der Debugger genau wichtig.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
geldis

Registriert seit: 19. Jan 2022
46 Beiträge
 
#7

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Gestern, 15:33
Also : ich mache das jetzt so :

Delphi-Quellcode:
// der Anwender ruft das Programm auf
ShellExecute(self.handle, 'open',Pchar(XMLPAth + 'emperormapper.exe'), '', nil, SW_SHOW);
  // .. delphi wartet ein bisschen bis der Prozess soweit ist das das Fenster steht ..
  Sleep(25);
  // jetzt funzt der Handle Zugriff und damit auch das verschieben
  If ProcessExists('emperormapper.exe') then
    begin
     HANDLE := FindWindow(Nil,'EmperorMapper');
     MoveWindow(HANDLE, Left, Top, 461, 430, True);
    end;
    // das Delphiprogramm wartet bis der Anwender die emperormapper.exe beendet
    While ProcessExists('emperormapper.exe') do
    begin
      Application.ProcessMessages;
    end;
// es geht weiter
Das funktioniert problemlos.

Aber Elegant ist das nicht. Gibt es da irgendwelche ernsthaften Probleme?

geldis
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.001 Beiträge
 
Delphi 12 Athens
 
#8

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Gestern, 17:37
Aber Elegant ist das nicht.
Warum machst du es denn so?

Im ersten Beitrag hast du doch selbst Code gezeigt, mit dem du deinen externen Prozess startest, dessen Handle bekommst (Info.hProcess) und dann auf dessen Ende wartest.

Was hindert dich denn daran, den Prozess zu starten, dir das Handle zu merken, deine Aktionen durchzuführen und dann genauso auf das Ende des Prozesses zu warten?
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
geldis

Registriert seit: 19. Jan 2022
46 Beiträge
 
#9

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Heute, 07:40
Moin.

Seien wir ehrlich : Das funktioniert problemlos und ich habe es einigermaßen verstanden.

Die Abteilung ShellExecute und vor allem die diversen Informationen wie
>> FProcessEntry32, Process32First(FSnapshotHandle, FProcessEntry32), FProcessEntry32.szExeFile, WaitForInputIdle ......

und das ganze andere Zeug - das steht jetzt auf der ToDo Liste. Ich muss und möchte das lernen und verstehen.

Bis dahin lasse ich das jetzt so. Falls niemand ensthafte Einwände hat.

Ich danke jedenfalls allen hier Beteiligten für die Unterstützung und vor allem für die Denkanstösse und Hinweise wo man denn überhaupt mal nachschaut.

geldis
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.001 Beiträge
 
Delphi 12 Athens
 
#10

AW: ShellExcecute/FindWindow/MoveWindow

  Alt Heute, 10:08
Hier mal ein Beispiel angelehnt an den ursprünglichen Code:
Delphi-Quellcode:
procedure RunAndWaitShell(const AExecutable, AParameter: string; AShowParameter: Integer; AOnAfterStart: TProc);
var
  ExecInfo: TShellExecuteInfo;
  WaitResult: DWord;
begin
  FillChar(ExecInfo, SizeOf(ExecInfo), 0);

  ExecInfo.cbSize := SizeOf(ExecInfo);
  ExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  ExecInfo.Wnd := Application.Handle;
  ExecInfo.lpVerb := 'open';
  ExecInfo.lpFile := PChar(AExecutable);
  ExecInfo.lpParameters := PChar(AParameter);
  ExecInfo.lpDirectory := nil;
  ExecInfo.nShow := AShowParameter;
  ExecInfo.hInstApp := 0;

  if ShellExecuteEx(@ExecInfo) then
  begin
    WaitResult := WaitForInputIdle(ExecInfo.hProcess, 10000);
    if WaitResult = WAIT_FAILED then
      ShowMessage('WaitForInputIdle ist fehlgeschlagen!');

    if Assigned(AOnAfterStart) then
      AOnAfterStart;

    repeat
      WaitResult := WaitForSingleObject(ExecInfo.hProcess, 500);
      Application.ProcessMessages;
    until WaitResult <> WAIT_TIMEOUT;

    CloseHandle(ExecInfo.hProcess);
  end
  else
    ShowMessage('Prozess konnte nicht gestartet werden!');
end;

// Aufruf:
  RunAndWaitShell('emperormapper.exe', '', SW_SHOW,
    procedure
    var
      WinHandle: THandle;
    begin
      WinHandle := FindWindow(nil, 'EmperorMapper');
      MoveWindow(WinHandle, 600, 600, 400, 400, True);
    end
  );
Zur Erklärung:
Der Prozess wird gestartet. Dann wird gewartet, bis der Prozess alle anstehenden Eingaben abgeschlossen hat und auf Eingaben wartet. Dann wird eine anonyme Methode aufgerufen, in der du deine Aktionen durchführen kannst. Und danach wird gewartet, bis der Prozess beendet ist.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz