Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi von gestarteten Programmen alle Fensterhandles in ini (https://www.delphipraxis.net/99435-von-gestarteten-programmen-alle-fensterhandles-ini.html)

bluescreen25 12. Sep 2007 08:41


von gestarteten Programmen alle Fensterhandles in ini
 
Hallo, ich kann aus meiner Anwendung heraus diverse externe Programme starten. Ich überwache auch via Findwindow in einer Schleife, ob das Fenster erzeugt wird.

Jetzt möchte ich das komplette Window-Handle in eine ini speichern. Am besten wäre es, wenn von der ext. Anwendung mehrere Fenster erzeugt werden, das diese gleich mit abgespeichert werden.

Grund ist, das ich zwar alle ext. Anwendung starten kann, aber es oft vorkommt, das das erste Fenster nicht das Hauptfenster ist, und wenn ich es zwischendurch nach vorne holen will, das es dann auf das falsche zugreift.

In der ini könnte man dann manuell das main-Handle an erster Stelle setzen, wenn mehrere vorhanden sind und bei 2.ten Start hat man sogleich das richtige Handle....weiterer Vorteil: man könnte, falls Abfragefenster bei Start einer Anwendung aufkommen, ggf die ini so auslesen, das das main-window nach vorne kommt und dann das Abfragefenster wenn vorhanden wiedrum oben auf (damit es nicht hinter dem Mainfenster verschwindet)

Oder gibt es bessere Möglichkeiten?

Gruß, bluescreen25

SirThornberry 12. Sep 2007 08:50

Re: von gestarteten Programmen alle Fensterhandles in ini
 
ich finde deine Lösung recht unschön. Starte deine Anwendung lieber mit CreateProzess und suche dann alle Fenster dieses Prozesses. Dann kannst du auch auf die Ini verzichten.
Und wenn das nicht geht, übergebe der Anwendung die du startest das Handle deines Programmes. Die Andere Anwendung kann dann nach dem Start eine Message mit ihrem Handle zurück schicken und du sparst dir eine unnötige Dateiarbeit.

hoika 12. Sep 2007 08:54

Re: von gestarteten Programmen alle Fensterhandles in ini
 
Hallo,

warum willst du etwas speichern,
was sich bei jedem Start eines Programm ändert ???

Das Handle wird von Windows vergeben.
Startest du den Editor, beendest ihn und
startest ihn neu, hat er ein anderes Handle.

Wenn du dir nur etwas merken willst,
erzeuge eine Klasse

type
TAppWindows = class
sAppName: String;
Handle: WORD
end

und packe die in eine TList;


Ansonsten FindWindow, FindWindowEx.


Heiko

bluescreen25 12. Sep 2007 10:46

Re: von gestarteten Programmen alle Fensterhandles in ini
 
Zitat:

Zitat von SirThornberry
ich finde deine Lösung recht unschön. Starte deine Anwendung lieber mit CreateProzess und suche dann alle Fenster dieses Prozesses. Dann kannst du auch auf die Ini verzichten.
Und wenn das nicht geht, übergebe der Anwendung die du startest das Handle deines Programmes. Die Andere Anwendung kann dann nach dem Start eine Message mit ihrem Handle zurück schicken und du sparst dir eine unnötige Dateiarbeit.

Soweit so gut, ich starte schon mit:
Delphi-Quellcode:
function RunProcess(FileName: string; ShowCmd: DWORD; wait: Boolean; ProcID: PDWORD): Longword;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb         := SizeOf(StartupInfo);
  StartupInfo.dwFlags    := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
  StartupInfo.wShowWindow := ShowCmd;
  if not CreateProcess(nil,@Filename[1],nil,nil,False,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,nil,nil,StartupInfo,ProcessInfo) then
  Result := WAIT_FAILED
  else
  begin
    if wait = FALSE then
    begin
      if ProcID <> nil then ProcID^ := ProcessInfo.dwProcessId;
      exit;
    end;
    WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    GetExitCodeProcess(ProcessInfo.hProcess, Result);
  end;
  if ProcessInfo.hProcess <> 0 then
    CloseHandle(ProcessInfo.hProcess);
  if ProcessInfo.hThread <> 0 then
    CloseHandle(ProcessInfo.hThread);
end;
und fange die Fenster mit:
Delphi-Quellcode:
repeat
   AppWindow := GetWndHandle(ProcID);
   application.ProcessMessages;    
   Application.BringToFront;
   sleep(500);                      
until (AppWindow <> 0) or stopSearch;//stopSearch durch Timer


if (AppWindow <> 0) then
begin
 //do something
end;
Desweiteren habe ich noch ein Abfangen, falls schon gestartet und bringe mir dann nur das App nach vorne jedoch überlagert meine Form (als kleine Toolleiste) das extApp.

Als Bespiel möchte ich mal ein Navigationsprogramm geben, welches mir bei jedem Start ein Fenster öffnet, welches Warnhinweise gibt, jedoch einmal bestätigt, brauche ich nur noch das 2.te Fenster, damit ich es nach vorne holen kann...in meinem Fall habe ich lediglich das 1.te eingefangen, welches nacher nicht mehr existiert und mir nichts bringt...

Andere Programme verhalten sich noch anders...in meiner App kann der User die externen Programme selber bestimmen, die er starten will, also weiss ich erstmal nichts über die externen Programme....muss die aber händeln...

Vielleicht hast du ein Beispiel parat, um erstmal alle Fenster die auf ein gestartetes Programm aufkommen, aus der ProcID zu ermitteln....

Wie würde man denn trotzdem die aus dem Findwindow in eine Datei speichern können ? Sprich Classname und Fenstertitel ?(Interessehalber)

Gruß, bluescreen25

bluescreen25 12. Sep 2007 11:08

Re: von gestarteten Programmen alle Fensterhandles in ini
 
Zitat:

Zitat von hoika
Hallo,

warum willst du etwas speichern,
was sich bei jedem Start eines Programm ändert ???

Das Handle wird von Windows vergeben.
Startest du den Editor, beendest ihn und
startest ihn neu, hat er ein anderes Handle.

Wenn du dir nur etwas merken willst,
erzeuge eine Klasse

type
TAppWindows = class
sAppName: String;
Handle: WORD
end

und packe die in eine TList;


Ansonsten FindWindow, FindWindowEx.


Heiko


Warum sind die Handles anders beim Editor nach erneutem Start ? Gerade mit Notepad ist es noch einfach den einzufangen. Dein Tipp mit FindWindowEx könnte hier noch was bringen, da könnte ich die erweiterten Fenster erhalten.

Achso,nochwas: Ich habe eine separate Config.exe, in der vom User die später nutzbaren extApps eingetragen werden.

Beim ersten Start der Apps ist alles kein Problem, vielmehr das nachträgliche einfangen des "richtigen" Mainfensters. Ich frage in meinem Programm ab, ob ein ext. App schon gestartet ist und wenn ja, dann Fenster nach vorne holen....

Hatte das App ein Copyright-Fenster zu Beginn, welches man wegklicken muss, dann habe ich auch nur das Handle...Mainwindow-Handle habe ich nicht.

Da sich viele Progs unterschiedlich verhalten, dachte ich mir, speziell für diesen Fall das pro App auszulagern (habe ja schon eine ini, in der die Apps mit Pfad aus der Config drinstehen) und die Fenster abzuspeichern.

Der User könnte im schlimmsten Fall die ini bearbeiten und die Fensterreihenfolge bzw Mainwindow nach oben schieben. Starten ginge dann über die exe, Fenster einfangen über das erste eingetragene Window. Falls noch weitere Fenster vorhanden, stehen die ab der 2.ten Stelle und werden dann falls gefunden, auch nach vorne vor das Mainwindow geholt...

Naja..etwas komplex der Gedanke....aber brauche ne Lösung, die funktioniert...

Gruß,bluescreen25

SirThornberry 12. Sep 2007 11:16

Re: von gestarteten Programmen alle Fensterhandles in ini
 
Hmm, ich blicke nicht ganz durch.
Du hast ein Programm (nachfolgend Programm1) welches ein anderes (nachfolgend Programm2) startet.
Hast du Programm1 selbst geschrieben?
Hast du Programm2 selbst geschrieben?

Wenn Programm1 die Handles von Programm2 sucht, warum willst du dann das Programm1 die Handles in eine Ini-Datei schreibt?


Und jetzt mein Teil als Moderator :mrgreen:
Nutze zukünftig bitte http://www.delphipraxis.net/template.../icon_edit.gif wenn du noch etwas hinzufügen willst. Denn es ist nicht gern gesehen das man immer wieder einen neuen Teil dazu schreibt ohne das inzwischen was von anderen geschrieben wurde (nach 24 Stunden sieht das anders aus). Grund dafür ist, das dein Beitrag dann auf der Hauptseite ganz nach oben wandert was wiederum ungerecht gegenüber den anderen ist welche nicht ständig pushen (ihren Beitrag nach oben bringen).

bluescreen25 12. Sep 2007 12:55

Re: von gestarteten Programmen alle Fensterhandles in ini
 
Zitat:

Zitat von SirThornberry
Hmm, ich blicke nicht ganz durch.
Du hast ein Programm (nachfolgend Programm1) welches ein anderes (nachfolgend Programm2) startet.
Hast du Programm1 selbst geschrieben?
Hast du Programm2 selbst geschrieben?

Wenn Programm1 die Handles von Programm2 sucht, warum willst du dann das Programm1 die Handles in eine Ini-Datei schreibt?


Und jetzt mein Teil als Moderator :mrgreen:
Nutze zukünftig bitte http://www.delphipraxis.net/template.../icon_edit.gif wenn du noch etwas hinzufügen willst. Denn es ist nicht gern gesehen das man immer wieder einen neuen Teil dazu schreibt ohne das inzwischen was von anderen geschrieben wurde (nach 24 Stunden sieht das anders aus). Grund dafür ist, das dein Beitrag dann auf der Hauptseite ganz nach oben wandert was wiederum ungerecht gegenüber den anderen ist welche nicht ständig pushen (ihren Beitrag nach oben bringen).

Öhmm, ich habe nix editiert oder erweitert, habe auf deinen Beitrag und den von Hoika geantwortet !

Also zum Thema:
Ich habe eine Anwendung geschrieben (CarPC_App) und diese beinhaltet einige Funktionen wie Mp3 oder Video/DVD-Player und halt die extApps.

Da können die User in der Config von der Platte Anwendungen raussuchen , die dann innerhalb des CarPC-Progs startbar sind. Werden extApps gestartet, wird die Form meiner Anwendung zu einer Art AppBar-Leiste, die TopMost ist.

Über die AppBar kann man zurück zu den anderen Forms wie mp3-player.
Ruft man dann nochmal das gleiche extApp auf (ist ja schon gestartet) dann wird es einfach nur nach vorne geholt. Ich kann aber im Moment aber nur Fenster nach vorne holen, durch das Handle aus: ProcID oder Findwindow,sprich classname und Fenstertitel. Klappt auch soweit.

Nur einige extApps haben halt diese Mehrfenster und das macht es etwas schwierig, wenn ich nicht das Mainwindow-Handle habe, sondern nur das Handle vom Copyright-Fenster oder wie bei der Navi (oben erwähnt) ein Warnfenster, das man immer einmal bei Start wegklicken muss. Man beachte auch mal den Fall, das beim Start ggf das Warnfenster noch gar nicht weggeklickt wird, man wieder zum mp3-player geht, danach wieder zurück zum extApp...

Zur Zeit habe ich bei einigen Sonder-Navi-Apps diese mit im Code eingebunden, aber auf Dauer muss ich eine andere Lösung finden, die entweder immer geht, oder "von aussen" beeinflussbar ist. Sprich der User nutzt XSpy und trägt in die ini ein, oder mein App findet alle Fenster und schreibt die in eine Datei und man kann die Reihenfolge selber ändern....

Irgendwas in der Art...

Siehe hier nochmal ein Sonderbeispiel, wo ein extApp ein Hauptfenster hat und noch ein weiteres, welches aber auch nach vorne geholt werden muss..

Delphi-Quellcode:
if app = 'pgs.exe' then//starten, danach Fenster einfangen
       begin
         repeat
           AppWindow := FindWindow('WC_LMSW2003','PocketGIS');
           Wnd1 := FindWindow('#32770','PocketGIS');  
           application.ProcessMessages;    
           setwindowlong(AppWindow, GWL_STYLE, getwindowlong(AppWindow, GWL_STYLE) and (not ws_dlgframe) and (not ws_border) and (not WS_SIZEBOX));
           Application.BringToFront;
           sleep(500);                      
          until ((AppWindow <> 0) and (Wnd1 <> 0)) or stopSearch;
       end;


if (AppWindow <> 0) then //wenn gefunden dann..
         begin                                
           if app = 'pgs.exe' then
           begin
             setwindowlong(AppWindow, GWL_STYLE, getwindowlong(AppWindow, GWL_STYLE) and (not ws_dlgframe) and (not ws_border) and (not WS_SIZEBOX));
             BringWindowToTop(wnd1);
           end else ShowWindow(AppWindow,SW_MAXIMIZE);



if EXERunning(app,false) then //wenn schon gestartet...dann
   begin
     ProcID := GetProcessID(app);
     if app = 'pgs.exe' then     //speziell für pgs.exe
     begin
       wnd1 := GetWndHandle(ProcID);
       ShowWindow(wnd1,SW_MAXIMIZE);
       BringWindowToTop(wnd1);
     end else......
Gruß, bluescreen25

shmia 12. Sep 2007 13:24

Re: von gestarteten Programmen alle Fensterhandles in ini
 
Es gibt da eine Software namens Phantom. Version 1.1 ist kostenlos.
Das Prinzip geht so:
Mit dem Programm Windows Declarations Recorder (WinDR) wird eine ganze Fensterhierarchie (Klassennamen, Positionsnr,..) als Textdatei gespeichert.
Hier ein Auszug:
Code:
[ ]MainWin "Phantom"
   ( )Tag="Delphi Praxis - Microsoft Internet Explorer"
   ( )Class="IEFrame"
   ( )Parent=1
   ( )Child=0
   [ ]Menu
      ( )Tag=
      ( )Class=Menu
      ( )Parent=0
      ( )Child=1
      [ ]
         ( )Tag=
         ( )Class=
         ( )Parent=0
         ( )Child=1
   [ ]MainWin "WorkerW1"
      ( )Tag=1
      ( )Class="WorkerW"
      ( )Parent=1
      ( )Child=1
      [ ]MainWin "ReBarWindow321"
         ( )Tag=1
         ( )Class="ReBarWindow32"
         ( )Parent=1
         ( )Child=1
Phantom hat nun eine eigene Programmiersprache, mit der diese Fenster manipuliert werden können.
Die zuvor erzeugten Dateien vom WinDR werden einfach importiert.
Der hierarchische Aufbau von Fenstern zeigt schon, dass du mit einer flachen INI-Datei nicht weit kommen wirst.

bluescreen25 13. Sep 2007 07:38

Re: von gestarteten Programmen alle Fensterhandles in ini
 
Zitat:

Zitat von shmia
Es gibt da eine Software namens Phantom. Version 1.1 ist kostenlos.
Das Prinzip geht so:
Mit dem Programm Windows Declarations Recorder (WinDR) wird eine ganze Fensterhierarchie (Klassennamen, Positionsnr,..) als Textdatei gespeichert.
Hier ein Auszug:
Code:
[ ]MainWin "Phantom"
   ...
      [ ]MainWin "ReBarWindow321"
         ( )Tag=1
         ( )Class="ReBarWindow32"
         ( )Parent=1
         ( )Child=1
Phantom hat nun eine eigene Programmiersprache, mit der diese Fenster manipuliert werden können.
Die zuvor erzeugten Dateien vom WinDR werden einfach importiert.
Der hierarchische Aufbau von Fenstern zeigt schon, dass du mit einer flachen INI-Datei nicht weit kommen wirst.

Hier zeigst du mir, das andere in der Lage sind Programme zu schreiben, die Fensterhandles auslagern können, damit komme ich leider nicht weiter.
Ich bin mir nicht sicher, was ich mit der Software da soll, oder wie ich da rausfinde, wie man alle Fensterhandles eines Prozesses gespeichert bekommt. (Das ist meine Ursprungsfrage gewesen, bzw eine andere gute Idee, wie man die extApps zuverlässig einfangen kann).

Trotzdem Danke.

Gruß, bluescreen25


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz