| 
   
    | ...retrieve a window handle? |   
    | Autor: 
      Thomas Stutz |  | [ Print tip 
] |  |  |  
 
 
| An important concept in Windows programming is the concept of an object handle.
 Many functions return a handle to an object that the function created or loaded
 from a resource. Internally, Windows keeps track of all of these handles,
 and the handle serves as the link through the operating system between the object
 and the application. There are several ways to obtain the handle of a window.
 
 Ein wichtiges Konzept in der Windows Programmierung ist das Konzept vom Objekt-Handle.
 Viele Funktionen geben ein Handle (eigentlich ein Zeiger) auf ein Objekt zurück.
 Windows verwaltet intern alle Handles.
 Diese dienen als Verknüpfung zwischen Objekt und der Applikation über das OS.
 Es gibt verschiedene Wege, wie man nach einem Fensterhandle suchen kann.
 Nachfolgend werden einige Funktionen zum Suchen von Fenstern besprochen
 und in einigen Beipielen ihre Anwendungen erläutert.
 
 | 
 
 
 
 
 
 I) FindWindow
 
 
 Syntax:
 
 FindWindow(lpClassName: PChar;  {a pointer to a null-terminated class name string}
 lpWindowName: PChar  {a pointer to a null-terminated window name string}
 ): HWND;  {returns a handle to a window}
 
 
 {
 1. The FindWindow function retrieves the handle to the top-level
 window whose class name and window name match the specified strings.
 This function does not search child windows.
 If the function succeeds, the return value is the handle to
 the window that has the specified class name and window name.
 If the function fails, the return value is 0.
 
 1. Der Funktionsaufruf FindWindow liefert das Handle
 (vom Typ HWND) auf das gesuchte Fenster,
 dabei wird nicht nach "Kinder"-Fenstern gesucht.
 Wenn die Funktion 1 zurückgibt, wurde das entsprechende Fenster
 gefunden.
 Wenn z.B nil als KlassenName angegeben wird, wird der
 1. Paramter ignoriert und es wird nur über den Fensternamen gesucht.
 
 Examples / Beispiele:
 
 Get the handle of Notepad by its Classname:
 Das Handle von Notepad über den Klassennamen ermitteln:
 }
 
 procedure TForm1.Button1Click(Sender: TObject);
 var
 hNotepadWindow: HWND;
 begin
 hNotepadWindow := FindWindow('notepad', nil);
 end;
 
 {
 Get the handle of Winword by its Classname and hide it/show it after 2 Sec.:
 Das Handle von Winword über den Klassennamen ermitteln und dann Word
 verstecken und nach nach 2 Sek. wieder anzeigen:
 }
 
 procedure TForm1.Button1Click(Sender: TObject);
 var
 hWordWindow: HWND;
 begin
 hWordWindow := FindWindow ('OpusApp', nil);
 ShowWindow(hWordWindow, SW_HIDE);
 Sleep(2000);
 ShowWindow(hWordWindow, SW_SHOW);
 end;
 
 {
 Get the handle of Internet Explorer and minimize/close all its windows:
 Das handle vom Internet Explorer ermitteln und danach all
 seine Fenster minimieren/schliessen:
 }
 
 procedure TForm1.Button1Click(Sender: TObject);
 var
 hIExplorer: HWND;
 begin
 hIExplorer := FindWindow('IEFrame', nil);
 if hIExplorer <> 0 then
 begin
 // Minimize IE:
 SendMessage(hIExplorer, WM_SYSCOMMAND, SC_MINIMIZE, 0);
 // Close IE:
 SendMessage(hIExplorer, WM_SYSCOMMAND, SC_CLOSE, 0);
 end;
 end;
 
 
 II) GetWindow
 
 
 {
 FindWindowByTitle returns the handle of a window that
 contains a certain "WindowTitle".
 
 FindWindowByTitle gibt das Handle jenes Fensters zurück,
 das im Titel den String "WindowTitle" enthält.
 }
 
 function FindWindowByTitle(WindowTitle: string): Hwnd;
 var
 NextHandle: Hwnd;
 NextTitle: array[0..260] of char;
 begin
 // Get the first window
 NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST);
 while NextHandle > 0 do
 begin
 // retrieve its text
 GetWindowText(NextHandle, NextTitle, 255);
 if Pos(WindowTitle, StrPas(NextTitle)) <> 0 then
 begin
 Result := NextHandle;
 Exit;
 end
 else
 // Get the next window
 NextHandle := GetWindow(NextHandle, GW_HWNDNEXT);
 end;
 Result := 0;
 end;
 
 {
 Example how to search for a window that contains the
 word "notepad" and maximize it.
 
 Beispiel, wie man ein Fenster "notepad" findet
 und es anschliessend maximiert.
 }
 
 procedure TForm1.Button1Click(Sender: TObject);
 var
 h: hwnd;
 begin
 h := FindWindowByTitle('notepad');
 if h <> 0 then // if we found notepad
 ShowWindow(h, SW_MAXIMIZE)
 else
 ShowMessage('not found.');
 end;
 
 
 III. FindWindowEx
 
 
 {Syntax:}
 
 FindWindowEx(Parent: HWND;  {a handle to a parent window}
 Child: HWND;  {a handle to a child window}
 ClassName: PChar;  {a pointer to a null-terminated class name string}
 WindowName: PChar  {a pointer to a null-terminated window name string}
 ): HWND;  {returns a handle to a window}
 
 
 {Description:
 
 FindWindowEx retrieves the handle of the window with the specified
 class name and window name.
 Unlike FindWindow, this function searches child windows, starting with
 the one following the given child window.
 
 FindWindowEx sucht nach "Child"-Fenster in einem Fenster.
 
 }
 
 {
 Example to find a TButton (Child Window) on a TForm
 Beispiel, um nach einem TButton auf einer Form zu suchen
 }
 
 procedure TForm1.Button1Click(Sender: TObject);
 var
 FoundWindow: HWND;
 WindowText: array[0..255] of char;
 begin
 {Find a TButton child window}
 FoundWindow := FindWindowEx(Form1.Handle, 0, 'TButton', nil);
 {Get its text}
 GetWindowText(FoundWindow, WindowText, 255);
 {Display it}
 label1.Caption := 'FindWindowEx found window handle ' +
 IntToStr(FoundWindow) + ': ' + WindowText;
 end;
 
 {
 Example to search for Edit field nr. x in another application and send a text to it
 
 Beispiel, wie man nach dem X. Feld in einer anderen Applikation sucht
 und ein Text schickt.
 }
 
 
 function FindControlByNumber(hApp: HWND; ControlClassName: string; ControlNr: Word = 1): HWND;
 var
 i: Word;
 hControl: HWND;
 begin
 Result := 0;
 if IsWindow(hApp) then
 begin
 Dec(ControlNr);
 hControl := 0;
 for i := 0 to ControlNr do
 begin
 hControl := FindWindowEx(hApp, hControl, PChar(ControlClassName), nil);
 if hControl = 0 then
 Exit;
 end;
 end;
 Result := hControl;
 end;
 
 
 procedure SetEditText(hApp: HWND; EditClassName, AText: string; EditNr: Integer);
 var
 hEdit: HWND;
 begin
 // Search for the 2. Edit Field in a application
 hEdit := FindControlByNumber(FindWindow('Write_Here_Class_Of_App', nil), 'Edit', 2);
 if hEdit <> 0 then
 // Test: Send a "Hello" to the Edit Field
 SendMessage(hEdit, WM_SETTEXT, 0, Integer(PChar('Hello')));
 end;
 
 
 IV) EnumWindows
 
 
 // Syntax:
 
 EnumWindows(lpEnumFunc: TFNWndEnumProc;  {the address of the enumeration callback function}
 lParam: LPARAM  {a 32-bit application-defined value}
 ): BOOL;  {returns TRUE or FALSE}
 
 {
 The EnumWindows function enumerates all top-level windows
 on the screen by passing the handle of each window, in
 turn, to an application-defined callback function.
 EnumWindows continues until the last top-level window is enumerated
 or the callback function returns FALSE.
 
 Die EnumWindows Funktion zählt alle Top-Level Fenster
 auf und gibt jeweils das Handle zurück.
 EnumWindows endet, wenn das letzte Fenster aufgezählt wurde
 oder die Callback-Funktion False zurückgibt.
 
 Callback Syntax: }
 
 EnumWindowsProc(hWnd: HWND;  {a handle to a top-level window}
 lParam: LPARAM  {the application-defined data}
 ): BOOL;  {returns TRUE or FALSE}
 
 
 {
 Example how to list all Top-Level Windows in a Listbox.
 
 Nachfolgend ein Beispiel, um alle Top-Level Fenster in
 einer Listbox anzuzeigen.
 }
 
 function EnumWindowsProc(wHandle: HWND; lb: TListBox): Bool; stdcall; export;
 var
 Title, ClassName: array[0..255] of char;
 begin
 Result := True;
 GetWindowText(wHandle, Title, 255);
 GetClassName(wHandle, ClassName, 255);
 if IsWindowVisible(wHandle) then
 lb.Items.Add(string(Title) + '-' + string(ClassName));
 end;
 
 procedure TForm1.Button1Click(Sender: TObject);
 begin
 EnumWindows(@EnumWindowsProc, Integer(Listbox1));
 end;
 
 
 
 V) EnumChildWindows
 
 
 //Syntax:
 
 EnumerateChildWindows(hWnd: HWND;{a handle to a top-level window}
 lParam: LPARAM): {a 32-bit application-defined value}
 BOOL; stdcall; {returns TRUE or FALSE}
 
 
 { Description :
 
 The EnumChildWindows function enumerates the child windows that belong to the
 specified parent window by passing the handle of each child window, in turn,
 to an application-defined callback function.
 EnumChildWindows continues until the last child window is enumerated or
 the callback function returns False.
 
 Die EnumChildWindows Funktion zählt alle zu einem Fenster gehörenden Child-Fenster
 auf und übergibt jeweils das Handle einer Callback Funktion.
 EnumChildWindows endet, wenn das letzte Child-Fenster aufgezählt wurde
 oder die Callback-Funktion False zurückgibt.
 
 Here is an example that lists the controls on a TPrintDialog
 Hier ein Beispiel, um alle Controls auf eines TPrintDialogs anzuzeigen
 
 }
 
 function EnumProc(wnd: HWND; Lines: TStrings): BOOL; stdcall;
 var
 buf, Caption: array[0..255] of char;
 begin
 Result := True;
 GetClassName(wnd, buf, SizeOf(buf) - 1);
 SendMessage(wnd, WM_GETTEXT, 256, Integer(@Caption));
 Lines.Add(Format('ID: %d, ClassName: %s, Caption: %s',
 [GetDlgCtrlID(wnd), buf, Caption]));
 end;
 
 procedure TForm1.PrintDialog1Show(Sender: TObject);
 begin
 Memo1.Clear;
 EnumChildWindows(printdialog1.Handle, @EnumProc, Integer(memo1.Lines));
 end;
 
 
 
 VI) EnumThreadWindows
 
 
 // Syntax:
 
 EnumThreadWindows(dwThreadId: DWORD;  {the thread identification number}
 lpfn: TFNWndEnumProc;  {the address of the enumeration callback function}
 lParam: LPARAM  {a 32-bit application-defined value}
 ): BOOL;  {returns TRUE or FALSE}
 
 
 {Description/ Beschreibung
 
 This function enumerates all of the nonchild windows associated with the specified thread.
 Each window handle associated with the specified thread is passed to an
 application-defined callback function. This function will continue until
 all of the windows are enumerated or the callback function returns False.
 
 Diese Funktion listet alle "nonchild"-Fenster eines Threads auf.
 Jedes mit diesem Tread verknüpfte Fenster wird an eine Callback Funktion übergeben.
 Diese Funktion wird so lange ausgeführt, bis alle Fentster aufgezählt wurden oder
 bis die Callback Funktion False zurückgibt.
 
 
 Syntax of the Callback function:
 Syntax der Callback Funktion:
 }
 
 EnumThreadWndProc(hWnd: HWND;  {a handle to a window}
 lParam: LPARAM  {the application-defined data}
 ): BOOL;
 
 
 {
 Example: Finding all Windows belonging to a Thread
 Beispiel: Alle zu einem Thread gehörenden Fenster auflisten
 }
 
 function EnumerateThreadWindows(Wnd: HWND; Data: lParam): BOOL;
 var
 WindowText: array[0..255] of char; // holds the text of the window
 begin
 { Get the text from the window }
 GetWindowText(Wnd, WindowText, 255);
 { Display it in the listbox}
 Form1.ListBox1.Items.Add(WindowText);
 { Continue the enumeration }
 Result := True;
 end;
 
 procedure TForm1.Button1Click(Sender: TObject);
 begin
 { Clear the listbox }
 ListBox1.Items.Clear;
 
 { Enumerate all windows that belong to the current thread }
 EnumThreadWindows(GetCurrentThreadID, @EnumerateThreadWindows, 0);
 end;
 
 
   |