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 FensterHandle über den Prozess ermitteln (https://www.delphipraxis.net/132461-fensterhandle-ueber-den-prozess-ermitteln.html)

Asatru 13. Apr 2009 10:45


FensterHandle über den Prozess ermitteln
 
Guten Tag und frohe Ostern,

Hab mal wieder eine kleine Frage, nur leider wees ich nicht ganz wie ich sie formulieren soll. Ich habe ein Programm eben mehrmals auf dem Rechner laufen kann und besitzt auch immer ein anderen Namen. Also schätze ich mal das findwindow dann rausfällt.

Zum testen habsch folgenden Code bis jetzt

Delphi-Quellcode:
  procedure TForm1.Label1Click(Sender: TObject);
var
  handle1,handle2: HWND;
  x,y: String;
begin
  handle1 := FindWindow('wxWindowClassNR', '[123]WheresMyChar');
  handle1 := FindWindowEx(handle1, 0, 'wxWindowClassNR', 'ID_PANEL1');
  handle1 := FindWindowEx(handle1, 0, 'wxWindowClassNR', 'ID_PANEL2');
  handle1 := GetDlgItem(handle1, 532);

  handle2 := FindWindow('wxWindowClassNR', '[123]WhersMyChar');
  handle2 := FindWindowEx(handle2, 0, 'wxWindowClassNR', 'ID_PANEL1');
  handle2 := FindWindowEx(handle2, 0, 'wxWindowClassNR', 'ID_PANEL2');
  handle2 := GetDlgItem(handle2, 534);

  if handle1 and handle2 <> 0 then
  begin
    x := PCHar('x: ' + GetWinText(handle1));
    y := PCHar(' y: ' + GetWinText(handle2));
    //Hier wird Code später weitergeführt zur auflistung der Daten

  end;
end;
Dieser Test lief wunderbar. Nun möchte ich mir aber das HWND nicht anhand des Textes holen sondern anhand des Prozesses (Beschreibung) Weil dieser immer gleich ist und der Inhalt von [ und ] immer anders sein kann und er soll es solange wiederholen bis eben alle gefunden wurden.


Hoffe ihr konntet mich verstehen, was mein Vorhaben ist!

jaenicke 13. Apr 2009 10:55

Re: GetDlgItem
 
Wie wäre es mit EnumWindows + GetClassName?

// EDIT1:
Nebenbei: Wozu suchst du die selben Handles zweimal? Das ist doch das selbe wie so:
Delphi-Quellcode:
  handle1 := FindWindow('wxWindowClassNR', '[123]WheresMyChar');
  handle1 := FindWindowEx(handle1, 0, 'wxWindowClassNR', 'ID_PANEL1');
  handle1 := FindWindowEx(handle1, 0, 'wxWindowClassNR', 'ID_PANEL2');
  handle2 := GetDlgItem(handle1, 534);
  handle1 := GetDlgItem(handle1, 532);
// EDIT2:
Und deine if-Abfrage ist Quatsch... So machst du ein logisches und mit den beiden Handles...

quendolineDD 13. Apr 2009 11:00

Re: GetDlgItem
 
Delphi-Quellcode:
if (handle1 <> INVALID_HANDLE_VALUE) and (handle2 <> INVALID_HANDLE_VALUE) then

Asatru 13. Apr 2009 11:07

Re: GetDlgItem
 
Danke für eure Hilfestellung, werd mal reinschnuppern

Ja ist neuland und da mach ich mir es eben lieber komplizierter als das es gar nicht funzt, werd aber besserung geloben:-P

MFG

Luckie 13. Apr 2009 12:07

Re: GetDlgItem
 
Äh, was hat das jett mit GetDlgItem zu tun? Dein eigentliches Problem scheint doch zu sein, das Fenster zu finden oder?

Asatru 13. Apr 2009 18:05

Re: GetDlgItem
 
Ich wusste leider nicht wie ich es nennen soll, deshalb habsch einfach mal nen namen aus der Funktion genommen die ich für wichtig hielt! Hoffe ist net so schlimm!

MFG

Luckie 13. Apr 2009 18:07

Re: GetDlgItem
 
Schlimm nicht aber blöd. Un dim letzten Absatz hast du doch geschriben was du machen willst: Das fensterhanlde über den Prozess ermitteln.

Asatru 13. Apr 2009 19:27

Re: FensterHandle über den Prozess ermitteln
 
Habs mal geändert wie ein Mann :-P

So hab mich mal ein bisschen von google beraten lassen aber im entdefekt bin ich bei 0 :roll:

Auflisten der Fenster versteh ich teilweise
So sollte dann eingentlich die "Schleife" aussehen oder binsch aufn falschen Schiff?

Nur will mein Logisches Denken nicht verstehen wie ich das GetClassName in das EnumWindows einbinde.

Gibts vlt noch ein Gutes Tutorial (Auf Deutsch) was ich vlt übersehen habe im www und mich mit der Materie etwas mehr vertraut macht?


Schon mal danke im Voraus und noch frohe Ostern!

MFG


PS: OK 0 wäre bissle übertrieben, allgemein anzeigen ist mir klar aber direkt das suchen auf ein spezielles ist mir Bahnhof!

jaenicke 13. Apr 2009 19:33

Re: FensterHandle über den Prozess ermitteln
 
Zitat:

Zitat von Asatru
Nur will mein Logisches Denken nicht verstehen wie ich das GetClassName in das EnumWindows einbinde.

Genau das steht in deinem ersten Link unter EnumWindows schon drin... :roll:

Nur dass du die Klasse nicht auflisten sondern mit deiner gesuchten Klasse vergleichen willst...

Satty67 13. Apr 2009 21:34

Re: FensterHandle über den Prozess ermitteln
 
Also bei Delphi 5 gibt es die Unit TlHelp32, mit der sich ein Schnappschuss der Prozesse machen lässt. Aus dem Schnappschuß kann man dann Prozesse und deren Exe-Namen ermitteln. Natürlich auch die zugehörigen Fenster, aber ersters könnte ja schon reichen.

Hier mal ein Ausschnitt aus meinem Quellcode, denke das sollte fast schon reichen
Delphi-Quellcode:
uses TlHelp32, ShellApi;

var
  Handle : THandle;
  Continue : boolean;
  ProcEntry : TProcessEntry32;
  i : Integer;
begin
  i := 0;
  Handle := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
  ProcEntry.dwSize := Sizeof(ProcEntry);

  // gehe alle Prozesse durch (m.H. der TlHelp32 - Unit)
  Continue := Process32First(Handle, ProcEntry);

  while Continue do begin

    SetLength(TaskListe,i +1);

    // Daten zum Prozess ermitteln
    ProcID := ProcEntry.th32ProcessID;
    Threads := ProcEntry.cntThreads;
    ExeFile := ProcEntry.szExeFile;
    if ExeFile = '[System Process]' then
      ExeFile := 'Leerlaufprozess';

    // Nächster Prozess
    Continue := Process32Next(Handle, ProcEntry);
    inc(i);
  end;
  CloseHandle(Handle);
zum Fenster durchlaufen mal der Ausschnitt:
Delphi-Quellcode:
var
  Current : hwnd;
  i : Integer;
begin
  // Erstes Fenster holen
  i := 0;
  Current := GetTopWindow(GetDesktopWindow);

  while Current <> 0 do begin

    // Daten zum Fenster ermitteln
    visible := IsWindowVisible(Current);
    iconic := IsIconic(Current);
    handle := Current;
    parent := GetParent(Current);
    GetWindowThreadProcessID(Current, ProcID);
    GetWindowText(Current, Titel, 255);
    GetClassName(Current, Klasse, 255);

    // Nächstes Fenster
    Current := GetNextWindow(Current,GW_HWNDNEXT);
    inc(i);
  end;
end;
Die hier erhaltenen Informationen (z.B. ProcID) kann man mit der Information aus dem vorherigen Beispiel verknüpfen.

Die Variablen, auf die zugewiesen wird, sehen im Beispiel sinnlos aus. Das liegt daran, das ich den Code aus einem Programm ausgeschnitten hab' (da wird auf ein dyn. Record-Array zugewiesen)

jaenicke 13. Apr 2009 21:36

Re: FensterHandle über den Prozess ermitteln
 
Aber es geht doch um das Auslesen von Daten aus Fenstern mehrerer Instanzen eines Programms. :gruebel:

Das geht über EnumWindows doch sinnvoller würde ich sagen.

Satty67 13. Apr 2009 21:44

Re: FensterHandle über den Prozess ermitteln
 
Ja, war nicht so schnell... hatte erst mal den ersten Teil gepostet ;) Wobei das iterieren wohl EnumWindows gleich kommt, nur ohne CallBack-Prozedur.

Jetzt gibt es halt mit dem Klassennamen des (Delphi) mainForm ein Problem, der muss nicht eindeutig sein, oder?

jaenicke 13. Apr 2009 21:46

Re: FensterHandle über den Prozess ermitteln
 
Also dass der auch unterschiedlich sein wird, bezweifle ich einmal, der Fenstertitel ist ja logisch, aber der Klassenname sollte wohl gleich bleiben.

Außerdem wurde davon nix gesagt. Wenn das auch der Fall wäre, wäre es natürlich über die Prozesse von hintenherum am sinnvollsten, da gebe ich dir Recht.

Satty67 13. Apr 2009 21:49

Re: FensterHandle über den Prozess ermitteln
 
Ja, meine ja gleiche Klassennamen unterschiedlicher Delphi Programme... oder hab' ich da im Moment einen Denkfehler? Bei eigenen Programmen vergibt man natürlich möglichst unique Namen.

jaenicke 13. Apr 2009 21:50

Re: FensterHandle über den Prozess ermitteln
 
Naja, schon, aber es geht doch soweit ich das verstanden habe um das selbe Programm und ggf. mehrere Instanzen davon.

Und deshalb kommt man mit FindWindow eben nicht weiter, weil man da zwar den Fenstertitel weglassen kann, wenn der unterschiedlich ist, es aber nur das erste passende Fenster findet.

Satty67 13. Apr 2009 21:55

Re: FensterHandle über den Prozess ermitteln
 
Ja, hatte wohl einen Denkfehler bei der Fragestellung. Dachte er sucht Instanzen eines (fremden) Delphi-Programmes, das u.U. die Klassennamen TApplication und TForm haben könnte, wie 1000 andere Delphi Programme (die natürlich nicht alle auf einem Rechner laufen).

Dann EnumWindows/CallBackProcedure oder GetDesktopWindow/GetNextWindow

jaenicke 13. Apr 2009 21:57

Re: FensterHandle über den Prozess ermitteln
 
Genau, und wie das geht steht ja in seinem eigenen Link bereits drin, nur dass dort die gefundenen Fensterdaten eben ausgegeben und nicht ausgewertet werden.

[OT]Das ist ja fast wie ein Chat. :mrgreen:[/OT]

Satty67 13. Apr 2009 21:59

Re: FensterHandle über den Prozess ermitteln
 
[OT]Ja wenn nix g'scheites im TV läuft ;)[/OT]

Immerhin hat der Thread jetzt eine weitere Lösung bekommen, falls jemand nach dem Exe-Namen eines Prozesses sucht.

Asatru 14. Apr 2009 16:18

Re: FensterHandle über den Prozess ermitteln
 
:-P Freut mich wenn ich euch die lange weile nehme *fg* Hätte aber mal noch einige Fragen.

1. wo ist es besser den Vergleich zu machen in der procedur oder in der Function oder ist das Banane
2. Wenn in der procedur, bedeutet das ich muss alles was ich machen will in die klammer schreiben?

In Gedanken ist mir eigentlich klar wie es schlicht auszusehen hat, also der Vergleich aber um es auf papier zu bringen fehlt mir der Einstieg (Frage 1 und 2)

MFG

Klaus01 14. Apr 2009 16:35

Re: FensterHandle über den Prozess ermitteln
 
Zitat:

Zitat von Asatru
:-P Freut mich wenn ich euch die lange weile nehme *fg* Hätte aber mal noch einige Fragen.

1. wo ist es besser den Vergleich zu machen in der procedur oder in der Function oder ist das Banane
2. Wenn in der procedur, bedeutet das ich muss alles was ich machen will in die klammer schreiben?

In Gedanken ist mir eigentlich klar wie es schlicht auszusehen hat, also der Vergleich aber um es auf papier zu bringen fehlt mir der Einstieg (Frage 1 und 2)

MFG

.. eingentlich würde sich da die Funktion anbieten,
den Du willst ja das Ergebnis des Vergleiches haben.

Grüße
Klaus

Asatru 14. Apr 2009 16:46

Re: FensterHandle über den Prozess ermitteln
 
Ok das hilft mir schonmal zu 50% weiter nun nur die Frage, wie verbinde ich dann sowas in der Procedur?

Damit ich dann eben Testläufe machen kann? Muss dann mein quellcode der sich dann das handle holt in die klammern verstaut werden von enumWindows?

MFG

jaenicke 14. Apr 2009 17:28

Re: FensterHandle über den Prozess ermitteln
 
Ich würde das in die Callbackprozedur legen oder von da aus eine andere mit dem Fensterhandle als Parameter aufrufen. ;-)

Asatru 14. Apr 2009 17:58

Re: FensterHandle über den Prozess ermitteln
 
Stehe grad uffn schlauch, hab mal bissle durchgetest aber nie funzte es, zu testzwecken behalte ich nun das auflisten der Klassen bei und baue Vorher nur eben eine Abfrage rein.

Ist es ein falscher Weg wenn ich einfach nur Frage

wenn classname gleich diesen Ausdruck hat dann adde den Klassennamen

?!?

Delphi-Quellcode:
function EnumWindowsProc(wHandle: HWND; lb: TListBox): Bool; stdcall; export;
var
  ClassName: array[0..255] of char;
  ClassName_gesucht: array[0..255] of char;
begin
  GetClassName(wHandle, ClassName, SizeOf(ClassName)); // Klassenname ermitteln
  ClassName_gesucht:= 'wxWindowClassNR';
  if Classname = ClassName_gesucht then
     lb.Items.Add(string(ClassName));
end;

procedure TForm1.Label1Click(Sender: TObject);
begin
 EnumWindows(@EnumWindowsProc, Integer(Listbox1));
end;

jaenicke 14. Apr 2009 19:51

Re: FensterHandle über den Prozess ermitteln
 
Passiert nix, oder was passiert (nicht)?

Asatru 14. Apr 2009 21:44

Re: FensterHandle über den Prozess ermitteln
 
hab classname_gesucht mal mit als array angegeben aber passiert nie was, wollte sagen eben wenn classname übereinstimmt dann soll ereben alle classnamen mir mal anzeigen damitich erstmal weis das es funktioniert der vergleich, aber irgendwie komme ich net uff den richtigen vergleich!

x000x 15. Apr 2009 00:09

Re: FensterHandle über den Prozess ermitteln
 
Moin moin,

in deiner Callback Funktion fehlt ein Result := True ...
So wie es jetzt aussieht, steigt er nach dem 1. Aufruf aus.

Asatru 15. Apr 2009 15:25

Re: FensterHandle über den Prozess ermitteln
 
Ja sorry vergessen trotzdem passiert einfach nix dann beim klicken auf mein Label, aber rein vom quellcode mit

Delphi-Quellcode:
result := true;
ist den mein Vergleich richtig ausgedrückt?

DeddyH 15. Apr 2009 15:29

Re: FensterHandle über den Prozess ermitteln
 
Und wenn Du die Arrays vor Gebrauch erst einmal nullst?
Delphi-Quellcode:
FillChar(Classname,SizeOf(Classname),#0);

Asatru 15. Apr 2009 15:36

Re: FensterHandle über den Prozess ermitteln
 
löl

recht Herzlichen Dank nun hat es geklappt


MFG

Edit: Mir hat sich grad ein Neues Problem eröffnet. Folgende Thematik:

Also ich will mir aus einem Programm 2 Zahlen holen (X und Y Koordinate) Nur das Problem ist, das eine andere Anwendung schon alle Fenster (Wo ich x und y hole) via WinAPI in seine eigenen Tabsheets gezogen hat! Muss ich dem Prog nun sagen das jeder Tab eigentlich eigenes Window ist? Wenn ja wie müsste ich an die Sache rangehen? MFG

Delphi-Quellcode:
function EnumWindowsProc(wHandle: HWND; lb: TListBox): Bool; stdcall; export;
var
  Title, ClassName: array[0..255] of char;
  ClassName_gesucht: array[0..255] of char;
  xcor,ycor: String;
begin
  Result:= true;
  FillChar(Classname,SizeOf(Classname),#0);
  GetWindowText(wHandle, Title, SizeOf(Title));
  GetClassName(wHandle, ClassName, SizeOf(ClassName)); // Klassenname ermitteln
  Classname_gesucht := 'WindowsForms10.Window.8.app.0.378734a' ;
  if Classname = ClassName_gesucht then
      begin
            wHandle := FindWindowEx(wHandle, 0, 'WindowsForms10.SysTabControl32.app.0.378734a', nil);
            wHandle := FindWindowEx(wHandle, 0, 'WindowsForms10.Window.8.app.0.378734a', nil);
            wHandle := FindWindowEx(wHandle, 0, 'wxWindowClassNR', nil);
            wHandle := FindWindowEx(wHandle, 0, 'wxWindowClassNR', 'ID_PANEL1');
            wHandle := FindWindowEx(wHandle, 0, 'wxWindowClassNR', 'ID_PANEL2');
            wHandle := GetDlgItem(wHandle, 532);
                if wHandle <> 0 then
                    begin
                        xcor := PCHar('x: ' + GetWinText(wHandle));
                        lb.Items.Add(xcor);
                    end;
      end;



end;

procedure TForm1.Button1Click(Sender: TObject);
begin
EnumWindows(@EnumWindowsProc, Integer(Listbox1));
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:29 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