Repository navigation
SysWin Window Size and Position
Home › All Categories › sys/win › Window size and position
Reads and sets a window's position and size in pixels, and centres windows and controls.
Every function here takes a window handle: a top-level window, a dialog or a control. Sizes are
in physical pixels unless the name ends in ForDpi, in which case the values you pass are
96-DPI units and are multiplied by the desktop's scaling ratio first, so 400 becomes 600
on a display set to 150 %.
Three rectangles describe a window:
| Rectangle | Covers | Coordinates | Read it with |
|---|---|---|---|
| Window | the whole window: caption, borders, menu and, for a shown top-level window, the invisible resize border and drop shadow | screen | GetWindowRect |
| Bounds | the visible frame only, without the drop shadow | screen | GetWindowBounds |
| Client | the area inside the borders that the window paints itself | client: the top-left corner is always (0, 0) | GetWindowClientRect |
The location of a child window or control is relative to its parent's client area; the location of a top-level window is relative to the screen.
#import "sys/win"
using winA window whose client area is 400 × 220 at 96 DPI on any display, centred in the work area, with a button that reports the three sizes in the caption:
#import "sys/win"
#import "sys/win/gui"
using win, gui
declare function WndProc( byval hwnd as HWND, byval uMsg as UINT, byval wParam as WPARAM, byval lParam as LPARAM ) as LRESULT
function main() as long
SetProcessDpiAwareness( PROCESS_SYSTEM_DPI_AWARE )
dim pWindow as CWindow = "SizeDemo"
dim hWin as HWND = pWindow.Create( NULL, "Window size and position", @WndProc )
SetWindowClientSizeForDpi( hWin, 400, 220 )
CenterWindow( hWin )
dim hButton as HWND = pWindow.AddControl( "Button", hWin, 100, "&Measure", 150, 90, 100, 30 )
CenterControlH( hButton )
return pWindow.DoEvents( SW_NORMAL )
end function
function WndProc( byval hwnd as HWND, byval uMsg as UINT, byval wParam as WPARAM, byval lParam as LPARAM ) as LRESULT
select case uMsg
case WM_COMMAND
if CBCTL( wParam, lParam ) = 100 andalso CBCTLMSG( wParam, lParam ) = BN_CLICKED then
var (l, t, r, b) = GetWindowBounds( hwnd )
SetWindowText( hwnd, "window " & GetWindowWidth( hwnd ) & " x " & GetWindowHeight( hwnd ) & _
", frame " & ( r - l ) & " x " & ( b - t ) & _
", client " & GetWindowClientWidth( hwnd ) & " x " & GetWindowClientHeight( hwnd ) )
end if
return 0
case WM_DESTROY
PostQuitMessage( 0 )
return 0
end select
return DefWindowProcW( hwnd, uMsg, wParam, lParam )
end function
end main()On a typical Windows 11 display the window rectangle is 14 pixels wider than the visible frame: the difference is the invisible resize border.
| Function | Does |
|---|---|
| GetWindowRect | Returns the window rectangle in screen coordinates. |
| GetWindowBounds | Returns the visible frame of a window, without its drop shadow. |
| GetWindowWidth | Returns the width of the window rectangle. |
| GetWindowHeight | Returns the height of the window rectangle. |
| GetWindowSize | Reads the width and height of the window rectangle into two variables. |
| SetWindowSize | Resizes a window without moving it. |
| SetWindowSizeForDpi | Resizes a window to a size given in 96-DPI units. |
| GetWindowClientRect | Returns the client rectangle. |
| GetWindowClientWidth | Returns the width of the client area. |
| GetWindowClientHeight | Returns the height of the client area. |
| SetWindowClientSize | Resizes a window so that its client area has a given size. |
| SetWindowClientSizeForDpi | Resizes a window so that its client area has a size given in 96-DPI units. |
| GetWindowLocation | Reads the top-left corner of a window, relative to its parent. |
| SetWindowLocation | Moves a window without resizing it. |
| SetWindowLocationForDpi | Moves a window to a position given in 96-DPI units. |
| SetWindowPosForDPI | Moves, resizes and reorders a window, with position and size in 96-DPI units. |
| MoveWindowForDPI | Moves and resizes a window, with position and size in 96-DPI units. |
| CenterWindow | Centres a window over its parent or in the work area. |
| CenterControlH | Centres a control horizontally in its parent. |
| CenterControlV | Centres a control vertically in its parent. |
| ForceVisibleDisplay | Moves a window that is off every screen back onto the nearest one. |
function GetWindowRect( byval hWin as HWND ) as ( long, long, long, long )Returns the window rectangle as ( left, top, right, bottom ), in screen coordinates. right
and bottom are one past the last pixel, so right - left is the width.
The rectangle includes the caption, borders and menu. Once a top-level window has been shown it
also includes the invisible resize border and the drop shadow; use
GetWindowBounds for the frame the user sees. For the whole desktop pass
GetDesktopWindow().
| Parameter | Meaning |
|---|---|
hWin |
The window or control. |
Returns the four edges. GetLastError() is nonzero afterwards when the call succeeded and
0 when it failed (an invalid handle gives four zeros).
The one-argument form belongs to win; the Windows function of the same name, which fills a
RECT, is still there with two arguments.
Example
var (l, t, r, b) = GetWindowRect( hwnd )
if GetLastError() then print "left"; l; " top"; t; " width"; r - l; " height"; b - tMicrosoft Learn: GetWindowRect
function GetWindowBounds( byval hWin as HWND ) as ( long, long, long, long )Returns the visible frame of a window as ( left, top, right, bottom ), in screen coordinates:
the window rectangle without the invisible resize border and the drop shadow. The values are
physical pixels, not adjusted for DPI virtualisation.
The frame is only known once the window has been shown; before that the call fails.
| Parameter | Meaning |
|---|---|
hWin |
A top-level window. |
Returns the four edges. GetLastError() is S_OK (0) afterwards when the call succeeded,
otherwise the failing HRESULT.
Example
var (l, t, r, b) = GetWindowBounds( hwnd )
if GetLastError() = S_OK then print "visible frame:"; r - l; " x"; b - tMicrosoft Learn: DwmGetWindowAttribute with DWMWA_EXTENDED_FRAME_BOUNDS
function GetWindowWidth( byval hWin as HWND ) as longReturns the width of the window rectangle in pixels, borders included. Pass GetDesktopWindow()
for the width of the primary screen.
Returns the width, or 0 for an invalid handle.
Example
print "desktop width:"; GetWindowWidth( GetDesktopWindow() )function GetWindowHeight( byval hWin as HWND ) as longReturns the height of the window rectangle in pixels, caption and borders included. Pass
GetDesktopWindow() for the height of the primary screen.
Returns the height, or 0 for an invalid handle.
Example
print "window height:"; GetWindowHeight( hwnd )function GetWindowSize( byval hWin as HWND, byref nWidth as long, byref nHeight as long ) as booleanReads the width and height of the window rectangle into nWidth and nHeight, in one call.
| Parameter | Meaning |
|---|---|
hWin |
The window or control. |
nWidth |
Receives the width in pixels. |
nHeight |
Receives the height in pixels. |
Returns true on success; on failure false, and GetLastError() says why.
Example
dim as long w, h
if GetWindowSize( hwnd, w, h ) then print w; " x"; hfunction SetWindowSize( byval hWin as HWND, byval nWidth as long, byval nHeight as long ) as booleanResizes a window to nWidth × nHeight pixels, borders included. Its position and its place in
the Z order stay as they are.
Returns true on success; on failure false, and GetLastError() says why.
Example
SetWindowSize( hwnd, 640, 480 )Microsoft Learn: SetWindowPos
function SetWindowSizeForDpi( byval hWin as HWND, byval nWidth as long, byval nHeight as long ) as booleanResizes a window like SetWindowSize, but nWidth and nHeight are 96-DPI
units: each is multiplied by the desktop's scaling ratio (GetLogPixelsX() / 96 and
GetLogPixelsY() / 96) first.
Returns true on success; on failure false, and GetLastError() says why.
Example
SetWindowSizeForDpi( hwnd, 640, 480 ) ' 960 x 720 at 150 %function GetWindowClientRect( byval hWin as HWND ) as ( long, long, long, long )Returns the client rectangle as ( left, top, right, bottom ). Client coordinates start at the
top-left corner of the client area, so left and top are always 0 and right and bottom are
the width and height.
Returns the four edges. GetLastError() is nonzero afterwards when the call succeeded and
0 when it failed.
Example
var (l, t, r, b) = GetWindowClientRect( hwnd )
if GetLastError() then print "client area:"; r; " x"; bMicrosoft Learn: GetClientRect
function GetWindowClientWidth( byval hWin as HWND ) as longReturns the width of the client area in pixels: the window's width less its borders and, if it has one, its vertical scroll bar.
Returns the width, or 0 for an invalid handle.
Example
print "client width:"; GetWindowClientWidth( hwnd )function GetWindowClientHeight( byval hWin as HWND ) as longReturns the height of the client area in pixels: the window's height less its caption, menu, borders and, if it has one, its horizontal scroll bar.
Returns the height, or 0 for an invalid handle.
Example
print "client height:"; GetWindowClientHeight( hwnd )sub SetWindowClientSize( byval hWin as HWND, byval nWidth as long, byval nHeight as long, byval rxRatio as single = 1, byval ryRatio as single = 1 )Resizes a window so that its client area is nWidth × nHeight pixels, working out the
borders, caption and menu from the window's own styles. A menu bar that wraps onto a second line
and a horizontal or vertical scroll bar are allowed for. The window does not move or activate.
| Parameter | Meaning |
|---|---|
hWin |
A window. |
nWidth, nHeight
|
The client size wanted. |
rxRatio, ryRatio
|
Optional factors each size is multiplied by first; 1 leaves it as given. |
Example
SetWindowClientSize( hwnd, 400, 300 )Microsoft Learn: AdjustWindowRectEx
sub SetWindowClientSizeForDpi( byval hWin as HWND, byval nWidth as long, byval nHeight as long )Resizes a window so that its client area is nWidth × nHeight 96-DPI units: the same as
SetWindowClientSize with the desktop's horizontal and vertical scaling
ratios passed as rxRatio and ryRatio. Use it to lay out a window once, at 96 DPI, and have it
come out the same physical size on every display.
Example
SetWindowClientSizeForDpi( hwnd, 400, 300 ) ' 600 x 450 pixels at 150 %sub GetWindowLocation( byval hWin as HWND, byref nLeft as long, byref nTop as long )Reads the top-left corner of a window, in pixels. For a control or child window the point is relative to the parent's client area; for a top-level window it is in screen coordinates.
| Parameter | Meaning |
|---|---|
hWin |
The window or control. |
nLeft |
Receives the x coordinate. |
nTop |
Receives the y coordinate. |
Example
dim as long x, y
GetWindowLocation( hCtrl, x, y )
print "the control is at"; x; ","; yMicrosoft Learn: MapWindowPoints
function SetWindowLocation( byval hWin as HWND, byval nLeft as long, byval nTop as long ) as booleanMoves a window so that its top-left corner is at (nLeft, nTop), in the same coordinates as
GetWindowLocation. Its size and place in the Z order stay as they are.
Returns true on success; on failure false, and GetLastError() says why.
Example
SetWindowLocation( hCtrl, 10, 10 )function SetWindowLocationForDpi( byval hWin as HWND, byval nLeft as long, byval nTop as long ) as booleanMoves a window like SetWindowLocation, but nLeft and nTop are 96-DPI
units and are scaled by the desktop's ratios first.
Returns true on success; on failure false, and GetLastError() says why.
Example
SetWindowLocationForDpi( hCtrl, 10, 40 ) ' 15, 60 at 150 %function SetWindowPosForDPI( byval hwnd as HWND, byval hWndInsertAfter as HWND, byval x as long, byval y as long, byval cx as long, byval cy as long, byval uFlags as UINT = SWP_NOZORDER ) as booleanCalls Windows' SetWindowPos with x, y, cx and cy multiplied by the desktop's scaling
ratios first, so they are given in 96-DPI units.
| Parameter | Meaning |
|---|---|
hwnd |
The window. |
hWndInsertAfter |
The window to place it after in the Z order, or HWND_TOP, HWND_BOTTOM, HWND_TOPMOST, HWND_NOTOPMOST. Ignored with SWP_NOZORDER. |
x, y
|
The new position. |
cx, cy
|
The new size. |
uFlags |
SWP_* flags; the default keeps the Z order. Add SWP_NOMOVE or SWP_NOSIZE to keep the position or the size. |
Returns true on success; on failure false, and GetLastError() says why.
Example
SetWindowPosForDPI( hCtrl, NULL, 20, 20, 120, 28 )Microsoft Learn: SetWindowPos
function MoveWindowForDPI( byval hwnd as HWND, byval x as long, byval y as long, byval nWidth as long, byval nHeight as long, byval bRepaint as boolean = true ) as booleanCalls Windows' MoveWindow with the position and size multiplied by the desktop's scaling ratios
first, so they are given in 96-DPI units.
| Parameter | Meaning |
|---|---|
hwnd |
The window. |
x, y
|
The new position. |
nWidth, nHeight
|
The new size. |
bRepaint |
true (the default) repaints the window after the move. |
Returns true on success; on failure false, and GetLastError() says why.
Example
MoveWindowForDPI( hCtrl, 20, 60, 200, 24 )Microsoft Learn: MoveWindow
sub CenterWindow( byval hWin as HWND = NULL, byval hwndParent as HWND = NULL )Centres a window over hwndParent, or in the work area of the primary display when
hwndParent is NULL. The result is kept inside the work area (the screen less the taskbar), so
a window centred over a parent near the edge stops at the edge. The size and Z order do not
change.
To centre a child window, pass its parent as hwndParent.
| Parameter | Meaning |
|---|---|
hWin |
The window to move. |
hwndParent |
The window to centre over, or NULL for the work area. |
Example
CenterWindow( hwnd ) ' in the work area
CenterWindow( hDlg, hwnd ) ' over its ownerMicrosoft Learn: SystemParametersInfoW with SPI_GETWORKAREA
sub CenterControlH( byval hCtrl as HWND )Moves a control so that it is centred horizontally in its parent's client area. Its vertical position and its size stay as they are.
Example
CenterControlH( hCtrl )sub CenterControlV( byval hCtrl as HWND )Moves a control so that it is centred vertically in its parent's client area.
Example
CenterControlV( hCtrl )sub ForceVisibleDisplay( byval hWin as HWND )Brings back a window that is on no display at all, by centring it in the work area of the display nearest to where it was. A window that is at least partly on some display is left alone.
A program that restores its last position at start-up can open off-screen after the user unplugs or rearranges a monitor. Call this once the window has been created and placed.
Example
SetWindowLocation( hwnd, 5000, 5000 ) ' a saved position, now off every screen
ForceVisibleDisplay( hwnd )Microsoft Learn: MonitorFromRect
- Category: sys/win
-
Display, screen and DPI for the scaling ratios the
ForDpifunctions use
tiko-lang · Home · Feature Index · Keyword Index · License
FreeBASIC manual pages reproduced under the GNU FDL 1.3.
- Home
- What Is tiko-lang
- Quick Start
- Installing on macOS
- Debugging
- Feature Index
- Compatibility
- FAQ
- AI Cheatsheet
- Generics
- Interfaces
- For Each
- Iterators
- Tuples
- Array Results
- Defer
- Lambdas
- Block Strings
- Partial Types
- String Slices
- Embed
- Typed Variadics
- C Header Import
- Foreign Library Linking
- UString
- Fixed-Width Types
- Nullptr
- String Library
- Format
- Array
- Map
- Set
- LinkedList
- OrderedMap
- OrderedSet
- Sorting
- Optional
- Result
- Smart Pointers
- Date and Time (Chrono)
- Time Zones
- Filesystem
- File Streams
- Config (INI and TOML)
- Codec
- Hash
- UUID
- OS
- Process
- Net
- HTTP and TLS
- Math Library
- Finance
- Logging
- Terminal TUI Library
- PsControls
- tkControls
- sys/win
- Goroutines and Channels
- LLVM Backend
- tiko build
- TIKO_COMPILER
- Variable Declarations
- Standard Data Types
- User Defined Types
- Procedures
- Operators
- Control Flow Statements
- Converting Data Types
- Array Functions
- String Functions
- Mathematical Functions
- Bit Manipulation
- Date and Time Functions
- File I/O Functions
- Console Functions
- User Input (Runtime Library)
- User Input Functions (Graphics Library)
- Screen Functions
- 2D Drawing Functions
- Graphics Library Reference
- Graphics Keyword List
- Memory Functions
- Threading Support Functions
- Error Handling Functions
- Operating System Functions
- Preprocessor
- Intrinsic Defines
- Miscellaneous Keywords
- Modularizing