quickwin 2.3.1 → 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 (97) hide show
  1. package/README.en.md +1 -2
  2. package/README.md +1 -2
  3. package/constants.ts +15 -0
  4. package/enum_map.d.ts +3 -0
  5. package/examples/PdfCanvas.js +1 -1
  6. package/examples/PdfCanvas.tsx +2 -2
  7. package/examples/execd/main.js +334 -188
  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/react-qw/components/DateTimePicker.js +6 -7
  34. package/lib/react-qw/components/Input.js +5 -1
  35. package/lib/react-qw/components/ListView.js +8 -6
  36. package/lib/react-qw/components/ScrollView.js +28 -22
  37. package/lib/react-qw/index.js +7 -5
  38. package/lib/react-qw/index.ts +5 -5
  39. package/lib/react-qw/props.js +3 -3
  40. package/lib/react-qw/props.ts +3 -3
  41. package/lib/react-qw/reconciler.js +12 -17
  42. package/lib/react-qw/reconciler.ts +12 -16
  43. package/lib/text-measure.js +9 -6
  44. package/lib/text-measure.ts +9 -6
  45. package/lib/windows/comctl32.js +3 -2
  46. package/lib/windows/comctl32.ts +3 -2
  47. package/lib/windows/gdi32.js +28 -6
  48. package/lib/windows/gdi32.ts +30 -6
  49. package/lib/windows/kernel32.js +9 -0
  50. package/lib/windows/kernel32.ts +9 -0
  51. package/lib/windows/shell32.js +11 -2
  52. package/lib/windows/shell32.ts +13 -2
  53. package/lib/windows/structs.js +51 -0
  54. package/lib/windows/structs.ts +55 -0
  55. package/lib/windows/user32.js +6 -5
  56. package/lib/windows/user32.ts +6 -5
  57. package/main.js +13 -5
  58. package/package.json +2 -2
  59. package/quickwin.d.ts +13 -115
  60. package/qwin-nowasm-x86.exe +0 -0
  61. package/qwin-nowasm.exe +0 -0
  62. package/qwin-x86.exe +0 -0
  63. package/qwin.exe +0 -0
  64. package/test/bench_ffi_callraw.js +3 -4
  65. package/test/bench_ffi_callraw.ts +3 -4
  66. package/test/debug/mupdf_debug.js +4 -22
  67. package/test/debug/wasm_export_debug.js +2 -12
  68. package/test/debug/wasm_names.js +3 -13
  69. package/test/example.pdf +0 -0
  70. package/test/mupdf-cdn.js +40 -0
  71. package/test/mupdf-cdn.ts +43 -0
  72. package/test/test_ffi.js +8 -9
  73. package/test/test_ffi.ts +8 -9
  74. package/test/test_ffi_abi.js +6 -6
  75. package/test/test_ffi_abi.ts +8 -8
  76. package/test/test_ffi_windows.js +82 -11
  77. package/test/test_ffi_windows.ts +85 -11
  78. package/test/test_gdi_draw.js +3 -3
  79. package/test/test_gdi_draw.ts +4 -4
  80. package/test/test_mupdf_render.js +4 -22
  81. package/test/test_mupdf_render.ts +4 -23
  82. package/test/test_mupdf_twice.js +4 -19
  83. package/test/test_mupdf_twice.ts +4 -20
  84. package/test/test_mupdf_wasm.js +10 -4
  85. package/test/test_mupdf_wasm.ts +6 -4
  86. package/test/test_react_complex.js +316 -140
  87. package/test/test_react_counter.js +295 -133
  88. package/test/test_react_flex.js +297 -138
  89. package/test/test_react_hidden.js +296 -134
  90. package/test/test_react_listview_link.js +288 -131
  91. package/test/test_react_notify.js +290 -133
  92. package/test/test_react_render.js +295 -133
  93. package/vendor/mupdf-wasm/mupdf-wasm.d.ts +0 -571
  94. package/vendor/mupdf-wasm/mupdf-wasm.js +0 -2749
  95. package/vendor/mupdf-wasm/mupdf-wasm.wasm +0 -0
  96. package/vendor/mupdf-wasm/mupdf.d.ts +0 -939
  97. package/vendor/mupdf-wasm/mupdf.js +0 -3317
@@ -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)
package/main.js CHANGED
@@ -1,6 +1,11 @@
1
- import { CallWindowProc, CreateSystemDpiFont, CreateWindow as CreateWindowWithoutScale, DefWindowProc, GetScaleFactor, GetWindowLongPtr, GetWindowText, RegisterClass, SendMessage, SetWindowProc, ShowWindow, } from "gui";
2
- const scaleFactor = GetScaleFactor();
3
- const dpiFont = CreateSystemDpiFont();
1
+ import { CreateWindow as CreateWindowWithoutScale, DefWindowProc, RegisterClass, SendMessage, SetWindowProc, } from "gui";
2
+ // Win32 直通:CallWindowProc / GetWindowLongPtr / GetWindowText 无引擎状态,
3
+ // 已从 gui 模块摘除,走 lib/windows 的 FFI 绑定
4
+ import { CallWindowProc, GetWindowLongPtr, GetWindowText, GetWindowTextLength, ShowWindow } from "./lib/windows/user32.js";
5
+ import { WCHAR } from "./lib/ffi/bind.js";
6
+ import { createSystemDpiFont, getScaleFactor } from "./lib/dpi.js";
7
+ const scaleFactor = getScaleFactor();
8
+ const dpiFont = createSystemDpiFont();
4
9
  if (!dpiFont)
5
10
  throw new Error('Failed to create DPI font');
6
11
  const CreateWindow = (className, title, style, x, y, cx, cy, parent, id) => {
@@ -26,7 +31,10 @@ function wndProc(hwnd, msg, wParam, lParam) {
26
31
  return 0;
27
32
  if (!list)
28
33
  return 0;
29
- const text = GetWindowText(edit);
34
+ const cap = GetWindowTextLength(edit) + 1;
35
+ const buf = WCHAR.alloc(cap);
36
+ GetWindowText(edit, buf, cap);
37
+ const text = WCHAR.decode(buf);
30
38
  if (text.trim())
31
39
  SendMessage(list, 384 /* LbMsg.ADDSTRING */, 0, text);
32
40
  return 0;
@@ -43,4 +51,4 @@ function wndProc(hwnd, msg, wParam, lParam) {
43
51
  RegisterClass("MainWindow", wndProc);
44
52
  var hwnd = CreateWindow("MainWindow", "Todo List", 13565952 /* WindowStyle.OVERLAPPEDWINDOW */, 0, 0, 600, 400, null, null);
45
53
  if (hwnd)
46
- ShowWindow(hwnd);
54
+ ShowWindow(hwnd, 1 /* ShowWindowCmd.SHOWNORMAL */);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "quickwin",
4
- "version": "2.3.1",
4
+ "version": "3.0.0",
5
5
  "description": "QuickJS Win32 runtime — GUI, networking, WASM, FFI, and more",
6
6
  "bin": {
7
7
  "quickwin": "qwin.exe",
@@ -22,7 +22,6 @@
22
22
  "lib/",
23
23
  "test/",
24
24
  "examples/",
25
- "vendor/",
26
25
  "quickwin.d.ts",
27
26
  "constants.ts",
28
27
  "enum_map.d.ts",
@@ -36,6 +35,7 @@
36
35
  "url": "git+https://github.com/quickwinlabs/quickwin.git"
37
36
  },
38
37
  "devDependencies": {
38
+ "@quickwinlabs/mupdf-wasm": "^1.28.0",
39
39
  "@types/node": "^24.13.2",
40
40
  "@types/react": "^19.2.17",
41
41
  "@types/react-reconciler": "^0.33.0",
package/quickwin.d.ts CHANGED
@@ -421,96 +421,23 @@ declare module "wolfssl" {
421
421
 
422
422
  }
423
423
 
424
- declare module "win" {
425
- /** 与 ffi 的 Ptr<"HMODULE"> 同型(ptrBrand string 键)——FFI 侧 <HMODULE>ptr 位(HINSTANCE 语义)直收 */
426
- type HMODULE = number & { readonly ptrBrand: "HMODULE" };
427
-
428
- function LoadLibrary(libName: string): HMODULE | null;
429
- function GetProcAddress(hModule: HMODULE, procName: string): number | null;
430
- function FreeLibrary(hModule: HMODULE): boolean;
431
- /** GetModuleFileName(hModule?) — 传 HMODULE 或不传(当前进程),返回模块完整路径;失败返回 undefined */
432
- function GetModuleFileName(hModule?: HMODULE): string | undefined;
433
- /** GetModuleHandle(moduleName?) — 不传返回当前 exe 的模块句柄;失败返回 null */
434
- function GetModuleHandle(moduleName?: string): HMODULE | null;
435
- }
436
-
437
424
  declare module "gui" {
438
425
  /** 与 ffi 的 Ptr<"N"> 结构同型(ptrBrand string 键,见 lib/ffi/ctype.ts)——各句柄可在
439
426
  * gui 模块与 FFI 绑定两体系间互认直传(原 unique symbol 键只有 HWND 打通) */
440
427
  type HWND = number & { readonly ptrBrand: "HWND" };
441
428
  type HMENU = number & { readonly ptrBrand: "HMENU" };
442
- type HFONT = number & { readonly ptrBrand: "HFONT" };
443
429
  type HICON = number & { readonly ptrBrand: "HICON" };
444
- type WNDPROC = number & { readonly ptrBrand: "WNDPROC" };
445
- // 枚举唯一定义在 constants.ts(真实 .ts,tsc/esbuild 均内联);此处别名仅供签名引用,
446
- // 使用方请直接 import { WindowStyle } from 'quickwin/constants'。
447
- // Gwlp/ImageType 的成员访问(如 Gwlp.WNDPROC)需写 import('./constants').Gwlp.WNDPROC
448
- // ——类型别名不建命名空间,无法穿透取成员。
449
- type GetWindowCmd = import('./constants').GetWindowCmd;
450
- type ShowWindowCmd = import('./constants').ShowWindowCmd;
451
- type SetWindowPosHwnd = import('./constants').SetWindowPosHwnd;
452
- type Gwlp = import('./constants').Gwlp;
453
- type NotifyIconCmd = import('./constants').NotifyIconCmd;
454
- type ImageType = import('./constants').ImageType;
455
- type IDI = import('./constants').IDI;
456
- type ScrollBar = import('./constants').ScrollBar;
430
+ // 枚举唯一定义在 constants.ts(真实 .ts,tsc/esbuild 均内联);本模块不再转出枚举
431
+ // 别名与 RECT 等结构类型——Win32 直通请走 lib/windows(含常量与结构定义)
457
432
 
458
433
  function RegisterClass(className: string, wndProc?: (hwnd: HWND, msg: number, wParam: number, lParam: number) => number): number;
459
434
  function CreateWindow(className: string, title: string, style: number, x: number, y: number, width: number, height: number, parent: HWND | null, menu: HMENU | null): HWND | null;
460
435
  // 销毁窗口及其所有子窗口,自动清理 WNDPROC 和 JS 引用
461
436
  function DestroyWindow(hwnd: HWND): boolean;
462
- function GetWindow(hwnd: HWND, cmd: GetWindowCmd): HWND;
463
-
464
- function ShowWindow(hwnd: HWND, nCmdShow?: ShowWindowCmd): void;
465
437
  function SetWindowProc(hwnd: HWND, wndProc: (hwnd: HWND, msg: number, wParam: number, lParam: number) => number): void;
466
438
  function DefWindowProc(hwnd: HWND, msg: number, wParam: number, lParam: number): number;
467
- function PostQuitMessage(exitCode: number): void;
468
439
  function SendMessage(hwnd: HWND, msg: number, wParam: number, lParam: number | string): number;
469
- function MessageBox(message: string): void;
470
- function SetWindowText(hwnd: HWND, text: string): void;
471
- function GetWindowText(hwnd: HWND): string;
472
- function GetScaleFactor(): number;
473
- function CreateSystemDpiFont(): HFONT | null;
474
- type GwlpReturnType<T extends Gwlp> = T extends import('./constants').Gwlp.WNDPROC ? WNDPROC : number;
475
- function GetWindowLongPtr<T extends Gwlp>(hwnd: HWND, nIndex: T): GwlpReturnType<T>;
476
- function SetWindowLongPtr(hwnd: HWND, nIndex: Gwlp, newLong: number): number;
477
440
  function UnsetWindowProc(hwnd: HWND): boolean;
478
- function CallWindowProc(wndProc: WNDPROC, hwnd: HWND, msg: number, wParam: number, lParam: number): number;
479
- function SetParent(hwnd: HWND, parent: HWND | null): void;
480
- function EnableWindow(hwnd: HWND, enable: boolean): void;
481
- function SetWindowPos(hwnd: HWND, insertAfter: SetWindowPosHwnd, x: number, y: number, width: number, height: number, flags: number): void;
482
-
483
-
484
-
485
- interface NotifyIconData {
486
- hwnd: HWND
487
- uID?: number
488
- flags?: number
489
- callbackMessage?: number
490
- hIcon?: HICON
491
- tip?: string
492
- }
493
-
494
- function ShellNotifyIcon(cmd: NotifyIconCmd, nid: NotifyIconData): boolean;
495
- /**
496
- * Thin wrapper around LoadImageW. Parameter order matches Win32 LoadImageW: (hinst, name, uType?, cx?, cy?, fuLoad?).
497
- * hinst: null for system resources/file path, number for module handle;
498
- * name: when hinst=null, a system icon IDI or .ico file path; when hinst=module handle, a resource ID (number) or resource name (string);
499
- * uType: ImageType constant, default IMAGE_ICON (returns HICON), pass BITMAP/CURSOR for number return;
500
- * cx/cy: target size (0 for default, use LoadImageFlag.DEFAULTSIZE for system default size);
501
- * fuLoad: LoadImageFlag constants. Note: loading system icons (IDI_*, hinst=null) requires LoadImageFlag.SHARED.
502
- * Example: import { IDI, ImageType, LoadImageFlag } from 'quickwin/constants'
503
- * gui.LoadImage(null, "app.ico", ImageType.ICON, 32, 32, LoadImageFlag.LOADFROMFILE)
504
- * gui.LoadImage(null, IDI.APPLICATION, ImageType.ICON, 0, 0, LoadImageFlag.SHARED)
505
- */
506
- function LoadImage<H extends (import("win").HMODULE) | null, T extends ImageType = import('./constants').ImageType.ICON>(
507
- hinst: H,
508
- name: H extends null ? string | IDI : string | number,
509
- uType?: T,
510
- cx?: number,
511
- cy?: number,
512
- fuLoad?: number
513
- ): T extends import('./constants').ImageType.ICON ? HICON | null : number | null;
514
441
  /**
515
442
  * Loads the first icon group (RT_GROUP_ICON) from this exe, i.e. the custom icon
516
443
  * embedded by rcedit. Works with any resource ID including 0. Returns null if the
@@ -519,46 +446,6 @@ declare module "gui" {
519
446
  * Example: gui.LoadAppIcon() → HICON of the exe's icon.
520
447
  */
521
448
  function LoadAppIcon(cx?: number, cy?: number): HICON | null;
522
- /** 从 BGRA 像素数据创建 32bpp top-down DIB,data 为 length >= width*height*4 的 ArrayBuffer,返回 HBITMAP */
523
- function CreateBitmapFromPixels(width: number, height: number, data: ArrayBuffer): number | null;
524
- function DeleteObject(hObject: number): boolean;
525
- function ImageListCreate(cx: number, cy: number, flags?: number, initial?: number, grow?: number): number | null;
526
- function ImageListAdd(himl: number, hBitmap: number): number;
527
- function ImageListDestroy(himl: number): boolean;
528
-
529
-
530
- function CreatePopupMenu(): HMENU | null;
531
- function AppendMenu(menu: HMENU, flags: number, id: number, text: string): boolean;
532
- function TrackPopupMenu(menu: HMENU, x: number, y: number, flags?: number, hwnd?: HWND): number;
533
- function DestroyMenu(menu: HMENU): boolean;
534
- function SetForegroundWindow(hwnd: HWND): boolean;
535
- /** Returns [x, y] or null */
536
- function GetCursorPos(): [number, number] | null;
537
- /** Returns [width, height] of the primary monitor */
538
- function GetScreenSize(): [number, number];
539
- /** Client-area/mouse rect: { left, top, right, bottom } */
540
- type RECT = { left: number; top: number; right: number; bottom: number };
541
- /** Returns { left, top, right, bottom } of client area, or null if invalid */
542
- function GetClientRect(hwnd: HWND): RECT | null;
543
-
544
- function GetWindowRect(hwnd: HWND): RECT | null;
545
- /** Invalidates client area (rect can be null/undefined for full window) */
546
- function InvalidateRect(hwnd: HWND, rect?: RECT | null, erase?: boolean): void;
547
- /** Forces immediate repaint of invalidated area */
548
- function UpdateWindow(hwnd: HWND): void;
549
- /** Checks if the window handle is valid */
550
- function IsWindow(hwnd: HWND): boolean;
551
- /** Sets scroll info; returns current scroll box position. Signature matches Win32 SetScrollInfo. */
552
- function SetScrollInfo(hwnd: HWND, bar: ScrollBar, info: { pos?: number; page?: number; min?: number; max?: number }, redraw?: boolean): number;
553
-
554
- /** Gets scroll info. Signature matches Win32 GetScrollInfo. */
555
- function GetScrollInfo(hwnd: HWND, bar: ScrollBar): { pos: number; page: number; min: number; max: number; trackPos: number };
556
-
557
- /** Shows or hides a scroll bar. Signature matches Win32 ShowScrollBar. */
558
- function ShowScrollBar(hwnd: HWND, bar: ScrollBar, show: boolean): boolean;
559
-
560
-
561
-
562
449
 
563
450
 
564
451
 
@@ -585,6 +472,12 @@ declare module "gui" {
585
472
  }
586
473
 
587
474
  declare module "ffi" {
475
+ /** 指针品牌唯一定义在 lib/ffi/ctype.ts(此处只转发,不手抄结构)——本模块返回的
476
+ * 句柄 / 地址即对应 C 侧指针位,空值形态同 FFI 层:NULL(0),不是 JS null。 */
477
+ type Ptr<N extends string> = import('./lib/ffi/ctype').Ptr<N>;
478
+ type MaybePtr<N extends string> = import('./lib/ffi/ctype').MaybePtr<N>;
479
+ type HMODULE = Ptr<"HMODULE">;
480
+
588
481
  function ffiCall(func: number, argFrame: ArrayBuffer, retBuf: ArrayBuffer, retIsFp: 0 | 1): void;
589
482
  function bufferPtr(buf: ArrayBuffer): number;
590
483
  function readByte(ptr: number): number;
@@ -592,6 +485,11 @@ declare module "ffi" {
592
485
  function writeByte(ptr: number, value: number): void;
593
486
  function closureNew(argBytes: number, retKind: number, wrapper: (frame: ArrayBuffer, retBuf: ArrayBuffer) => void): number;
594
487
  function closureFree(ptr: number): void;
488
+ /** LoadLibraryW 直映:FFI 自举入口(ffi 自身没有 dlopen,取符号必先装载),
489
+ * 成功为模块句柄 <HMODULE>ptr(HINSTANCE 语义),失败为空指针(0);按真值收窄。 */
490
+ function LoadLibrary(libName: string): MaybePtr<"HMODULE">;
491
+ /** GetProcAddress 直映:成功为函数地址 <FARPROC>ptr,失败为空指针(0)。 */
492
+ function GetProcAddress(hModule: HMODULE, procName: string): MaybePtr<"FARPROC">;
595
493
  }
596
494
 
597
495
 
Binary file
package/qwin-nowasm.exe CHANGED
Binary file
package/qwin-x86.exe CHANGED
Binary file
package/qwin.exe CHANGED
Binary file
@@ -13,7 +13,6 @@
13
13
  // 结束必须 DestroyWindow + std.exit。
14
14
  import * as std from 'std';
15
15
  import * as gui from 'gui';
16
- import * as win from 'win';
17
16
  import * as ffi from 'ffi';
18
17
  import { bind } from '../lib/ffi/bind.js';
19
18
  const WM_NULL = 0x0000;
@@ -37,11 +36,11 @@ function step(msg) {
37
36
  step('stage: imports ok');
38
37
  // ---- proc 地址(B/C 臂绕过 bind 直驱 ffiCall)----
39
38
  function procOf(dll, name) {
40
- const h = win.LoadLibrary(dll);
39
+ const h = ffi.LoadLibrary(dll);
41
40
  if (!h)
42
41
  throw new Error('LoadLibrary(' + dll + ') failed');
43
- const p = win.GetProcAddress(h, name);
44
- if (p === null)
42
+ const p = ffi.GetProcAddress(h, name);
43
+ if (!p)
45
44
  throw new Error('GetProcAddress(' + dll + '!' + name + ') failed');
46
45
  return p;
47
46
  }
@@ -13,7 +13,6 @@
13
13
  // 结束必须 DestroyWindow + std.exit。
14
14
  import * as std from 'std'
15
15
  import * as gui from 'gui'
16
- import * as win from 'win'
17
16
  import * as ffi from 'ffi'
18
17
  import { bind } from '../lib/ffi/bind.js'
19
18
 
@@ -39,10 +38,10 @@ step('stage: imports ok')
39
38
 
40
39
  // ---- proc 地址(B/C 臂绕过 bind 直驱 ffiCall)----
41
40
  function procOf(dll: string, name: string): number {
42
- const h = win.LoadLibrary(dll)
41
+ const h = ffi.LoadLibrary(dll)
43
42
  if (!h) throw new Error('LoadLibrary(' + dll + ') failed')
44
- const p = win.GetProcAddress(h, name)
45
- if (p === null) throw new Error('GetProcAddress(' + dll + '!' + name + ') failed')
43
+ const p = ffi.GetProcAddress(h, name)
44
+ if (!p) throw new Error('GetProcAddress(' + dll + '!' + name + ') failed')
46
45
  return p
47
46
  }
48
47
  const pNop0 = procOf('test/nop.dll', 'nop0')