quickwin 1.2.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +3 -3
- package/README.md +21 -24
- package/examples/PdfCanvas.js +8 -37
- package/examples/PdfCanvas.tsx +11 -41
- package/examples/exec_server.js +20054 -1423
- 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 +31 -73
- package/examples/pdf_preview2.ts +33 -76
- package/examples/pdf_viewer.js +1496 -616
- package/examples/pdf_viewer.tsx +23 -64
- package/examples/setres.js +22 -47
- package/examples/setres.ts +23 -57
- package/examples/test_gallery.js +1491 -525
- package/examples/test_react_lazy.js +1455 -500
- package/examples/test_react_listbox.js +1454 -499
- package/examples/test_root_window.js +1450 -495
- package/examples/test_tab.js +1455 -500
- package/lib/abort.js +70 -0
- package/lib/abort.ts +69 -0
- package/lib/certs.js +214 -0
- package/lib/certs.ts +224 -0
- package/lib/exec-log.js +15 -0
- package/lib/exec-log.ts +30 -0
- package/lib/fetch.js +37 -4
- package/lib/fetch.ts +35 -4
- package/lib/ffi/bind.js +352 -0
- package/lib/ffi/bind.ts +442 -0
- package/lib/ffi/ctype.js +168 -0
- package/lib/ffi/ctype.ts +331 -0
- package/lib/ffi/index.js +6 -0
- package/lib/ffi/index.ts +6 -0
- package/lib/ffi/struct.js +412 -0
- package/lib/ffi/struct.ts +664 -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 +20 -33
- package/lib/react-qw/components/Input.js +3 -10
- package/lib/react-qw/components/Link.js +7 -22
- package/lib/react-qw/components/ListView.js +80 -141
- package/lib/react-qw/components/PathPicker.js +36 -80
- 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 +15 -20
- package/lib/react-qw/components/Tooltip.js +21 -20
- package/lib/react-qw/components/TreeView.js +14 -47
- package/lib/react-qw/index.js +4 -2
- package/lib/react-qw/index.ts +4 -2
- package/lib/react-qw/nmhdr.js +5 -0
- package/lib/react-qw/nmhdr.ts +7 -0
- 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 +18 -35
- package/lib/text-measure.ts +20 -37
- package/lib/websocket.js +12 -2
- package/lib/websocket.ts +15 -2
- package/lib/windows/comctl32.js +18 -0
- package/lib/windows/comctl32.ts +20 -0
- package/lib/windows/comdlg32.js +7 -0
- package/lib/windows/comdlg32.ts +9 -0
- package/lib/windows/gdi32.js +90 -0
- package/lib/windows/gdi32.ts +97 -0
- package/lib/windows/kernel32.js +66 -0
- package/lib/windows/kernel32.ts +76 -0
- package/lib/windows/ntdll.js +8 -0
- package/lib/windows/ntdll.ts +10 -0
- package/lib/windows/ole32.js +7 -0
- package/lib/windows/ole32.ts +9 -0
- package/lib/windows/shell32.js +11 -0
- package/lib/windows/shell32.ts +14 -0
- package/lib/windows/structs.js +384 -0
- package/lib/windows/structs.ts +422 -0
- package/lib/windows/user32.js +469 -0
- package/lib/windows/user32.ts +502 -0
- package/package.json +1 -1
- package/quickwin.d.ts +22 -33
- package/quickwin_const.d.ts +1 -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 +14 -4
- package/test/run.ts +15 -5
- package/test/test_basic_fetch.js +8 -0
- package/test/test_basic_fetch.ts +9 -0
- package/test/test_ffi.js +33 -47
- package/test/test_ffi.ts +41 -60
- package/test/test_ffi_abi.js +235 -0
- package/test/test_ffi_abi.ts +218 -0
- package/test/test_ffi_bind.js +572 -0
- package/test/test_ffi_bind.ts +597 -0
- package/test/test_ffi_struct.js +745 -0
- package/test/test_ffi_struct.ts +798 -0
- 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_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 +70 -8
- package/test/test_net_fetch.ts +69 -7
- package/test/test_net_websocket.js +1 -1
- package/test/test_net_websocket.ts +1 -1
- package/test/test_react_complex.js +1465 -510
- package/test/test_react_counter.js +1455 -500
- package/test/test_react_flex.js +1475 -513
- package/test/test_react_hidden.js +1458 -503
- package/test/test_react_listview_link.js +1455 -500
- package/test/test_react_notify.js +18534 -0
- package/test/test_react_render.js +1455 -500
- package/test/test_wolfssl_read.js +3 -2
- package/test/test_wolfssl_read.ts +3 -1
- 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/examples/pdf_viewer.tsx
CHANGED
|
@@ -1,76 +1,35 @@
|
|
|
1
|
+
import { MaybePtr, PtrArrayBuffer } from '../lib/ffi/ctype.js'
|
|
1
2
|
import '../lib/polyfill.js'
|
|
2
3
|
import * as std from 'std'
|
|
3
4
|
import * as gui from 'gui'
|
|
4
|
-
import * as win from 'win'
|
|
5
|
-
import * as ffi from 'ffi'
|
|
6
5
|
import type { Document, Page, Pixmap } from '../vendor/mupdf-wasm/mupdf.js'
|
|
7
6
|
import { useState } from 'react'
|
|
8
7
|
import { render, Button, Input, ScrollView } from '../lib/react-qw/index.js'
|
|
8
|
+
import { WCHAR } from '../lib/ffi/bind.js'
|
|
9
9
|
import { PdfCanvas } from './PdfCanvas.js'
|
|
10
|
+
import { OPENFILENAMEW } from '../lib/windows/structs.js'
|
|
11
|
+
import { GetOpenFileName } from '../lib/windows/comdlg32.js'
|
|
10
12
|
|
|
11
13
|
type MuPdf = typeof import('../vendor/mupdf-wasm/mupdf.js')
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
const FFI_PTR = ffi.FFI_TYPE_POINTER
|
|
29
|
-
const FFI_U32 = ffi.FFI_TYPE_UINT32
|
|
30
|
-
|
|
31
|
-
function strToWide(str: string): ArrayBuffer {
|
|
32
|
-
const buf = new ArrayBuffer((str.length + 1) * 2)
|
|
33
|
-
const dv = new DataView(buf)
|
|
34
|
-
for (let i = 0; i < str.length; i++) dv.setUint16(i * 2, str.charCodeAt(i), true)
|
|
35
|
-
return buf
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function wideToStr(buf: ArrayBuffer): string {
|
|
39
|
-
const dv = new DataView(buf)
|
|
40
|
-
const chars: number[] = []
|
|
41
|
-
for (let i = 0; i < buf.byteLength; i += 2) {
|
|
42
|
-
const c = dv.getUint16(i, true)
|
|
43
|
-
if (c === 0) break
|
|
44
|
-
chars.push(c)
|
|
45
|
-
}
|
|
46
|
-
return String.fromCharCode(...chars)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function setPtr(dv: DataView, off: number, ptr: number): void {
|
|
50
|
-
dv.setUint32(off, ptr & 0xFFFFFFFF, true)
|
|
51
|
-
dv.setUint32(off + 4, Math.floor(ptr / 0x100000000), true)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function openPdfFileDialog(owner: number): string | null {
|
|
55
|
-
const structBuf = new ArrayBuffer(152)
|
|
56
|
-
const sv = new DataView(structBuf)
|
|
57
|
-
const fileBuf = new ArrayBuffer(260 * 2)
|
|
58
|
-
const filterWide = strToWide('PDF Files\0*.pdf\0All Files\0*.*\0\0')
|
|
59
|
-
|
|
60
|
-
sv.setUint32(0, 152, true)
|
|
61
|
-
sv.setUint32(8, owner & 0xFFFFFFFF, true)
|
|
62
|
-
sv.setUint32(12, Math.floor(owner / 0x100000000), true)
|
|
63
|
-
|
|
64
|
-
setPtr(sv, 24, ffi.bufferPtr(filterWide))
|
|
65
|
-
setPtr(sv, 48, ffi.bufferPtr(fileBuf))
|
|
66
|
-
sv.setUint32(56, 260, true)
|
|
67
|
-
|
|
68
|
-
sv.setUint32(96, 0x1000 | 0x0800 | 0x0004, true)
|
|
69
|
-
|
|
70
|
-
const ret = ffi.ffiCall(GetOpenFileNameW_, [FFI_PTR], [structBuf], FFI_U32)
|
|
15
|
+
function openPdfFileDialog(owner: MaybePtr<'HWND'>): string | null {
|
|
16
|
+
const fileBuf = WCHAR.alloc(260)
|
|
17
|
+
const filterWide = WCHAR.encode('PDF Files\0*.pdf\0All Files\0*.*\0\0')
|
|
18
|
+
// 缺省字段跳过 = fresh buffer 上留 0
|
|
19
|
+
const ofn: PtrArrayBuffer<'OPENFILENAMEW'> & { __keep?: ArrayBuffer[] } = OPENFILENAMEW.encode({
|
|
20
|
+
lStructSize: OPENFILENAMEW.size,
|
|
21
|
+
hwndOwner: owner,
|
|
22
|
+
lpstrFilter: filterWide.ptr,
|
|
23
|
+
lpstrFile: fileBuf.ptr,
|
|
24
|
+
nMaxFile: 260,
|
|
25
|
+
Flags: 0x1000 | 0x0800 | 0x0004,
|
|
26
|
+
})
|
|
27
|
+
ofn.__keep = [fileBuf, filterWide]
|
|
28
|
+
|
|
29
|
+
const ret = GetOpenFileName(ofn)
|
|
71
30
|
if (!ret) return null
|
|
72
31
|
|
|
73
|
-
const path =
|
|
32
|
+
const path = WCHAR.decode(fileBuf)
|
|
74
33
|
return path.length > 0 ? path : null
|
|
75
34
|
}
|
|
76
35
|
|
|
@@ -98,7 +57,7 @@ async function loadMupdf(): Promise<MuPdf | null> {
|
|
|
98
57
|
}
|
|
99
58
|
|
|
100
59
|
interface PixmapInfo {
|
|
101
|
-
data:
|
|
60
|
+
data: PtrArrayBuffer<string>
|
|
102
61
|
w: number
|
|
103
62
|
h: number
|
|
104
63
|
}
|
|
@@ -159,7 +118,7 @@ function renderPdfPage(mupdf: MuPdf, filePath: string, pageIndex: number): Pixma
|
|
|
159
118
|
const dibStride = Math.floor((w * 3 + 3) / 4) * 4
|
|
160
119
|
|
|
161
120
|
const dibSize = h * dibStride
|
|
162
|
-
const dibBuffer = new
|
|
121
|
+
const dibBuffer = new PtrArrayBuffer(dibSize)
|
|
163
122
|
const dib = new Uint8Array(dibBuffer)
|
|
164
123
|
|
|
165
124
|
for (let y = 0; y < h; y++) {
|
|
@@ -186,7 +145,7 @@ function renderPdfPage(mupdf: MuPdf, filePath: string, pageIndex: number): Pixma
|
|
|
186
145
|
}
|
|
187
146
|
}
|
|
188
147
|
|
|
189
|
-
function App({ mupdf, mainHwnd: hwnd }: { mupdf: MuPdf; mainHwnd:
|
|
148
|
+
function App({ mupdf, mainHwnd: hwnd }: { mupdf: MuPdf; mainHwnd: gui.HWND }) {
|
|
190
149
|
const [filePath, setFilePath] = useState('')
|
|
191
150
|
const [currentPage, setCurrentPage] = useState(0)
|
|
192
151
|
const [pixmap, setPixmap] = useState<PixmapInfo | undefined>(undefined)
|
package/examples/setres.js
CHANGED
|
@@ -1,24 +1,8 @@
|
|
|
1
1
|
import * as std from 'std';
|
|
2
2
|
import * as gui from 'gui';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
if (!user32) {
|
|
7
|
-
print('LoadLibrary user32 failed');
|
|
8
|
-
std.exit(1);
|
|
9
|
-
}
|
|
10
|
-
function loadProc(lib, name) {
|
|
11
|
-
const ptr = win.GetProcAddress(lib, name);
|
|
12
|
-
if (!ptr) {
|
|
13
|
-
print('GetProcAddress ' + name + ' failed');
|
|
14
|
-
std.exit(1);
|
|
15
|
-
}
|
|
16
|
-
return ptr;
|
|
17
|
-
}
|
|
18
|
-
const EnumDisplaySettingsA = loadProc(user32, 'EnumDisplaySettingsA');
|
|
19
|
-
const ChangeDisplaySettingsA = loadProc(user32, 'ChangeDisplaySettingsA');
|
|
20
|
-
/** DEVMODEA used by EnumDisplaySettings; driver reports actual dmSize (often 124). */
|
|
21
|
-
const DEVMODE_SIZE = 220;
|
|
3
|
+
import { NULL } from '../lib/ffi/ctype.js';
|
|
4
|
+
import { ChangeDisplaySettings, EnumDisplaySettings } from '../lib/windows/user32.js';
|
|
5
|
+
import { DEVMODEW } from '../lib/windows/structs.js';
|
|
22
6
|
const DM_PELSWIDTH = 0x00800000;
|
|
23
7
|
const DM_PELSHEIGHT = 0x01000000;
|
|
24
8
|
const ENUM_CURRENT_SETTINGS = -1;
|
|
@@ -35,35 +19,27 @@ const DISP_CHANGE = {
|
|
|
35
19
|
[-6]: 'BADDUALVIEW',
|
|
36
20
|
};
|
|
37
21
|
function newDevMode() {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return buf;
|
|
41
|
-
}
|
|
42
|
-
function enumMode(modeNum, buf) {
|
|
43
|
-
return ffi.ffiCall(EnumDisplaySettingsA, [ffi.FFI_TYPE_POINTER, ffi.FFI_TYPE_SINT32, ffi.FFI_TYPE_POINTER], [null, modeNum, buf], ffi.FFI_TYPE_SINT32);
|
|
44
|
-
}
|
|
45
|
-
function getPels(dv) {
|
|
46
|
-
return [dv.getUint32(108, true), dv.getUint32(112, true), dv.getUint32(120, true)];
|
|
22
|
+
// dmSize = 结构自身大小是 Win32 要求(否则 API 拒绝);其余字段由 Enum 就地填充
|
|
23
|
+
return DEVMODEW.encode({ dmSize: DEVMODEW.size });
|
|
47
24
|
}
|
|
48
25
|
function applyFromCurrent(w, h, flags, label) {
|
|
49
26
|
const dm = newDevMode();
|
|
50
|
-
if (!
|
|
27
|
+
if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, dm.ptr)) {
|
|
51
28
|
print(label + ': EnumDisplaySettings CURRENT failed');
|
|
52
29
|
return null;
|
|
53
30
|
}
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const ret = ffi.ffiCall(ChangeDisplaySettingsA, [ffi.FFI_TYPE_POINTER, ffi.FFI_TYPE_UINT32], [dm, flags], ffi.FFI_TYPE_SINT32);
|
|
31
|
+
const cur = DEVMODEW.decode(dm);
|
|
32
|
+
print(label + ': base size=' + cur.dmSize + ' extra=' + cur.dmDriverExtra +
|
|
33
|
+
' fields=0x' + cur.dmFields.toString(16) +
|
|
34
|
+
' ' + cur.dmPelsWidth + 'x' + cur.dmPelsHeight +
|
|
35
|
+
'@' + cur.dmDisplayFrequency + ' bpp=' + cur.dmBitsPerPel);
|
|
36
|
+
// 复用同一 buffer 原地改三项(encode 缺省字段跳过 = 保留 Enum 填的其余项)
|
|
37
|
+
DEVMODEW.encode({
|
|
38
|
+
dmFields: cur.dmFields | DM_PELSWIDTH | DM_PELSHEIGHT,
|
|
39
|
+
dmPelsWidth: w,
|
|
40
|
+
dmPelsHeight: h,
|
|
41
|
+
}, dm);
|
|
42
|
+
const ret = ChangeDisplaySettings(dm.ptr, flags);
|
|
67
43
|
print(label + ': ChangeDisplaySettings ' + w + 'x' + h +
|
|
68
44
|
' flags=0x' + flags.toString(16) + ' ret=' + ret + ' (' + (DISP_CHANGE[ret] ?? '?') + ')');
|
|
69
45
|
return ret;
|
|
@@ -78,13 +54,12 @@ print('before GetScreenSize: ' + JSON.stringify(gui.GetScreenSize()));
|
|
|
78
54
|
const probe = newDevMode();
|
|
79
55
|
const modes32 = [];
|
|
80
56
|
for (let i = 0; i < 200; i++) {
|
|
81
|
-
if (!
|
|
57
|
+
if (!EnumDisplaySettings(NULL, i, probe.ptr))
|
|
82
58
|
break;
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
59
|
+
const dm = DEVMODEW.decode(probe);
|
|
60
|
+
if (dm.dmBitsPerPel !== 32)
|
|
85
61
|
continue;
|
|
86
|
-
|
|
87
|
-
modes32.push(p[0] + 'x' + p[1] + '@' + p[2]);
|
|
62
|
+
modes32.push(dm.dmPelsWidth + 'x' + dm.dmPelsHeight + '@' + dm.dmDisplayFrequency);
|
|
88
63
|
}
|
|
89
64
|
print('32bpp modes sample: ' + modes32.slice(0, 25).join(', ') + (modes32.length > 25 ? ' ...' : ''));
|
|
90
65
|
const testRet = applyFromCurrent(targetW, targetH, CDS_TEST, 'TEST');
|
package/examples/setres.ts
CHANGED
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
import * as std from 'std'
|
|
2
2
|
import * as gui from 'gui'
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import { NULL } from '../lib/ffi/ctype.js'
|
|
4
|
+
import { ChangeDisplaySettings, EnumDisplaySettings } from '../lib/windows/user32.js'
|
|
5
|
+
import { DEVMODEW } from '../lib/windows/structs.js'
|
|
5
6
|
|
|
6
|
-
const user32 = win.LoadLibrary('user32.dll')
|
|
7
|
-
if (!user32) { print('LoadLibrary user32 failed'); std.exit(1) }
|
|
8
|
-
|
|
9
|
-
function loadProc(lib: win.HMODULE, name: string): number {
|
|
10
|
-
const ptr = win.GetProcAddress(lib, name)
|
|
11
|
-
if (!ptr) { print('GetProcAddress ' + name + ' failed'); std.exit(1) }
|
|
12
|
-
return ptr
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const EnumDisplaySettingsA = loadProc(user32, 'EnumDisplaySettingsA')
|
|
16
|
-
const ChangeDisplaySettingsA = loadProc(user32, 'ChangeDisplaySettingsA')
|
|
17
|
-
|
|
18
|
-
/** DEVMODEA used by EnumDisplaySettings; driver reports actual dmSize (often 124). */
|
|
19
|
-
const DEVMODE_SIZE = 220
|
|
20
7
|
const DM_PELSWIDTH = 0x00800000
|
|
21
8
|
const DM_PELSHEIGHT = 0x01000000
|
|
22
9
|
const ENUM_CURRENT_SETTINGS = -1
|
|
@@ -34,51 +21,31 @@ const DISP_CHANGE: Record<number, string> = {
|
|
|
34
21
|
[-6]: 'BADDUALVIEW',
|
|
35
22
|
}
|
|
36
23
|
|
|
37
|
-
function newDevMode()
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return buf
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function enumMode(modeNum: number, buf: ArrayBuffer): number {
|
|
44
|
-
return ffi.ffiCall(
|
|
45
|
-
EnumDisplaySettingsA,
|
|
46
|
-
[ffi.FFI_TYPE_POINTER, ffi.FFI_TYPE_SINT32, ffi.FFI_TYPE_POINTER],
|
|
47
|
-
[null, modeNum, buf],
|
|
48
|
-
ffi.FFI_TYPE_SINT32,
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function getPels(dv: DataView): [number, number, number] {
|
|
53
|
-
return [dv.getUint32(108, true), dv.getUint32(112, true), dv.getUint32(120, true)]
|
|
24
|
+
function newDevMode() {
|
|
25
|
+
// dmSize = 结构自身大小是 Win32 要求(否则 API 拒绝);其余字段由 Enum 就地填充
|
|
26
|
+
return DEVMODEW.encode({ dmSize: DEVMODEW.size })
|
|
54
27
|
}
|
|
55
28
|
|
|
56
29
|
function applyFromCurrent(w: number, h: number, flags: number, label: string): number | null {
|
|
57
30
|
const dm = newDevMode()
|
|
58
|
-
if (!
|
|
31
|
+
if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, dm.ptr)) {
|
|
59
32
|
print(label + ': EnumDisplaySettings CURRENT failed')
|
|
60
33
|
return null
|
|
61
34
|
}
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const bpp = dv.getUint32(104, true)
|
|
68
|
-
const freq = dv.getUint32(120, true)
|
|
69
|
-
print(label + ': base size=' + size + ' extra=' + extra + ' fields=0x' + fields.toString(16) +
|
|
70
|
-
' ' + before[0] + 'x' + before[1] + '@' + freq + ' bpp=' + bpp)
|
|
35
|
+
const cur = DEVMODEW.decode(dm)
|
|
36
|
+
print(label + ': base size=' + cur.dmSize + ' extra=' + cur.dmDriverExtra +
|
|
37
|
+
' fields=0x' + cur.dmFields.toString(16) +
|
|
38
|
+
' ' + cur.dmPelsWidth + 'x' + cur.dmPelsHeight +
|
|
39
|
+
'@' + cur.dmDisplayFrequency + ' bpp=' + cur.dmBitsPerPel)
|
|
71
40
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
41
|
+
// 复用同一 buffer 原地改三项(encode 缺省字段跳过 = 保留 Enum 填的其余项)
|
|
42
|
+
DEVMODEW.encode({
|
|
43
|
+
dmFields: cur.dmFields | DM_PELSWIDTH | DM_PELSHEIGHT,
|
|
44
|
+
dmPelsWidth: w,
|
|
45
|
+
dmPelsHeight: h,
|
|
46
|
+
}, dm)
|
|
75
47
|
|
|
76
|
-
const ret =
|
|
77
|
-
ChangeDisplaySettingsA,
|
|
78
|
-
[ffi.FFI_TYPE_POINTER, ffi.FFI_TYPE_UINT32],
|
|
79
|
-
[dm, flags],
|
|
80
|
-
ffi.FFI_TYPE_SINT32,
|
|
81
|
-
)
|
|
48
|
+
const ret = ChangeDisplaySettings(dm.ptr, flags)
|
|
82
49
|
print(label + ': ChangeDisplaySettings ' + w + 'x' + h +
|
|
83
50
|
' flags=0x' + flags.toString(16) + ' ret=' + ret + ' (' + (DISP_CHANGE[ret] ?? '?') + ')')
|
|
84
51
|
return ret
|
|
@@ -96,11 +63,10 @@ print('before GetScreenSize: ' + JSON.stringify(gui.GetScreenSize()))
|
|
|
96
63
|
const probe = newDevMode()
|
|
97
64
|
const modes32: string[] = []
|
|
98
65
|
for (let i = 0; i < 200; i++) {
|
|
99
|
-
if (!
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
102
|
-
|
|
103
|
-
modes32.push(p[0] + 'x' + p[1] + '@' + p[2])
|
|
66
|
+
if (!EnumDisplaySettings(NULL, i, probe.ptr)) break
|
|
67
|
+
const dm = DEVMODEW.decode(probe)
|
|
68
|
+
if (dm.dmBitsPerPel !== 32) continue
|
|
69
|
+
modes32.push(dm.dmPelsWidth + 'x' + dm.dmPelsHeight + '@' + dm.dmDisplayFrequency)
|
|
104
70
|
}
|
|
105
71
|
print('32bpp modes sample: ' + modes32.slice(0, 25).join(', ') + (modes32.length > 25 ? ' ...' : ''))
|
|
106
72
|
|