Understanding SetWindowPos and Window Z‑Order Control in Delphi
This page explains how to control window position, size, and Z‑order in Delphi using the Windows API function SetWindowPos.
It includes practical examples such as making a window topmost (HWND_TOPMOST), sending it to the back (HWND_BOTTOM), or updating it without activating it (SWP_NOACTIVATE).
The meanings and usage of common SWP flags are clearly summarized to help you understand how each option affects window behavior.
The article also covers how to obtain window handles using FindWindow, and how to read or change a window’s title bar text using SetWindowText and GetWindowText.
SetWindowPos
SetWindowPos is a Windows API function that changes a window’s size, position, and Z‑order.
SetWindowPos(hWnd: HWND; hWndInsertAfter: HWND; X, Y, cx, cy: Integer; uFlags: UINT): BOOL; stdcall;
- hWnd
- The handle of the target window.
- hWndInsertAfter
-
A handle to the window that the target window should be placed after in the Z‑order,
or one of the following predefined values:
Value Description HWND_BOTTOM Places the window at the bottom of the Z‑order. HWND_TOP Places the window at the top of the Z‑order. HWND_TOPMOST Makes the window topmost (always above non‑topmost windows). HWND_NOTOPMOST Removes the topmost status and returns the window to the normal Z‑order. - X
- The window’s X position in client coordinates.
- Y
- The window’s Y position in client coordinates.
- cx
- The width of the window.
- cy
- The height of the window.
- uFlags
-
A combination of flags that control how the window is moved, sized, or displayed.
Common values include:
Value Description SWP_HIDEWINDOW Hides the window. SWP_SHOWWINDOW Shows the window. SWP_NOACTIVATE Moves or resizes the window without activating it. SWP_NOMOVE Keeps the current position (X and Y parameters are ignored). SWP_NOOWNERZORDER
or
SWP_NOREPOSITIONDoes not change the owner window’s Z‑order. (Maintains the relative order of owned windows when changing Z‑order.) SWP_NOSIZE Keeps the current size (cx and cy parameters are ignored). SWP_NOZORDER Does not change the Z‑order (hWndInsertAfter is ignored).
SetForegroundWindow
Brings the thread that created the specified window into the foreground and activates the window,
allowing it to receive keyboard input and focus.
The Z‑order is not changed.
SetForegroundWindow(hWnd: HWND): BOOL; stdcall;
- hWnd
- The handle of the target window.
FindWindow
Retrieves the handle of the top‑level window whose class name and/or window name matches the specified strings.
The search is case‑insensitive and does not include child windows.
FindWindow(lpClassName, lpWindowName: LPCWSTR): HWND; stdcall;
- lpClassName
-
The class name of the window to search for.
If you do not know the class name, you can inspect it using tools such as Mam Spy--.
- lpWindowName
- The window name (the text displayed in the title bar) to search for.
Example: Making a Window Always Topmost
When the button is clicked, the window is set to always stay on top of all non‑topmost windows.
procedure TForm1.Button1Click(Sender: TObject); begin SetWindowPos(Self.Handle, HWND_TOPMOST, 0,0,0,0, SWP_NOMOVE or SWP_NOSIZE); end;
Examples Using SetForegroundWindow and SetWindowPos
This example sends the window to the bottom of the Z‑order and then brings it to the foreground as the active window.
procedure TForm1.Button2Click(Sender: TObject); begin SetWindowPos(Self.Handle, HWND_BOTTOM, 0,0,0,0, SWP_NOMOVE or SWP_NOSIZE); SetForegroundWindow(Self.Handle); end;
The following example launches Notepad, waits until its window handle becomes available, moves it to position (0,0), resizes it to 1000×500, sets it as topmost, and finally removes the topmost state.
procedure TForm1.Button2Click(Sender: TObject);
var h: THandle;
begin
// Launch Notepad
ShellExecute(Self.Handle, nil, 'notepad.exe', nil, nil, SW_SHOW);
// Wait until the Notepad window becomes available
h := 0;
while h = 0 do
begin
// Find the Notepad window (class name "Notepad")
h := FindWindow('Notepad', nil);
Sleep(200);
end;
// Bring the current window to the foreground
SetForegroundWindow(Self.Handle);
// Move Notepad to (0,0), resize to 1000x500, and make it topmost
SetWindowPos(h, HWND_TOPMOST, 0,0, 1000,500, SWP_NOACTIVATE);
// Remove the topmost state
SetWindowPos(h, HWND_NOTOPMOST, 0,0, 0,0,
SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);
end;
SetWindowText
Changes the text displayed in the title bar of the specified window.
SetWindowText(hWnd: HWND; lpString: LPCWSTR): BOOL; stdcall; overload;
- hWnd
- The handle of the target window.
- lpString
- The new title text or control text to set.
GetWindowText
Retrieves the text displayed in the title bar of the specified window.
GetWindowText(hWnd: HWND; lpString: LPWSTR; nMaxCount: Integer): Integer; stdcall;
- hWnd
- The handle of the target window.
- lpString
- The buffer that receives the window text.
- nMaxCount
- The maximum number of characters to copy into the buffer (any additional characters are truncated).
Example: Using SetWindowText and GetWindowText
This example changes the window’s title bar text to “Hello” and then retrieves the updated title.
procedure TForm1.Button4Click(Sender: TObject); var ch: array[0..1023] of Char; begin SetWindowText(Self.Handle, 'Hello'); GetWindowText(Self.Handle, @ch[0], Length(ch)); ShowMessage(ch); end;
