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.
- package/README.en.md +1 -2
- package/README.md +1 -2
- package/constants.ts +15 -0
- package/enum_map.d.ts +3 -0
- package/examples/PdfCanvas.js +1 -1
- package/examples/PdfCanvas.tsx +2 -2
- package/examples/execd/main.js +334 -188
- package/examples/pdf_preview2.js +76 -67
- package/examples/pdf_preview2.ts +84 -64
- package/examples/pdf_viewer.js +4932 -1029
- package/examples/pdf_viewer.tsx +11 -22
- package/examples/test_gallery.js +308 -143
- package/examples/test_gallery.tsx +12 -7
- package/examples/test_react_lazy.js +295 -133
- package/examples/test_react_lazy.tsx +4 -3
- package/examples/test_react_listbox.js +293 -132
- package/examples/test_react_listbox.tsx +3 -2
- package/examples/test_root_window.js +283 -126
- package/examples/test_tab.js +295 -133
- package/examples/test_tab.tsx +4 -3
- package/examples/tray_demo.js +37 -30
- package/examples/tray_demo.tsx +39 -32
- package/lib/bitmap.js +40 -0
- package/lib/bitmap.ts +39 -0
- package/lib/certs.js +31 -3
- package/lib/certs.ts +32 -3
- package/lib/dpi.js +30 -0
- package/lib/dpi.ts +31 -0
- package/lib/dumpRects.js +14 -7
- package/lib/dumpRects.ts +14 -6
- package/lib/ffi/bind.js +5 -4
- package/lib/ffi/bind.ts +9 -8
- package/lib/react-qw/components/DateTimePicker.js +6 -7
- package/lib/react-qw/components/Input.js +5 -1
- package/lib/react-qw/components/ListView.js +8 -6
- package/lib/react-qw/components/ScrollView.js +28 -22
- package/lib/react-qw/index.js +7 -5
- package/lib/react-qw/index.ts +5 -5
- package/lib/react-qw/props.js +3 -3
- package/lib/react-qw/props.ts +3 -3
- package/lib/react-qw/reconciler.js +12 -17
- package/lib/react-qw/reconciler.ts +12 -16
- package/lib/text-measure.js +9 -6
- package/lib/text-measure.ts +9 -6
- package/lib/windows/comctl32.js +3 -2
- package/lib/windows/comctl32.ts +3 -2
- package/lib/windows/gdi32.js +28 -6
- package/lib/windows/gdi32.ts +30 -6
- package/lib/windows/kernel32.js +9 -0
- package/lib/windows/kernel32.ts +9 -0
- package/lib/windows/shell32.js +11 -2
- package/lib/windows/shell32.ts +13 -2
- package/lib/windows/structs.js +51 -0
- package/lib/windows/structs.ts +55 -0
- package/lib/windows/user32.js +6 -5
- package/lib/windows/user32.ts +6 -5
- package/main.js +13 -5
- package/package.json +2 -2
- package/quickwin.d.ts +13 -115
- package/qwin-nowasm-x86.exe +0 -0
- package/qwin-nowasm.exe +0 -0
- package/qwin-x86.exe +0 -0
- package/qwin.exe +0 -0
- package/test/bench_ffi_callraw.js +3 -4
- package/test/bench_ffi_callraw.ts +3 -4
- package/test/debug/mupdf_debug.js +4 -22
- package/test/debug/wasm_export_debug.js +2 -12
- package/test/debug/wasm_names.js +3 -13
- package/test/example.pdf +0 -0
- package/test/mupdf-cdn.js +40 -0
- package/test/mupdf-cdn.ts +43 -0
- package/test/test_ffi.js +8 -9
- package/test/test_ffi.ts +8 -9
- package/test/test_ffi_abi.js +6 -6
- package/test/test_ffi_abi.ts +8 -8
- package/test/test_ffi_windows.js +82 -11
- package/test/test_ffi_windows.ts +85 -11
- package/test/test_gdi_draw.js +3 -3
- package/test/test_gdi_draw.ts +4 -4
- package/test/test_mupdf_render.js +4 -22
- package/test/test_mupdf_render.ts +4 -23
- package/test/test_mupdf_twice.js +4 -19
- package/test/test_mupdf_twice.ts +4 -20
- package/test/test_mupdf_wasm.js +10 -4
- package/test/test_mupdf_wasm.ts +6 -4
- package/test/test_react_complex.js +316 -140
- package/test/test_react_counter.js +295 -133
- package/test/test_react_flex.js +297 -138
- package/test/test_react_hidden.js +296 -134
- package/test/test_react_listview_link.js +288 -131
- package/test/test_react_notify.js +290 -133
- package/test/test_react_render.js +295 -133
- package/vendor/mupdf-wasm/mupdf-wasm.d.ts +0 -571
- package/vendor/mupdf-wasm/mupdf-wasm.js +0 -2749
- package/vendor/mupdf-wasm/mupdf-wasm.wasm +0 -0
- package/vendor/mupdf-wasm/mupdf.d.ts +0 -939
- package/vendor/mupdf-wasm/mupdf.js +0 -3317
package/lib/windows/gdi32.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
package/lib/windows/kernel32.js
CHANGED
|
@@ -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 检查兜底,无需接收缓冲) */
|
package/lib/windows/kernel32.ts
CHANGED
|
@@ -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 检查兜底,无需接收缓冲) */
|
package/lib/windows/shell32.js
CHANGED
|
@@ -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 });
|
package/lib/windows/shell32.ts
CHANGED
|
@@ -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 })
|
package/lib/windows/structs.js
CHANGED
|
@@ -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);
|
package/lib/windows/structs.ts
CHANGED
|
@@ -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)
|
package/lib/windows/user32.js
CHANGED
|
@@ -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
|
|
500
|
-
* @param args_6
|
|
501
|
-
export const TrackPopupMenu = /*@__PURE__*/ b('TrackPopupMenu', '<HMENU>ptr u32 i32 i32 i32 <
|
|
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
|
|
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)
|
package/lib/windows/user32.ts
CHANGED
|
@@ -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
|
|
525
|
-
* @param args_6
|
|
526
|
-
export const TrackPopupMenu = /*@__PURE__*/ b('TrackPopupMenu', '<HMENU>ptr u32 i32 i32 i32 <
|
|
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
|
|
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 {
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
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": "
|
|
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
|
-
|
|
445
|
-
//
|
|
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
|
|
package/qwin-nowasm-x86.exe
CHANGED
|
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 =
|
|
39
|
+
const h = ffi.LoadLibrary(dll);
|
|
41
40
|
if (!h)
|
|
42
41
|
throw new Error('LoadLibrary(' + dll + ') failed');
|
|
43
|
-
const p =
|
|
44
|
-
if (p
|
|
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 =
|
|
41
|
+
const h = ffi.LoadLibrary(dll)
|
|
43
42
|
if (!h) throw new Error('LoadLibrary(' + dll + ') failed')
|
|
44
|
-
const p =
|
|
45
|
-
if (p
|
|
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')
|