mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-18 22:46:38 +08:00
4.0 KiB
4.0 KiB
AtomUI.Native — Windows 平台 API 文档
概述
Windows 平台通过 user32.dll 的窗口扩展样式(Extended Window Styles)机制实现窗口级鼠标事件穿透。所有 API 均标注 [SupportedOSPlatform("windows")]。
1. 公共扩展方法
1.1 SetWindowIgnoreMouseEvents
设置窗口是否忽略(穿透)鼠标输入事件。
internal static void SetWindowIgnoreMouseEvents(this WindowBase window, bool flag)
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
window |
WindowBase |
Avalonia 窗口实例 |
flag |
bool |
true 启用穿透,false 禁用穿透 |
异常:
| 异常类型 | 条件 |
|---|---|
ArgumentException |
窗口句柄无效(IntPtr.Zero) |
PlatformNotSupportedException |
当前平台不受支持 |
Windows 实现原理:
通过修改窗口扩展样式(GWL_EXSTYLE)中的 WS_EX_TRANSPARENT 和 WS_EX_LAYERED 位标志:
- 启用穿透:
ExStyle |= (WS_EX_TRANSPARENT | WS_EX_LAYERED) - 禁用穿透:
ExStyle &= ~(WS_EX_TRANSPARENT | WS_EX_LAYERED)
⚠️
WS_EX_LAYERED是WS_EX_TRANSPARENT生效的前提条件,两者必须同时设置。
1.2 IsWindowIgnoreMouseEvents
查询窗口当前是否处于鼠标事件穿透状态。
internal static bool IsWindowIgnoreMouseEvents(this WindowBase window)
参数:
| 参数 | 类型 | 说明 |
|---|---|---|
window |
WindowBase |
Avalonia 窗口实例 |
返回值:
| 类型 | 说明 |
|---|---|
bool |
true 表示窗口正在穿透鼠标事件 |
Windows 实现原理:
读取窗口扩展样式并检查 WS_EX_TRANSPARENT 位:
(GetWindowLongPtr(handle, GWL_EXSTYLE) & WS_EX_TRANSPARENT) != 0
2. P/Invoke 声明
命名空间:
AtomUI.Native.Windows
类:internal static class WindowUtilsInterop
平台:[SupportedOSPlatform("windows")]
2.1 Win32 函数
GetWindowLongPtr
获取窗口的扩展样式或其他窗口属性。
[DllImport("user32.dll", EntryPoint = "GetWindowLongW", SetLastError = true)]
public static extern long GetWindowLongPtr(IntPtr hWnd, int nIndex);
| 参数 | 类型 | 说明 |
|---|---|---|
hWnd |
IntPtr |
窗口句柄 |
nIndex |
int |
属性索引(如 GWL_EXSTYLE = -20) |
返回值: 请求的窗口属性值(long)。
SetWindowLongPtr
设置窗口的扩展样式或其他窗口属性。
[DllImport("user32.dll", EntryPoint = "SetWindowLongW", SetLastError = true)]
public static extern long SetWindowLongPtr(IntPtr hWnd, int nIndex, long dwNewLong);
| 参数 | 类型 | 说明 |
|---|---|---|
hWnd |
IntPtr |
窗口句柄 |
nIndex |
int |
属性索引 |
dwNewLong |
long |
新的属性值 |
返回值: 设置前的旧属性值(long)。
2.2 常量定义
| 常量 | 值 | 类型 | 说明 |
|---|---|---|---|
GWL_STYLE |
-16 |
int |
窗口样式索引 |
GWL_EXSTYLE |
-20 |
int |
扩展窗口样式索引 |
WS_EX_TRANSPARENT |
0x20L |
long |
鼠标事件穿透标志位 |
WS_EX_LAYERED |
0x80000L |
long |
分层窗口标志位(穿透的前提条件) |
3. 使用示例
// 启用窗口鼠标事件穿透
window.SetWindowIgnoreMouseEvents(true);
// 查询是否处于穿透状态
bool isPassThrough = window.IsWindowIgnoreMouseEvents();
// 禁用穿透,恢复正常鼠标交互
window.SetWindowIgnoreMouseEvents(false);
4. 注意事项
- 句柄有效性 — 调用前确保
window.PlatformImpl?.Handle?.Handle不为null或IntPtr.Zero - 样式组合 —
WS_EX_TRANSPARENT必须与WS_EX_LAYERED同时使用才能实现完整的鼠标穿透 - 线程安全 — Win32 窗口操作应在 UI 线程执行
- 副作用 — 设置
WS_EX_LAYERED可能影响窗口的渲染行为,对于已经是分层窗口的场景无额外影响