--- source_files: - Common/DTS.Common/Classes/WinApi/WindowsAPIHelpers.cs generated_at: "2026-04-16T03:16:58.945801+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "32ac28362ec2b57c" --- # WinApi ## Documentation: `WindowsAPIHelpers.cs` --- ### 1. **Purpose** This module provides interoperability helpers for Windows API integration, specifically to support custom window sizing and positioning behavior in WPF applications. It defines P/Invoke-compatible structures (`POINT`, `RECT`, `MINMAXINFO`, `MONITORINFO`, `WINDOWPOS`, `WM`, `SWP`) and exposes two Win32 functions (`GetMonitorInfo`, `MonitorFromWindow`) to enable accurate adjustment of a window’s maximized size and position to match the *work area* of the monitor on which the window resides—rather than the full screen (which may include taskbars or other non-client areas). This is typically used in response to the `WM_GETMINMAXINFO` message to prevent maximized windows from overlapping system UI elements. --- ### 2. **Public Interface** #### Structs - **`POINT`** ```csharp [StructLayout(LayoutKind.Sequential)] public struct POINT { public int x; public int y; public POINT(int x, int y); } ``` Represents a point in 2D space with integer coordinates. Used as a field in other structures. - **`RECT`** ```csharp [StructLayout(LayoutKind.Sequential, Pack = 0)] public struct RECT { public int left, top, right, bottom; public static readonly RECT Empty; public int Width { get; } public int Height { get; } public RECT(int left, int top, int right, int bottom); public bool IsEmpty { get; } public override string ToString(); public override bool Equals(object obj); public override int GetHashCode(); public static bool operator ==(RECT, RECT); public static bool operator !=(RECT, RECT); } ``` Represents a rectangle with integer coordinates. Includes computed `Width` and `Height` properties, equality operators, and an `IsEmpty` check (true if `left >= right` or `top >= bottom`). Note: `Height` is computed as `bottom - top` (not `Math.Abs`), so negative heights are possible if `bottom < top`. - **`MINMAXINFO`** ```csharp [StructLayout(LayoutKind.Sequential)] public struct MINMAXINFO { public POINT ptReserved; public POINT ptMaxSize; public POINT ptMaxPosition; public POINT ptMinTrackSize; public POINT ptMaxTrackSize; } ``` Used to convey minimum/maximum tracking and maximized window geometry. Populated by `GetMinMaxInfo`. - **`MONITORINFO`** ```csharp [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; } ``` Contains monitor-specific information. `cbSize` is auto-initialized to the unmanaged size of the struct. `rcMonitor` is the full monitor rectangle; `rcWork` is the work area (excluding taskbars, etc.). - **`WINDOWPOS`** ```csharp [StructLayout(LayoutKind.Sequential)] public struct WINDOWPOS { public IntPtr hwnd; public IntPtr hwndInsertAfter; public int x, y, cx, cy; public int flags; } ``` Used in `WM_WINDOWPOSCHANGING`/`WM_WINDOWPOSCHANGED` messages. Not used directly in this file but defined for completeness. #### Enums - **`WM`** ```csharp public enum WM { WINDOWMAX = 0x0024, WINDOWPOSCHANGING = 0x0046; } ``` Windows message constants. `WINDOWMAX` is likely a typo or nonstandard alias (standard is `WM_SYSCOMMAND` with `SC_MAXIMIZE`, or `WM_SIZE` with `SIZE_MAXIMIZED`). `WINDOWPOSCHANGING` is `WM_WINDOWPOSCHANGING`. - **`SWP`** ```csharp public enum SWP { NOMOVE = 0x0002; } ``` Flags for `SetWindowPos`. `NOMOVE` preserves current position. #### Methods - **`GetMinMaxInfo(IntPtr hwnd, IntPtr lParam)`** ```csharp public static void GetMinMaxInfo(IntPtr hwnd, IntPtr lParam) ``` Handles the `WM_GETMINMAXINFO` message by adjusting `ptMaxSize` and `ptMaxPosition` in the `MINMAXINFO` structure to fit the *work area* of the monitor containing `hwnd`. Uses `MonitorFromWindow` with `MONITOR_DEFAULTTONEAREST` (`0x00000002`) to locate the monitor, then calls `GetMonitorInfo` to retrieve monitor geometry. Writes the modified `MINMAXINFO` back to `lParam`. #### P/Invoke Exports - **`GetMonitorInfo`** ```csharp [DllImport("user32")] public static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi); ``` Retrieves monitor information. Caller must initialize `MONITORINFO.cbSize` before calling. - **`MonitorFromWindow`** ```csharp [DllImport("User32")] public static extern IntPtr MonitorFromWindow(IntPtr handle, int flags); ``` Returns a handle to the monitor that contains the window. `flags` is typically `MONITOR_DEFAULTTONEAREST` (`0x00000002`). --- ### 3. **Invariants** - `MONITORINFO.cbSize` **must** be set to `Marshal.SizeOf(typeof(MONITORINFO))` before calling `GetMonitorInfo`; otherwise, the call will fail (returns `false`). - `RECT.IsEmpty` is defined as `left >= right || top >= bottom`. This implies a rectangle with `left == right` or `top == bottom` is considered empty. - `RECT.Height` is computed as `bottom - top` (not `Math.Abs(bottom - top)`), so if `bottom < top`, `Height` is negative. This may indicate an inverted rectangle (e.g., from drag-select), but the code does not enforce non-negative height. - `GetMinMaxInfo` assumes the window is on a valid monitor. If `MonitorFromWindow` returns `IntPtr.Zero`, no adjustment is made, and the original `MINMAXINFO` values are preserved. - The `ptMaxPosition` values are computed as absolute offsets from the monitor’s left/top edge (`Math.Abs(rcWorkArea.left - rcMonitorArea.left)`), which correctly yields the top-left corner of the work area relative to the monitor. --- ### 4. **Dependencies** #### Dependencies *on* this module: - **WPF/Win32 interop layer**: This module is intended for use in WPF applications (evidenced by `System.Windows` namespace usage, though not directly referenced in this file). Likely consumed by window message handlers (e.g., `Window.SourceInitialized` or `OnSourceInitialized` overrides) to subclass window procedures and handle `WM_GETMINMAXINFO`. - **`System.Runtime.InteropServices`**: Required for `StructLayout`, `DllImport`, `Marshal.PtrToStructure`, and `Marshal.StructureToPtr`. #### Dependencies *of* this module: - **`user32.dll`**: For `GetMonitorInfo` and `MonitorFromWindow`. - **No external libraries beyond .NET Framework core types** (no NuGet dependencies implied). #### Known consumers (inferred): - Any class handling `WM_GETMINMAXINFO` (e.g., via `HwndSource.AddHook`) will call `WindowsAPIHelpers.GetMinMaxInfo`. - Likely used in custom window management logic (e.g., `MainWindow.xaml.cs` or a base window class). --- ### 5. **Gotchas** - **`RECT.Height` is *not* absolute**: `Height => bottom - top` (not `Math.Abs`). This may cause unexpected negative heights if rectangles are inverted. Use `Math.Abs` externally if needed. - **`MONITORINFO` is a `class`, not a `struct`**: This is unusual for P/Invoke marshaling (typically `struct` is preferred). While it works due to `StructLayout`, it introduces heap allocation and reference semantics. Ensure the instance is not reused across threads without synchronization. - **`WINDOWMAX` enum value is nonstandard**: The Win32 constant for maximization is `WM_SYSCOMMAND` with `SC_MAXIMIZE` (0xF030), not `0x0024`. `0x0024` is `WM_USER + 36` in some contexts but not a standard system message. This may be a typo or internal alias. - **`rcMonitor` vs `rcWork` semantics**: `rcMonitor` is the full monitor bounds; `rcWork` excludes taskbars, etc. The code correctly uses `rcWork` for `ptMaxSize`/`ptMaxPosition`, but callers must understand this distinction. - **No validation of `lParam` in `GetMinMaxInfo`**: Assumes `lParam` points to a valid `MINMAXINFO` structure. Passing `IntPtr.Zero` or invalid memory will cause a crash. - **Missing `WM` constants**: Only two `WM` values are defined (`WINDOWMAX`, `WINDOWPOSCHANGING`). Other common messages (e.g., `WM_SIZE`, `WM_GETMINMAXINFO`) are not included, suggesting this is a partial set. - **`MONITOR_DEFAULTTONEAREST` flag is hardcoded**: The `MonitorFromWindow` call uses `0x00000002` directly instead of a named constant (e.g., `MONITOR_DEFAULTTONEAREST = 2`). While correct, it reduces readability. None identified beyond these.