Jump to content
Gonzalez

[TUT] Retrieve a Window Handle (Delphi)

Recommended Posts

Author: bubzuru

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.

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.

Examples :

Get the handle of Notepad by its Classname:

  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.:

Code:

  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:

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".

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.

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.

Example to find a TButton (Child Window) on a TForm

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

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.

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.

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.

Here is an example that lists the controls on a TPrintDialog

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

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.

Syntax of the Callback function:

EnumThreadWndProc(hWnd: HWND; {a handle to a window}

lParam: LPARAM {the application-defined data}

): BOOL;

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;

  • Downvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...