quickwin 1.2.1 → 2.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 (137) hide show
  1. package/README.en.md +3 -3
  2. package/README.md +21 -24
  3. package/examples/PdfCanvas.js +8 -37
  4. package/examples/PdfCanvas.tsx +11 -41
  5. package/examples/exec_server.js +20054 -1423
  6. package/examples/exec_server.tsx +489 -0
  7. package/examples/exec_server_worker.js +383 -33
  8. package/examples/exec_server_worker.ts +408 -30
  9. package/examples/pdf_preview2.js +31 -73
  10. package/examples/pdf_preview2.ts +33 -76
  11. package/examples/pdf_viewer.js +1496 -616
  12. package/examples/pdf_viewer.tsx +23 -64
  13. package/examples/setres.js +22 -47
  14. package/examples/setres.ts +23 -57
  15. package/examples/test_gallery.js +1491 -525
  16. package/examples/test_react_lazy.js +1455 -500
  17. package/examples/test_react_listbox.js +1454 -499
  18. package/examples/test_root_window.js +1450 -495
  19. package/examples/test_tab.js +1455 -500
  20. package/lib/abort.js +70 -0
  21. package/lib/abort.ts +69 -0
  22. package/lib/certs.js +214 -0
  23. package/lib/certs.ts +224 -0
  24. package/lib/exec-log.js +15 -0
  25. package/lib/exec-log.ts +30 -0
  26. package/lib/fetch.js +37 -4
  27. package/lib/fetch.ts +35 -4
  28. package/lib/ffi/bind.js +352 -0
  29. package/lib/ffi/bind.ts +442 -0
  30. package/lib/ffi/ctype.js +168 -0
  31. package/lib/ffi/ctype.ts +331 -0
  32. package/lib/ffi/index.js +6 -0
  33. package/lib/ffi/index.ts +6 -0
  34. package/lib/ffi/struct.js +412 -0
  35. package/lib/ffi/struct.ts +664 -0
  36. package/lib/http-common.js +43 -5
  37. package/lib/http-common.ts +48 -6
  38. package/lib/http-server.js +187 -29
  39. package/lib/http-server.ts +177 -26
  40. package/lib/react-qw/components/DateTimePicker.js +20 -33
  41. package/lib/react-qw/components/Input.js +3 -10
  42. package/lib/react-qw/components/Link.js +7 -22
  43. package/lib/react-qw/components/ListView.js +80 -141
  44. package/lib/react-qw/components/PathPicker.js +36 -80
  45. package/lib/react-qw/components/ScrollView.js +15 -8
  46. package/lib/react-qw/components/Slider.js +2 -1
  47. package/lib/react-qw/components/Tab.js +15 -20
  48. package/lib/react-qw/components/Tooltip.js +21 -20
  49. package/lib/react-qw/components/TreeView.js +14 -47
  50. package/lib/react-qw/index.js +4 -2
  51. package/lib/react-qw/index.ts +4 -2
  52. package/lib/react-qw/nmhdr.js +5 -0
  53. package/lib/react-qw/nmhdr.ts +7 -0
  54. package/lib/react-qw/props.js +7 -2
  55. package/lib/react-qw/props.ts +7 -3
  56. package/lib/react-qw/reconciler.js +23 -13
  57. package/lib/react-qw/reconciler.ts +22 -13
  58. package/lib/text-measure.js +18 -35
  59. package/lib/text-measure.ts +20 -37
  60. package/lib/websocket.js +12 -2
  61. package/lib/websocket.ts +15 -2
  62. package/lib/windows/comctl32.js +18 -0
  63. package/lib/windows/comctl32.ts +20 -0
  64. package/lib/windows/comdlg32.js +7 -0
  65. package/lib/windows/comdlg32.ts +9 -0
  66. package/lib/windows/gdi32.js +90 -0
  67. package/lib/windows/gdi32.ts +97 -0
  68. package/lib/windows/kernel32.js +66 -0
  69. package/lib/windows/kernel32.ts +76 -0
  70. package/lib/windows/ntdll.js +8 -0
  71. package/lib/windows/ntdll.ts +10 -0
  72. package/lib/windows/ole32.js +7 -0
  73. package/lib/windows/ole32.ts +9 -0
  74. package/lib/windows/shell32.js +11 -0
  75. package/lib/windows/shell32.ts +14 -0
  76. package/lib/windows/structs.js +384 -0
  77. package/lib/windows/structs.ts +422 -0
  78. package/lib/windows/user32.js +469 -0
  79. package/lib/windows/user32.ts +502 -0
  80. package/package.json +1 -1
  81. package/quickwin.d.ts +22 -33
  82. package/quickwin_const.d.ts +1 -0
  83. package/qwin-nowasm-x86.exe +0 -0
  84. package/qwin-nowasm.exe +0 -0
  85. package/qwin-x86.exe +0 -0
  86. package/qwin.exe +0 -0
  87. package/test/bench_ffi_callraw.js +236 -0
  88. package/test/bench_ffi_callraw.ts +236 -0
  89. package/test/bench_ffi_overhead.js +139 -0
  90. package/test/bench_ffi_overhead.ts +141 -0
  91. package/test/bench_sendmessage.js +104 -0
  92. package/test/bench_sendmessage.ts +100 -0
  93. package/test/bench_sendmessage_nonnull.js +187 -0
  94. package/test/bench_sendmessage_nonnull.ts +188 -0
  95. package/test/run.js +14 -4
  96. package/test/run.ts +15 -5
  97. package/test/test_basic_fetch.js +8 -0
  98. package/test/test_basic_fetch.ts +9 -0
  99. package/test/test_ffi.js +33 -47
  100. package/test/test_ffi.ts +41 -60
  101. package/test/test_ffi_abi.js +235 -0
  102. package/test/test_ffi_abi.ts +218 -0
  103. package/test/test_ffi_bind.js +572 -0
  104. package/test/test_ffi_bind.ts +597 -0
  105. package/test/test_ffi_struct.js +745 -0
  106. package/test/test_ffi_struct.ts +798 -0
  107. package/test/test_ffi_struct_layout.js +495 -0
  108. package/test/test_ffi_struct_layout.ts +543 -0
  109. package/test/test_ffi_user32.js +103 -0
  110. package/test/test_ffi_user32.ts +113 -0
  111. package/test/test_ffi_windows.js +101 -0
  112. package/test/test_ffi_windows.ts +113 -0
  113. package/test/test_helper.js +8 -1
  114. package/test/test_helper.ts +9 -1
  115. package/test/test_http_import.js +18 -0
  116. package/test/test_http_import.ts +19 -0
  117. package/test/test_http_server.js +73 -1
  118. package/test/test_http_server.ts +75 -1
  119. package/test/test_ipv6.js +2 -2
  120. package/test/test_ipv6.ts +2 -2
  121. package/test/test_net_fetch.js +70 -8
  122. package/test/test_net_fetch.ts +69 -7
  123. package/test/test_net_websocket.js +1 -1
  124. package/test/test_net_websocket.ts +1 -1
  125. package/test/test_react_complex.js +1465 -510
  126. package/test/test_react_counter.js +1455 -500
  127. package/test/test_react_flex.js +1475 -513
  128. package/test/test_react_hidden.js +1458 -503
  129. package/test/test_react_listview_link.js +1455 -500
  130. package/test/test_react_notify.js +18534 -0
  131. package/test/test_react_render.js +1455 -500
  132. package/test/test_wolfssl_read.js +3 -2
  133. package/test/test_wolfssl_read.ts +3 -1
  134. package/test/test_worker_net.js +35 -17
  135. package/test/test_worker_net.ts +27 -15
  136. package/tsconfig.json +1 -1
  137. package/examples/exec_server.ts +0 -80
package/lib/websocket.js CHANGED
@@ -295,7 +295,13 @@ class WebSocketImpl {
295
295
  doError(new Error('SSL_CTX_new failed'));
296
296
  return;
297
297
  }
298
- wolfssl.wolfSSL_CTX_set_verify(this._ctx, 0 /* wolfssl.VerifyMode.SSL_VERIFY_NONE */);
298
+ if (this._options.rejectUnauthorized === false) {
299
+ wolfssl.wolfSSL_CTX_set_verify(this._ctx, 0 /* wolfssl.VerifyMode.SSL_VERIFY_NONE */);
300
+ }
301
+ else {
302
+ wolfssl.wolfSSL_CTX_set_verify(this._ctx, 1 /* wolfssl.VerifyMode.SSL_VERIFY_PEER */);
303
+ wolfssl.loadTrustedCerts(this._ctx);
304
+ }
299
305
  this._ssl = wolfssl.wolfSSL_new(this._ctx);
300
306
  if (!this._ssl) {
301
307
  doError(new Error('SSL_new failed'));
@@ -303,8 +309,12 @@ class WebSocketImpl {
303
309
  }
304
310
  wolfssl.wolfSSL_set_fd(this._ssl, sock.get_fd(fd));
305
311
  const sniHost = host;
306
- if (sniHost)
312
+ if (sniHost) {
307
313
  wolfssl.wolfSSL_UseSNI(this._ssl, 0 /* wolfssl.SniType.WOLFSSL_SNI_HOST_NAME */, sniHost);
314
+ if (this._options.rejectUnauthorized !== false) {
315
+ wolfssl.wolfSSL_check_domain_name(this._ssl, sniHost);
316
+ }
317
+ }
308
318
  state = 'handshake';
309
319
  }
310
320
  else {
package/lib/websocket.ts CHANGED
@@ -151,6 +151,9 @@ function tryParseFrame(buffer: Uint8Array): ParsedFrame | null {
151
151
 
152
152
  interface WebSocketOptions {
153
153
  headers?: Record<string, string>
154
+ /** Non-standard: when false, TLS certificate verification is skipped
155
+ * (mirrors Node's tls.connect rejectUnauthorized option). */
156
+ rejectUnauthorized?: boolean
154
157
  }
155
158
 
156
159
 
@@ -318,12 +321,22 @@ class WebSocketImpl {
318
321
  const method = wolfssl.wolfTLSv1_2_client_method()
319
322
  this._ctx = wolfssl.wolfSSL_CTX_new(method)
320
323
  if (!this._ctx) { doError(new Error('SSL_CTX_new failed')); return }
321
- wolfssl.wolfSSL_CTX_set_verify(this._ctx, wolfssl.VerifyMode.SSL_VERIFY_NONE)
324
+ if (this._options.rejectUnauthorized === false) {
325
+ wolfssl.wolfSSL_CTX_set_verify(this._ctx, wolfssl.VerifyMode.SSL_VERIFY_NONE)
326
+ } else {
327
+ wolfssl.wolfSSL_CTX_set_verify(this._ctx, wolfssl.VerifyMode.SSL_VERIFY_PEER)
328
+ wolfssl.loadTrustedCerts(this._ctx)
329
+ }
322
330
  this._ssl = wolfssl.wolfSSL_new(this._ctx)
323
331
  if (!this._ssl) { doError(new Error('SSL_new failed')); return }
324
332
  wolfssl.wolfSSL_set_fd(this._ssl, sock.get_fd(fd))
325
333
  const sniHost = host
326
- if (sniHost) wolfssl.wolfSSL_UseSNI(this._ssl, wolfssl.SniType.WOLFSSL_SNI_HOST_NAME, sniHost)
334
+ if (sniHost) {
335
+ wolfssl.wolfSSL_UseSNI(this._ssl, wolfssl.SniType.WOLFSSL_SNI_HOST_NAME, sniHost)
336
+ if (this._options.rejectUnauthorized !== false) {
337
+ wolfssl.wolfSSL_check_domain_name(this._ssl, sniHost)
338
+ }
339
+ }
327
340
  state = 'handshake'
328
341
  } else {
329
342
  this._sendRawStr(request)
@@ -0,0 +1,18 @@
1
+ // comctl32 绑定(ImageList 系列;HIMAGELIST 为不透明句柄保持 <>ptr)
2
+ import { bind } from '../ffi/bind.js';
3
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
4
+ const b = (name, sig) => bind('comctl32.dll', name, sig);
5
+ /** 创建图像列表;失败 → 0
6
+ * @param args_0 cx 图像宽度(像素)
7
+ * @param args_1 cy 图像高度(像素)
8
+ * @param args_2 flags ILC_* 标志(ILC_COLOR32 = 4)
9
+ * @param args_3 initial 初始图像数,0 = 默认
10
+ * @param args_4 grow 扩容步长,0 = 默认 */
11
+ export const ImageListCreate = /*@__PURE__*/ b('ImageList_Create', 'i32 i32 u32 i32 i32 -> <>ptr');
12
+ /** 追加位图到图像列表;返回新图像索引(-1 失败)
13
+ * @param args_0 himl
14
+ * @param args_1 hbmImage 源位图句柄(HBITMAP) */
15
+ export const ImageListAdd = /*@__PURE__*/ b('ImageList_Add', '<>ptr <>ptr -> i32');
16
+ /** 销毁图像列表;成功 → 非 0
17
+ * @param args_0 himl */
18
+ export const ImageListDestroy = /*@__PURE__*/ b('ImageList_Destroy', '<>ptr -> i32');
@@ -0,0 +1,20 @@
1
+ // comctl32 绑定(ImageList 系列;HIMAGELIST 为不透明句柄保持 <>ptr)
2
+ import { bind } from '../ffi/bind.js'
3
+
4
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
5
+ const b = <const S extends string>(name: string, sig: S) => bind('comctl32.dll', name, sig)
6
+
7
+ /** 创建图像列表;失败 → 0
8
+ * @param args_0 cx 图像宽度(像素)
9
+ * @param args_1 cy 图像高度(像素)
10
+ * @param args_2 flags ILC_* 标志(ILC_COLOR32 = 4)
11
+ * @param args_3 initial 初始图像数,0 = 默认
12
+ * @param args_4 grow 扩容步长,0 = 默认 */
13
+ export const ImageListCreate = /*@__PURE__*/ b('ImageList_Create', 'i32 i32 u32 i32 i32 -> <>ptr')
14
+ /** 追加位图到图像列表;返回新图像索引(-1 失败)
15
+ * @param args_0 himl
16
+ * @param args_1 hbmImage 源位图句柄(HBITMAP) */
17
+ export const ImageListAdd = /*@__PURE__*/ b('ImageList_Add', '<>ptr <>ptr -> i32')
18
+ /** 销毁图像列表;成功 → 非 0
19
+ * @param args_0 himl */
20
+ export const ImageListDestroy = /*@__PURE__*/ b('ImageList_Destroy', '<>ptr -> i32')
@@ -0,0 +1,7 @@
1
+ // comdlg32 绑定(通用文件对话框;GetOpenFileName 无 A/W 混用——一律 W 版)
2
+ import { bind } from '../ffi/bind.js';
3
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
4
+ const b = (name, sig) => bind('comdlg32.dll', name, sig);
5
+ /** 打开/保存文件对话框;用户确认 → 非 0(lpstrFile 缓冲即选中路径),取消/出错 → 0
6
+ * @param args_0 pOpenfn OPENFILENAMEW.encode(...).ptr(lStructSize 必须 = OPENFILENAMEW.size,见 structs.ts) */
7
+ export const GetOpenFileName = /*@__PURE__*/ b('GetOpenFileNameW', '<BYTE>ptr -> u32');
@@ -0,0 +1,9 @@
1
+ // comdlg32 绑定(通用文件对话框;GetOpenFileName 无 A/W 混用——一律 W 版)
2
+ import { bind } from '../ffi/bind.js'
3
+
4
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
5
+ const b = <const S extends string>(name: string, sig: S) => bind('comdlg32.dll', name, sig)
6
+
7
+ /** 打开/保存文件对话框;用户确认 → 非 0(lpstrFile 缓冲即选中路径),取消/出错 → 0
8
+ * @param args_0 pOpenfn OPENFILENAMEW.encode(...).ptr(lStructSize 必须 = OPENFILENAMEW.size,见 structs.ts) */
9
+ export const GetOpenFileName = /*@__PURE__*/ b('GetOpenFileNameW', '<BYTE>ptr -> u32')
@@ -0,0 +1,90 @@
1
+ // gdi32 绑定(品牌约定见 lib/windows/user32.ts 头注释):
2
+ // - HDC 出入参用 <HDC>ptr(品牌指针 Ptr<'HDC'>,与 user32 的 GetDC/ReleaseDC 同型互认)
3
+ // - GDI 对象通用句柄(HBRUSH/HPEN/HFONT/HBITMAP 在 Win32 同为 HGDIOBJ)保持 <>ptr——
4
+ // 异种对象互传由运行时句柄有效性判定,类型层不设品牌
5
+ // - 结构位按方向分流:CreateFontIndirect 的 LOGFONTW 是纯入参位,注册 encoder 收
6
+ // DeepPartial 对象直传(缺省字段跳过 = 保持 0 合法零值语义)
7
+ import { bind } from '../ffi/bind.js';
8
+ import { LOGFONTW } from './structs.js';
9
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释;第三参透传 encoders)
10
+ const b = (name, sig, encoders) => bind('gdi32.dll', name, sig, encoders);
11
+ /** 创建实心画刷;失败 → 0;配对 DeleteObject
12
+ * @param args_0 crColor 画刷颜色 0x00BBGGRR */
13
+ export const CreateSolidBrush = /*@__PURE__*/ b('CreateSolidBrush', 'u32 -> <>ptr');
14
+ /** 删除 GDI 对象(画刷/画笔/字体/位图等通用句柄,传 CreateXxx 返回的 number);成功 → 非 0
15
+ * @param args_0 hGdiObj */
16
+ export const DeleteObject = /*@__PURE__*/ b('DeleteObject', '<>ptr -> i32');
17
+ /** 取设备能力值
18
+ * @param args_0 hdc
19
+ * @param args_1 index 能力索引(LOGPIXELSX = 88,LOGPIXELSY = 90,BITSPIXEL = 12 等) */
20
+ export const GetDeviceCaps = /*@__PURE__*/ b('GetDeviceCaps', '<HDC>ptr! i32@DeviceCap -> i32');
21
+ /** 按 LOGFONTW 创建字体(入参位对象直传 DeepPartial:至少给 lfHeight 与 lfFaceName,其余缺省
22
+ * 跳过保持 0);失败 → 0;配对 DeleteObject
23
+ * @param args_0 lplf LOGFONTW 对象 */
24
+ export const CreateFontIndirect = /*@__PURE__*/ b('CreateFontIndirectW', '<LOGFONTW>ptr -> <>ptr', { LOGFONTW });
25
+ // ============ 内存 DC / 位图(截屏类流程:CreateCompatibleDC → SelectObject → BitBlt → GetDIBits)============
26
+ /** 建与 hdc 兼容的内存 DC;失败 → NULL;配对 DeleteDC
27
+ * @param args_0 hdc 参考 DC,NULL = 与屏幕兼容 */
28
+ export const CreateCompatibleDC = /*@__PURE__*/ b('CreateCompatibleDC', '<HDC>ptr -> <HDC>ptr');
29
+ /** 建与 hdc 兼容的位图(尺寸取决于 hdc 当前选中对象:内存 DC 刚建时选中 1×1 单色图,
30
+ * 所以要传屏幕 DC);失败 → NULL;配对 DeleteObject
31
+ * @param args_0 hdc 参考 DC(决定位图格式,须为屏幕或真实 DC)
32
+ * @param args_1 cx 宽度(像素)
33
+ * @param args_2 cy 高度(像素) */
34
+ export const CreateCompatibleBitmap = /*@__PURE__*/ b('CreateCompatibleBitmap', '<HDC>ptr! i32 i32 -> <>ptr');
35
+ /** 把 GDI 对象选进 hdc,返回被替换的旧对象(用完选回去再删除新对象);失败 → NULL
36
+ * @param args_0 hdc 目标 DC
37
+ * @param args_1 h 新对象句柄(HGDIOBJ 通称) */
38
+ export const SelectObject = /*@__PURE__*/ b('SelectObject', '<HDC>ptr! <>ptr -> <>ptr');
39
+ /** 位块传送;成功 → 非 0
40
+ * @param args_0 hdcDest 目标 DC
41
+ * @param args_1 xDest 目标左上角 x
42
+ * @param args_2 yDest 目标左上角 y
43
+ * @param args_3 cx 传送宽度
44
+ * @param args_4 cy 传送高度
45
+ * @param args_5 hdcSrc 源 DC
46
+ * @param args_6 x1 源起始 x
47
+ * @param args_7 y1 源起始 y
48
+ * @param args_8 dwRop 光栅操作码(SRCCOPY = 0x00CC0020) */
49
+ // hdcDest 非空(!);hdcSrc 在 PATCOPY 等特定 rop 下 C 允许 NULL,保持可空档。
50
+ export const BitBlt = /*@__PURE__*/ b('BitBlt', '<HDC>ptr! i32 i32 i32 i32 <HDC>ptr i32 i32 u32 -> i32');
51
+ /** 取位图像素到 lpvBits(lpbmi 为 BITMAPINFO,32bpp BI_RGB 无颜色表时头部即全部:
52
+ * 有颜色表的格式由调用方自备更大的缓冲);返回成功取到的扫描行数,失败 → 0
53
+ * @param args_0 hdc
54
+ * @param args_1 hbm 位图句柄
55
+ * @param args_2 uStartScan 起始扫描行
56
+ * @param args_3 cLines 扫描行数
57
+ * @param args_4 lpvBits 像素接收缓冲(ArrayBuffer)
58
+ * @param args_5 lpbmi BITMAPINFO 缓冲(BITMAPINFOHEADER.encode({...}).ptr)
59
+ * @param args_6 uUsage DIB_RGB_COLORS(0) */
60
+ export const GetDIBits = /*@__PURE__*/ b('GetDIBits', '<HDC>ptr! <>ptr u32 u32 <BYTE>ptr <>ptr u32 -> i32');
61
+ /** 取 GDI 对象信息到 lpv(hFont → LOGFONTW 等);返回写入的字节数,失败 → 0
62
+ * @param args_0 h GDI 对象句柄(字体/画笔/位图等)
63
+ * @param args_1 cb 输出缓冲字节数(如 LOGFONTW.size)
64
+ * @param args_2 lpv 输出缓冲(LOGFONTW.alloc() 等) */
65
+ export const GetObject = /*@__PURE__*/ b('GetObjectW', '<>ptr i32 <BYTE>ptr -> i32');
66
+ /** 删除内存 DC(CreateCompatibleDC 建的);成功 → 非 0
67
+ * @param args_0 hdc 要删的 DC */
68
+ export const DeleteDC = /*@__PURE__*/ b('DeleteDC', '<HDC>ptr! -> i32');
69
+ /** 用画刷图案填充矩形;成功 → 非 0
70
+ * @param args_0 hdc 目标 DC
71
+ * @param args_1 x 左上角 x
72
+ * @param args_2 y 左上角 y
73
+ * @param args_3 w 宽度
74
+ * @param args_4 h 高度
75
+ * @param args_5 rop 光栅操作码(PATCOPY 等) */
76
+ export const PatBlt = /*@__PURE__*/ b('PatBlt', '<HDC>ptr! i32 i32 i32 i32 u32 -> i32');
77
+ /** 把 DIB 位图画到目标 DC;返回扫描行数,失败 → 0
78
+ * @param args_0 hdc 目标 DC
79
+ * @param args_1 xDest 目标左上角 x
80
+ * @param args_2 yDest 目标左上角 y
81
+ * @param args_3 DestWidth 目标宽度
82
+ * @param args_4 DestHeight 目标高度
83
+ * @param args_5 xSrc 源起始 x
84
+ * @param args_6 ySrc 源起始 y
85
+ * @param args_7 uStartScan 起始扫描行
86
+ * @param args_8 uNumScans 扫描行数
87
+ * @param args_9 lpvBits 像素缓冲(ArrayBuffer)
88
+ * @param args_10 lpbmi BITMAPINFO 缓冲
89
+ * @param args_11 iUsage DIB_RGB_COLORS(0) */
90
+ export const SetDIBitsToDevice = /*@__PURE__*/ b('SetDIBitsToDevice', '<HDC>ptr! i32 i32 u32 u32 i32 i32 u32 u32 <BYTE>ptr <BYTE>ptr u32 -> i32');
@@ -0,0 +1,97 @@
1
+ // gdi32 绑定(品牌约定见 lib/windows/user32.ts 头注释):
2
+ // - HDC 出入参用 <HDC>ptr(品牌指针 Ptr<'HDC'>,与 user32 的 GetDC/ReleaseDC 同型互认)
3
+ // - GDI 对象通用句柄(HBRUSH/HPEN/HFONT/HBITMAP 在 Win32 同为 HGDIOBJ)保持 <>ptr——
4
+ // 异种对象互传由运行时句柄有效性判定,类型层不设品牌
5
+ // - 结构位按方向分流:CreateFontIndirect 的 LOGFONTW 是纯入参位,注册 encoder 收
6
+ // DeepPartial 对象直传(缺省字段跳过 = 保持 0 合法零值语义)
7
+ import { bind, type CodecMap } from '../ffi/bind.js'
8
+ import { LOGFONTW } from './structs.js'
9
+
10
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释;第三参透传 encoders)
11
+ const b = <const S extends string, const LE extends CodecMap = {}>(name: string, sig: S, encoders?: LE) =>
12
+ bind('gdi32.dll', name, sig, encoders)
13
+
14
+ /** 创建实心画刷;失败 → 0;配对 DeleteObject
15
+ * @param args_0 crColor 画刷颜色 0x00BBGGRR */
16
+ export const CreateSolidBrush = /*@__PURE__*/ b('CreateSolidBrush', 'u32 -> <>ptr')
17
+ /** 删除 GDI 对象(画刷/画笔/字体/位图等通用句柄,传 CreateXxx 返回的 number);成功 → 非 0
18
+ * @param args_0 hGdiObj */
19
+ export const DeleteObject = /*@__PURE__*/ b('DeleteObject', '<>ptr -> i32')
20
+ /** 取设备能力值
21
+ * @param args_0 hdc
22
+ * @param args_1 index 能力索引(LOGPIXELSX = 88,LOGPIXELSY = 90,BITSPIXEL = 12 等) */
23
+ export const GetDeviceCaps = /*@__PURE__*/ b('GetDeviceCaps', '<HDC>ptr! i32@DeviceCap -> i32')
24
+ /** 按 LOGFONTW 创建字体(入参位对象直传 DeepPartial:至少给 lfHeight 与 lfFaceName,其余缺省
25
+ * 跳过保持 0);失败 → 0;配对 DeleteObject
26
+ * @param args_0 lplf LOGFONTW 对象 */
27
+ export const CreateFontIndirect = /*@__PURE__*/ b('CreateFontIndirectW', '<LOGFONTW>ptr -> <>ptr', { LOGFONTW })
28
+
29
+ // ============ 内存 DC / 位图(截屏类流程:CreateCompatibleDC → SelectObject → BitBlt → GetDIBits)============
30
+
31
+ /** 建与 hdc 兼容的内存 DC;失败 → NULL;配对 DeleteDC
32
+ * @param args_0 hdc 参考 DC,NULL = 与屏幕兼容 */
33
+ export const CreateCompatibleDC = /*@__PURE__*/ b('CreateCompatibleDC', '<HDC>ptr -> <HDC>ptr')
34
+ /** 建与 hdc 兼容的位图(尺寸取决于 hdc 当前选中对象:内存 DC 刚建时选中 1×1 单色图,
35
+ * 所以要传屏幕 DC);失败 → NULL;配对 DeleteObject
36
+ * @param args_0 hdc 参考 DC(决定位图格式,须为屏幕或真实 DC)
37
+ * @param args_1 cx 宽度(像素)
38
+ * @param args_2 cy 高度(像素) */
39
+ export const CreateCompatibleBitmap = /*@__PURE__*/ b('CreateCompatibleBitmap', '<HDC>ptr! i32 i32 -> <>ptr')
40
+ /** 把 GDI 对象选进 hdc,返回被替换的旧对象(用完选回去再删除新对象);失败 → NULL
41
+ * @param args_0 hdc 目标 DC
42
+ * @param args_1 h 新对象句柄(HGDIOBJ 通称) */
43
+ export const SelectObject = /*@__PURE__*/ b('SelectObject', '<HDC>ptr! <>ptr -> <>ptr')
44
+ /** 位块传送;成功 → 非 0
45
+ * @param args_0 hdcDest 目标 DC
46
+ * @param args_1 xDest 目标左上角 x
47
+ * @param args_2 yDest 目标左上角 y
48
+ * @param args_3 cx 传送宽度
49
+ * @param args_4 cy 传送高度
50
+ * @param args_5 hdcSrc 源 DC
51
+ * @param args_6 x1 源起始 x
52
+ * @param args_7 y1 源起始 y
53
+ * @param args_8 dwRop 光栅操作码(SRCCOPY = 0x00CC0020) */
54
+ // hdcDest 非空(!);hdcSrc 在 PATCOPY 等特定 rop 下 C 允许 NULL,保持可空档。
55
+ export const BitBlt = /*@__PURE__*/ b('BitBlt', '<HDC>ptr! i32 i32 i32 i32 <HDC>ptr i32 i32 u32 -> i32')
56
+ /** 取位图像素到 lpvBits(lpbmi 为 BITMAPINFO,32bpp BI_RGB 无颜色表时头部即全部:
57
+ * 有颜色表的格式由调用方自备更大的缓冲);返回成功取到的扫描行数,失败 → 0
58
+ * @param args_0 hdc
59
+ * @param args_1 hbm 位图句柄
60
+ * @param args_2 uStartScan 起始扫描行
61
+ * @param args_3 cLines 扫描行数
62
+ * @param args_4 lpvBits 像素接收缓冲(ArrayBuffer)
63
+ * @param args_5 lpbmi BITMAPINFO 缓冲(BITMAPINFOHEADER.encode({...}).ptr)
64
+ * @param args_6 uUsage DIB_RGB_COLORS(0) */
65
+ export const GetDIBits = /*@__PURE__*/ b('GetDIBits', '<HDC>ptr! <>ptr u32 u32 <BYTE>ptr <>ptr u32 -> i32')
66
+ /** 取 GDI 对象信息到 lpv(hFont → LOGFONTW 等);返回写入的字节数,失败 → 0
67
+ * @param args_0 h GDI 对象句柄(字体/画笔/位图等)
68
+ * @param args_1 cb 输出缓冲字节数(如 LOGFONTW.size)
69
+ * @param args_2 lpv 输出缓冲(LOGFONTW.alloc() 等) */
70
+ export const GetObject = /*@__PURE__*/ b('GetObjectW', '<>ptr i32 <BYTE>ptr -> i32')
71
+ /** 删除内存 DC(CreateCompatibleDC 建的);成功 → 非 0
72
+ * @param args_0 hdc 要删的 DC */
73
+ export const DeleteDC = /*@__PURE__*/ b('DeleteDC', '<HDC>ptr! -> i32')
74
+
75
+ /** 用画刷图案填充矩形;成功 → 非 0
76
+ * @param args_0 hdc 目标 DC
77
+ * @param args_1 x 左上角 x
78
+ * @param args_2 y 左上角 y
79
+ * @param args_3 w 宽度
80
+ * @param args_4 h 高度
81
+ * @param args_5 rop 光栅操作码(PATCOPY 等) */
82
+ export const PatBlt = /*@__PURE__*/ b('PatBlt', '<HDC>ptr! i32 i32 i32 i32 u32 -> i32')
83
+ /** 把 DIB 位图画到目标 DC;返回扫描行数,失败 → 0
84
+ * @param args_0 hdc 目标 DC
85
+ * @param args_1 xDest 目标左上角 x
86
+ * @param args_2 yDest 目标左上角 y
87
+ * @param args_3 DestWidth 目标宽度
88
+ * @param args_4 DestHeight 目标高度
89
+ * @param args_5 xSrc 源起始 x
90
+ * @param args_6 ySrc 源起始 y
91
+ * @param args_7 uStartScan 起始扫描行
92
+ * @param args_8 uNumScans 扫描行数
93
+ * @param args_9 lpvBits 像素缓冲(ArrayBuffer)
94
+ * @param args_10 lpbmi BITMAPINFO 缓冲
95
+ * @param args_11 iUsage DIB_RGB_COLORS(0) */
96
+ export const SetDIBitsToDevice = /*@__PURE__*/ b('SetDIBitsToDevice',
97
+ '<HDC>ptr! i32 i32 u32 u32 i32 i32 u32 u32 <BYTE>ptr <BYTE>ptr u32 -> i32')
@@ -0,0 +1,66 @@
1
+ // kernel32.dll 绑定(进程 / 管道 / 系统信息子集;品牌约定见 lib/windows/user32.ts 头注释):
2
+ // - 内核对象句柄按用途分品牌:管道/文件 <HFILE>ptr、进程 <HPROCESS>ptr、线程
3
+ // <HTHREAD>ptr(CreatePipe 的 HANDLE* 出参槽是缓冲地址非句柄值,仍 <>ptr);
4
+ // CloseHandle/WaitForSingleObject 全家族位保持 <>ptr 收宽(品牌 number 子类型可
5
+ // 直传),异种对象深层互传由运行时句柄有效性判定兜底
6
+ // - 结构位按方向分流(结构定义见 ./structs.ts,布局随进程位宽,struct 按 os.arch 推):
7
+ // STARTUPINFOW 纯入参位注册 encoder → DeepPartial 对象直传;
8
+ // PROCESS_INFORMATION 出参位不注册 → 只收 def 分配的 .ptr,读回走 decode
9
+ // - 缓冲区 / DWORD 出参位用 <BYTE>ptr 直接收 PtrArrayBuffer(DataView / TypedArray 原地读回)
10
+ // - 空指针位(lpApplicationName / lpProcessAttributes 等)传 NULL(来自 ../ffi/ctype.js);
11
+ // 传 JS null/undefined 会在参数槽 fail-loud
12
+ // - 返回值 0 保真(C→JS 不做 0→null);BOOL 型返回 i32,成功 → 非 0,失败 → 0(原因见 GetLastError)
13
+ import { bind } from '../ffi/bind.js';
14
+ import { STARTUPINFOW } from './structs.js';
15
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
16
+ const b = (name, sig, encoders) => bind('kernel32.dll', name, sig, encoders);
17
+ // ============ 管道 / 进程 ============
18
+ /** 建匿名管道;成功 → 非 0
19
+ * @param args_0 hReadPipe 出参槽(读端句柄写回,<>ptr 缓冲地址)
20
+ * @param args_1 hWritePipe 出参槽(写端句柄写回,<>ptr 缓冲地址)
21
+ * @param args_2 lpPipeAttributes 安全属性,传 NULL
22
+ * @param args_3 nSize 管道缓冲字节数,0 = 系统默认 */
23
+ export const CreatePipe = /*@__PURE__*/ b('CreatePipe', '<>ptr <>ptr <>ptr u32 -> i32');
24
+ /** 设句柄标志;成功 → 非 0
25
+ * @param args_0 hHandle 文件/管道句柄
26
+ * @param args_1 dwMask 要改的标志位掩码(HANDLE_FLAG_*)
27
+ * @param args_2 dwFlags 标志新值(继承 = 1,不继承 = 0) */
28
+ export const SetHandleInformation = /*@__PURE__*/ b('SetHandleInformation', '<HFILE>ptr! u32 u32 -> i32');
29
+ /** 建进程;成功 → 非 0
30
+ * @param args_0 lpApplicationName 可执行文件路径 string 或 NULL
31
+ * @param args_1 lpCommandLine 命令行 string(含参数)或 NULL
32
+ * @param args_2 lpProcessAttributes 进程安全属性,传 NULL
33
+ * @param args_3 lpThreadAttributes 线程安全属性,传 NULL
34
+ * @param args_4 bInheritHandles 非 0 继承父进程句柄
35
+ * @param args_5 dwCreationFlags 创建标志(CREATE_NO_WINDOW = 0x08000000 等)
36
+ * @param args_6 lpEnvironment 环境块,传 NULL 继承当前环境
37
+ * @param args_7 lpCurrentDirectory 工作目录 string 或 NULL
38
+ * @param args_8 lpStartupInfo STARTUPINFOW 对象(cb 必填)
39
+ * @param args_9 lpProcessInformation 出参槽,传 PROCESS_INFORMATION.alloc().ptr */
40
+ export const CreateProcess = /*@__PURE__*/ b('CreateProcessW', '<WCHAR>ptr <WCHAR>ptr <>ptr <>ptr i32 u32 <>ptr <WCHAR>ptr <STARTUPINFOW>ptr <PROCESS_INFORMATION>ptr -> i32', { STARTUPINFOW });
41
+ /** 等内核对象就绪;返回 WAIT_* 码
42
+ * @param args_0 hHandle 内核对象句柄
43
+ * @param args_1 dwMilliseconds 超时毫秒,0xffffffff = 无限等 */
44
+ export const WaitForSingleObject = /*@__PURE__*/ b('WaitForSingleObject', '<>ptr u32 -> u32');
45
+ /** 取进程退出码(带符号读);成功 → 非 0
46
+ * @param args_0 hProcess 进程句柄
47
+ * @param args_1 lpExitCode 出参槽,传 Int32Array(1).buffer 读回退出码 */
48
+ export const GetExitCodeProcess = /*@__PURE__*/ b('GetExitCodeProcess', '<HPROCESS>ptr! <BYTE>ptr -> i32');
49
+ /** 关闭内核对象句柄;成功 → 非 0
50
+ * @param args_0 hObject 任意内核对象 */
51
+ export const CloseHandle = /*@__PURE__*/ b('CloseHandle', '<>ptr -> i32');
52
+ // ============ 文件 I/O ============
53
+ /** 同步读文件 / 管道;成功 → 非 0,管道写端全部关闭后读返回 0(EOF)
54
+ * @param args_0 hFile 文件/管道句柄
55
+ * @param args_1 lpBuffer 接收缓冲(<BYTE>ptr,PtrArrayBuffer 原地读回)
56
+ * @param args_2 nNumberOfBytesToRead 请求读取的字节数
57
+ * @param args_3 lpNumberOfBytesRead 出参槽,传 Uint32Array(1).buffer 读实际字节数
58
+ * @param args_4 lpOverlapped 重叠结构,传 NULL(同步读) */
59
+ export const ReadFile = /*@__PURE__*/ b('ReadFile', '<HFILE>ptr! <BYTE>ptr u32 <BYTE>ptr <>ptr -> i32');
60
+ // ============ 系统 / 错误 ============
61
+ /** 取调用线程最近一次 Win32 错误码 */
62
+ export const GetLastError = /*@__PURE__*/ b('GetLastError', ' -> u32');
63
+ /** 取 System32 目录路径(宽字符);返回写入的字符数(不含 NUL,0 失败)
64
+ * @param args_0 lpBuffer 接收缓冲,传 WCHAR.alloc(n)
65
+ * @param args_1 uSize 缓冲容量(WCHAR 个数,含 NUL 余量) */
66
+ export const GetSystemDirectory = /*@__PURE__*/ b('GetSystemDirectoryW', '<BYTE>ptr u32 -> u32');
@@ -0,0 +1,76 @@
1
+ // kernel32.dll 绑定(进程 / 管道 / 系统信息子集;品牌约定见 lib/windows/user32.ts 头注释):
2
+ // - 内核对象句柄按用途分品牌:管道/文件 <HFILE>ptr、进程 <HPROCESS>ptr、线程
3
+ // <HTHREAD>ptr(CreatePipe 的 HANDLE* 出参槽是缓冲地址非句柄值,仍 <>ptr);
4
+ // CloseHandle/WaitForSingleObject 全家族位保持 <>ptr 收宽(品牌 number 子类型可
5
+ // 直传),异种对象深层互传由运行时句柄有效性判定兜底
6
+ // - 结构位按方向分流(结构定义见 ./structs.ts,布局随进程位宽,struct 按 os.arch 推):
7
+ // STARTUPINFOW 纯入参位注册 encoder → DeepPartial 对象直传;
8
+ // PROCESS_INFORMATION 出参位不注册 → 只收 def 分配的 .ptr,读回走 decode
9
+ // - 缓冲区 / DWORD 出参位用 <BYTE>ptr 直接收 PtrArrayBuffer(DataView / TypedArray 原地读回)
10
+ // - 空指针位(lpApplicationName / lpProcessAttributes 等)传 NULL(来自 ../ffi/ctype.js);
11
+ // 传 JS null/undefined 会在参数槽 fail-loud
12
+ // - 返回值 0 保真(C→JS 不做 0→null);BOOL 型返回 i32,成功 → 非 0,失败 → 0(原因见 GetLastError)
13
+ import { bind, type CodecMap } from '../ffi/bind.js'
14
+ import { STARTUPINFOW } from './structs.js'
15
+
16
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
17
+ const b = <const S extends string, const LE extends CodecMap = {}>(name: string, sig: S, encoders?: LE) =>
18
+ bind('kernel32.dll', name, sig, encoders)
19
+
20
+ // ============ 管道 / 进程 ============
21
+
22
+ /** 建匿名管道;成功 → 非 0
23
+ * @param args_0 hReadPipe 出参槽(读端句柄写回,<>ptr 缓冲地址)
24
+ * @param args_1 hWritePipe 出参槽(写端句柄写回,<>ptr 缓冲地址)
25
+ * @param args_2 lpPipeAttributes 安全属性,传 NULL
26
+ * @param args_3 nSize 管道缓冲字节数,0 = 系统默认 */
27
+ export const CreatePipe = /*@__PURE__*/ b('CreatePipe', '<>ptr <>ptr <>ptr u32 -> i32')
28
+ /** 设句柄标志;成功 → 非 0
29
+ * @param args_0 hHandle 文件/管道句柄
30
+ * @param args_1 dwMask 要改的标志位掩码(HANDLE_FLAG_*)
31
+ * @param args_2 dwFlags 标志新值(继承 = 1,不继承 = 0) */
32
+ export const SetHandleInformation = /*@__PURE__*/ b('SetHandleInformation', '<HFILE>ptr! u32 u32 -> i32')
33
+ /** 建进程;成功 → 非 0
34
+ * @param args_0 lpApplicationName 可执行文件路径 string 或 NULL
35
+ * @param args_1 lpCommandLine 命令行 string(含参数)或 NULL
36
+ * @param args_2 lpProcessAttributes 进程安全属性,传 NULL
37
+ * @param args_3 lpThreadAttributes 线程安全属性,传 NULL
38
+ * @param args_4 bInheritHandles 非 0 继承父进程句柄
39
+ * @param args_5 dwCreationFlags 创建标志(CREATE_NO_WINDOW = 0x08000000 等)
40
+ * @param args_6 lpEnvironment 环境块,传 NULL 继承当前环境
41
+ * @param args_7 lpCurrentDirectory 工作目录 string 或 NULL
42
+ * @param args_8 lpStartupInfo STARTUPINFOW 对象(cb 必填)
43
+ * @param args_9 lpProcessInformation 出参槽,传 PROCESS_INFORMATION.alloc().ptr */
44
+ export const CreateProcess = /*@__PURE__*/ b('CreateProcessW',
45
+ '<WCHAR>ptr <WCHAR>ptr <>ptr <>ptr i32 u32 <>ptr <WCHAR>ptr <STARTUPINFOW>ptr <PROCESS_INFORMATION>ptr -> i32',
46
+ { STARTUPINFOW })
47
+ /** 等内核对象就绪;返回 WAIT_* 码
48
+ * @param args_0 hHandle 内核对象句柄
49
+ * @param args_1 dwMilliseconds 超时毫秒,0xffffffff = 无限等 */
50
+ export const WaitForSingleObject = /*@__PURE__*/ b('WaitForSingleObject', '<>ptr u32 -> u32')
51
+ /** 取进程退出码(带符号读);成功 → 非 0
52
+ * @param args_0 hProcess 进程句柄
53
+ * @param args_1 lpExitCode 出参槽,传 Int32Array(1).buffer 读回退出码 */
54
+ export const GetExitCodeProcess = /*@__PURE__*/ b('GetExitCodeProcess', '<HPROCESS>ptr! <BYTE>ptr -> i32')
55
+ /** 关闭内核对象句柄;成功 → 非 0
56
+ * @param args_0 hObject 任意内核对象 */
57
+ export const CloseHandle = /*@__PURE__*/ b('CloseHandle', '<>ptr -> i32')
58
+
59
+ // ============ 文件 I/O ============
60
+
61
+ /** 同步读文件 / 管道;成功 → 非 0,管道写端全部关闭后读返回 0(EOF)
62
+ * @param args_0 hFile 文件/管道句柄
63
+ * @param args_1 lpBuffer 接收缓冲(<BYTE>ptr,PtrArrayBuffer 原地读回)
64
+ * @param args_2 nNumberOfBytesToRead 请求读取的字节数
65
+ * @param args_3 lpNumberOfBytesRead 出参槽,传 Uint32Array(1).buffer 读实际字节数
66
+ * @param args_4 lpOverlapped 重叠结构,传 NULL(同步读) */
67
+ export const ReadFile = /*@__PURE__*/ b('ReadFile', '<HFILE>ptr! <BYTE>ptr u32 <BYTE>ptr <>ptr -> i32')
68
+
69
+ // ============ 系统 / 错误 ============
70
+
71
+ /** 取调用线程最近一次 Win32 错误码 */
72
+ export const GetLastError = /*@__PURE__*/ b('GetLastError', ' -> u32')
73
+ /** 取 System32 目录路径(宽字符);返回写入的字符数(不含 NUL,0 失败)
74
+ * @param args_0 lpBuffer 接收缓冲,传 WCHAR.alloc(n)
75
+ * @param args_1 uSize 缓冲容量(WCHAR 个数,含 NUL 余量) */
76
+ export const GetSystemDirectory = /*@__PURE__*/ b('GetSystemDirectoryW', '<BYTE>ptr u32 -> u32')
@@ -0,0 +1,8 @@
1
+ // ntdll 绑定(仅 RtlGetVersion——绕过 GetVersionEx 的兼容性谎言取真实版本)
2
+ import { bind } from '../ffi/bind.js';
3
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
4
+ const b = (name, sig) => bind('ntdll.dll', name, sig);
5
+ /** 取真实 OS 版本(成功 → 0);缓冲必须用 OSVERSIONINFO_148(148B 特制布局,
6
+ * 标准 OSVERSIONINFOW 会越界写坏调用方堆,见 structs.ts)
7
+ * @param args_0 lpVersionInformation OSVERSIONINFO_148.encode(...).ptr 出参缓冲 */
8
+ export const RtlGetVersion = /*@__PURE__*/ b('RtlGetVersion', '<BYTE>ptr -> i32');
@@ -0,0 +1,10 @@
1
+ // ntdll 绑定(仅 RtlGetVersion——绕过 GetVersionEx 的兼容性谎言取真实版本)
2
+ import { bind } from '../ffi/bind.js'
3
+
4
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
5
+ const b = <const S extends string>(name: string, sig: S) => bind('ntdll.dll', name, sig)
6
+
7
+ /** 取真实 OS 版本(成功 → 0);缓冲必须用 OSVERSIONINFO_148(148B 特制布局,
8
+ * 标准 OSVERSIONINFOW 会越界写坏调用方堆,见 structs.ts)
9
+ * @param args_0 lpVersionInformation OSVERSIONINFO_148.encode(...).ptr 出参缓冲 */
10
+ export const RtlGetVersion = /*@__PURE__*/ b('RtlGetVersion', '<BYTE>ptr -> i32')
@@ -0,0 +1,7 @@
1
+ // ole32 绑定(COM 内存管理;仅 CoTaskMemFree——shell 对话框返回的 PIDL 需它释放)
2
+ import { bind } from '../ffi/bind.js';
3
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
4
+ const b = (name, sig) => bind('ole32.dll', name, sig);
5
+ /** 释放 CoTaskMemAlloc 分配的内存(SHBrowseForFolder 返回的 PIDL 等);无返回值
6
+ * @param args_0 pv CoTaskMem 分配的指针(0/NULL 安全) */
7
+ export const CoTaskMemFree = /*@__PURE__*/ b('CoTaskMemFree', '<>ptr -> void');
@@ -0,0 +1,9 @@
1
+ // ole32 绑定(COM 内存管理;仅 CoTaskMemFree——shell 对话框返回的 PIDL 需它释放)
2
+ import { bind } from '../ffi/bind.js'
3
+
4
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
5
+ const b = <const S extends string>(name: string, sig: S) => bind('ole32.dll', name, sig)
6
+
7
+ /** 释放 CoTaskMemAlloc 分配的内存(SHBrowseForFolder 返回的 PIDL 等);无返回值
8
+ * @param args_0 pv CoTaskMem 分配的指针(0/NULL 安全) */
9
+ export const CoTaskMemFree = /*@__PURE__*/ b('CoTaskMemFree', '<>ptr -> void')
@@ -0,0 +1,11 @@
1
+ // shell32 绑定(shell 对话框 / PIDL→路径)
2
+ import { bind } from '../ffi/bind.js';
3
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
4
+ const b = (name, sig) => bind('shell32.dll', name, sig);
5
+ /** 文件夹浏览对话框;返回 PIDL,取消 → 0;PIDL 用 ole32.CoTaskMemFree 释放
6
+ * @param args_0 pbi BROWSEINFOW.encode(...).ptr(见 structs.ts) */
7
+ export const SHBrowseForFolder = /*@__PURE__*/ b('SHBrowseForFolderW', '<BYTE>ptr -> <>ptr');
8
+ /** PIDL → 文件系统全路径;PIDL 在文件系统中 → 非 0,否则 0(缓冲内容未定义)
9
+ * @param args_0 pidl SHBrowseForFolder 等返回的 PIDL
10
+ * @param args_1 pszPath 出参缓冲,WCHAR.alloc(260)(MAX_PATH=260)、WCHAR.decode 读回 */
11
+ export const SHGetPathFromIDList = /*@__PURE__*/ b('SHGetPathFromIDListW', '<>ptr <BYTE>ptr -> u32');
@@ -0,0 +1,14 @@
1
+ // shell32 绑定(shell 对话框 / PIDL→路径)
2
+ import { bind } from '../ffi/bind.js'
3
+
4
+ // dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
5
+ const b = <const S extends string>(name: string, sig: S) => bind('shell32.dll', name, sig)
6
+
7
+ /** 文件夹浏览对话框;返回 PIDL,取消 → 0;PIDL 用 ole32.CoTaskMemFree 释放
8
+ * @param args_0 pbi BROWSEINFOW.encode(...).ptr(见 structs.ts) */
9
+ export const SHBrowseForFolder = /*@__PURE__*/ b('SHBrowseForFolderW', '<BYTE>ptr -> <>ptr')
10
+
11
+ /** PIDL → 文件系统全路径;PIDL 在文件系统中 → 非 0,否则 0(缓冲内容未定义)
12
+ * @param args_0 pidl SHBrowseForFolder 等返回的 PIDL
13
+ * @param args_1 pszPath 出参缓冲,WCHAR.alloc(260)(MAX_PATH=260)、WCHAR.decode 读回 */
14
+ export const SHGetPathFromIDList = /*@__PURE__*/ b('SHGetPathFromIDListW', '<>ptr <BYTE>ptr -> u32')