quickwin 2.3.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.en.md +1 -2
  2. package/README.md +1 -2
  3. package/constants.ts +22 -0
  4. package/enum_map.d.ts +4 -0
  5. package/examples/PdfCanvas.js +1 -1
  6. package/examples/PdfCanvas.tsx +2 -2
  7. package/examples/execd/main.js +491 -217
  8. package/examples/pdf_preview2.js +76 -67
  9. package/examples/pdf_preview2.ts +84 -64
  10. package/examples/pdf_viewer.js +4932 -1029
  11. package/examples/pdf_viewer.tsx +11 -22
  12. package/examples/test_gallery.js +308 -143
  13. package/examples/test_gallery.tsx +12 -7
  14. package/examples/test_react_lazy.js +295 -133
  15. package/examples/test_react_lazy.tsx +4 -3
  16. package/examples/test_react_listbox.js +293 -132
  17. package/examples/test_react_listbox.tsx +3 -2
  18. package/examples/test_root_window.js +283 -126
  19. package/examples/test_tab.js +295 -133
  20. package/examples/test_tab.tsx +4 -3
  21. package/examples/tray_demo.js +37 -30
  22. package/examples/tray_demo.tsx +39 -32
  23. package/lib/bitmap.js +40 -0
  24. package/lib/bitmap.ts +39 -0
  25. package/lib/certs.js +31 -3
  26. package/lib/certs.ts +32 -3
  27. package/lib/dpi.js +30 -0
  28. package/lib/dpi.ts +31 -0
  29. package/lib/dumpRects.js +14 -7
  30. package/lib/dumpRects.ts +14 -6
  31. package/lib/ffi/bind.js +5 -4
  32. package/lib/ffi/bind.ts +9 -8
  33. package/lib/http-server.js +50 -25
  34. package/lib/http-server.ts +51 -23
  35. package/lib/react-qw/components/DateTimePicker.js +6 -7
  36. package/lib/react-qw/components/Input.js +5 -1
  37. package/lib/react-qw/components/ListView.js +8 -6
  38. package/lib/react-qw/components/ScrollView.js +28 -22
  39. package/lib/react-qw/index.js +7 -5
  40. package/lib/react-qw/index.ts +5 -5
  41. package/lib/react-qw/props.js +3 -3
  42. package/lib/react-qw/props.ts +3 -3
  43. package/lib/react-qw/reconciler.js +12 -17
  44. package/lib/react-qw/reconciler.ts +12 -16
  45. package/lib/text-measure.js +9 -6
  46. package/lib/text-measure.ts +9 -6
  47. package/lib/windows/comctl32.js +3 -2
  48. package/lib/windows/comctl32.ts +3 -2
  49. package/lib/windows/gdi32.js +28 -6
  50. package/lib/windows/gdi32.ts +30 -6
  51. package/lib/windows/kernel32.js +9 -0
  52. package/lib/windows/kernel32.ts +9 -0
  53. package/lib/windows/shell32.js +11 -2
  54. package/lib/windows/shell32.ts +13 -2
  55. package/lib/windows/structs.js +51 -0
  56. package/lib/windows/structs.ts +55 -0
  57. package/lib/windows/user32.js +6 -5
  58. package/lib/windows/user32.ts +6 -5
  59. package/main.js +13 -5
  60. package/package.json +2 -2
  61. package/quickwin.d.ts +13 -115
  62. package/qwin-nowasm-x86.exe +0 -0
  63. package/qwin-nowasm.exe +0 -0
  64. package/qwin-x86.exe +0 -0
  65. package/qwin.exe +0 -0
  66. package/test/bench_ffi_callraw.js +3 -4
  67. package/test/bench_ffi_callraw.ts +3 -4
  68. package/test/debug/mupdf_debug.js +4 -22
  69. package/test/debug/wasm_export_debug.js +2 -12
  70. package/test/debug/wasm_names.js +3 -13
  71. package/test/example.pdf +0 -0
  72. package/test/mupdf-cdn.js +40 -0
  73. package/test/mupdf-cdn.ts +43 -0
  74. package/test/test_ffi.js +8 -9
  75. package/test/test_ffi.ts +8 -9
  76. package/test/test_ffi_abi.js +6 -6
  77. package/test/test_ffi_abi.ts +8 -8
  78. package/test/test_ffi_windows.js +82 -11
  79. package/test/test_ffi_windows.ts +85 -11
  80. package/test/test_gdi_draw.js +3 -3
  81. package/test/test_gdi_draw.ts +4 -4
  82. package/test/test_mupdf_render.js +4 -22
  83. package/test/test_mupdf_render.ts +4 -23
  84. package/test/test_mupdf_twice.js +4 -19
  85. package/test/test_mupdf_twice.ts +4 -20
  86. package/test/test_mupdf_wasm.js +10 -4
  87. package/test/test_mupdf_wasm.ts +6 -4
  88. package/test/test_react_complex.js +316 -140
  89. package/test/test_react_counter.js +295 -133
  90. package/test/test_react_flex.js +297 -138
  91. package/test/test_react_hidden.js +296 -134
  92. package/test/test_react_listview_link.js +288 -131
  93. package/test/test_react_notify.js +290 -133
  94. package/test/test_react_render.js +295 -133
  95. package/vendor/mupdf-wasm/mupdf-wasm.d.ts +0 -571
  96. package/vendor/mupdf-wasm/mupdf-wasm.js +0 -2749
  97. package/vendor/mupdf-wasm/mupdf-wasm.wasm +0 -0
  98. package/vendor/mupdf-wasm/mupdf.d.ts +0 -939
  99. package/vendor/mupdf-wasm/mupdf.js +0 -3317
@@ -1,5 +1,5 @@
1
1
  import * as gui from 'gui'
2
- import { SetWindowText, EnableWindow } from '../windows/user32.js'
2
+ import { SetWindowText, EnableWindow, ShowWindow } from '../windows/user32.js'
3
3
  import type { Instance, Props } from './reconciler.js'
4
4
  import { EditMsg, ShowWindowCmd } from '../../constants'
5
5
 
@@ -33,9 +33,9 @@ export function applyProps(
33
33
  EnableWindow(hwnd, !newProps.disabled ? 1 : 0)
34
34
  }
35
35
  if ('hidden' in newProps) {
36
- gui.ShowWindow(hwnd, newProps.hidden ? ShowWindowCmd.HIDE : ShowWindowCmd.SHOW)
36
+ ShowWindow(hwnd, newProps.hidden ? ShowWindowCmd.HIDE : ShowWindowCmd.SHOW)
37
37
  }
38
38
  if ('visible' in newProps) {
39
- gui.ShowWindow(hwnd, newProps.visible ? ShowWindowCmd.SHOW : ShowWindowCmd.HIDE)
39
+ ShowWindow(hwnd, newProps.visible ? ShowWindowCmd.SHOW : ShowWindowCmd.HIDE)
40
40
  }
41
41
  }
@@ -3,21 +3,15 @@ import { createContext } from 'react';
3
3
  import { DefaultEventPriority, NoEventPriority } from 'react-reconciler/constants';
4
4
  import * as gui from 'gui';
5
5
  import * as os from 'os';
6
- import { GetDC, ReleaseDC, GetWindowLongPtr, CallWindowProc, SetWindowPos, InvalidateRect, SetParent, SetWindowText } from '../windows/user32.js';
7
- import { GetDeviceCaps } from '../windows/gdi32.js';
6
+ import { GetClientRect, GetWindowLongPtr, CallWindowProc, SetWindowPos, ShowWindow, InvalidateRect, SetParent, SetWindowText } from '../windows/user32.js';
7
+ import { createSystemDpiFont, getScaleFactor } from '../dpi.js';
8
+ import { RECT } from '../windows/structs.js';
8
9
  import { NULL } from '../ffi/ctype.js';
9
10
  import { applyProps } from './props.js';
10
11
  import { calculateFlexLayout } from './layout.js';
11
12
  import { getButtonIdealSize, measureTextForHwnd } from '../text-measure.js';
12
- const dpiFont = gui.CreateSystemDpiFont();
13
- // GetScaleFactor 等价内联:GetDC → GetDeviceCaps(LOGPIXELSX=88) → ReleaseDC 配对
14
- export const scaleFactor = (() => {
15
- const hdc = GetDC(NULL);
16
- const dpi = hdc ? GetDeviceCaps(hdc, 88) : 96;
17
- if (hdc)
18
- ReleaseDC(NULL, hdc);
19
- return dpi / 96;
20
- })();
13
+ const dpiFont = createSystemDpiFont();
14
+ export const scaleFactor = getScaleFactor();
21
15
  const DELAYED_CONTROLS = new Set(['SysListView32', 'SysTreeView32', 'LISTBOX', 'COMBOBOX', 'msctls_trackbar32', 'SysDateTimePick32', 'SysLink']);
22
16
  function isDelayedControl(winClass) {
23
17
  return DELAYED_CONTROLS.has(winClass);
@@ -59,11 +53,12 @@ function runFlexLayout(inst) {
59
53
  const visible = children.filter(c => !c.props.hidden);
60
54
  if (visible.length === 0)
61
55
  return;
62
- const rect = gui.GetClientRect(inst.hwnd);
63
- if (!rect) {
56
+ const rcBuf = RECT.alloc();
57
+ if (!GetClientRect(inst.hwnd, rcBuf.ptr)) {
64
58
  console.log('flex: no rect for', inst.hwnd, inst.type);
65
59
  return;
66
60
  }
61
+ const rect = RECT.decode(rcBuf);
67
62
  const pw = (rect.right - rect.left) / scaleFactor;
68
63
  const ph = (rect.bottom - rect.top) / scaleFactor;
69
64
  if (pw <= 0 || ph <= 0) {
@@ -260,19 +255,19 @@ const hostConfig = {
260
255
  },
261
256
  hideInstance(instance) {
262
257
  if (instance.hwnd !== null)
263
- gui.ShowWindow(instance.hwnd, 0 /* ShowWindowCmd.HIDE */);
258
+ ShowWindow(instance.hwnd, 0 /* ShowWindowCmd.HIDE */);
264
259
  },
265
260
  hideTextInstance(instance) {
266
261
  if (instance.hwnd !== null)
267
- gui.ShowWindow(instance.hwnd, 0 /* ShowWindowCmd.HIDE */);
262
+ ShowWindow(instance.hwnd, 0 /* ShowWindowCmd.HIDE */);
268
263
  },
269
264
  unhideInstance(instance, _props) {
270
265
  if (instance.hwnd !== null)
271
- gui.ShowWindow(instance.hwnd, 5 /* ShowWindowCmd.SHOW */);
266
+ ShowWindow(instance.hwnd, 5 /* ShowWindowCmd.SHOW */);
272
267
  },
273
268
  unhideTextInstance(instance, _text) {
274
269
  if (instance.hwnd !== null)
275
- gui.ShowWindow(instance.hwnd, 5 /* ShowWindowCmd.SHOW */);
270
+ ShowWindow(instance.hwnd, 5 /* ShowWindowCmd.SHOW */);
276
271
  },
277
272
  shouldSetTextContent(_type, props) {
278
273
  return typeof props.children === 'string' || typeof props.children === 'number';
@@ -3,8 +3,9 @@ import { createContext } from 'react'
3
3
  import { DefaultEventPriority, NoEventPriority } from 'react-reconciler/constants'
4
4
  import * as gui from 'gui'
5
5
  import * as os from 'os'
6
- import { GetDC, ReleaseDC, GetWindowLongPtr, CallWindowProc, SetWindowPos, InvalidateRect, SetParent, SetWindowText } from '../windows/user32.js'
7
- import { GetDeviceCaps } from '../windows/gdi32.js'
6
+ import { GetClientRect, GetWindowLongPtr, CallWindowProc, SetWindowPos, ShowWindow, InvalidateRect, SetParent, SetWindowText } from '../windows/user32.js'
7
+ import { createSystemDpiFont, getScaleFactor } from '../dpi.js'
8
+ import { RECT } from '../windows/structs.js'
8
9
  import { NULL } from '../ffi/ctype.js'
9
10
  import { applyProps } from './props.js'
10
11
  import { calculateFlexLayout, type FlexStyle } from './layout.js'
@@ -15,14 +16,8 @@ import { Gwlp, SetWindowPosFlag, SetWindowPosHwnd, ShowWindowCmd, WindowStyle, W
15
16
  // DEBUG 由 esbuild --define 在 bundle 时替换(见 build.ts),生产环境为 false
16
17
  declare const DEBUG: boolean
17
18
 
18
- const dpiFont = gui.CreateSystemDpiFont()
19
- // GetScaleFactor 等价内联:GetDC → GetDeviceCaps(LOGPIXELSX=88) → ReleaseDC 配对
20
- export const scaleFactor = (() => {
21
- const hdc = GetDC(NULL)
22
- const dpi = hdc ? GetDeviceCaps(hdc, 88) : 96
23
- if (hdc) ReleaseDC(NULL, hdc)
24
- return dpi / 96
25
- })()
19
+ const dpiFont = createSystemDpiFont()
20
+ export const scaleFactor = getScaleFactor()
26
21
 
27
22
  type Container = gui.HWND
28
23
  export type Props = WIntrinsicProps
@@ -83,8 +78,9 @@ function runFlexLayout(inst: Instance) {
83
78
  const flex: FlexStyle = s || {}
84
79
  const visible = children.filter(c => !c.props.hidden)
85
80
  if (visible.length === 0) return
86
- const rect = gui.GetClientRect(inst.hwnd!)
87
- if (!rect) { console.log('flex: no rect for', inst.hwnd, inst.type); return }
81
+ const rcBuf = RECT.alloc()
82
+ if (!GetClientRect(inst.hwnd!, rcBuf.ptr)) { console.log('flex: no rect for', inst.hwnd, inst.type); return }
83
+ const rect = RECT.decode(rcBuf)
88
84
  const pw = (rect.right - rect.left) / scaleFactor
89
85
  const ph = (rect.bottom - rect.top) / scaleFactor
90
86
  if (pw <= 0 || ph <= 0) { console.log('flex: zero size for', inst.hwnd, inst.type, pw, ph); return }
@@ -284,19 +280,19 @@ const hostConfig: QuickWinHostConfig = {
284
280
  },
285
281
 
286
282
  hideInstance(instance: Instance) {
287
- if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd, ShowWindowCmd.HIDE)
283
+ if (instance.hwnd !== null) ShowWindow(instance.hwnd, ShowWindowCmd.HIDE)
288
284
  },
289
285
 
290
286
  hideTextInstance(instance: Instance) {
291
- if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd, ShowWindowCmd.HIDE)
287
+ if (instance.hwnd !== null) ShowWindow(instance.hwnd, ShowWindowCmd.HIDE)
292
288
  },
293
289
 
294
290
  unhideInstance(instance: Instance, _props: Props) {
295
- if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd, ShowWindowCmd.SHOW)
291
+ if (instance.hwnd !== null) ShowWindow(instance.hwnd, ShowWindowCmd.SHOW)
296
292
  },
297
293
 
298
294
  unhideTextInstance(instance: Instance, _text: string) {
299
- if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd, ShowWindowCmd.SHOW)
295
+ if (instance.hwnd !== null) ShowWindow(instance.hwnd, ShowWindowCmd.SHOW)
300
296
  },
301
297
 
302
298
  shouldSetTextContent(_type: string, props: Props) {
@@ -1,6 +1,6 @@
1
1
  import { NULL } from './ffi/ctype.js';
2
2
  import * as gui from 'gui';
3
- import { DrawText, GetDC, ReleaseDC } from './windows/user32.js';
3
+ import { DrawText, GetDC, GetClientRect, GetWindowRect, ReleaseDC } from './windows/user32.js';
4
4
  import { SelectObject } from './windows/gdi32.js';
5
5
  import { RECT, SIZE } from './windows/structs.js';
6
6
  export function measureText(hdc, text, maxWidth) {
@@ -29,11 +29,14 @@ export function measureTextForHwnd(hwnd, text) {
29
29
  if (hFont)
30
30
  SelectObject(hdc, oldFont);
31
31
  ReleaseDC(hwnd, hdc);
32
- const wr = gui.GetWindowRect(hwnd);
33
- const cr = gui.GetClientRect(hwnd);
34
- if (wr && cr) {
35
- result.width += (wr.right - wr.left) - (cr.right - cr.left);
36
- result.height += (wr.bottom - wr.top) - (cr.bottom - cr.top);
32
+ const wr = RECT.alloc();
33
+ const cr = RECT.alloc();
34
+ const okWr = GetWindowRect(hwnd, wr.ptr);
35
+ const okCr = GetClientRect(hwnd, cr.ptr);
36
+ if (okWr && okCr) {
37
+ const w = RECT.decode(wr), c = RECT.decode(cr);
38
+ result.width += (w.right - w.left) - (c.right - c.left);
39
+ result.height += (w.bottom - w.top) - (c.bottom - c.top);
37
40
  }
38
41
  return result;
39
42
  }
@@ -1,6 +1,6 @@
1
1
  import { NULL, type Ptr } from './ffi/ctype.js'
2
2
  import * as gui from 'gui'
3
- import { DrawText, GetDC, ReleaseDC } from './windows/user32.js'
3
+ import { DrawText, GetDC, GetClientRect, GetWindowRect, ReleaseDC } from './windows/user32.js'
4
4
  import { SelectObject } from './windows/gdi32.js'
5
5
  import { RECT, SIZE } from './windows/structs.js'
6
6
  import { ButtonExtMsg, DrawTextFlag, WmMsg } from '../constants'
@@ -31,11 +31,14 @@ export function measureTextForHwnd(hwnd: gui.HWND, text: string): { width: numbe
31
31
  const result = measureText(hdc, text, 0)
32
32
  if (hFont) SelectObject(hdc, oldFont)
33
33
  ReleaseDC(hwnd, hdc)
34
- const wr = gui.GetWindowRect(hwnd)
35
- const cr = gui.GetClientRect(hwnd)
36
- if (wr && cr) {
37
- result.width += (wr.right - wr.left) - (cr.right - cr.left)
38
- result.height += (wr.bottom - wr.top) - (cr.bottom - cr.top)
34
+ const wr = RECT.alloc()
35
+ const cr = RECT.alloc()
36
+ const okWr = GetWindowRect(hwnd, wr.ptr)
37
+ const okCr = GetClientRect(hwnd, cr.ptr)
38
+ if (okWr && okCr) {
39
+ const w = RECT.decode(wr), c = RECT.decode(cr)
40
+ result.width += (w.right - w.left) - (c.right - c.left)
41
+ result.height += (w.bottom - w.top) - (c.bottom - c.top)
39
42
  }
40
43
  return result
41
44
  }
@@ -11,8 +11,9 @@ export const ImageListCreate = /*@__PURE__*/ b('ImageList_Create', 'i32 i32 u32
11
11
  /** 加位图进图像列表
12
12
  * @returns 新索引(-1 失败)
13
13
  * @param args_0 himl 图像列表句柄
14
- * @param args_1 hbm 位图句柄(gdi32 <HGDIOBJ>ptr 产物,如 CreateCompatibleBitmap) */
15
- export const ImageListAdd = /*@__PURE__*/ b('ImageList_Add', '<HIMAGELIST>ptr <HGDIOBJ>ptr -> i32');
14
+ * @param args_1 hbmImage 位图句柄(gdi32 <HGDIOBJ>ptr 产物,如 CreateCompatibleBitmap)
15
+ * @param args_2 hbmMask 掩码位图;32bpp 图像传 NULL */
16
+ export const ImageListAdd = /*@__PURE__*/ b('ImageList_Add', '<HIMAGELIST>ptr <HGDIOBJ>ptr <HGDIOBJ>ptr -> i32');
16
17
  /** 销毁图像列表
17
18
  * @returns 成功 → 非 0 */
18
19
  export const ImageListDestroy = /*@__PURE__*/ b('ImageList_Destroy', '<HIMAGELIST>ptr -> i32');
@@ -12,8 +12,9 @@ export const ImageListCreate = /*@__PURE__*/ b('ImageList_Create', 'i32 i32 u32
12
12
  /** 加位图进图像列表
13
13
  * @returns 新索引(-1 失败)
14
14
  * @param args_0 himl 图像列表句柄
15
- * @param args_1 hbm 位图句柄(gdi32 <HGDIOBJ>ptr 产物,如 CreateCompatibleBitmap) */
16
- export const ImageListAdd = /*@__PURE__*/ b('ImageList_Add', '<HIMAGELIST>ptr <HGDIOBJ>ptr -> i32')
15
+ * @param args_1 hbmImage 位图句柄(gdi32 <HGDIOBJ>ptr 产物,如 CreateCompatibleBitmap)
16
+ * @param args_2 hbmMask 掩码位图;32bpp 图像传 NULL */
17
+ export const ImageListAdd = /*@__PURE__*/ b('ImageList_Add', '<HIMAGELIST>ptr <HGDIOBJ>ptr <HGDIOBJ>ptr -> i32')
17
18
  /** 销毁图像列表
18
19
  * @returns 成功 → 非 0 */
19
20
  export const ImageListDestroy = /*@__PURE__*/ b('ImageList_Destroy', '<HIMAGELIST>ptr -> i32')
@@ -80,8 +80,30 @@ export const BitBlt = /*@__PURE__*/ b('BitBlt', '<HDC>ptr! i32 i32 i32 i32 <HDC>
80
80
  * @param args_3 cLines 扫描行数
81
81
  * @param args_4 lpvBits 像素接收缓冲(ArrayBuffer)
82
82
  * @param args_5 lpbmi BITMAPINFO 缓冲(BITMAPINFOHEADER.encode({...}).ptr)
83
- * @param args_6 uUsage DIB_RGB_COLORS(0) */
84
- export const GetDIBits = /*@__PURE__*/ b('GetDIBits', '<HDC>ptr! <HGDIOBJ>ptr u32 u32 <BYTE>ptr <>ptr u32 -> i32');
83
+ * @param args_6 uUsage ColorUse.RGB_COLORS */
84
+ export const GetDIBits = /*@__PURE__*/ b('GetDIBits', '<HDC>ptr! <HGDIOBJ>ptr u32 u32 <BYTE>ptr <>ptr u32@ColorUse -> i32');
85
+ /** 建 32bpp DIB 段位图(biHeight 负 = 自顶向下,像素内存由系统分配)——像素内容靠
86
+ * SetDIBits 从调用方缓冲装入,故 ppvBits 出参槽可传 NULL 不取位地址(要直写像素
87
+ * 才需要非空槽)
88
+ * @returns 位图句柄;失败 → 0(用完 DeleteObject)
89
+ * @param args_0 hdc 参考 DC(NULL 即可,只取 DIB 格式)
90
+ * @param args_1 pbmi BITMAPINFO 缓冲(BITMAPINFOHEADER.encode({...}).ptr,同 GetDIBits)
91
+ * @param args_2 iUsage ColorUse.RGB_COLORS
92
+ * @param args_3 ppvBits 收位地址的出参槽(NULL = 不取)
93
+ * @param args_4 hSection NULL(无文件映射区)
94
+ * @param args_5 offset 位数据在映射区内的偏移(无映射区恒 0) */
95
+ export const CreateDIBSection = /*@__PURE__*/ b('CreateDIBSection', '<HDC>ptr <>ptr u32@ColorUse <>ptr <>ptr u32 -> <HGDIOBJ>ptr');
96
+ /** 把 lpvBits 的像素装进位图(lpbmi 描述源的格式;ColorUse.RGB_COLORS 时 hdc 只定
97
+ * 目标格式,本仓传 NULL 实测可用——MSDN:仅 DIB_PAL_COLORS 才用 hdc)
98
+ * @returns 成功复制的扫描行数;失败 → 0
99
+ * @param args_0 hdc 参考 DC(NULL 即可,见上)
100
+ * @param args_1 hbm 目标位图(DIB 段同可用)
101
+ * @param args_2 uStartScan 起始扫描行
102
+ * @param args_3 cLines 扫描行数
103
+ * @param args_4 lpvBits 像素源缓冲(ArrayBuffer)
104
+ * @param args_5 lpbmi BITMAPINFO 缓冲(同 GetDIBits)
105
+ * @param args_6 iUsage ColorUse.RGB_COLORS */
106
+ export const SetDIBits = /*@__PURE__*/ b('SetDIBits', '<HDC>ptr <HGDIOBJ>ptr! u32 u32 <BYTE>ptr <>ptr u32@ColorUse -> i32');
85
107
  /** 取 GDI 对象信息到 lpv(hFont → LOGFONTW 等)
86
108
  * @returns 写入的字节数;失败 → 0
87
109
  * @param args_0 h GDI 对象句柄(字体/画笔/位图等)
@@ -171,8 +193,8 @@ export const MaskBlt = /*@__PURE__*/ b('MaskBlt', '<HDC>ptr! i32 i32 i32 i32 <HD
171
193
  * @param args_8 uNumScans 扫描行数
172
194
  * @param args_9 lpvBits 像素缓冲(ArrayBuffer)
173
195
  * @param args_10 lpbmi BITMAPINFO 缓冲
174
- * @param args_11 iUsage DIB_RGB_COLORS(0) */
175
- export const SetDIBitsToDevice = /*@__PURE__*/ b('SetDIBitsToDevice', '<HDC>ptr! i32 i32 u32 u32 i32 i32 u32 u32 <BYTE>ptr <BYTE>ptr u32 -> i32');
196
+ * @param args_11 iUsage ColorUse.RGB_COLORS */
197
+ export const SetDIBitsToDevice = /*@__PURE__*/ b('SetDIBitsToDevice', '<HDC>ptr! i32 i32 u32 u32 i32 i32 u32 u32 <BYTE>ptr <BYTE>ptr u32@ColorUse -> i32');
176
198
  /** 拉伸 DIB 传送(内存像素缓冲直接放/缩到目标,免创建 HBITMAP 中转);
177
199
  * DestWidth/DestHeight 传 0 = 源自然尺寸;SrcWidth/SrcHeight 负 = 翻转
178
200
  * @returns 成功 → 扫描行数;失败 → 0
@@ -186,9 +208,9 @@ export const SetDIBitsToDevice = /*@__PURE__*/ b('SetDIBitsToDevice', '<HDC>ptr!
186
208
  * @param args_8 SrcHeight 源区高
187
209
  * @param args_9 lpvBits 像素缓冲(ArrayBuffer)
188
210
  * @param args_10 lpbmi BITMAPINFO 缓冲(BITMAPINFOHEADER.encode({...}).ptr)
189
- * @param args_11 iUsage DIB_RGB_COLORS(0)
211
+ * @param args_11 iUsage ColorUse.RGB_COLORS
190
212
  * @param args_12 rop RasterOp.SRCCOPY 等互斥单选光栅操作码 */
191
- export const StretchDIBits = /*@__PURE__*/ b('StretchDIBits', '<HDC>ptr! i32 i32 i32 i32 i32 i32 i32 i32 <BYTE>ptr <BYTE>ptr u32 u32@RasterOp -> i32');
213
+ export const StretchDIBits = /*@__PURE__*/ b('StretchDIBits', '<HDC>ptr! i32 i32 i32 i32 i32 i32 i32 i32 <BYTE>ptr <BYTE>ptr u32@ColorUse u32@RasterOp -> i32');
192
214
  // ============ 画图原语(笔 / 线 / 形状 / 文字) ============
193
215
  /** 取系统共享对象(笔/刷/字体/调色板);共享句柄不要 DeleteObject——
194
216
  * SelectObject 选入 hdc 生效(如 NULL_BRUSH 让形状只描边不填充)
@@ -89,8 +89,32 @@ export const BitBlt = /*@__PURE__*/ b('BitBlt', '<HDC>ptr! i32 i32 i32 i32 <HDC>
89
89
  * @param args_3 cLines 扫描行数
90
90
  * @param args_4 lpvBits 像素接收缓冲(ArrayBuffer)
91
91
  * @param args_5 lpbmi BITMAPINFO 缓冲(BITMAPINFOHEADER.encode({...}).ptr)
92
- * @param args_6 uUsage DIB_RGB_COLORS(0) */
93
- export const GetDIBits = /*@__PURE__*/ b('GetDIBits', '<HDC>ptr! <HGDIOBJ>ptr u32 u32 <BYTE>ptr <>ptr u32 -> i32')
92
+ * @param args_6 uUsage ColorUse.RGB_COLORS */
93
+ export const GetDIBits = /*@__PURE__*/ b('GetDIBits', '<HDC>ptr! <HGDIOBJ>ptr u32 u32 <BYTE>ptr <>ptr u32@ColorUse -> i32')
94
+ /** 建 32bpp DIB 段位图(biHeight 负 = 自顶向下,像素内存由系统分配)——像素内容靠
95
+ * SetDIBits 从调用方缓冲装入,故 ppvBits 出参槽可传 NULL 不取位地址(要直写像素
96
+ * 才需要非空槽)
97
+ * @returns 位图句柄;失败 → 0(用完 DeleteObject)
98
+ * @param args_0 hdc 参考 DC(NULL 即可,只取 DIB 格式)
99
+ * @param args_1 pbmi BITMAPINFO 缓冲(BITMAPINFOHEADER.encode({...}).ptr,同 GetDIBits)
100
+ * @param args_2 iUsage ColorUse.RGB_COLORS
101
+ * @param args_3 ppvBits 收位地址的出参槽(NULL = 不取)
102
+ * @param args_4 hSection NULL(无文件映射区)
103
+ * @param args_5 offset 位数据在映射区内的偏移(无映射区恒 0) */
104
+ export const CreateDIBSection = /*@__PURE__*/ b('CreateDIBSection',
105
+ '<HDC>ptr <>ptr u32@ColorUse <>ptr <>ptr u32 -> <HGDIOBJ>ptr')
106
+ /** 把 lpvBits 的像素装进位图(lpbmi 描述源的格式;ColorUse.RGB_COLORS 时 hdc 只定
107
+ * 目标格式,本仓传 NULL 实测可用——MSDN:仅 DIB_PAL_COLORS 才用 hdc)
108
+ * @returns 成功复制的扫描行数;失败 → 0
109
+ * @param args_0 hdc 参考 DC(NULL 即可,见上)
110
+ * @param args_1 hbm 目标位图(DIB 段同可用)
111
+ * @param args_2 uStartScan 起始扫描行
112
+ * @param args_3 cLines 扫描行数
113
+ * @param args_4 lpvBits 像素源缓冲(ArrayBuffer)
114
+ * @param args_5 lpbmi BITMAPINFO 缓冲(同 GetDIBits)
115
+ * @param args_6 iUsage ColorUse.RGB_COLORS */
116
+ export const SetDIBits = /*@__PURE__*/ b('SetDIBits',
117
+ '<HDC>ptr <HGDIOBJ>ptr! u32 u32 <BYTE>ptr <>ptr u32@ColorUse -> i32')
94
118
  /** 取 GDI 对象信息到 lpv(hFont → LOGFONTW 等)
95
119
  * @returns 写入的字节数;失败 → 0
96
120
  * @param args_0 h GDI 对象句柄(字体/画笔/位图等)
@@ -184,9 +208,9 @@ export const MaskBlt = /*@__PURE__*/ b('MaskBlt',
184
208
  * @param args_8 uNumScans 扫描行数
185
209
  * @param args_9 lpvBits 像素缓冲(ArrayBuffer)
186
210
  * @param args_10 lpbmi BITMAPINFO 缓冲
187
- * @param args_11 iUsage DIB_RGB_COLORS(0) */
211
+ * @param args_11 iUsage ColorUse.RGB_COLORS */
188
212
  export const SetDIBitsToDevice = /*@__PURE__*/ b('SetDIBitsToDevice',
189
- '<HDC>ptr! i32 i32 u32 u32 i32 i32 u32 u32 <BYTE>ptr <BYTE>ptr u32 -> i32')
213
+ '<HDC>ptr! i32 i32 u32 u32 i32 i32 u32 u32 <BYTE>ptr <BYTE>ptr u32@ColorUse -> i32')
190
214
 
191
215
  /** 拉伸 DIB 传送(内存像素缓冲直接放/缩到目标,免创建 HBITMAP 中转);
192
216
  * DestWidth/DestHeight 传 0 = 源自然尺寸;SrcWidth/SrcHeight 负 = 翻转
@@ -201,10 +225,10 @@ export const SetDIBitsToDevice = /*@__PURE__*/ b('SetDIBitsToDevice',
201
225
  * @param args_8 SrcHeight 源区高
202
226
  * @param args_9 lpvBits 像素缓冲(ArrayBuffer)
203
227
  * @param args_10 lpbmi BITMAPINFO 缓冲(BITMAPINFOHEADER.encode({...}).ptr)
204
- * @param args_11 iUsage DIB_RGB_COLORS(0)
228
+ * @param args_11 iUsage ColorUse.RGB_COLORS
205
229
  * @param args_12 rop RasterOp.SRCCOPY 等互斥单选光栅操作码 */
206
230
  export const StretchDIBits = /*@__PURE__*/ b('StretchDIBits',
207
- '<HDC>ptr! i32 i32 i32 i32 i32 i32 i32 i32 <BYTE>ptr <BYTE>ptr u32 u32@RasterOp -> i32')
231
+ '<HDC>ptr! i32 i32 i32 i32 i32 i32 i32 i32 <BYTE>ptr <BYTE>ptr u32@ColorUse u32@RasterOp -> i32')
208
232
 
209
233
  // ============ 画图原语(笔 / 线 / 形状 / 文字) ============
210
234
 
@@ -266,6 +266,15 @@ export const GetComputerName = /*@__PURE__*/ b('GetComputerNameW', '<BYTE>ptr <B
266
266
  * @param args_1 lpFilename 接收缓冲,传 WCHAR.alloc(n)
267
267
  * @param args_2 nSize 缓冲容量(WCHAR 个数) */
268
268
  export const GetModuleFileName = /*@__PURE__*/ b('GetModuleFileNameW', '<HMODULE>ptr <BYTE>ptr u32 -> u32');
269
+ /** 取**已加载**模块的句柄(不加载、不加引用计数;LoadLibrary 的反向查询)
270
+ * @returns 模块句柄(HMODULE/HINSTANCE,与 win 模块同型);失败 → NULL
271
+ * @param args_0 lpModuleName 模块名(大小写不敏感,`.dll` 可省;只认模块名不认路径),
272
+ * 传 NULL = 当前进程主 exe —— `<WCHAR>ptr` 位收 string 或 NULL(JS null/undefined 会 fail-loud) */
273
+ export const GetModuleHandle = /*@__PURE__*/ b('GetModuleHandleW', '<WCHAR>ptr -> <HMODULE>ptr');
274
+ /** 卸载 LoadLibrary 加载的模块(引用计数减 1);GetModuleHandle 拿到的句柄**不可**传此 API
275
+ * @returns 成功 → 非 0
276
+ * @param args_0 hModule LoadLibrary 返回的模块句柄 */
277
+ export const FreeLibrary = /*@__PURE__*/ b('FreeLibrary', '<HMODULE>ptr -> i32');
269
278
  /** 进程命令行(含程序名;进程启动即有值,永不返回 NULL)
270
279
  * @returns 命令行整串(返回位 `<WCHAR>ptr!`:内建 WCHAR codec 自动解码为 string,
271
280
  * `!` 担保非 NULL 由返回位 0 检查兜底,无需接收缓冲) */
@@ -297,6 +297,15 @@ export const GetComputerName = /*@__PURE__*/ b('GetComputerNameW', '<BYTE>ptr <B
297
297
  * @param args_1 lpFilename 接收缓冲,传 WCHAR.alloc(n)
298
298
  * @param args_2 nSize 缓冲容量(WCHAR 个数) */
299
299
  export const GetModuleFileName = /*@__PURE__*/ b('GetModuleFileNameW', '<HMODULE>ptr <BYTE>ptr u32 -> u32')
300
+ /** 取**已加载**模块的句柄(不加载、不加引用计数;LoadLibrary 的反向查询)
301
+ * @returns 模块句柄(HMODULE/HINSTANCE,与 win 模块同型);失败 → NULL
302
+ * @param args_0 lpModuleName 模块名(大小写不敏感,`.dll` 可省;只认模块名不认路径),
303
+ * 传 NULL = 当前进程主 exe —— `<WCHAR>ptr` 位收 string 或 NULL(JS null/undefined 会 fail-loud) */
304
+ export const GetModuleHandle = /*@__PURE__*/ b('GetModuleHandleW', '<WCHAR>ptr -> <HMODULE>ptr')
305
+ /** 卸载 LoadLibrary 加载的模块(引用计数减 1);GetModuleHandle 拿到的句柄**不可**传此 API
306
+ * @returns 成功 → 非 0
307
+ * @param args_0 hModule LoadLibrary 返回的模块句柄 */
308
+ export const FreeLibrary = /*@__PURE__*/ b('FreeLibrary', '<HMODULE>ptr -> i32')
300
309
  /** 进程命令行(含程序名;进程启动即有值,永不返回 NULL)
301
310
  * @returns 命令行整串(返回位 `<WCHAR>ptr!`:内建 WCHAR codec 自动解码为 string,
302
311
  * `!` 担保非 NULL 由返回位 0 检查兜底,无需接收缓冲) */
@@ -1,6 +1,6 @@
1
- // shell32 绑定(shell 对话框 / PIDL→路径 / 托盘图标定位)
1
+ // shell32 绑定(shell 对话框 / PIDL→路径 / 托盘图标增删与定位)
2
2
  import { bind } from '../ffi/bind.js';
3
- import { NOTIFYICONIDENTIFIER } from './structs.js';
3
+ import { NOTIFYICONIDENTIFIER, NOTIFYICONDATAW } from './structs.js';
4
4
  // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释);第三参透传
5
5
  // encoders(结构入参位注册,方向约定见 lib/windows/user32.ts 头注释)
6
6
  const b = (name, sig, encoders) => bind('shell32.dll', name, sig, encoders);
@@ -32,3 +32,12 @@ export const Shell_NotifyIconGetRect = (() => {
32
32
  return null; // XP 等老系统无此导出(可选 API);探测走 examples/execd/tray.ts
33
33
  }
34
34
  })();
35
+ /** 托盘通知图标增删改(Shell_NotifyIconW;XP 起即有)
36
+ * @returns 成功 → 非 0,失败 → 0
37
+ * @param args_0 dwMessage NotifyIconCmd(ADD / MODIFY / DELETE / SETVERSION…;DELETE 只需
38
+ * hWnd+uID)
39
+ * @param args_1 lpData NOTIFYICONDATAW 对象直传(encoder 已注册,缺省字段跳过);cbSize 填
40
+ * NOTIFYICONDATAW.size、uFlags 取 NotifyIconFlag.*(ICON/MESSAGE/TIP…,决定下面哪些字段
41
+ * 生效)、uCallbackMessage 常填自定义消息号、hIcon 接 LoadImage/LoadAppIcon 的结果、
42
+ * szTip 直接给 string(宽字符串糖,最长 127 字符) */
43
+ export const ShellNotifyIcon = /*@__PURE__*/ b('Shell_NotifyIconW', 'u32 <NOTIFYICONDATAW>ptr -> i32', { NOTIFYICONDATAW });
@@ -1,6 +1,6 @@
1
- // shell32 绑定(shell 对话框 / PIDL→路径 / 托盘图标定位)
1
+ // shell32 绑定(shell 对话框 / PIDL→路径 / 托盘图标增删与定位)
2
2
  import { bind, type CodecMap } from '../ffi/bind.js'
3
- import { NOTIFYICONIDENTIFIER } from './structs.js'
3
+ import { NOTIFYICONIDENTIFIER, NOTIFYICONDATAW } from './structs.js'
4
4
 
5
5
  // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释);第三参透传
6
6
  // encoders(结构入参位注册,方向约定见 lib/windows/user32.ts 头注释)
@@ -37,3 +37,14 @@ export const Shell_NotifyIconGetRect = (() => {
37
37
  return null // XP 等老系统无此导出(可选 API);探测走 examples/execd/tray.ts
38
38
  }
39
39
  })()
40
+
41
+ /** 托盘通知图标增删改(Shell_NotifyIconW;XP 起即有)
42
+ * @returns 成功 → 非 0,失败 → 0
43
+ * @param args_0 dwMessage NotifyIconCmd(ADD / MODIFY / DELETE / SETVERSION…;DELETE 只需
44
+ * hWnd+uID)
45
+ * @param args_1 lpData NOTIFYICONDATAW 对象直传(encoder 已注册,缺省字段跳过);cbSize 填
46
+ * NOTIFYICONDATAW.size、uFlags 取 NotifyIconFlag.*(ICON/MESSAGE/TIP…,决定下面哪些字段
47
+ * 生效)、uCallbackMessage 常填自定义消息号、hIcon 接 LoadImage/LoadAppIcon 的结果、
48
+ * szTip 直接给 string(宽字符串糖,最长 127 字符) */
49
+ export const ShellNotifyIcon = /*@__PURE__*/ b('Shell_NotifyIconW',
50
+ 'u32 <NOTIFYICONDATAW>ptr -> i32', { NOTIFYICONDATAW })
@@ -78,6 +78,29 @@ export const LOGFONTW_DECL = {
78
78
  lfFaceName: 'u16[32]@utf-16le',
79
79
  };
80
80
  export const LOGFONTW = /* @__PURE__ */ struct('LOGFONTW', LOGFONTW_DECL);
81
+ /** 非客户区度量(504B,x64/ia32 同布局):内嵌 4 个 LOGFONTW + iPaddedBorderWidth(Vista+);
82
+ * SystemParametersInfo(SPI_GETNONCLIENTMETRICS) 纯出参位(不注册 encoder:
83
+ * encode({cbSize}) 建缓冲带初值 → 传 .ptr → decode 读回 lfMessageFont 等) */
84
+ export const NONCLIENTMETRICSW_DECL = {
85
+ '#': 'struct',
86
+ cbSize: 'u32',
87
+ iBorderWidth: 'i32',
88
+ iScrollWidth: 'i32',
89
+ iScrollHeight: 'i32',
90
+ iCaptionWidth: 'i32',
91
+ iCaptionHeight: 'i32',
92
+ lfCaptionFont: LOGFONTW_DECL,
93
+ iSmCaptionWidth: 'i32',
94
+ iSmCaptionHeight: 'i32',
95
+ lfSmCaptionFont: LOGFONTW_DECL,
96
+ iMenuWidth: 'i32',
97
+ iMenuHeight: 'i32',
98
+ lfMenuFont: LOGFONTW_DECL,
99
+ lfStatusFont: LOGFONTW_DECL,
100
+ lfMessageFont: LOGFONTW_DECL,
101
+ iPaddedBorderWidth: 'i32',
102
+ };
103
+ export const NONCLIENTMETRICSW = /* @__PURE__ */ struct('NONCLIENTMETRICSW', NONCLIENTMETRICSW_DECL);
81
104
  /** TEXTMETRICW(60B = 11 LONG + 4 WCHAR + 5 BYTE 尾部补齐,双架构同布局):
82
105
  * GetTextMetrics 纯出参位(不注册 encoder:TEXTMETRICW.alloc().ptr 进、decode 读回) */
83
106
  export const TEXTMETRICW_DECL = {
@@ -655,3 +678,31 @@ export const NOTIFYICONIDENTIFIER_DECL = {
655
678
  guidItem: 'u32[4]',
656
679
  };
657
680
  export const NOTIFYICONIDENTIFIER = /* @__PURE__ */ struct('NOTIFYICONIDENTIFIER', NOTIFYICONIDENTIFIER_DECL);
681
+ /** NOTIFYICONDATAW(Shell_NotifyIconW;x86 956B / x64 976B——hWnd/hIcon/hBalloonIcon 随
682
+ * 位宽,GUID 固定 16B;偏移经 mingw 头文件实测对齐)。cbSize 调用前填
683
+ * NOTIFYICONDATAW.size(cb 结构惯例,同 NOTIFYICONIDENTIFIER / SCROLLINFO)——
684
+ * 本声明取 Vista+ 布局(与 mingw sizeof 一致),XP 上同样可注册(实测)。
685
+ * szTip/szInfo/szInfoTitle 走宽字符串糖(u16[N]@utf-16le,同 LOGFONTW.lfFaceName);
686
+ * 图标句柄用裸 <>ptr:LoadImageW 的返回类型由 uType 决定(HICON/HCURSOR/HBITMAP),
687
+ * 绑定给不出品牌——裸地址收品牌指针(子型)无障碍;
688
+ * uTimeout 与 uVersion 是同址 union,本仓只用前者(恒 0,不走版本协商),
689
+ * 故按单字段 u32 声明而非 union 布局。 */
690
+ export const NOTIFYICONDATAW_DECL = {
691
+ '#': 'struct',
692
+ cbSize: 'u32',
693
+ hWnd: '<HWND>ptr',
694
+ uID: 'u32',
695
+ uFlags: 'u32',
696
+ uCallbackMessage: 'u32',
697
+ hIcon: '<>ptr',
698
+ szTip: 'u16[128]@utf-16le',
699
+ dwState: 'u32',
700
+ dwStateMask: 'u32',
701
+ szInfo: 'u16[256]@utf-16le',
702
+ uTimeout: 'u32',
703
+ szInfoTitle: 'u16[64]@utf-16le',
704
+ dwInfoFlags: 'u32',
705
+ guidItem: 'u32[4]',
706
+ hBalloonIcon: '<>ptr',
707
+ };
708
+ export const NOTIFYICONDATAW = /* @__PURE__ */ struct('NOTIFYICONDATAW', NOTIFYICONDATAW_DECL);
@@ -93,6 +93,31 @@ export const LOGFONTW_DECL = {
93
93
 
94
94
  export const LOGFONTW = /* @__PURE__ */ struct('LOGFONTW', LOGFONTW_DECL)
95
95
 
96
+ /** 非客户区度量(504B,x64/ia32 同布局):内嵌 4 个 LOGFONTW + iPaddedBorderWidth(Vista+);
97
+ * SystemParametersInfo(SPI_GETNONCLIENTMETRICS) 纯出参位(不注册 encoder:
98
+ * encode({cbSize}) 建缓冲带初值 → 传 .ptr → decode 读回 lfMessageFont 等) */
99
+ export const NONCLIENTMETRICSW_DECL = {
100
+ '#': 'struct',
101
+ cbSize: 'u32',
102
+ iBorderWidth: 'i32',
103
+ iScrollWidth: 'i32',
104
+ iScrollHeight: 'i32',
105
+ iCaptionWidth: 'i32',
106
+ iCaptionHeight: 'i32',
107
+ lfCaptionFont: LOGFONTW_DECL,
108
+ iSmCaptionWidth: 'i32',
109
+ iSmCaptionHeight: 'i32',
110
+ lfSmCaptionFont: LOGFONTW_DECL,
111
+ iMenuWidth: 'i32',
112
+ iMenuHeight: 'i32',
113
+ lfMenuFont: LOGFONTW_DECL,
114
+ lfStatusFont: LOGFONTW_DECL,
115
+ lfMessageFont: LOGFONTW_DECL,
116
+ iPaddedBorderWidth: 'i32',
117
+ } satisfies C_Struct
118
+
119
+ export const NONCLIENTMETRICSW = /* @__PURE__ */ struct('NONCLIENTMETRICSW', NONCLIENTMETRICSW_DECL)
120
+
96
121
  /** TEXTMETRICW(60B = 11 LONG + 4 WCHAR + 5 BYTE 尾部补齐,双架构同布局):
97
122
  * GetTextMetrics 纯出参位(不注册 encoder:TEXTMETRICW.alloc().ptr 进、decode 读回) */
98
123
  export const TEXTMETRICW_DECL = {
@@ -750,3 +775,33 @@ export const NOTIFYICONIDENTIFIER_DECL = {
750
775
  } satisfies C_Struct
751
776
 
752
777
  export const NOTIFYICONIDENTIFIER = /* @__PURE__ */ struct('NOTIFYICONIDENTIFIER', NOTIFYICONIDENTIFIER_DECL)
778
+
779
+ /** NOTIFYICONDATAW(Shell_NotifyIconW;x86 956B / x64 976B——hWnd/hIcon/hBalloonIcon 随
780
+ * 位宽,GUID 固定 16B;偏移经 mingw 头文件实测对齐)。cbSize 调用前填
781
+ * NOTIFYICONDATAW.size(cb 结构惯例,同 NOTIFYICONIDENTIFIER / SCROLLINFO)——
782
+ * 本声明取 Vista+ 布局(与 mingw sizeof 一致),XP 上同样可注册(实测)。
783
+ * szTip/szInfo/szInfoTitle 走宽字符串糖(u16[N]@utf-16le,同 LOGFONTW.lfFaceName);
784
+ * 图标句柄用裸 <>ptr:LoadImageW 的返回类型由 uType 决定(HICON/HCURSOR/HBITMAP),
785
+ * 绑定给不出品牌——裸地址收品牌指针(子型)无障碍;
786
+ * uTimeout 与 uVersion 是同址 union,本仓只用前者(恒 0,不走版本协商),
787
+ * 故按单字段 u32 声明而非 union 布局。 */
788
+ export const NOTIFYICONDATAW_DECL = {
789
+ '#': 'struct',
790
+ cbSize: 'u32',
791
+ hWnd: '<HWND>ptr',
792
+ uID: 'u32',
793
+ uFlags: 'u32',
794
+ uCallbackMessage: 'u32',
795
+ hIcon: '<>ptr',
796
+ szTip: 'u16[128]@utf-16le',
797
+ dwState: 'u32',
798
+ dwStateMask: 'u32',
799
+ szInfo: 'u16[256]@utf-16le',
800
+ uTimeout: 'u32',
801
+ szInfoTitle: 'u16[64]@utf-16le',
802
+ dwInfoFlags: 'u32',
803
+ guidItem: 'u32[4]',
804
+ hBalloonIcon: '<>ptr',
805
+ } satisfies C_Struct
806
+
807
+ export const NOTIFYICONDATAW = /* @__PURE__ */ struct('NOTIFYICONDATAW', NOTIFYICONDATAW_DECL)
@@ -495,10 +495,10 @@ export const GetSubMenu = /*@__PURE__*/ b('GetSubMenu', '<HMENU>ptr i32 -> <HMEN
495
495
  * @param args_1 uFlags TPM_* 标志
496
496
  * @param args_2 x 屏幕 x
497
497
  * @param args_3 y 屏幕 y
498
- * @param args_4 nReserved 保留,传 0
499
- * @param args_5 prcRect 点击区矩形(DeepPartial RECT / .ptr / NULL)
500
- * @param args_6 hdc 参考 DC,可 NULL */
501
- export const TrackPopupMenu = /*@__PURE__*/ b('TrackPopupMenu', '<HMENU>ptr u32 i32 i32 i32 <RECT>ptr <HDC>ptr -> i32', { RECT });
498
+ * @param args_4 nReserved 保留,传 0(TrackPopupMenuEx 才用)
499
+ * @param args_5 hWnd 拥有者窗口(TPM_RETURNCMD 时命令 ID 回到该窗口所属线程队列)
500
+ * @param args_6 prcRect 保留位,传 NULL(Win32 文档标注本 API 忽略此参数) */
501
+ export const TrackPopupMenu = /*@__PURE__*/ b('TrackPopupMenu', '<HMENU>ptr u32 i32 i32 i32 <HWND>ptr <RECT>ptr -> i32', { RECT });
502
502
  /** 创建弹出菜单;配对 DestroyMenu
503
503
  * @returns 菜单句柄;失败 → NULL */
504
504
  export const CreatePopupMenu = /*@__PURE__*/ b('CreatePopupMenu', ' -> <HMENU>ptr');
@@ -534,7 +534,8 @@ export const MessageBox = /*@__PURE__*/ b('MessageBoxW', '<HWND>ptr <WCHAR>ptr <
534
534
  // ============ 图像 ============
535
535
  /** 按名加载图像(string 自动编码;uType/fuLoad 用 Win32 真值——与 ImageType 枚举当前值
536
536
  * 不同)
537
- * @returns 图像句柄;失败 → 0
537
+ * @returns 图像句柄——类型随 uType(IMAGE_ICON→HICON / CURSOR→HCURSOR / BITMAP→HBITMAP),
538
+ * 绑定侧给不出品牌故为裸地址档;失败 → 0
538
539
  * @param args_0 hinst 模块句柄,NULL = 系统资源或 .ico 文件
539
540
  * @param args_1 name 图像名 string(资源名或文件路径)
540
541
  * @param args_2 uType IMAGE_* 真值(BITMAP=0/CURSOR=1/ICON=2)
@@ -520,10 +520,10 @@ export const GetSubMenu = /*@__PURE__*/ b('GetSubMenu', '<HMENU>ptr i32 -> <HMEN
520
520
  * @param args_1 uFlags TPM_* 标志
521
521
  * @param args_2 x 屏幕 x
522
522
  * @param args_3 y 屏幕 y
523
- * @param args_4 nReserved 保留,传 0
524
- * @param args_5 prcRect 点击区矩形(DeepPartial RECT / .ptr / NULL)
525
- * @param args_6 hdc 参考 DC,可 NULL */
526
- export const TrackPopupMenu = /*@__PURE__*/ b('TrackPopupMenu', '<HMENU>ptr u32 i32 i32 i32 <RECT>ptr <HDC>ptr -> i32', { RECT })
523
+ * @param args_4 nReserved 保留,传 0(TrackPopupMenuEx 才用)
524
+ * @param args_5 hWnd 拥有者窗口(TPM_RETURNCMD 时命令 ID 回到该窗口所属线程队列)
525
+ * @param args_6 prcRect 保留位,传 NULL(Win32 文档标注本 API 忽略此参数) */
526
+ export const TrackPopupMenu = /*@__PURE__*/ b('TrackPopupMenu', '<HMENU>ptr u32 i32 i32 i32 <HWND>ptr <RECT>ptr -> i32', { RECT })
527
527
  /** 创建弹出菜单;配对 DestroyMenu
528
528
  * @returns 菜单句柄;失败 → NULL */
529
529
  export const CreatePopupMenu = /*@__PURE__*/ b('CreatePopupMenu', ' -> <HMENU>ptr')
@@ -565,7 +565,8 @@ export const MessageBox = /*@__PURE__*/ b('MessageBoxW', '<HWND>ptr <WCHAR>ptr <
565
565
 
566
566
  /** 按名加载图像(string 自动编码;uType/fuLoad 用 Win32 真值——与 ImageType 枚举当前值
567
567
  * 不同)
568
- * @returns 图像句柄;失败 → 0
568
+ * @returns 图像句柄——类型随 uType(IMAGE_ICON→HICON / CURSOR→HCURSOR / BITMAP→HBITMAP),
569
+ * 绑定侧给不出品牌故为裸地址档;失败 → 0
569
570
  * @param args_0 hinst 模块句柄,NULL = 系统资源或 .ico 文件
570
571
  * @param args_1 name 图像名 string(资源名或文件路径)
571
572
  * @param args_2 uType IMAGE_* 真值(BITMAP=0/CURSOR=1/ICON=2)