Files
DP44/enriched-qwen3-coder-next/Common/DTS.Common/Classes/WinApi.md

169 lines
8.4 KiB
Markdown
Raw Normal View History

2026-04-17 14:55:32 -04:00
---
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 windows 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 monitors 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.