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_preview2.ts
CHANGED
|
@@ -1,67 +1,26 @@
|
|
|
1
|
+
import { 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 { assertNonNullable } from '../lib/assert.js'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const _user32 = win.LoadLibrary('user32.dll')
|
|
14
|
-
const _gdi32 = win.LoadLibrary('gdi32.dll')
|
|
15
|
-
const _comdlg32 = win.LoadLibrary('comdlg32.dll')
|
|
7
|
+
import { WCHAR } from '../lib/ffi/bind.js'
|
|
8
|
+
import { BITMAPINFOHEADER, OPENFILENAMEW } from '../lib/windows/structs.js'
|
|
9
|
+
import { GetOpenFileName } from '../lib/windows/comdlg32.js'
|
|
10
|
+
import { GetDC, ReleaseDC } from '../lib/windows/user32.js'
|
|
11
|
+
import { PatBlt, SetDIBitsToDevice } from '../lib/windows/gdi32.js'
|
|
16
12
|
|
|
17
13
|
type MuPdf = typeof import('../vendor/mupdf-wasm/mupdf.js')
|
|
18
|
-
if (!(_user32 && _gdi32 && _comdlg32)) std.exit(0)
|
|
19
|
-
|
|
20
|
-
function loadProc(lib: win.HMODULE, name: string): number {
|
|
21
|
-
const ptr = win.GetProcAddress(lib, name)
|
|
22
|
-
if (!ptr) { std.printf('Error: cannot load %s\n', name); std.exit(1) }
|
|
23
|
-
return ptr
|
|
24
|
-
}
|
|
25
14
|
|
|
26
|
-
const GetOpenFileNameW = loadProc(_comdlg32, 'GetOpenFileNameW')
|
|
27
|
-
const SetDIBitsToDevice = loadProc(_gdi32, 'SetDIBitsToDevice')
|
|
28
|
-
const GetDC = loadProc(_user32, 'GetDC')
|
|
29
|
-
const ReleaseDC = loadProc(_user32, 'ReleaseDC')
|
|
30
|
-
const PatBlt = loadProc(_gdi32, 'PatBlt')
|
|
31
15
|
const WHITENESS = 0x00FF0062
|
|
32
16
|
|
|
33
|
-
function makeBitmapInfo(w: number, h: number)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
bv.setUint32(0, 40, true)
|
|
37
|
-
bv.setInt32(4, w, true)
|
|
38
|
-
bv.setInt32(8, -h, true)
|
|
39
|
-
bv.setUint16(12, 1, true)
|
|
40
|
-
bv.setUint16(14, 24, true)
|
|
41
|
-
return bmi
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function strToWide(str: string): ArrayBuffer {
|
|
45
|
-
return new TextEncoder('utf-16le').encode(str + '\0').buffer
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function wideToStr(buf: ArrayBuffer): string {
|
|
49
|
-
const dv = new DataView(buf)
|
|
50
|
-
const chars: number[] = []
|
|
51
|
-
for (let i = 0; i < buf.byteLength; i += 2) {
|
|
52
|
-
const c = dv.getUint16(i, true); if (c === 0) break
|
|
53
|
-
chars.push(c)
|
|
54
|
-
}
|
|
55
|
-
return String.fromCharCode(...chars)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function setPtr(dv: DataView, off: number, ptr: number): void {
|
|
59
|
-
dv.setUint32(off, ptr & 0xFFFFFFFF, true)
|
|
60
|
-
dv.setUint32(off + 4, Math.floor(ptr / 0x100000000), true)
|
|
17
|
+
function makeBitmapInfo(w: number, h: number) {
|
|
18
|
+
// biHeight 负 = 自顶向下(DIB 原点左上);biCompression 缺省 0 = BI_RGB 无压缩
|
|
19
|
+
return BITMAPINFOHEADER.encode({ biSize: BITMAPINFOHEADER.size, biWidth: w, biHeight: -h, biPlanes: 1, biBitCount: 24 })
|
|
61
20
|
}
|
|
62
21
|
|
|
63
22
|
interface PixmapInfo {
|
|
64
|
-
data:
|
|
23
|
+
data: PtrArrayBuffer<string>; w: number; h: number
|
|
65
24
|
}
|
|
66
25
|
|
|
67
26
|
let hwndMain: gui.HWND | null = null
|
|
@@ -117,7 +76,8 @@ function renderPdfPage(mupdf: MuPdf, filePath: string, pageIndex: number): Pixma
|
|
|
117
76
|
const srcStride = pixmap.getStride()
|
|
118
77
|
const w = pixmap.getWidth(), h = pixmap.getHeight()
|
|
119
78
|
const dibStride = Math.floor((w * 3 + 3) / 4) * 4
|
|
120
|
-
const
|
|
79
|
+
const dibBuffer = new PtrArrayBuffer(h * dibStride)
|
|
80
|
+
const dib = new Uint8Array(dibBuffer)
|
|
121
81
|
for (let y = 0; y < h; y++) {
|
|
122
82
|
const srcOff = y * srcStride, dstOff = y * dibStride
|
|
123
83
|
for (let x = 0; x < w; x++) {
|
|
@@ -126,25 +86,27 @@ function renderPdfPage(mupdf: MuPdf, filePath: string, pageIndex: number): Pixma
|
|
|
126
86
|
}
|
|
127
87
|
}
|
|
128
88
|
const totalPages = cachedDoc.countPages()
|
|
129
|
-
return { data:
|
|
89
|
+
return { data: dibBuffer, w, h, totalPages }
|
|
130
90
|
} catch (e) { std.printf('Error rendering: %s\n', String(e)); clearCachedDoc(); return null }
|
|
131
91
|
finally { if (pixmap) try { pixmap.destroy() } catch {}; if (page) try { page.destroy() } catch {} }
|
|
132
92
|
}
|
|
133
93
|
|
|
134
94
|
function openPdfFileDialog(): string | null {
|
|
135
95
|
assertNonNullable(hwndMain)
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
96
|
+
const fileBuf = WCHAR.alloc(260)
|
|
97
|
+
const filterWide = WCHAR.encode('PDF Files\0*.pdf\0All Files\0*.*\0\0')
|
|
98
|
+
// 缺省字段跳过 = fresh buffer 上留 0
|
|
99
|
+
const ofn: PtrArrayBuffer<'OPENFILENAMEW'> & { __keep?: ArrayBuffer[] } = OPENFILENAMEW.encode({
|
|
100
|
+
lStructSize: OPENFILENAMEW.size,
|
|
101
|
+
hwndOwner: hwndMain,
|
|
102
|
+
lpstrFilter: filterWide.ptr,
|
|
103
|
+
lpstrFile: fileBuf.ptr,
|
|
104
|
+
nMaxFile: 260,
|
|
105
|
+
Flags: 0x1000 | 0x0800 | 0x0004,
|
|
106
|
+
})
|
|
107
|
+
ofn.__keep = [fileBuf, filterWide]
|
|
108
|
+
const ret = GetOpenFileName(ofn)
|
|
109
|
+
return ret ? WCHAR.decode(fileBuf) : null
|
|
148
110
|
}
|
|
149
111
|
|
|
150
112
|
function updateScrollRange(): void {
|
|
@@ -299,15 +261,11 @@ let hwndBtnNext: gui.HWND | null = null
|
|
|
299
261
|
gui.DefWindowProc(hwnd, msg, wParam, lParam)
|
|
300
262
|
const pm = currentPixmap
|
|
301
263
|
if (!pm) return 0
|
|
302
|
-
const hdc =
|
|
264
|
+
const hdc = GetDC(hwnd)
|
|
303
265
|
if (hdc) {
|
|
304
266
|
const bmi = makeBitmapInfo(pm.w, pm.h)
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
FFI_S32, FFI_S32, FFI_U32, FFI_U32,
|
|
308
|
-
FFI_PTR, FFI_PTR, FFI_U32
|
|
309
|
-
], [hdc, 0, 0, pm.w, pm.h, 0, 0, 0, pm.h, pm.data, bmi, 0], FFI_S32)
|
|
310
|
-
ffi.ffiCall(ReleaseDC, [ffi.FFI_TYPE_UINT64, ffi.FFI_TYPE_UINT64], [hwnd, hdc], FFI_S32)
|
|
267
|
+
SetDIBitsToDevice(hdc, 0, 0, pm.w, pm.h, 0, 0, 0, pm.h, pm.data, bmi, 0)
|
|
268
|
+
ReleaseDC(hwnd, hdc)
|
|
311
269
|
}
|
|
312
270
|
return 0
|
|
313
271
|
}
|
|
@@ -321,11 +279,10 @@ let hwndBtnNext: gui.HWND | null = null
|
|
|
321
279
|
const cr = gui.GetClientRect(hwnd)
|
|
322
280
|
if (cr) {
|
|
323
281
|
const cw = cr.right - cr.left, ch = cr.bottom - cr.top
|
|
324
|
-
|
|
282
|
+
const hdc = GetDC(hwnd)
|
|
325
283
|
if (hdc) {
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
ffi.ffiCall(ReleaseDC, [ffi.FFI_TYPE_UINT64, ffi.FFI_TYPE_UINT64], [hwnd, hdc], FFI_S32)
|
|
284
|
+
PatBlt(hdc, 0, 0, cw, ch, WHITENESS)
|
|
285
|
+
ReleaseDC(hwnd, hdc)
|
|
329
286
|
}
|
|
330
287
|
}
|
|
331
288
|
gui.DefWindowProc(hwnd, msg, wParam, lParam)
|