8.9 KiB
source_files, generated_at, model, schema_version, sha256
| source_files | generated_at | model | schema_version | sha256 | |
|---|---|---|---|---|---|
|
2026-04-16T02:41:05.548844+00:00 | Qwen/Qwen3-Coder-Next-FP8 | 1 | 74033c59308d77b1 |
WinApi
Documentation: WindowsAPIHelpers.cs
1. Purpose
This module provides low-level Windows API interop helpers for managing window placement and sizing behavior, specifically to ensure that maximized windows align with the work area (i.e., excluding taskbar, docked toolbars) of the appropriate monitor in multi-monitor setups. It defines P/Invoke signatures and supporting structures (POINT, RECT, MINMAXINFO, MONITORINFO, WINDOWPOS) and exposes a helper method GetMinMaxInfo that adjusts the ptMaxSize and ptMaxPosition fields of a MINMAXINFO structure during a WM_GETMINMAXINFO message. This ensures windows maximize correctly to the visible screen area of the monitor containing the window, rather than the primary monitor’s full screen bounds.
2. Public Interface
Structs & Classes
-
POINT[StructLayout(LayoutKind.Sequential)] public struct POINT { public int x; public int y; public POINT(int x, int y); }Represents a point in screen coordinates. Used as a field in
MINMAXINFOand elsewhere. -
MINMAXINFO[StructLayout(LayoutKind.Sequential)] public struct MINMAXINFO { public POINT ptReserved; public POINT ptMaxSize; public POINT ptMaxPosition; public POINT ptMinTrackSize; public POINT ptMaxTrackSize; }Used in
WM_GETMINMAXINFOto specify minimum/maximum tracking sizes and maximized window geometry. TheptMaxSizeandptMaxPositionfields are modified byGetMinMaxInfo. -
MONITORINFO[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class MONITORINFO { public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); public RECT rcMonitor = new RECT(); public RECT rcWork = new RECT(); public int dwFlags = 0; }Container for monitor-specific information.
cbSizeis auto-initialized to the correct size.rcMonitorholds the full monitor bounds;rcWorkholds the work area (usable screen space). -
RECT[StructLayout(LayoutKind.Sequential, Pack = 0)] public struct RECT { public int left, top, right, bottom; public static readonly RECT Empty; public int Width => Math.Abs(right - left); public int Height => bottom - top; public bool IsEmpty => left >= right || top >= bottom; // ... constructors, equality, operators ... }Represents a rectangle in screen coordinates. Includes computed properties (
Width,Height,IsEmpty) and value-based equality (==,!=,Equals,GetHashCode). Note:Heightis computed asbottom - top(notMath.Abs), so negative heights are possible ifbottom < top. -
WINDOWPOS[StructLayout(LayoutKind.Sequential)] public struct WINDOWPOS { public IntPtr hwnd; public IntPtr hwndInsertAfter; public int x, y, cx, cy; public int flags; }Mirrors the Win32
WINDOWPOSstructure used inWM_WINDOWPOSCHANGING/WM_WINDOWPOSCHANGED.
Enums
-
WMpublic enum WM { WINDOWMAX = 0x0024, WINDOWPOSCHANGING = 0x0046 }Subset of Windows message constants. Note:
WINDOWMAXis likely a typo/misnomer forWM_WINDOWMAXIMIZED(which does not exist); standardWM_SYSCOMMANDwithSC_MAXIMIZEis more common.WINDOWPOSCHANGINGis correctlyWM_WINDOWPOSCHANGING. -
SWPpublic enum SWP { NOMOVE = 0x0002 }Subset of
SetWindowPosflags.NOMOVEpreserves current position when resizing.
Methods
-
GetMinMaxInfo(IntPtr hwnd, IntPtr lParam)public static void GetMinMaxInfo(IntPtr hwnd, IntPtr lParam)Reads a
MINMAXINFOstructure fromlParam, queries the monitor containinghwnd, retrieves its work area (rcWork) and full monitor area (rcMonitor), then updatesmmi.ptMaxPositionandmmi.ptMaxSizeto align the maximized window with the work area of the current monitor. Writes the modified structure back tolParam. This is intended to be called in response toWM_GETMINMAXINFO(0x0024). -
GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi)[DllImport("user32")] public static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);P/Invoke wrapper for
GetMonitorInfoW. Fillslpmiwith monitor data. Caller must setlpmi.cbSize(handled byMONITORINFO’s field initializer). -
MonitorFromWindow(IntPtr handle, int flags)[DllImport("User32")] public static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);P/Invoke wrapper for
MonitorFromWindow. ReturnsIntPtr.Zeroon failure. Used withMONITOR_DEFAULTTONEAREST(0x00000002).
3. Invariants
-
MONITORINFO.cbSizemust be set correctly before callingGetMonitorInfo:
TheMONITORINFOclass initializescbSizetoMarshal.SizeOf(typeof(MONITORINFO))in its field initializer, ensuring correctness for P/Invoke. -
RECTdimensions assume left ≤ right and top ≤ bottom:
WidthusesMath.Abs(right - left), butHeightdoes not (bottom - top). Ifbottom < top,Heightwill be negative. No validation enforces non-negative dimensions. -
GetMinMaxInfomodifiesptMaxSizeandptMaxPositiononly:
OtherMINMAXINFOfields (ptReserved,ptMinTrackSize,ptMaxTrackSize) are preserved as-is. -
Monitor query uses
MONITOR_DEFAULTTONEAREST:
Ifhwndis invalid or no monitor contains it,MonitorFromWindowreturnsIntPtr.Zero, andGetMinMaxInfoskips modification (no crash, but no adjustment either).
4. Dependencies
-
Runtime Dependencies:
System.Runtime.InteropServices(forStructLayout,Marshal,DllImport)System.Windows(though no WPF types are used in this file—likely a legacy/unused reference)- Win32
user32.dll(forGetMonitorInfo,MonitorFromWindow)
-
Consumers (inferred):
This module is designed to be used by code handlingWM_GETMINMAXINFO(e.g., in a WPF/WinForms window procedure). The methodGetMinMaxInfois called with the window handle andlParamfrom the message. No other direct dependencies are visible in the source. -
Missing Dependencies:
RECTis used but not defined in this file—this is a contradiction. The source definesRECThere, but theRECTused inMONITORINFOis initialized asnew RECT(). This impliesRECTmust be defined here (and it is), so no external dependency is needed.- No
usingforSystem.Drawingor other types—RECTis self-contained.
5. Gotchas
-
RECT.Heightis not absolute:
Height => bottom - top(notMath.Abs). Ifbottom < top,Heightis negative. This may cause unexpected behavior if consumers assume non-negative height. -
MONITORINFOis aclass, not astruct:
This is unusual for P/Invoke marshaling (wherestructis typical). While it works due tocbSizeinitialization andMarshal.PtrToStructure/StructureToPtr, using aclasshere risks reference-type semantics (e.g., accidental sharing). Astructwould be safer and more conventional. -
GetMinMaxInfosilently fails if monitor query fails:
IfMonitorFromWindowreturnsIntPtr.Zero(e.g., invalidhwnd), no adjustment occurs. No error is logged or thrown—consumers must verify behavior. -
WM.WINDOWMAXis likely incorrect:
0x0024isWM_SYSCOMMAND, not a maximization message.WM_GETMINMAXINFOis0x0024—this is the same value. The enum nameWINDOWMAXis misleading; it should beGETMINMAXINFO. This is a naming bug. -
RECT.IsEmptyuses>=(not>):
IsEmpty => left >= right || top >= bottomcorrectly handles degenerate rectangles (e.g.,left == right), but consumers may overlook that empty rectangles have zero area. -
No thread-safety guarantees:
GetMinMaxInfomutates aMINMAXINFOviaMarshal.PtrToStructure/StructureToPtr. While the operation is read-modify-write on a copy (safe), the use ofMONITORINFOas aclass(reference type) could introduce issues if reused across threads without copying. -
MONITORINFO.rcMonitorandrcWorkare initialized tonew RECT():
RECT()sets all fields to0, sorcMonitorandrcWorkstart as(0,0,0,0). This is safe for P/Invoke sinceGetMonitorInfooverwrites them. -
No handling of DPI scaling:
All coordinates are in physical pixels (Win32 convention). If the application is DPI-aware, callers must ensurehwndcorresponds to the correct DPI context. No DPI scaling is applied inGetMinMaxInfo.
No other issues are apparent from the source alone.