AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Library: Windows API / MS.NET Framework API Delphi Das Handle eines Fensters herausfinden
Thema durchsuchen
Ansicht
Themen-Optionen

Das Handle eines Fensters herausfinden

Ein Thema von Chewie · begonnen am 31. Aug 2002
Antwort Antwort
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#1

Das Handle eines Fensters herausfinden

  Alt 31. Aug 2002, 17:31
Handles auf Objekte in sichtbaren Fenstern kann man mit EnumWindows recht einfach finden. Komplizierter sieht es schon aus, wenn das Programm im Hintergrund läuft und z. B. in die Tray minmimiert ist.

Da ich in den letzten Wochen dies das ein oder andere Mal gebraucht habe und dabei wieder dank der netten Leute hier einiges über die WinAPI & nonVCL-Programmierung gelernt hab, schreib ich diesen Tip.

Es ist wohl nicht der sicherste Code, ich habe keine try..finally-Blöcke etc. verwendet wie ich es vielleicht hätte tun sollen, aber es funktioniert und vielleicht liefere ich die nach.


Folgendermaßen funnktioniert das Ganze:

1.

Delphi-Quellcode:
type DWordArray = Array of DWord;


function GetThreadID(const FileName: String): DWordArray;
var
  ToolHnd, MToolHnd: HWND;
  PE32: TProcessEntry32;
  ME32: TModuleEntry32;
  TE32: TThreadEntry32;
  PIDArray, TIDArray: DWordArray;
  PID: DWord;
  a: Byte;
begin
  Result := nil;
  PIDArray := nil;
  TIDArray := nil;
  ToolHnd := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS or TH32CS_SNAPTHREAD, 0);
  if ToolHnd <> ERROR_INVALID_HANDLE then
  begin
    PE32.dwSize := SizeOf(ProcessEntry32);
    if Process32First(ToolHnd, PE32) then
    begin
      repeat
        if CompareText(ExtractFileName(FileName), PE32.szExeFile) = 0 then
        begin
          SetLength(PIDArray, Length(PIDArray) + 1);
          PIDArray[Length(PIDArray)-1] := PE32.th32ProcessID;
        end;
      until not Process32Next(ToolHnd, PE32);
    end
    else
    begin
      Result := nil;
      Exit;
    end;
    PID := 0;
    if Length(PIDArray) = 0 then
    begin
      Result := nil;
      Exit;
    end;
    for a := 0 to Length(PIDArray) - 1 do
    begin
      MToolHnd := CreateToolHelp32Snapshot(TH32CS_SNAPMODULE, PIDArray[a]);
      if MToolHnd <> ERROR_INVALID_HANDLE then
      begin
        ME32.dwSize := SizeOf(ModuleEntry32);
        if Module32First(MToolHnd, ME32) then
        begin
          repeat
            if CompareText(FileName, ME32.szExePath) = 0 then
            begin
              PID := ME32.th32ProcessID;
              break;
            end;
          until not Module32Next(MToolHnd, ME32);
        end
        else
        begin
          Result := nil;
          Exit;
        end;
      end;
      CloseHandle(MToolHnd);
    end;
  end
  else
  begin
    Result := nil;
    Exit;
  end;
  TE32.dwSize := Sizeof(ThreadEntry32);
  if Thread32First(ToolHnd, TE32) then
  begin
    repeat
      if TE32.th32OwnerProcessID = PID then
      begin
        SetLength(TIDArray, Length(TIDArray) + 1);
        TIDArray[Length(TIDArray)-1] := TE32.th32ThreadID;
      end;
    until not Thread32Next(ToolHnd, TE32);
  end
  else
  begin
    Result := nil;
    Exit;
  end;
  if Length(TIDArray) = 0 then
  begin
    Result := nil;
    Exit;
  end;
  CloseHandle(ToolHnd);
  if Length(TIDArray) <> 0 then Result := TIDArray;
end;
Hier wird an die Funktion der Name + Pfad des Programms übergeben, in dem nach dem Handle gesucht werden soll. Das Programm sollte nur einmal laufen. Diese Funktion liefert die IDs aller Threads des gesuchten Prozesses.

2. Wir enumerieren die Fenster jedes Threads

Delphi-Quellcode:
for a := 0 to Length(TIDArray) - 1 do
begin
  EnumThreadWindows(TIDArray[a], @EnumWndProc, LabelHnd);
end;
Die Callback-Funktion:
Delphi-Quellcode:
{ Thread-Window-Callback-Funktion }
function EnumWndProc(Hnd: HWND; lParam: LParam): Boolean; stdcall;
var
  Buf: array[0..1024] of Char;
  ClassName, WindowText: string;
begin
  Result := True;
SetString(ClassName, Buf, GetClassName(Hnd, Buf, 1024));
  SetLength(WindowText, SendMessage(Hnd, WM_GETTEXTLENGTH, 0, 0));
  if ClassName = ClassName_gesucht then
    if WindowText = WindowText_gesucht then
    begin
      Result := False;
      Hnd_gesucht := Hnd;
    end;
  EnumChildWindows(Hnd, @EnumChildProc, lParam);
end;
Dazu werden folgende globalen Variablen benötigt:
Delphi-Quellcode:
var
  Hnd_gesucht: HWND; //unser gesuchtes Handle
  ClassName_gesucht: String; //Der Klassentyp des gesuchten Objekts
  WindowText_gesucht: String; //Die Caption des gesuchten Objekts
Wenn man z. B. den Button Button1 suchen will, muss man für ClassName TButton und für WindowText die Caption des Buttons einsetzen.

3.

Wenn in der ThreadWindow-Funktion das Fenster nicht gefunden wird, kann es noch ein Kind-Fenster eines Threadfensters sein. Um das herauszufinden, wird in der obigen Callback-Funktion die EnumChildWindows-Funktion aufgerufenn. Die Callback-Funktion dieser Funktion ist wiederum fast identisch mit der anderen Callback-Funktion, da ja nach dem gleichen gesucht wird:
Delphi-Quellcode:
var
  Buf: array[0..1024] of Char;
  ClassName, WindowText: string;
begin
  Result := True;
SetString(ClassName, Buf, GetClassName(Hnd, Buf, 1024));
  SetLength(WindowText, SendMessage(Hnd, WM_GETTEXTLENGTH, 0, 0));
  if ClassName = ClassName_gesucht then
    if WindowText = WindowText_gesucht then
    begin
      Result := False;
      Hnd_gesucht := Hnd;
    end;
end;
Jetzt haben wir entweder das Handle des Objekts oder das Objekt existert nicht und Hnd_gesucht erfährt keine Wertänderung.

[edit=Matze][ code ] durch [ delphi ]-Tags ersetzt. Mfg, Matze[/edit]
[edit=Phoenix]Versuch, den Syntax-Highlighter nochmal anzustubbsen. Mfg, Phoenix[/edit]
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  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 09:20 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