quickwin 2.2.0 → 2.3.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 +7 -7
- package/README.md +7 -7
- package/constants.ts +1063 -0
- package/enum_map.d.ts +129 -0
- package/examples/PdfCanvas.js +2 -2
- package/examples/PdfCanvas.tsx +3 -2
- package/examples/{execd.js → execd/main.js} +563 -122
- package/examples/execd/tray.js +192 -0
- package/examples/{execd_worker.js → execd/worker.js} +7 -7
- package/examples/pdf_preview2.js +46 -46
- package/examples/pdf_preview2.ts +55 -54
- package/examples/pdf_viewer.js +34 -19
- package/examples/pdf_viewer.tsx +6 -5
- package/examples/test_gallery.js +35 -20
- package/examples/test_gallery.tsx +9 -8
- package/examples/test_react_lazy.js +34 -19
- package/examples/test_react_lazy.tsx +7 -6
- package/examples/test_react_listbox.js +34 -19
- package/examples/test_react_listbox.tsx +8 -7
- package/examples/test_root_window.js +34 -19
- package/examples/test_root_window.tsx +5 -5
- package/examples/test_tab.js +34 -19
- package/examples/test_tab.tsx +7 -6
- package/examples/tray_demo.js +8 -8
- package/examples/tray_demo.tsx +9 -8
- package/lib/dumpRects.js +2 -2
- package/lib/dumpRects.ts +3 -2
- package/lib/fetch.js +15 -15
- package/lib/fetch.ts +16 -15
- package/lib/ffi/bind.js +3 -3
- package/lib/ffi/bind.ts +3 -3
- package/lib/http-server.js +4 -4
- package/lib/http-server.ts +5 -4
- package/lib/react-qw/components/Button.js +2 -2
- package/lib/react-qw/components/CheckBox.js +4 -4
- package/lib/react-qw/components/ComboBox.js +10 -10
- package/lib/react-qw/components/DateTimePicker.js +12 -12
- package/lib/react-qw/components/Input.js +7 -7
- package/lib/react-qw/components/Link.js +4 -4
- package/lib/react-qw/components/ListBox.js +12 -12
- package/lib/react-qw/components/ListView.js +35 -35
- package/lib/react-qw/components/PathPicker.js +3 -3
- package/lib/react-qw/components/ProgressBar.js +4 -4
- package/lib/react-qw/components/RadioButton.js +4 -4
- package/lib/react-qw/components/ScrollView.js +28 -28
- package/lib/react-qw/components/Slider.js +11 -11
- package/lib/react-qw/components/Tab.js +10 -10
- package/lib/react-qw/components/Tooltip.js +8 -8
- package/lib/react-qw/components/TreeView.js +20 -20
- package/lib/react-qw/index.js +5 -5
- package/lib/react-qw/index.ts +6 -5
- package/lib/react-qw/props.js +4 -4
- package/lib/react-qw/props.ts +5 -4
- package/lib/react-qw/reconciler.js +10 -10
- package/lib/react-qw/reconciler.ts +11 -10
- package/lib/text-measure.js +3 -3
- package/lib/text-measure.ts +4 -3
- package/lib/websocket.js +17 -17
- package/lib/websocket.ts +18 -17
- package/lib/windows/advapi32.js +7 -7
- package/lib/windows/advapi32.ts +7 -7
- package/lib/windows/gdi32.js +16 -16
- package/lib/windows/gdi32.ts +16 -16
- package/lib/windows/kernel32.js +41 -2
- package/lib/windows/kernel32.ts +45 -2
- package/lib/windows/shell32.js +24 -3
- package/lib/windows/shell32.ts +27 -4
- package/lib/windows/structs.js +54 -0
- package/lib/windows/structs.ts +63 -1
- package/lib/windows/user32.js +18 -6
- package/lib/windows/user32.ts +18 -6
- package/lib/windows/winspool.js +3 -3
- package/lib/windows/winspool.ts +3 -3
- package/package.json +4 -3
- package/quickwin.d.ts +32 -10
- 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/test_ffi_bind.js +7 -7
- package/test/test_ffi_bind.ts +8 -8
- package/test/test_ffi_struct.js +2 -2
- package/test/test_ffi_struct.ts +3 -3
- package/test/test_ffi_windows.js +1 -1
- package/test/test_ffi_windows.ts +1 -1
- package/test/test_files.js +7 -7
- package/test/test_files.ts +8 -8
- package/test/test_gdi_draw.js +51 -51
- package/test/test_gdi_draw.ts +57 -57
- package/test/test_http_server.js +3 -3
- package/test/test_http_server.ts +4 -3
- package/test/test_ipv6.js +3 -3
- package/test/test_ipv6.ts +4 -3
- package/test/test_net_event.js +3 -3
- package/test/test_net_event.ts +4 -3
- package/test/test_printer.js +4 -4
- package/test/test_printer.ts +5 -5
- package/test/test_react_complex.js +36 -21
- package/test/test_react_counter.js +34 -19
- package/test/test_react_flex.js +36 -21
- package/test/test_react_hidden.js +34 -19
- package/test/test_react_listview_link.js +35 -20
- package/test/test_react_notify.js +52 -37
- package/test/test_react_render.js +34 -19
- package/test/test_registry.js +6 -6
- package/test/test_registry.ts +8 -8
- package/test/test_wolfssl_read.js +8 -8
- package/test/test_wolfssl_read.ts +9 -8
- package/examples/execd.tsx +0 -798
- package/examples/execd_worker.ts +0 -127
- package/quickwin_const.d.ts +0 -1063
package/lib/react-qw/index.js
CHANGED
|
@@ -10,7 +10,7 @@ function ensureDefaultClass() {
|
|
|
10
10
|
return DEFAULT_CLASS;
|
|
11
11
|
gui.RegisterClass(DEFAULT_CLASS, (hwnd, msg, wParam, lParam) => {
|
|
12
12
|
const entry = rootMap.get(hwnd);
|
|
13
|
-
if (msg === 2 /*
|
|
13
|
+
if (msg === 2 /* WmMsg.DESTROY */ && entry) {
|
|
14
14
|
rootMap.delete(hwnd);
|
|
15
15
|
reconciler.updateContainer(null, entry.root, null, () => {
|
|
16
16
|
instancesByHwnd.delete(hwnd);
|
|
@@ -19,7 +19,7 @@ function ensureDefaultClass() {
|
|
|
19
19
|
const result = entry?.onEvent?.({ hwnd, msg, wParam, lParam });
|
|
20
20
|
if (typeof result === 'number')
|
|
21
21
|
return result;
|
|
22
|
-
if (msg === 5 /*
|
|
22
|
+
if (msg === 5 /* WmMsg.SIZE */)
|
|
23
23
|
forceFlexLayout(hwnd);
|
|
24
24
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
25
25
|
});
|
|
@@ -31,15 +31,15 @@ export function createRoot(container) {
|
|
|
31
31
|
if (typeof container === 'object') {
|
|
32
32
|
const cfg = container;
|
|
33
33
|
const className = ensureDefaultClass();
|
|
34
|
-
const ws = (cfg.ws ?? 0) | 13565952 /*
|
|
34
|
+
const ws = (cfg.ws ?? 0) | 13565952 /* WindowStyle.OVERLAPPEDWINDOW */;
|
|
35
35
|
const w = (cfg.width ?? 800) * scaleFactor;
|
|
36
36
|
const h = (cfg.height ?? 600) * scaleFactor;
|
|
37
37
|
// GetScreenSize 等价内联:SM_CXSCREEN=0 / SM_CYSCREEN=1
|
|
38
38
|
const [sw, sh] = [GetSystemMetrics(0), GetSystemMetrics(1)];
|
|
39
39
|
const x = cfg.x === undefined ? ((sw - w) / 2) | 0
|
|
40
|
-
: cfg.x === -2147483648 /*
|
|
40
|
+
: cfg.x === -2147483648 /* CreatePos.USEDEFAULT */ ? -2147483648 /* CreatePos.USEDEFAULT */ : cfg.x * scaleFactor;
|
|
41
41
|
const y = cfg.y === undefined ? ((sh - h) / 2) | 0
|
|
42
|
-
: cfg.y === -2147483648 /*
|
|
42
|
+
: cfg.y === -2147483648 /* CreatePos.USEDEFAULT */ ? -2147483648 /* CreatePos.USEDEFAULT */ : cfg.y * scaleFactor;
|
|
43
43
|
const hwin = gui.CreateWindow(className, cfg.text || '', ws, x, y, w, h, null, null);
|
|
44
44
|
if (!hwin)
|
|
45
45
|
throw new Error('CreateWindow failed');
|
package/lib/react-qw/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as gui from 'gui'
|
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import { DefWindowProc, GetSystemMetrics } from '../windows/user32.js'
|
|
4
4
|
import reconciler, { scaleFactor, instancesByHwnd, forceFlexLayout, type Instance } from './reconciler.js'
|
|
5
|
+
import { CreatePos, WindowStyle, WmMsg } from '../../constants'
|
|
5
6
|
|
|
6
7
|
const noop = () => { }
|
|
7
8
|
|
|
@@ -24,7 +25,7 @@ function ensureDefaultClass() {
|
|
|
24
25
|
if (defaultClassRegistered) return DEFAULT_CLASS
|
|
25
26
|
gui.RegisterClass(DEFAULT_CLASS, (hwnd, msg, wParam, lParam) => {
|
|
26
27
|
const entry = rootMap.get(hwnd)
|
|
27
|
-
if (msg ===
|
|
28
|
+
if (msg === WmMsg.DESTROY && entry) {
|
|
28
29
|
rootMap.delete(hwnd)
|
|
29
30
|
reconciler.updateContainer(null, entry.root, null, () => {
|
|
30
31
|
instancesByHwnd.delete(hwnd)
|
|
@@ -32,7 +33,7 @@ function ensureDefaultClass() {
|
|
|
32
33
|
}
|
|
33
34
|
const result = entry?.onEvent?.({ hwnd, msg, wParam, lParam })
|
|
34
35
|
if (typeof result === 'number') return result
|
|
35
|
-
if (msg ===
|
|
36
|
+
if (msg === WmMsg.SIZE) forceFlexLayout(hwnd)
|
|
36
37
|
return DefWindowProc(hwnd, msg, wParam, lParam)
|
|
37
38
|
})
|
|
38
39
|
defaultClassRegistered = true
|
|
@@ -44,16 +45,16 @@ export function createRoot(container: gui.HWND | RootWindowConfig) {
|
|
|
44
45
|
if (typeof container === 'object') {
|
|
45
46
|
const cfg = container
|
|
46
47
|
const className = ensureDefaultClass()
|
|
47
|
-
const ws = (cfg.ws ?? 0) |
|
|
48
|
+
const ws = (cfg.ws ?? 0) | WindowStyle.OVERLAPPEDWINDOW
|
|
48
49
|
const w = (cfg.width ?? 800) * scaleFactor
|
|
49
50
|
const h = (cfg.height ?? 600) * scaleFactor
|
|
50
51
|
// GetScreenSize 等价内联:SM_CXSCREEN=0 / SM_CYSCREEN=1
|
|
51
52
|
const [sw, sh] = [GetSystemMetrics(0), GetSystemMetrics(1)]
|
|
52
53
|
const x = cfg.x === undefined ? ((sw - w) / 2) | 0
|
|
53
|
-
: cfg.x ===
|
|
54
|
+
: cfg.x === CreatePos.USEDEFAULT ? CreatePos.USEDEFAULT
|
|
54
55
|
: cfg.x * scaleFactor
|
|
55
56
|
const y = cfg.y === undefined ? ((sh - h) / 2) | 0
|
|
56
|
-
: cfg.y ===
|
|
57
|
+
: cfg.y === CreatePos.USEDEFAULT ? CreatePos.USEDEFAULT
|
|
57
58
|
: cfg.y * scaleFactor
|
|
58
59
|
const hwin = gui.CreateWindow(className, cfg.text || '', ws, x, y, w, h, null, null)
|
|
59
60
|
if (!hwin) throw new Error('CreateWindow failed')
|
package/lib/react-qw/props.js
CHANGED
|
@@ -12,21 +12,21 @@ export function applyProps(instance, newProps, _oldProps) {
|
|
|
12
12
|
if (textVal !== undefined) {
|
|
13
13
|
let cursor = -1;
|
|
14
14
|
if (instance.type === 'EDIT') {
|
|
15
|
-
const sel = gui.SendMessage(hwnd, 176 /*
|
|
15
|
+
const sel = gui.SendMessage(hwnd, 176 /* EditMsg.GETSEL */, 0, 0);
|
|
16
16
|
cursor = sel >>> 16;
|
|
17
17
|
}
|
|
18
18
|
SetWindowText(hwnd, textVal);
|
|
19
19
|
if (instance.type === 'EDIT' && cursor >= 0) {
|
|
20
|
-
gui.SendMessage(hwnd, 177 /*
|
|
20
|
+
gui.SendMessage(hwnd, 177 /* EditMsg.SETSEL */, cursor, cursor);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
if ('disabled' in newProps) {
|
|
24
24
|
EnableWindow(hwnd, !newProps.disabled ? 1 : 0);
|
|
25
25
|
}
|
|
26
26
|
if ('hidden' in newProps) {
|
|
27
|
-
gui.ShowWindow(hwnd, newProps.hidden ? 0 /*
|
|
27
|
+
gui.ShowWindow(hwnd, newProps.hidden ? 0 /* ShowWindowCmd.HIDE */ : 5 /* ShowWindowCmd.SHOW */);
|
|
28
28
|
}
|
|
29
29
|
if ('visible' in newProps) {
|
|
30
|
-
gui.ShowWindow(hwnd, newProps.visible ? 5 /*
|
|
30
|
+
gui.ShowWindow(hwnd, newProps.visible ? 5 /* ShowWindowCmd.SHOW */ : 0 /* ShowWindowCmd.HIDE */);
|
|
31
31
|
}
|
|
32
32
|
}
|
package/lib/react-qw/props.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as gui from 'gui'
|
|
2
2
|
import { SetWindowText, EnableWindow } from '../windows/user32.js'
|
|
3
3
|
import type { Instance, Props } from './reconciler.js'
|
|
4
|
+
import { EditMsg, ShowWindowCmd } from '../../constants'
|
|
4
5
|
|
|
5
6
|
export function applyProps(
|
|
6
7
|
instance: Instance,
|
|
@@ -20,21 +21,21 @@ export function applyProps(
|
|
|
20
21
|
if (textVal !== undefined) {
|
|
21
22
|
let cursor = -1
|
|
22
23
|
if (instance.type === 'EDIT') {
|
|
23
|
-
const sel = gui.SendMessage(hwnd,
|
|
24
|
+
const sel = gui.SendMessage(hwnd, EditMsg.GETSEL, 0, 0)
|
|
24
25
|
cursor = sel >>> 16
|
|
25
26
|
}
|
|
26
27
|
SetWindowText(hwnd, textVal)
|
|
27
28
|
if (instance.type === 'EDIT' && cursor >= 0) {
|
|
28
|
-
gui.SendMessage(hwnd,
|
|
29
|
+
gui.SendMessage(hwnd, EditMsg.SETSEL, cursor, cursor)
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
if ('disabled' in newProps) {
|
|
32
33
|
EnableWindow(hwnd, !newProps.disabled ? 1 : 0)
|
|
33
34
|
}
|
|
34
35
|
if ('hidden' in newProps) {
|
|
35
|
-
gui.ShowWindow(hwnd, newProps.hidden ?
|
|
36
|
+
gui.ShowWindow(hwnd, newProps.hidden ? ShowWindowCmd.HIDE : ShowWindowCmd.SHOW)
|
|
36
37
|
}
|
|
37
38
|
if ('visible' in newProps) {
|
|
38
|
-
gui.ShowWindow(hwnd, newProps.visible ?
|
|
39
|
+
gui.ShowWindow(hwnd, newProps.visible ? ShowWindowCmd.SHOW : ShowWindowCmd.HIDE)
|
|
39
40
|
}
|
|
40
41
|
}
|
|
@@ -24,7 +24,7 @@ function isDelayedControl(winClass) {
|
|
|
24
24
|
}
|
|
25
25
|
function setupWindowProc(instance, hwnd) {
|
|
26
26
|
instance.hwnd = hwnd;
|
|
27
|
-
const oldProc = GetWindowLongPtr(hwnd, -4 /*
|
|
27
|
+
const oldProc = GetWindowLongPtr(hwnd, -4 /* Gwlp.WNDPROC */);
|
|
28
28
|
instancesByHwnd.set(hwnd, instance);
|
|
29
29
|
gui.SetWindowProc(hwnd, (hwnd, msg, wParam, lParam) => {
|
|
30
30
|
const ev = instance.props.onEvent;
|
|
@@ -42,10 +42,10 @@ function ensureChildWindow(child, parentHwnd) {
|
|
|
42
42
|
if (child.hwnd !== null)
|
|
43
43
|
return child.hwnd;
|
|
44
44
|
const sty = child.props.style || {};
|
|
45
|
-
const ws = ((child.props.ws ?? 0) | 1073741824 /*
|
|
45
|
+
const ws = ((child.props.ws ?? 0) | 1073741824 /* WindowStyle.CHILD */) & ~268435456 /* WindowStyle.VISIBLE */;
|
|
46
46
|
const hwnd = gui.CreateWindow(child.type, child.props.text || '', ws, 0, 0, (typeof sty.width === 'number' ? sty.width : 100) * scaleFactor, (typeof sty.height === 'number' ? sty.height : 30) * scaleFactor, parentHwnd, null);
|
|
47
47
|
if (dpiFont)
|
|
48
|
-
gui.SendMessage(hwnd, 48 /*
|
|
48
|
+
gui.SendMessage(hwnd, 48 /* WmMsg.SETFONT */, dpiFont, 1);
|
|
49
49
|
setupWindowProc(child, hwnd);
|
|
50
50
|
return hwnd;
|
|
51
51
|
}
|
|
@@ -104,7 +104,7 @@ function runFlexLayout(inst) {
|
|
|
104
104
|
if (lr && lr.x === r.x && lr.y === r.y && lr.w === r.width && lr.h === r.height)
|
|
105
105
|
continue;
|
|
106
106
|
console.log('flex: set', child.type, child.hwnd, 'to', r.x, r.y, r.width, r.height);
|
|
107
|
-
SetWindowPos(child.hwnd, 0 /*
|
|
107
|
+
SetWindowPos(child.hwnd, 0 /* SetWindowPosHwnd.TOP */, (r.x + pl) * scaleFactor, (r.y + pt) * scaleFactor, r.width * scaleFactor, r.height * scaleFactor, 64 /* SetWindowPosFlag.SWP_SHOWWINDOW */);
|
|
108
108
|
InvalidateRect(child.hwnd, NULL, 1);
|
|
109
109
|
child.lastRect = { x: r.x, y: r.y, w: r.width, h: r.height };
|
|
110
110
|
}
|
|
@@ -133,12 +133,12 @@ const hostConfig = {
|
|
|
133
133
|
}
|
|
134
134
|
const sty = props.style || {};
|
|
135
135
|
// reconciler 创建的都是子窗口,确保 WS_CHILD 避免定位异常;创建时不带 WS_VISIBLE 防止 (0,0) 闪烁
|
|
136
|
-
const ws = ((props.ws ?? 0) | 1073741824 /*
|
|
136
|
+
const ws = ((props.ws ?? 0) | 1073741824 /* WindowStyle.CHILD */) & ~268435456 /* WindowStyle.VISIBLE */;
|
|
137
137
|
if (DEBUG)
|
|
138
138
|
console.log('[reconciler] CreateWindow args:', winClass, props.text ?? '', ws, 0, 0, sty.width ?? 100, sty.height ?? 30, rootContainer);
|
|
139
139
|
const hwnd = gui.CreateWindow(winClass, props.text ?? '', ws, 0, 0, (typeof sty.width === 'number' ? sty.width : 100) * scaleFactor, (typeof sty.height === 'number' ? sty.height : 30) * scaleFactor, rootContainer, null);
|
|
140
140
|
if (dpiFont)
|
|
141
|
-
gui.SendMessage(hwnd, 48 /*
|
|
141
|
+
gui.SendMessage(hwnd, 48 /* WmMsg.SETFONT */, dpiFont, 1);
|
|
142
142
|
if (DEBUG)
|
|
143
143
|
console.log('[reconciler] createInstance hwnd result:', hwnd, 'null?', hwnd === null);
|
|
144
144
|
const instance = { hwnd, type: winClass, props, children: [] };
|
|
@@ -260,19 +260,19 @@ const hostConfig = {
|
|
|
260
260
|
},
|
|
261
261
|
hideInstance(instance) {
|
|
262
262
|
if (instance.hwnd !== null)
|
|
263
|
-
gui.ShowWindow(instance.hwnd, 0 /*
|
|
263
|
+
gui.ShowWindow(instance.hwnd, 0 /* ShowWindowCmd.HIDE */);
|
|
264
264
|
},
|
|
265
265
|
hideTextInstance(instance) {
|
|
266
266
|
if (instance.hwnd !== null)
|
|
267
|
-
gui.ShowWindow(instance.hwnd, 0 /*
|
|
267
|
+
gui.ShowWindow(instance.hwnd, 0 /* ShowWindowCmd.HIDE */);
|
|
268
268
|
},
|
|
269
269
|
unhideInstance(instance, _props) {
|
|
270
270
|
if (instance.hwnd !== null)
|
|
271
|
-
gui.ShowWindow(instance.hwnd, 5 /*
|
|
271
|
+
gui.ShowWindow(instance.hwnd, 5 /* ShowWindowCmd.SHOW */);
|
|
272
272
|
},
|
|
273
273
|
unhideTextInstance(instance, _text) {
|
|
274
274
|
if (instance.hwnd !== null)
|
|
275
|
-
gui.ShowWindow(instance.hwnd, 5 /*
|
|
275
|
+
gui.ShowWindow(instance.hwnd, 5 /* ShowWindowCmd.SHOW */);
|
|
276
276
|
},
|
|
277
277
|
shouldSetTextContent(_type, props) {
|
|
278
278
|
return typeof props.children === 'string' || typeof props.children === 'number';
|
|
@@ -10,6 +10,7 @@ import { applyProps } from './props.js'
|
|
|
10
10
|
import { calculateFlexLayout, type FlexStyle } from './layout.js'
|
|
11
11
|
import { getButtonIdealSize, measureTextForHwnd } from '../text-measure.js'
|
|
12
12
|
import type { WIntrinsicProps } from './jsx.js'
|
|
13
|
+
import { Gwlp, SetWindowPosFlag, SetWindowPosHwnd, ShowWindowCmd, WindowStyle, WmMsg } from '../../constants'
|
|
13
14
|
|
|
14
15
|
// DEBUG 由 esbuild --define 在 bundle 时替换(见 build.ts),生产环境为 false
|
|
15
16
|
declare const DEBUG: boolean
|
|
@@ -42,7 +43,7 @@ function isDelayedControl(winClass: string): boolean {
|
|
|
42
43
|
|
|
43
44
|
function setupWindowProc(instance: Instance, hwnd: gui.HWND) {
|
|
44
45
|
instance.hwnd = hwnd
|
|
45
|
-
const oldProc = GetWindowLongPtr(hwnd,
|
|
46
|
+
const oldProc = GetWindowLongPtr(hwnd, Gwlp.WNDPROC)
|
|
46
47
|
instancesByHwnd.set(hwnd, instance)
|
|
47
48
|
gui.SetWindowProc(hwnd, (hwnd: gui.HWND, msg: number, wParam: number, lParam: number) => {
|
|
48
49
|
const ev = instance.props.onEvent
|
|
@@ -59,14 +60,14 @@ function setupWindowProc(instance: Instance, hwnd: gui.HWND) {
|
|
|
59
60
|
function ensureChildWindow(child: Instance, parentHwnd: gui.HWND): gui.HWND {
|
|
60
61
|
if (child.hwnd !== null) return child.hwnd
|
|
61
62
|
const sty = child.props.style || {}
|
|
62
|
-
const ws = ((child.props.ws ?? 0) |
|
|
63
|
+
const ws = ((child.props.ws ?? 0) | WindowStyle.CHILD) & ~WindowStyle.VISIBLE
|
|
63
64
|
const hwnd = gui.CreateWindow(
|
|
64
65
|
child.type, child.props.text || '', ws,
|
|
65
66
|
0, 0,
|
|
66
67
|
(typeof sty.width === 'number' ? sty.width : 100) * scaleFactor, (typeof sty.height === 'number' ? sty.height : 30) * scaleFactor,
|
|
67
68
|
parentHwnd, null
|
|
68
69
|
)!
|
|
69
|
-
if (dpiFont) gui.SendMessage(hwnd,
|
|
70
|
+
if (dpiFont) gui.SendMessage(hwnd, WmMsg.SETFONT, dpiFont, 1)
|
|
70
71
|
setupWindowProc(child, hwnd)
|
|
71
72
|
return hwnd
|
|
72
73
|
}
|
|
@@ -118,7 +119,7 @@ function runFlexLayout(inst: Instance) {
|
|
|
118
119
|
const lr = child.lastRect
|
|
119
120
|
if (lr && lr.x === r.x && lr.y === r.y && lr.w === r.width && lr.h === r.height) continue
|
|
120
121
|
console.log('flex: set', child.type, child.hwnd, 'to', r.x, r.y, r.width, r.height)
|
|
121
|
-
SetWindowPos(child.hwnd!,
|
|
122
|
+
SetWindowPos(child.hwnd!, SetWindowPosHwnd.TOP, (r.x + pl) * scaleFactor, (r.y + pt) * scaleFactor, r.width * scaleFactor, r.height * scaleFactor, SetWindowPosFlag.SWP_SHOWWINDOW)
|
|
122
123
|
InvalidateRect(child.hwnd!, NULL, 1)
|
|
123
124
|
child.lastRect = { x: r.x, y: r.y, w: r.width, h: r.height }
|
|
124
125
|
}
|
|
@@ -164,7 +165,7 @@ const hostConfig: QuickWinHostConfig = {
|
|
|
164
165
|
}
|
|
165
166
|
const sty = props.style || {}
|
|
166
167
|
// reconciler 创建的都是子窗口,确保 WS_CHILD 避免定位异常;创建时不带 WS_VISIBLE 防止 (0,0) 闪烁
|
|
167
|
-
const ws = ((props.ws ?? 0) |
|
|
168
|
+
const ws = ((props.ws ?? 0) | WindowStyle.CHILD) & ~WindowStyle.VISIBLE
|
|
168
169
|
if (DEBUG) console.log('[reconciler] CreateWindow args:', winClass, props.text ?? '', ws, 0, 0, sty.width ?? 100, sty.height ?? 30, rootContainer)
|
|
169
170
|
const hwnd = gui.CreateWindow(
|
|
170
171
|
winClass, props.text ?? '', ws,
|
|
@@ -172,7 +173,7 @@ const hostConfig: QuickWinHostConfig = {
|
|
|
172
173
|
(typeof sty.width === 'number' ? sty.width : 100) * scaleFactor, (typeof sty.height === 'number' ? sty.height : 30) * scaleFactor,
|
|
173
174
|
rootContainer, null
|
|
174
175
|
)!
|
|
175
|
-
if (dpiFont) gui.SendMessage(hwnd,
|
|
176
|
+
if (dpiFont) gui.SendMessage(hwnd, WmMsg.SETFONT, dpiFont, 1)
|
|
176
177
|
if (DEBUG) console.log('[reconciler] createInstance hwnd result:', hwnd, 'null?', hwnd === null)
|
|
177
178
|
const instance: Instance = { hwnd, type: winClass, props, children: [] }
|
|
178
179
|
setupWindowProc(instance, hwnd)
|
|
@@ -283,19 +284,19 @@ const hostConfig: QuickWinHostConfig = {
|
|
|
283
284
|
},
|
|
284
285
|
|
|
285
286
|
hideInstance(instance: Instance) {
|
|
286
|
-
if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd,
|
|
287
|
+
if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd, ShowWindowCmd.HIDE)
|
|
287
288
|
},
|
|
288
289
|
|
|
289
290
|
hideTextInstance(instance: Instance) {
|
|
290
|
-
if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd,
|
|
291
|
+
if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd, ShowWindowCmd.HIDE)
|
|
291
292
|
},
|
|
292
293
|
|
|
293
294
|
unhideInstance(instance: Instance, _props: Props) {
|
|
294
|
-
if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd,
|
|
295
|
+
if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd, ShowWindowCmd.SHOW)
|
|
295
296
|
},
|
|
296
297
|
|
|
297
298
|
unhideTextInstance(instance: Instance, _text: string) {
|
|
298
|
-
if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd,
|
|
299
|
+
if (instance.hwnd !== null) gui.ShowWindow(instance.hwnd, ShowWindowCmd.SHOW)
|
|
299
300
|
},
|
|
300
301
|
|
|
301
302
|
shouldSetTextContent(_type: string, props: Props) {
|
package/lib/text-measure.js
CHANGED
|
@@ -7,14 +7,14 @@ export function measureText(hdc, text, maxWidth) {
|
|
|
7
7
|
// rect 双向位不注册 encoder(CALCRECT 就地写回):encode(初值) 新建 + DeepPartial 初值一步到位
|
|
8
8
|
//(left/top/bottom 缺省跳过保持 0)→ 传 .ptr → decode 读回
|
|
9
9
|
const r = RECT.encode({ right: maxWidth });
|
|
10
|
-
DrawText(hdc, text, -1, r.ptr, 1024 /*
|
|
10
|
+
DrawText(hdc, text, -1, r.ptr, 1024 /* DrawTextFlag.CALCRECT */);
|
|
11
11
|
const { right, bottom } = RECT.decode(r);
|
|
12
12
|
return { width: right, height: bottom };
|
|
13
13
|
}
|
|
14
14
|
export function getButtonIdealSize(hwnd) {
|
|
15
15
|
// SIZE 纯出参位(GETIDEALSIZE 就地写回):alloc → 传 .ptr → decode 读回
|
|
16
16
|
const size = SIZE.alloc();
|
|
17
|
-
gui.SendMessage(hwnd, 5633 /*
|
|
17
|
+
gui.SendMessage(hwnd, 5633 /* ButtonExtMsg.GETIDEALSIZE */, 0, size.ptr);
|
|
18
18
|
const { cx, cy } = SIZE.decode(size);
|
|
19
19
|
return { width: cx, height: cy };
|
|
20
20
|
}
|
|
@@ -23,7 +23,7 @@ export function measureTextForHwnd(hwnd, text) {
|
|
|
23
23
|
if (!hdc)
|
|
24
24
|
return { width: 0, height: 0 };
|
|
25
25
|
// SendMessage 返回 LRESULT 裸数;GETFONT 语义为 HFONT——断言进 GDI 对象品牌链
|
|
26
|
-
const hFont = gui.SendMessage(hwnd, 49 /*
|
|
26
|
+
const hFont = gui.SendMessage(hwnd, 49 /* WmMsg.GETFONT */, 0, 0);
|
|
27
27
|
const oldFont = hFont ? SelectObject(hdc, hFont) : NULL;
|
|
28
28
|
const result = measureText(hdc, text, 0);
|
|
29
29
|
if (hFont)
|
package/lib/text-measure.ts
CHANGED
|
@@ -3,12 +3,13 @@ import * as gui from 'gui'
|
|
|
3
3
|
import { DrawText, GetDC, ReleaseDC } from './windows/user32.js'
|
|
4
4
|
import { SelectObject } from './windows/gdi32.js'
|
|
5
5
|
import { RECT, SIZE } from './windows/structs.js'
|
|
6
|
+
import { ButtonExtMsg, DrawTextFlag, WmMsg } from '../constants'
|
|
6
7
|
|
|
7
8
|
export function measureText(hdc: Ptr<'HDC'>, text: string, maxWidth: number): { width: number; height: number } {
|
|
8
9
|
// rect 双向位不注册 encoder(CALCRECT 就地写回):encode(初值) 新建 + DeepPartial 初值一步到位
|
|
9
10
|
//(left/top/bottom 缺省跳过保持 0)→ 传 .ptr → decode 读回
|
|
10
11
|
const r = RECT.encode({ right: maxWidth })
|
|
11
|
-
DrawText(hdc, text, -1, r.ptr,
|
|
12
|
+
DrawText(hdc, text, -1, r.ptr, DrawTextFlag.CALCRECT)
|
|
12
13
|
const { right, bottom } = RECT.decode(r)
|
|
13
14
|
return { width: right, height: bottom }
|
|
14
15
|
}
|
|
@@ -16,7 +17,7 @@ export function measureText(hdc: Ptr<'HDC'>, text: string, maxWidth: number): {
|
|
|
16
17
|
export function getButtonIdealSize(hwnd: gui.HWND): { width: number; height: number } {
|
|
17
18
|
// SIZE 纯出参位(GETIDEALSIZE 就地写回):alloc → 传 .ptr → decode 读回
|
|
18
19
|
const size = SIZE.alloc()
|
|
19
|
-
gui.SendMessage(hwnd,
|
|
20
|
+
gui.SendMessage(hwnd, ButtonExtMsg.GETIDEALSIZE, 0, size.ptr)
|
|
20
21
|
const { cx, cy } = SIZE.decode(size)
|
|
21
22
|
return { width: cx, height: cy }
|
|
22
23
|
}
|
|
@@ -25,7 +26,7 @@ export function measureTextForHwnd(hwnd: gui.HWND, text: string): { width: numbe
|
|
|
25
26
|
const hdc = GetDC(hwnd)
|
|
26
27
|
if (!hdc) return { width: 0, height: 0 }
|
|
27
28
|
// SendMessage 返回 LRESULT 裸数;GETFONT 语义为 HFONT——断言进 GDI 对象品牌链
|
|
28
|
-
const hFont = gui.SendMessage(hwnd,
|
|
29
|
+
const hFont = gui.SendMessage(hwnd, WmMsg.GETFONT, 0, 0) as Ptr<'HGDIOBJ'>
|
|
29
30
|
const oldFont = hFont ? SelectObject(hdc, hFont) : NULL
|
|
30
31
|
const result = measureText(hdc, text, 0)
|
|
31
32
|
if (hFont) SelectObject(hdc, oldFont)
|
package/lib/websocket.js
CHANGED
|
@@ -273,16 +273,16 @@ class WebSocketImpl {
|
|
|
273
273
|
if (this._processingHandshake)
|
|
274
274
|
return;
|
|
275
275
|
if (resolved && state === 'open') {
|
|
276
|
-
if (event.lNetworkEvents & 1 /*
|
|
276
|
+
if (event.lNetworkEvents & 1 /* FdEvent.FD_READ */) {
|
|
277
277
|
this._onData();
|
|
278
278
|
}
|
|
279
|
-
if (event.lNetworkEvents & 32 /*
|
|
279
|
+
if (event.lNetworkEvents & 32 /* FdEvent.FD_CLOSE */) {
|
|
280
280
|
this._cleanup();
|
|
281
281
|
this._setState(State.CLOSED);
|
|
282
282
|
}
|
|
283
283
|
return;
|
|
284
284
|
}
|
|
285
|
-
if (event.lNetworkEvents & 16 /*
|
|
285
|
+
if (event.lNetworkEvents & 16 /* FdEvent.FD_CONNECT */) {
|
|
286
286
|
const errCode = event.iErrorCode[0];
|
|
287
287
|
if (errCode !== 0) {
|
|
288
288
|
doError(new Error('Connection failed: ' + errCode));
|
|
@@ -296,10 +296,10 @@ class WebSocketImpl {
|
|
|
296
296
|
return;
|
|
297
297
|
}
|
|
298
298
|
if (this._options.rejectUnauthorized === false) {
|
|
299
|
-
wolfssl.wolfSSL_CTX_set_verify(this._ctx, 0 /*
|
|
299
|
+
wolfssl.wolfSSL_CTX_set_verify(this._ctx, 0 /* VerifyMode.SSL_VERIFY_NONE */);
|
|
300
300
|
}
|
|
301
301
|
else {
|
|
302
|
-
wolfssl.wolfSSL_CTX_set_verify(this._ctx, 1 /*
|
|
302
|
+
wolfssl.wolfSSL_CTX_set_verify(this._ctx, 1 /* VerifyMode.SSL_VERIFY_PEER */);
|
|
303
303
|
wolfssl.loadTrustedCerts(this._ctx);
|
|
304
304
|
}
|
|
305
305
|
this._ssl = wolfssl.wolfSSL_new(this._ctx);
|
|
@@ -310,7 +310,7 @@ class WebSocketImpl {
|
|
|
310
310
|
wolfssl.wolfSSL_set_fd(this._ssl, sock.get_fd(fd));
|
|
311
311
|
const sniHost = host;
|
|
312
312
|
if (sniHost) {
|
|
313
|
-
wolfssl.wolfSSL_UseSNI(this._ssl, 0 /*
|
|
313
|
+
wolfssl.wolfSSL_UseSNI(this._ssl, 0 /* SniType.WOLFSSL_SNI_HOST_NAME */, sniHost);
|
|
314
314
|
if (this._options.rejectUnauthorized !== false) {
|
|
315
315
|
wolfssl.wolfSSL_check_domain_name(this._ssl, sniHost);
|
|
316
316
|
}
|
|
@@ -322,21 +322,21 @@ class WebSocketImpl {
|
|
|
322
322
|
state = 'request';
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
|
-
if ((event.lNetworkEvents & 1 /*
|
|
325
|
+
if ((event.lNetworkEvents & 1 /* FdEvent.FD_READ */) || (event.lNetworkEvents & 2 /* FdEvent.FD_WRITE */)) {
|
|
326
326
|
if (state === 'handshake') {
|
|
327
327
|
if (!this._ssl) {
|
|
328
328
|
doError(new Error('TLS not initialized'));
|
|
329
329
|
return;
|
|
330
330
|
}
|
|
331
331
|
const ret = wolfssl.wolfSSL_connect(this._ssl);
|
|
332
|
-
if (ret === 1 /*
|
|
332
|
+
if (ret === 1 /* ReturnCode.SSL_SUCCESS */) {
|
|
333
333
|
this._sendRawStr(request);
|
|
334
334
|
state = 'request';
|
|
335
335
|
}
|
|
336
336
|
else {
|
|
337
337
|
const err = wolfssl.wolfSSL_get_error(this._ssl, ret);
|
|
338
|
-
if (err !== 2 /*
|
|
339
|
-
err !== 3 /*
|
|
338
|
+
if (err !== 2 /* WolfsslErrorCode.WOLFSSL_ERROR_WANT_READ */ &&
|
|
339
|
+
err !== 3 /* WolfsslErrorCode.WOLFSSL_ERROR_WANT_WRITE */) {
|
|
340
340
|
doError(new Error('TLS handshake failed: ' + err));
|
|
341
341
|
}
|
|
342
342
|
}
|
|
@@ -352,10 +352,10 @@ class WebSocketImpl {
|
|
|
352
352
|
}
|
|
353
353
|
else {
|
|
354
354
|
const err = wolfssl.wolfSSL_get_error(this._ssl, n);
|
|
355
|
-
if (err === 2 /*
|
|
356
|
-
err === 3 /*
|
|
355
|
+
if (err === 2 /* WolfsslErrorCode.WOLFSSL_ERROR_WANT_READ */ ||
|
|
356
|
+
err === 3 /* WolfsslErrorCode.WOLFSSL_ERROR_WANT_WRITE */)
|
|
357
357
|
break;
|
|
358
|
-
if (n === 0 || err === 6 /*
|
|
358
|
+
if (n === 0 || err === 6 /* WolfsslErrorCode.WOLFSSL_ERROR_ZERO_RETURN */)
|
|
359
359
|
break;
|
|
360
360
|
doError(new Error('TLS read failed: ' + err));
|
|
361
361
|
return;
|
|
@@ -417,7 +417,7 @@ class WebSocketImpl {
|
|
|
417
417
|
}
|
|
418
418
|
}
|
|
419
419
|
}
|
|
420
|
-
if (event.lNetworkEvents & 32 /*
|
|
420
|
+
if (event.lNetworkEvents & 32 /* FdEvent.FD_CLOSE */) {
|
|
421
421
|
if (state !== 'open') {
|
|
422
422
|
doError(new Error('Connection closed'));
|
|
423
423
|
}
|
|
@@ -464,10 +464,10 @@ class WebSocketImpl {
|
|
|
464
464
|
}
|
|
465
465
|
else {
|
|
466
466
|
const err = wolfssl.wolfSSL_get_error(this._ssl, n);
|
|
467
|
-
if (err === 2 /*
|
|
468
|
-
err === 3 /*
|
|
467
|
+
if (err === 2 /* WolfsslErrorCode.WOLFSSL_ERROR_WANT_READ */ ||
|
|
468
|
+
err === 3 /* WolfsslErrorCode.WOLFSSL_ERROR_WANT_WRITE */)
|
|
469
469
|
break;
|
|
470
|
-
if (n === 0 || err === 6 /*
|
|
470
|
+
if (n === 0 || err === 6 /* WolfsslErrorCode.WOLFSSL_ERROR_ZERO_RETURN */)
|
|
471
471
|
break;
|
|
472
472
|
this._fireError(new Error('TLS read failed: ' + err));
|
|
473
473
|
if (this._state !== State.CLOSED)
|
package/lib/websocket.ts
CHANGED
|
@@ -2,6 +2,7 @@ import '../lib/polyfill.js'
|
|
|
2
2
|
import * as sock from 'sock'
|
|
3
3
|
import * as wolfssl from 'wolfssl'
|
|
4
4
|
import * as os from 'os'
|
|
5
|
+
import { FdEvent, ReturnCode, SniType, VerifyMode, WolfsslErrorCode } from '../constants'
|
|
5
6
|
|
|
6
7
|
// ── Constants ──
|
|
7
8
|
|
|
@@ -301,17 +302,17 @@ class WebSocketImpl {
|
|
|
301
302
|
sock.set_on_event(fd, async (event: { lNetworkEvents: number; iErrorCode: number[] }) => {
|
|
302
303
|
if (this._processingHandshake) return
|
|
303
304
|
if (resolved && state === 'open') {
|
|
304
|
-
if (event.lNetworkEvents &
|
|
305
|
+
if (event.lNetworkEvents & FdEvent.FD_READ) {
|
|
305
306
|
this._onData()
|
|
306
307
|
}
|
|
307
|
-
if (event.lNetworkEvents &
|
|
308
|
+
if (event.lNetworkEvents & FdEvent.FD_CLOSE) {
|
|
308
309
|
this._cleanup()
|
|
309
310
|
this._setState(State.CLOSED)
|
|
310
311
|
}
|
|
311
312
|
return
|
|
312
313
|
}
|
|
313
314
|
|
|
314
|
-
if (event.lNetworkEvents &
|
|
315
|
+
if (event.lNetworkEvents & FdEvent.FD_CONNECT) {
|
|
315
316
|
const errCode = event.iErrorCode[0]
|
|
316
317
|
if (errCode !== 0) {
|
|
317
318
|
doError(new Error('Connection failed: ' + errCode))
|
|
@@ -322,9 +323,9 @@ class WebSocketImpl {
|
|
|
322
323
|
this._ctx = wolfssl.wolfSSL_CTX_new(method)
|
|
323
324
|
if (!this._ctx) { doError(new Error('SSL_CTX_new failed')); return }
|
|
324
325
|
if (this._options.rejectUnauthorized === false) {
|
|
325
|
-
wolfssl.wolfSSL_CTX_set_verify(this._ctx,
|
|
326
|
+
wolfssl.wolfSSL_CTX_set_verify(this._ctx, VerifyMode.SSL_VERIFY_NONE)
|
|
326
327
|
} else {
|
|
327
|
-
wolfssl.wolfSSL_CTX_set_verify(this._ctx,
|
|
328
|
+
wolfssl.wolfSSL_CTX_set_verify(this._ctx, VerifyMode.SSL_VERIFY_PEER)
|
|
328
329
|
wolfssl.loadTrustedCerts(this._ctx)
|
|
329
330
|
}
|
|
330
331
|
this._ssl = wolfssl.wolfSSL_new(this._ctx)
|
|
@@ -332,7 +333,7 @@ class WebSocketImpl {
|
|
|
332
333
|
wolfssl.wolfSSL_set_fd(this._ssl, sock.get_fd(fd))
|
|
333
334
|
const sniHost = host
|
|
334
335
|
if (sniHost) {
|
|
335
|
-
wolfssl.wolfSSL_UseSNI(this._ssl,
|
|
336
|
+
wolfssl.wolfSSL_UseSNI(this._ssl, SniType.WOLFSSL_SNI_HOST_NAME, sniHost)
|
|
336
337
|
if (this._options.rejectUnauthorized !== false) {
|
|
337
338
|
wolfssl.wolfSSL_check_domain_name(this._ssl, sniHost)
|
|
338
339
|
}
|
|
@@ -344,17 +345,17 @@ class WebSocketImpl {
|
|
|
344
345
|
}
|
|
345
346
|
}
|
|
346
347
|
|
|
347
|
-
if ((event.lNetworkEvents &
|
|
348
|
+
if ((event.lNetworkEvents & FdEvent.FD_READ) || (event.lNetworkEvents & FdEvent.FD_WRITE)) {
|
|
348
349
|
if (state === 'handshake') {
|
|
349
350
|
if (!this._ssl) { doError(new Error('TLS not initialized')); return }
|
|
350
351
|
const ret = wolfssl.wolfSSL_connect(this._ssl)
|
|
351
|
-
if (ret ===
|
|
352
|
+
if (ret === ReturnCode.SSL_SUCCESS) {
|
|
352
353
|
this._sendRawStr(request)
|
|
353
354
|
state = 'request'
|
|
354
355
|
} else {
|
|
355
356
|
const err = wolfssl.wolfSSL_get_error(this._ssl, ret)
|
|
356
|
-
if (err !==
|
|
357
|
-
err !==
|
|
357
|
+
if (err !== WolfsslErrorCode.WOLFSSL_ERROR_WANT_READ &&
|
|
358
|
+
err !== WolfsslErrorCode.WOLFSSL_ERROR_WANT_WRITE) {
|
|
358
359
|
doError(new Error('TLS handshake failed: ' + err))
|
|
359
360
|
}
|
|
360
361
|
}
|
|
@@ -369,9 +370,9 @@ class WebSocketImpl {
|
|
|
369
370
|
data = buf.slice(0, n)
|
|
370
371
|
} else {
|
|
371
372
|
const err = wolfssl.wolfSSL_get_error(this._ssl, n)
|
|
372
|
-
if (err ===
|
|
373
|
-
err ===
|
|
374
|
-
if (n === 0 || err ===
|
|
373
|
+
if (err === WolfsslErrorCode.WOLFSSL_ERROR_WANT_READ ||
|
|
374
|
+
err === WolfsslErrorCode.WOLFSSL_ERROR_WANT_WRITE) break
|
|
375
|
+
if (n === 0 || err === WolfsslErrorCode.WOLFSSL_ERROR_ZERO_RETURN) break
|
|
375
376
|
doError(new Error('TLS read failed: ' + err))
|
|
376
377
|
return
|
|
377
378
|
}
|
|
@@ -431,7 +432,7 @@ class WebSocketImpl {
|
|
|
431
432
|
}
|
|
432
433
|
}
|
|
433
434
|
|
|
434
|
-
if (event.lNetworkEvents &
|
|
435
|
+
if (event.lNetworkEvents & FdEvent.FD_CLOSE) {
|
|
435
436
|
if (state !== 'open') {
|
|
436
437
|
doError(new Error('Connection closed'))
|
|
437
438
|
}
|
|
@@ -477,9 +478,9 @@ class WebSocketImpl {
|
|
|
477
478
|
data = buf.slice(0, n)
|
|
478
479
|
} else {
|
|
479
480
|
const err = wolfssl.wolfSSL_get_error(this._ssl, n)
|
|
480
|
-
if (err ===
|
|
481
|
-
err ===
|
|
482
|
-
if (n === 0 || err ===
|
|
481
|
+
if (err === WolfsslErrorCode.WOLFSSL_ERROR_WANT_READ ||
|
|
482
|
+
err === WolfsslErrorCode.WOLFSSL_ERROR_WANT_WRITE) break
|
|
483
|
+
if (n === 0 || err === WolfsslErrorCode.WOLFSSL_ERROR_ZERO_RETURN) break
|
|
483
484
|
this._fireError(new Error('TLS read failed: ' + err))
|
|
484
485
|
if (this._state !== State.CLOSED) this._setState(State.CLOSED)
|
|
485
486
|
return
|
package/lib/windows/advapi32.js
CHANGED
|
@@ -4,13 +4,13 @@ import { bind } from '../ffi/bind.js';
|
|
|
4
4
|
const b = (name, sig) => bind('advapi32.dll', name, sig);
|
|
5
5
|
/** 创建/打开子键(子键不存在则创建,含中间层级)
|
|
6
6
|
* @returns 0 = ERROR_SUCCESS
|
|
7
|
-
* @param args_0 hKey 父键:
|
|
7
|
+
* @param args_0 hKey 父键:HKey.CURRENT_USER / LOCAL_MACHINE 预定义键,或本族
|
|
8
8
|
* Open/Create 返回的真实句柄(此位双来源,不标 @HKey——裸位收两种)
|
|
9
9
|
* @param args_1 lpSubKey 子键路径('Software\\X\\Y',可 NULL = 打开 hKey 自身副本)
|
|
10
10
|
* @param args_2 Reserved 保留,恒 0
|
|
11
11
|
* @param args_3 lpClass 键类名(一般 NULL)
|
|
12
12
|
* @param args_4 dwOptions 保留属性(恒 0)
|
|
13
|
-
* @param args_5 samDesired 访问掩码
|
|
13
|
+
* @param args_5 samDesired 访问掩码 RegAccess.READ / SET_VALUE(标准组合常量按成员收录)
|
|
14
14
|
* @param args_6 lpSecurityAttributes 安全描述符(一般 NULL)
|
|
15
15
|
* @param args_7 phkResult 出参:键句柄(PtrArrayBuffer(8),readPtr 按架构读回)
|
|
16
16
|
* @param args_8 lpdwDisposition 出参:新建/已存在标记(可 NULL) */
|
|
@@ -20,7 +20,7 @@ export const RegCreateKeyEx = /*@__PURE__*/ b('RegCreateKeyExW', '<>ptr <WCHAR>p
|
|
|
20
20
|
* @param args_0 hKey 父键(同 RegCreateKeyEx 的双来源语义)
|
|
21
21
|
* @param args_1 lpSubKey 子键路径(NULL = 打开 hKey 自身副本)
|
|
22
22
|
* @param args_2 ulOptions 保留,恒 0
|
|
23
|
-
* @param args_3 samDesired 访问掩码
|
|
23
|
+
* @param args_3 samDesired 访问掩码 RegAccess.READ / SET_VALUE
|
|
24
24
|
* @param args_4 phkResult 出参:键句柄 */
|
|
25
25
|
export const RegOpenKeyEx = /*@__PURE__*/ b('RegOpenKeyExW', '<>ptr <WCHAR>ptr u32 u32@RegAccess <BYTE>ptr -> i32');
|
|
26
26
|
/** 关闭键句柄;只关 Open/Create 返回的真实句柄——预定义键(HKEY_CURRENT_USER 等)
|
|
@@ -29,16 +29,16 @@ export const RegOpenKeyEx = /*@__PURE__*/ b('RegOpenKeyExW', '<>ptr <WCHAR>ptr u
|
|
|
29
29
|
export const RegCloseKey = /*@__PURE__*/ b('RegCloseKey', '<>ptr -> i32');
|
|
30
30
|
/** 写键值
|
|
31
31
|
* @returns 0 = ERROR_SUCCESS
|
|
32
|
-
* @param args_0 hKey 键句柄(须 KEY_SET_VALUE 权限,含于
|
|
32
|
+
* @param args_0 hKey 键句柄(须 KEY_SET_VALUE 权限,含于 RegAccess.SET_VALUE)
|
|
33
33
|
* @param args_1 lpValueName 值名(NULL = 键的默认值)
|
|
34
34
|
* @param args_2 Reserved 保留,恒 0
|
|
35
|
-
* @param args_3 dwType 值类型
|
|
35
|
+
* @param args_3 dwType 值类型 RegType.SZ(UTF-16 字符串)
|
|
36
36
|
* @param args_4 lpData 数据缓冲(REG_SZ:UTF-16LE 含结尾 NUL)
|
|
37
37
|
* @param args_5 cbData 数据字节数(REG_SZ = (字符数+1)*2) */
|
|
38
38
|
export const RegSetValueEx = /*@__PURE__*/ b('RegSetValueExW', '<>ptr <WCHAR>ptr u32 u32@RegType <BYTE>ptr u32 -> i32');
|
|
39
39
|
/** 读键值(两跳模式:第一跳 lpData=NULL 取尺寸/类型,第二跳按尺寸带缓冲读数据)
|
|
40
40
|
* @returns 0 = ERROR_SUCCESS;2 = ERROR_FILE_NOT_FOUND(值不存在)
|
|
41
|
-
* @param args_0 hKey 键句柄(须 KEY_QUERY_VALUE 权限,含于
|
|
41
|
+
* @param args_0 hKey 键句柄(须 KEY_QUERY_VALUE 权限,含于 RegAccess.READ)
|
|
42
42
|
* @param args_1 lpValueName 值名(NULL = 键的默认值)
|
|
43
43
|
* @param args_2 lpReserved 保留,恒 NULL
|
|
44
44
|
* @param args_3 lpType 出参:值类型(可 NULL)
|
|
@@ -46,7 +46,7 @@ export const RegSetValueEx = /*@__PURE__*/ b('RegSetValueExW', '<>ptr <WCHAR>ptr
|
|
|
46
46
|
* @param args_5 lpcbData 双向:入 = lpData 缓冲字节数(须预写)、出 = 实际字节数 */
|
|
47
47
|
export const RegQueryValueEx = /*@__PURE__*/ b('RegQueryValueExW', '<>ptr <WCHAR>ptr <>ptr <BYTE>ptr <BYTE>ptr <BYTE>ptr -> i32');
|
|
48
48
|
/** 删除子键(连值一起删);须父键 KEY_CREATE_SUB_KEY 权限——自己的 HKCU 直接传
|
|
49
|
-
*
|
|
49
|
+
* HKey.CURRENT_USER 即可
|
|
50
50
|
* @returns 0 = ERROR_SUCCESS;2 = 子键不存在
|
|
51
51
|
* @param args_0 hKey 父键
|
|
52
52
|
* @param args_1 lpSubKey 要删的子键路径(不可 NULL) */
|