quickwin 1.3.0 → 2.1.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 +18 -24
- package/README.md +17 -23
- package/examples/PdfCanvas.js +8 -37
- package/examples/PdfCanvas.tsx +11 -41
- package/examples/exec_server.js +20155 -1420
- package/examples/exec_server.tsx +489 -0
- package/examples/exec_server_worker.js +383 -33
- package/examples/exec_server_worker.ts +408 -30
- package/examples/pdf_preview2.js +25 -82
- package/examples/pdf_preview2.ts +27 -84
- package/examples/pdf_viewer.js +1424 -1180
- package/examples/pdf_viewer.tsx +16 -67
- package/examples/setres.js +22 -47
- package/examples/setres.ts +23 -57
- package/examples/test_gallery.js +1418 -1075
- package/examples/test_react_lazy.js +1391 -1059
- package/examples/test_react_listbox.js +1390 -1058
- package/examples/test_root_window.js +1384 -1052
- package/examples/test_tab.js +1391 -1059
- package/lib/abort.js +70 -0
- package/lib/abort.ts +69 -0
- package/lib/certs.js +219 -0
- package/lib/certs.ts +229 -0
- package/lib/exec-log.js +15 -0
- package/lib/exec-log.ts +30 -0
- package/lib/fetch.js +88 -7
- package/lib/fetch.ts +73 -7
- package/lib/ffi/bind.js +441 -0
- package/lib/ffi/bind.ts +539 -0
- package/lib/ffi/ctype.js +194 -0
- package/lib/ffi/ctype.ts +369 -0
- package/lib/ffi/index.js +6 -0
- package/lib/ffi/index.ts +6 -0
- package/lib/ffi/struct.js +490 -0
- package/lib/ffi/struct.ts +753 -0
- package/lib/http-common.js +43 -5
- package/lib/http-common.ts +48 -6
- package/lib/http-server.js +187 -29
- package/lib/http-server.ts +177 -26
- package/lib/react-qw/components/DateTimePicker.js +18 -37
- package/lib/react-qw/components/Input.js +3 -10
- package/lib/react-qw/components/Link.js +6 -19
- package/lib/react-qw/components/ListView.js +50 -154
- package/lib/react-qw/components/PathPicker.js +28 -88
- package/lib/react-qw/components/ScrollView.js +15 -8
- package/lib/react-qw/components/Slider.js +2 -1
- package/lib/react-qw/components/Tab.js +6 -22
- package/lib/react-qw/components/Tooltip.js +10 -21
- package/lib/react-qw/components/TreeView.js +8 -31
- package/lib/react-qw/index.js +5 -3
- package/lib/react-qw/index.ts +8 -3
- package/lib/react-qw/nmhdr.js +3 -24
- package/lib/react-qw/nmhdr.ts +5 -30
- package/lib/react-qw/props.js +7 -2
- package/lib/react-qw/props.ts +7 -3
- package/lib/react-qw/reconciler.js +23 -13
- package/lib/react-qw/reconciler.ts +22 -13
- package/lib/text-measure.js +20 -23
- package/lib/text-measure.ts +22 -26
- package/lib/websocket.js +44 -4
- package/lib/websocket.ts +40 -4
- package/lib/windows/advapi32.js +53 -0
- package/lib/windows/advapi32.ts +64 -0
- package/lib/windows/comctl32.js +18 -0
- package/lib/windows/comctl32.ts +19 -0
- package/lib/windows/comdlg32.js +8 -0
- package/lib/windows/comdlg32.ts +10 -0
- package/lib/windows/gdi32.js +392 -0
- package/lib/windows/gdi32.ts +420 -0
- package/lib/windows/kernel32.js +262 -0
- package/lib/windows/kernel32.ts +291 -0
- package/lib/windows/msimg32.js +38 -0
- package/lib/windows/msimg32.ts +45 -0
- package/lib/windows/ntdll.js +9 -0
- package/lib/windows/ntdll.ts +11 -0
- package/lib/windows/ole32.js +7 -0
- package/lib/windows/ole32.ts +9 -0
- package/lib/windows/psapi.js +32 -0
- package/lib/windows/psapi.ts +37 -0
- package/lib/windows/shell32.js +13 -0
- package/lib/windows/shell32.ts +16 -0
- package/lib/windows/structs.js +519 -0
- package/lib/windows/structs.ts +566 -0
- package/lib/windows/user32.js +572 -0
- package/lib/windows/user32.ts +607 -0
- package/lib/windows/version.js +29 -0
- package/lib/windows/version.ts +35 -0
- package/lib/windows/winspool.js +71 -0
- package/lib/windows/winspool.ts +80 -0
- package/package.json +1 -1
- package/quickwin.d.ts +31 -40
- package/quickwin_const.d.ts +137 -0
- 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 +236 -0
- package/test/bench_ffi_callraw.ts +236 -0
- package/test/bench_ffi_overhead.js +139 -0
- package/test/bench_ffi_overhead.ts +141 -0
- package/test/bench_sendmessage.js +104 -0
- package/test/bench_sendmessage.ts +100 -0
- package/test/bench_sendmessage_nonnull.js +187 -0
- package/test/bench_sendmessage_nonnull.ts +188 -0
- package/test/run.js +19 -4
- package/test/run.ts +20 -5
- package/test/test_basic_fetch.js +29 -0
- package/test/test_basic_fetch.ts +26 -0
- package/test/test_ffi.js +27 -45
- package/test/test_ffi.ts +35 -54
- package/test/test_ffi_abi.js +290 -0
- package/test/test_ffi_abi.ts +274 -0
- package/test/test_ffi_array.js +116 -0
- package/test/test_ffi_array.ts +141 -0
- package/test/test_ffi_bind.js +620 -8
- package/test/test_ffi_bind.ts +630 -8
- package/test/test_ffi_struct.js +632 -88
- package/test/test_ffi_struct.ts +666 -91
- package/test/test_ffi_struct_layout.js +495 -0
- package/test/test_ffi_struct_layout.ts +543 -0
- package/test/test_ffi_user32.js +103 -0
- package/test/test_ffi_user32.ts +113 -0
- package/test/test_ffi_windows.js +101 -0
- package/test/test_ffi_windows.ts +113 -0
- package/test/test_files.js +102 -0
- package/test/test_files.ts +121 -0
- package/test/test_gdi_draw.js +681 -0
- package/test/test_gdi_draw.ts +725 -0
- package/test/test_helper.js +8 -1
- package/test/test_helper.ts +9 -1
- package/test/test_http_import.js +18 -0
- package/test/test_http_import.ts +19 -0
- package/test/test_http_server.js +73 -1
- package/test/test_http_server.ts +75 -1
- package/test/test_ipv6.js +2 -2
- package/test/test_ipv6.ts +2 -2
- package/test/test_net_fetch.js +74 -11
- package/test/test_net_fetch.ts +73 -10
- package/test/test_net_websocket.js +1 -1
- package/test/test_net_websocket.ts +1 -1
- package/test/test_printer.js +137 -0
- package/test/test_printer.ts +148 -0
- package/test/test_proc.js +141 -0
- package/test/test_proc.ts +163 -0
- package/test/test_react_complex.js +1401 -1069
- package/test/test_react_counter.js +1391 -1059
- package/test/test_react_flex.js +1411 -1072
- package/test/test_react_hidden.js +1394 -1062
- package/test/test_react_listview_link.js +1391 -1059
- package/test/test_react_notify.js +18638 -0
- package/test/test_react_render.js +1391 -1059
- package/test/test_registry.js +74 -0
- package/test/test_registry.ts +95 -0
- package/test/test_sysinfo.js +122 -0
- package/test/test_sysinfo.ts +141 -0
- package/test/test_wolfssl_read.js +45 -43
- package/test/test_wolfssl_read.ts +42 -40
- package/test/test_worker_net.js +35 -17
- package/test/test_worker_net.ts +27 -15
- package/tsconfig.json +1 -1
- package/examples/exec_server.ts +0 -80
- package/lib/ffi-bind.js +0 -85
- package/lib/ffi-bind.ts +0 -170
- package/lib/ffi-struct.js +0 -224
- package/lib/ffi-struct.ts +0 -239
- package/lib/win-common-structs.js +0 -39
- package/lib/win-common-structs.ts +0 -41
package/lib/text-measure.ts
CHANGED
|
@@ -1,39 +1,35 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { NULL, type Ptr } from './ffi/ctype.js'
|
|
2
2
|
import * as gui from 'gui'
|
|
3
|
-
import {
|
|
3
|
+
import { DrawText, GetDC, ReleaseDC } from './windows/user32.js'
|
|
4
|
+
import { SelectObject } from './windows/gdi32.js'
|
|
5
|
+
import { RECT, SIZE } from './windows/structs.js'
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
export function measureText(hdc: number, text: string, maxWidth: number): { width: number; height: number } {
|
|
15
|
-
const rect = new ArrayBuffer(16)
|
|
16
|
-
const dv = new DataView(rect)
|
|
17
|
-
dv.setInt32(8, maxWidth, true)
|
|
18
|
-
user32.DrawTextW(hdc, text, -1, rect, gui.DrawTextFlag.CALCRECT)
|
|
19
|
-
return { width: dv.getInt32(8, true), height: dv.getInt32(12, true) }
|
|
7
|
+
export function measureText(hdc: Ptr<'HDC'>, text: string, maxWidth: number): { width: number; height: number } {
|
|
8
|
+
// rect 双向位不注册 encoder(CALCRECT 就地写回):encode(初值) 新建 + DeepPartial 初值一步到位
|
|
9
|
+
//(left/top/bottom 缺省跳过保持 0)→ 传 .ptr → decode 读回
|
|
10
|
+
const r = RECT.encode({ right: maxWidth })
|
|
11
|
+
DrawText(hdc, text, -1, r.ptr, gui.DrawTextFlag.CALCRECT)
|
|
12
|
+
const { right, bottom } = RECT.decode(r)
|
|
13
|
+
return { width: right, height: bottom }
|
|
20
14
|
}
|
|
21
15
|
|
|
22
16
|
export function getButtonIdealSize(hwnd: gui.HWND): { width: number; height: number } {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
// SIZE 纯出参位(GETIDEALSIZE 就地写回):alloc → 传 .ptr → decode 读回
|
|
18
|
+
const size = SIZE.alloc()
|
|
19
|
+
gui.SendMessage(hwnd, gui.ButtonExtMsg.GETIDEALSIZE, 0, size.ptr)
|
|
20
|
+
const { cx, cy } = SIZE.decode(size)
|
|
21
|
+
return { width: cx, height: cy }
|
|
27
22
|
}
|
|
28
23
|
|
|
29
24
|
export function measureTextForHwnd(hwnd: gui.HWND, text: string): { width: number; height: number } {
|
|
30
|
-
const hdc =
|
|
25
|
+
const hdc = GetDC(hwnd)
|
|
31
26
|
if (!hdc) return { width: 0, height: 0 }
|
|
32
|
-
|
|
33
|
-
const
|
|
27
|
+
// SendMessage 返回 LRESULT 裸数;GETFONT 语义为 HFONT——断言进 GDI 对象品牌链
|
|
28
|
+
const hFont = gui.SendMessage(hwnd, gui.WmMsg.GETFONT, 0, 0) as Ptr<'HGDIOBJ'>
|
|
29
|
+
const oldFont = hFont ? SelectObject(hdc, hFont) : NULL
|
|
34
30
|
const result = measureText(hdc, text, 0)
|
|
35
|
-
if (hFont)
|
|
36
|
-
|
|
31
|
+
if (hFont) SelectObject(hdc, oldFont)
|
|
32
|
+
ReleaseDC(hwnd, hdc)
|
|
37
33
|
const wr = gui.GetWindowRect(hwnd)
|
|
38
34
|
const cr = gui.GetClientRect(hwnd)
|
|
39
35
|
if (wr && cr) {
|
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
|
-
|
|
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 {
|
|
@@ -335,7 +345,21 @@ class WebSocketImpl {
|
|
|
335
345
|
while (true) {
|
|
336
346
|
let data;
|
|
337
347
|
if (isWSS && this._ssl) {
|
|
338
|
-
|
|
348
|
+
const buf = new ArrayBuffer(8192);
|
|
349
|
+
const n = wolfssl.wolfSSL_read(this._ssl, buf);
|
|
350
|
+
if (n > 0) {
|
|
351
|
+
data = buf.slice(0, n);
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
const err = wolfssl.wolfSSL_get_error(this._ssl, n);
|
|
355
|
+
if (err === 2 /* wolfssl.ErrorCode.WOLFSSL_ERROR_WANT_READ */ ||
|
|
356
|
+
err === 3 /* wolfssl.ErrorCode.WOLFSSL_ERROR_WANT_WRITE */)
|
|
357
|
+
break;
|
|
358
|
+
if (n === 0 || err === 6 /* wolfssl.ErrorCode.WOLFSSL_ERROR_ZERO_RETURN */)
|
|
359
|
+
break;
|
|
360
|
+
doError(new Error('TLS read failed: ' + err));
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
339
363
|
}
|
|
340
364
|
else if (this._sock !== null && this._sock >= 0) {
|
|
341
365
|
data = sock.recv(this._sock, 8192);
|
|
@@ -433,7 +457,23 @@ class WebSocketImpl {
|
|
|
433
457
|
while (true) {
|
|
434
458
|
let data;
|
|
435
459
|
if (this._ssl) {
|
|
436
|
-
|
|
460
|
+
const buf = new ArrayBuffer(8192);
|
|
461
|
+
const n = wolfssl.wolfSSL_read(this._ssl, buf);
|
|
462
|
+
if (n > 0) {
|
|
463
|
+
data = buf.slice(0, n);
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
const err = wolfssl.wolfSSL_get_error(this._ssl, n);
|
|
467
|
+
if (err === 2 /* wolfssl.ErrorCode.WOLFSSL_ERROR_WANT_READ */ ||
|
|
468
|
+
err === 3 /* wolfssl.ErrorCode.WOLFSSL_ERROR_WANT_WRITE */)
|
|
469
|
+
break;
|
|
470
|
+
if (n === 0 || err === 6 /* wolfssl.ErrorCode.WOLFSSL_ERROR_ZERO_RETURN */)
|
|
471
|
+
break;
|
|
472
|
+
this._fireError(new Error('TLS read failed: ' + err));
|
|
473
|
+
if (this._state !== State.CLOSED)
|
|
474
|
+
this._setState(State.CLOSED);
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
437
477
|
}
|
|
438
478
|
else if (this._sock !== null && this._sock >= 0) {
|
|
439
479
|
data = sock.recv(this._sock, 8192);
|
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
|
-
|
|
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)
|
|
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)
|
|
@@ -350,7 +363,18 @@ class WebSocketImpl {
|
|
|
350
363
|
while (true) {
|
|
351
364
|
let data: ArrayBuffer | null
|
|
352
365
|
if (isWSS && this._ssl) {
|
|
353
|
-
|
|
366
|
+
const buf = new ArrayBuffer(8192)
|
|
367
|
+
const n = wolfssl.wolfSSL_read(this._ssl, buf)
|
|
368
|
+
if (n > 0) {
|
|
369
|
+
data = buf.slice(0, n)
|
|
370
|
+
} else {
|
|
371
|
+
const err = wolfssl.wolfSSL_get_error(this._ssl, n)
|
|
372
|
+
if (err === wolfssl.ErrorCode.WOLFSSL_ERROR_WANT_READ ||
|
|
373
|
+
err === wolfssl.ErrorCode.WOLFSSL_ERROR_WANT_WRITE) break
|
|
374
|
+
if (n === 0 || err === wolfssl.ErrorCode.WOLFSSL_ERROR_ZERO_RETURN) break
|
|
375
|
+
doError(new Error('TLS read failed: ' + err))
|
|
376
|
+
return
|
|
377
|
+
}
|
|
354
378
|
} else if (this._sock !== null && this._sock >= 0) {
|
|
355
379
|
data = sock.recv(this._sock, 8192)
|
|
356
380
|
} else { break }
|
|
@@ -447,7 +471,19 @@ class WebSocketImpl {
|
|
|
447
471
|
while (true) {
|
|
448
472
|
let data: ArrayBuffer | null
|
|
449
473
|
if (this._ssl) {
|
|
450
|
-
|
|
474
|
+
const buf = new ArrayBuffer(8192)
|
|
475
|
+
const n = wolfssl.wolfSSL_read(this._ssl, buf)
|
|
476
|
+
if (n > 0) {
|
|
477
|
+
data = buf.slice(0, n)
|
|
478
|
+
} else {
|
|
479
|
+
const err = wolfssl.wolfSSL_get_error(this._ssl, n)
|
|
480
|
+
if (err === wolfssl.ErrorCode.WOLFSSL_ERROR_WANT_READ ||
|
|
481
|
+
err === wolfssl.ErrorCode.WOLFSSL_ERROR_WANT_WRITE) break
|
|
482
|
+
if (n === 0 || err === wolfssl.ErrorCode.WOLFSSL_ERROR_ZERO_RETURN) break
|
|
483
|
+
this._fireError(new Error('TLS read failed: ' + err))
|
|
484
|
+
if (this._state !== State.CLOSED) this._setState(State.CLOSED)
|
|
485
|
+
return
|
|
486
|
+
}
|
|
451
487
|
} else if (this._sock !== null && this._sock >= 0) {
|
|
452
488
|
data = sock.recv(this._sock, 8192)
|
|
453
489
|
} else { break }
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// advapi32 绑定(注册表 API;键名/值名一律 W 版 UTF-16)
|
|
2
|
+
import { bind } from '../ffi/bind.js';
|
|
3
|
+
// dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
|
|
4
|
+
const b = (name, sig) => bind('advapi32.dll', name, sig);
|
|
5
|
+
/** 创建/打开子键(子键不存在则创建,含中间层级)
|
|
6
|
+
* @returns 0 = ERROR_SUCCESS
|
|
7
|
+
* @param args_0 hKey 父键:gui.HKey.CURRENT_USER / LOCAL_MACHINE 预定义键,或本族
|
|
8
|
+
* Open/Create 返回的真实句柄(此位双来源,不标 @HKey——裸位收两种)
|
|
9
|
+
* @param args_1 lpSubKey 子键路径('Software\\X\\Y',可 NULL = 打开 hKey 自身副本)
|
|
10
|
+
* @param args_2 Reserved 保留,恒 0
|
|
11
|
+
* @param args_3 lpClass 键类名(一般 NULL)
|
|
12
|
+
* @param args_4 dwOptions 保留属性(恒 0)
|
|
13
|
+
* @param args_5 samDesired 访问掩码 gui.RegAccess.READ / SET_VALUE(标准组合常量按成员收录)
|
|
14
|
+
* @param args_6 lpSecurityAttributes 安全描述符(一般 NULL)
|
|
15
|
+
* @param args_7 phkResult 出参:键句柄(PtrArrayBuffer(8),readPtr 按架构读回)
|
|
16
|
+
* @param args_8 lpdwDisposition 出参:新建/已存在标记(可 NULL) */
|
|
17
|
+
export const RegCreateKeyEx = /*@__PURE__*/ b('RegCreateKeyExW', '<>ptr <WCHAR>ptr u32 <WCHAR>ptr u32 u32@RegAccess <>ptr <BYTE>ptr <BYTE>ptr -> i32');
|
|
18
|
+
/** 打开已有子键(不创建)
|
|
19
|
+
* @returns 0 = ERROR_SUCCESS;2 = ERROR_FILE_NOT_FOUND(子键不存在)
|
|
20
|
+
* @param args_0 hKey 父键(同 RegCreateKeyEx 的双来源语义)
|
|
21
|
+
* @param args_1 lpSubKey 子键路径(NULL = 打开 hKey 自身副本)
|
|
22
|
+
* @param args_2 ulOptions 保留,恒 0
|
|
23
|
+
* @param args_3 samDesired 访问掩码 gui.RegAccess.READ / SET_VALUE
|
|
24
|
+
* @param args_4 phkResult 出参:键句柄 */
|
|
25
|
+
export const RegOpenKeyEx = /*@__PURE__*/ b('RegOpenKeyExW', '<>ptr <WCHAR>ptr u32 u32@RegAccess <BYTE>ptr -> i32');
|
|
26
|
+
/** 关闭键句柄;只关 Open/Create 返回的真实句柄——预定义键(HKEY_CURRENT_USER 等)
|
|
27
|
+
* 不要关
|
|
28
|
+
* @returns 0 = ERROR_SUCCESS */
|
|
29
|
+
export const RegCloseKey = /*@__PURE__*/ b('RegCloseKey', '<>ptr -> i32');
|
|
30
|
+
/** 写键值
|
|
31
|
+
* @returns 0 = ERROR_SUCCESS
|
|
32
|
+
* @param args_0 hKey 键句柄(须 KEY_SET_VALUE 权限,含于 gui.RegAccess.SET_VALUE)
|
|
33
|
+
* @param args_1 lpValueName 值名(NULL = 键的默认值)
|
|
34
|
+
* @param args_2 Reserved 保留,恒 0
|
|
35
|
+
* @param args_3 dwType 值类型 gui.RegType.SZ(UTF-16 字符串)
|
|
36
|
+
* @param args_4 lpData 数据缓冲(REG_SZ:UTF-16LE 含结尾 NUL)
|
|
37
|
+
* @param args_5 cbData 数据字节数(REG_SZ = (字符数+1)*2) */
|
|
38
|
+
export const RegSetValueEx = /*@__PURE__*/ b('RegSetValueExW', '<>ptr <WCHAR>ptr u32 u32@RegType <BYTE>ptr u32 -> i32');
|
|
39
|
+
/** 读键值(两跳模式:第一跳 lpData=NULL 取尺寸/类型,第二跳按尺寸带缓冲读数据)
|
|
40
|
+
* @returns 0 = ERROR_SUCCESS;2 = ERROR_FILE_NOT_FOUND(值不存在)
|
|
41
|
+
* @param args_0 hKey 键句柄(须 KEY_QUERY_VALUE 权限,含于 gui.RegAccess.READ)
|
|
42
|
+
* @param args_1 lpValueName 值名(NULL = 键的默认值)
|
|
43
|
+
* @param args_2 lpReserved 保留,恒 NULL
|
|
44
|
+
* @param args_3 lpType 出参:值类型(可 NULL)
|
|
45
|
+
* @param args_4 lpData 数据缓冲(可 NULL = 只查尺寸)
|
|
46
|
+
* @param args_5 lpcbData 双向:入 = lpData 缓冲字节数(须预写)、出 = 实际字节数 */
|
|
47
|
+
export const RegQueryValueEx = /*@__PURE__*/ b('RegQueryValueExW', '<>ptr <WCHAR>ptr <>ptr <BYTE>ptr <BYTE>ptr <BYTE>ptr -> i32');
|
|
48
|
+
/** 删除子键(连值一起删);须父键 KEY_CREATE_SUB_KEY 权限——自己的 HKCU 直接传
|
|
49
|
+
* gui.HKey.CURRENT_USER 即可
|
|
50
|
+
* @returns 0 = ERROR_SUCCESS;2 = 子键不存在
|
|
51
|
+
* @param args_0 hKey 父键
|
|
52
|
+
* @param args_1 lpSubKey 要删的子键路径(不可 NULL) */
|
|
53
|
+
export const RegDeleteKey = /*@__PURE__*/ b('RegDeleteKeyW', '<>ptr <WCHAR>ptr -> i32');
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// advapi32 绑定(注册表 API;键名/值名一律 W 版 UTF-16)
|
|
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('advapi32.dll', name, sig)
|
|
6
|
+
|
|
7
|
+
/** 创建/打开子键(子键不存在则创建,含中间层级)
|
|
8
|
+
* @returns 0 = ERROR_SUCCESS
|
|
9
|
+
* @param args_0 hKey 父键:gui.HKey.CURRENT_USER / LOCAL_MACHINE 预定义键,或本族
|
|
10
|
+
* Open/Create 返回的真实句柄(此位双来源,不标 @HKey——裸位收两种)
|
|
11
|
+
* @param args_1 lpSubKey 子键路径('Software\\X\\Y',可 NULL = 打开 hKey 自身副本)
|
|
12
|
+
* @param args_2 Reserved 保留,恒 0
|
|
13
|
+
* @param args_3 lpClass 键类名(一般 NULL)
|
|
14
|
+
* @param args_4 dwOptions 保留属性(恒 0)
|
|
15
|
+
* @param args_5 samDesired 访问掩码 gui.RegAccess.READ / SET_VALUE(标准组合常量按成员收录)
|
|
16
|
+
* @param args_6 lpSecurityAttributes 安全描述符(一般 NULL)
|
|
17
|
+
* @param args_7 phkResult 出参:键句柄(PtrArrayBuffer(8),readPtr 按架构读回)
|
|
18
|
+
* @param args_8 lpdwDisposition 出参:新建/已存在标记(可 NULL) */
|
|
19
|
+
export const RegCreateKeyEx = /*@__PURE__*/ b('RegCreateKeyExW',
|
|
20
|
+
'<>ptr <WCHAR>ptr u32 <WCHAR>ptr u32 u32@RegAccess <>ptr <BYTE>ptr <BYTE>ptr -> i32')
|
|
21
|
+
|
|
22
|
+
/** 打开已有子键(不创建)
|
|
23
|
+
* @returns 0 = ERROR_SUCCESS;2 = ERROR_FILE_NOT_FOUND(子键不存在)
|
|
24
|
+
* @param args_0 hKey 父键(同 RegCreateKeyEx 的双来源语义)
|
|
25
|
+
* @param args_1 lpSubKey 子键路径(NULL = 打开 hKey 自身副本)
|
|
26
|
+
* @param args_2 ulOptions 保留,恒 0
|
|
27
|
+
* @param args_3 samDesired 访问掩码 gui.RegAccess.READ / SET_VALUE
|
|
28
|
+
* @param args_4 phkResult 出参:键句柄 */
|
|
29
|
+
export const RegOpenKeyEx = /*@__PURE__*/ b('RegOpenKeyExW',
|
|
30
|
+
'<>ptr <WCHAR>ptr u32 u32@RegAccess <BYTE>ptr -> i32')
|
|
31
|
+
|
|
32
|
+
/** 关闭键句柄;只关 Open/Create 返回的真实句柄——预定义键(HKEY_CURRENT_USER 等)
|
|
33
|
+
* 不要关
|
|
34
|
+
* @returns 0 = ERROR_SUCCESS */
|
|
35
|
+
export const RegCloseKey = /*@__PURE__*/ b('RegCloseKey', '<>ptr -> i32')
|
|
36
|
+
|
|
37
|
+
/** 写键值
|
|
38
|
+
* @returns 0 = ERROR_SUCCESS
|
|
39
|
+
* @param args_0 hKey 键句柄(须 KEY_SET_VALUE 权限,含于 gui.RegAccess.SET_VALUE)
|
|
40
|
+
* @param args_1 lpValueName 值名(NULL = 键的默认值)
|
|
41
|
+
* @param args_2 Reserved 保留,恒 0
|
|
42
|
+
* @param args_3 dwType 值类型 gui.RegType.SZ(UTF-16 字符串)
|
|
43
|
+
* @param args_4 lpData 数据缓冲(REG_SZ:UTF-16LE 含结尾 NUL)
|
|
44
|
+
* @param args_5 cbData 数据字节数(REG_SZ = (字符数+1)*2) */
|
|
45
|
+
export const RegSetValueEx = /*@__PURE__*/ b('RegSetValueExW',
|
|
46
|
+
'<>ptr <WCHAR>ptr u32 u32@RegType <BYTE>ptr u32 -> i32')
|
|
47
|
+
|
|
48
|
+
/** 读键值(两跳模式:第一跳 lpData=NULL 取尺寸/类型,第二跳按尺寸带缓冲读数据)
|
|
49
|
+
* @returns 0 = ERROR_SUCCESS;2 = ERROR_FILE_NOT_FOUND(值不存在)
|
|
50
|
+
* @param args_0 hKey 键句柄(须 KEY_QUERY_VALUE 权限,含于 gui.RegAccess.READ)
|
|
51
|
+
* @param args_1 lpValueName 值名(NULL = 键的默认值)
|
|
52
|
+
* @param args_2 lpReserved 保留,恒 NULL
|
|
53
|
+
* @param args_3 lpType 出参:值类型(可 NULL)
|
|
54
|
+
* @param args_4 lpData 数据缓冲(可 NULL = 只查尺寸)
|
|
55
|
+
* @param args_5 lpcbData 双向:入 = lpData 缓冲字节数(须预写)、出 = 实际字节数 */
|
|
56
|
+
export const RegQueryValueEx = /*@__PURE__*/ b('RegQueryValueExW',
|
|
57
|
+
'<>ptr <WCHAR>ptr <>ptr <BYTE>ptr <BYTE>ptr <BYTE>ptr -> i32')
|
|
58
|
+
|
|
59
|
+
/** 删除子键(连值一起删);须父键 KEY_CREATE_SUB_KEY 权限——自己的 HKCU 直接传
|
|
60
|
+
* gui.HKey.CURRENT_USER 即可
|
|
61
|
+
* @returns 0 = ERROR_SUCCESS;2 = 子键不存在
|
|
62
|
+
* @param args_0 hKey 父键
|
|
63
|
+
* @param args_1 lpSubKey 要删的子键路径(不可 NULL) */
|
|
64
|
+
export const RegDeleteKey = /*@__PURE__*/ b('RegDeleteKeyW', '<>ptr <WCHAR>ptr -> i32')
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// comctl32 绑定(ImageList 系列;HIMAGELIST 不透明句柄走 <HIMAGELIST>ptr 自产自收,
|
|
2
|
+
// Add 的 hbm 位与 gdi32 的 <HGDIOBJ>ptr 同型互认——CreateBitmap 产物直传)
|
|
3
|
+
import { bind } from '../ffi/bind.js';
|
|
4
|
+
// dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
|
|
5
|
+
const b = (name, sig) => bind('comctl32.dll', name, sig);
|
|
6
|
+
/** 建图像列表;配对 ImageListDestroy
|
|
7
|
+
* @returns 图像列表句柄;失败 → NULL
|
|
8
|
+
* @param args_0 cx/cy 图像尺寸 @param args_2 flags ILC_* 组合
|
|
9
|
+
* @param args_3 cInitial 初始容量 @param args_4 cGrow 增长步长 */
|
|
10
|
+
export const ImageListCreate = /*@__PURE__*/ b('ImageList_Create', 'i32 i32 u32 i32 i32 -> <HIMAGELIST>ptr');
|
|
11
|
+
/** 加位图进图像列表
|
|
12
|
+
* @returns 新索引(-1 失败)
|
|
13
|
+
* @param args_0 himl 图像列表句柄
|
|
14
|
+
* @param args_1 hbm 位图句柄(gdi32 <HGDIOBJ>ptr 产物,如 CreateCompatibleBitmap) */
|
|
15
|
+
export const ImageListAdd = /*@__PURE__*/ b('ImageList_Add', '<HIMAGELIST>ptr <HGDIOBJ>ptr -> i32');
|
|
16
|
+
/** 销毁图像列表
|
|
17
|
+
* @returns 成功 → 非 0 */
|
|
18
|
+
export const ImageListDestroy = /*@__PURE__*/ b('ImageList_Destroy', '<HIMAGELIST>ptr -> i32');
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// comctl32 绑定(ImageList 系列;HIMAGELIST 不透明句柄走 <HIMAGELIST>ptr 自产自收,
|
|
2
|
+
// Add 的 hbm 位与 gdi32 的 <HGDIOBJ>ptr 同型互认——CreateBitmap 产物直传)
|
|
3
|
+
import { bind } from '../ffi/bind.js'
|
|
4
|
+
|
|
5
|
+
// dll 名部分应用(工厂转调保泛型 infer,见 lib/windows/user32.ts 头注释)
|
|
6
|
+
const b = <const S extends string>(name: string, sig: S) => bind('comctl32.dll', name, sig)
|
|
7
|
+
/** 建图像列表;配对 ImageListDestroy
|
|
8
|
+
* @returns 图像列表句柄;失败 → NULL
|
|
9
|
+
* @param args_0 cx/cy 图像尺寸 @param args_2 flags ILC_* 组合
|
|
10
|
+
* @param args_3 cInitial 初始容量 @param args_4 cGrow 增长步长 */
|
|
11
|
+
export const ImageListCreate = /*@__PURE__*/ b('ImageList_Create', 'i32 i32 u32 i32 i32 -> <HIMAGELIST>ptr')
|
|
12
|
+
/** 加位图进图像列表
|
|
13
|
+
* @returns 新索引(-1 失败)
|
|
14
|
+
* @param args_0 himl 图像列表句柄
|
|
15
|
+
* @param args_1 hbm 位图句柄(gdi32 <HGDIOBJ>ptr 产物,如 CreateCompatibleBitmap) */
|
|
16
|
+
export const ImageListAdd = /*@__PURE__*/ b('ImageList_Add', '<HIMAGELIST>ptr <HGDIOBJ>ptr -> i32')
|
|
17
|
+
/** 销毁图像列表
|
|
18
|
+
* @returns 成功 → 非 0 */
|
|
19
|
+
export const ImageListDestroy = /*@__PURE__*/ b('ImageList_Destroy', '<HIMAGELIST>ptr -> i32')
|
|
@@ -0,0 +1,8 @@
|
|
|
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
|
+
/** 打开/保存文件对话框
|
|
6
|
+
* @returns 用户确认 → 非 0(lpstrFile 缓冲即选中路径),取消/出错 → 0
|
|
7
|
+
* @param args_0 pOpenfn OPENFILENAMEW.encode(...).ptr(lStructSize 必须 = OPENFILENAMEW.size,见 structs.ts) */
|
|
8
|
+
export const GetOpenFileName = /*@__PURE__*/ b('GetOpenFileNameW', '<OPENFILENAMEW>ptr -> u32');
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
/** 打开/保存文件对话框
|
|
8
|
+
* @returns 用户确认 → 非 0(lpstrFile 缓冲即选中路径),取消/出错 → 0
|
|
9
|
+
* @param args_0 pOpenfn OPENFILENAMEW.encode(...).ptr(lStructSize 必须 = OPENFILENAMEW.size,见 structs.ts) */
|
|
10
|
+
export const GetOpenFileName = /*@__PURE__*/ b('GetOpenFileNameW', '<OPENFILENAMEW>ptr -> u32')
|