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.
Files changed (167) hide show
  1. package/README.en.md +18 -24
  2. package/README.md +17 -23
  3. package/examples/PdfCanvas.js +8 -37
  4. package/examples/PdfCanvas.tsx +11 -41
  5. package/examples/exec_server.js +20155 -1420
  6. package/examples/exec_server.tsx +489 -0
  7. package/examples/exec_server_worker.js +383 -33
  8. package/examples/exec_server_worker.ts +408 -30
  9. package/examples/pdf_preview2.js +25 -82
  10. package/examples/pdf_preview2.ts +27 -84
  11. package/examples/pdf_viewer.js +1424 -1180
  12. package/examples/pdf_viewer.tsx +16 -67
  13. package/examples/setres.js +22 -47
  14. package/examples/setres.ts +23 -57
  15. package/examples/test_gallery.js +1418 -1075
  16. package/examples/test_react_lazy.js +1391 -1059
  17. package/examples/test_react_listbox.js +1390 -1058
  18. package/examples/test_root_window.js +1384 -1052
  19. package/examples/test_tab.js +1391 -1059
  20. package/lib/abort.js +70 -0
  21. package/lib/abort.ts +69 -0
  22. package/lib/certs.js +219 -0
  23. package/lib/certs.ts +229 -0
  24. package/lib/exec-log.js +15 -0
  25. package/lib/exec-log.ts +30 -0
  26. package/lib/fetch.js +88 -7
  27. package/lib/fetch.ts +73 -7
  28. package/lib/ffi/bind.js +441 -0
  29. package/lib/ffi/bind.ts +539 -0
  30. package/lib/ffi/ctype.js +194 -0
  31. package/lib/ffi/ctype.ts +369 -0
  32. package/lib/ffi/index.js +6 -0
  33. package/lib/ffi/index.ts +6 -0
  34. package/lib/ffi/struct.js +490 -0
  35. package/lib/ffi/struct.ts +753 -0
  36. package/lib/http-common.js +43 -5
  37. package/lib/http-common.ts +48 -6
  38. package/lib/http-server.js +187 -29
  39. package/lib/http-server.ts +177 -26
  40. package/lib/react-qw/components/DateTimePicker.js +18 -37
  41. package/lib/react-qw/components/Input.js +3 -10
  42. package/lib/react-qw/components/Link.js +6 -19
  43. package/lib/react-qw/components/ListView.js +50 -154
  44. package/lib/react-qw/components/PathPicker.js +28 -88
  45. package/lib/react-qw/components/ScrollView.js +15 -8
  46. package/lib/react-qw/components/Slider.js +2 -1
  47. package/lib/react-qw/components/Tab.js +6 -22
  48. package/lib/react-qw/components/Tooltip.js +10 -21
  49. package/lib/react-qw/components/TreeView.js +8 -31
  50. package/lib/react-qw/index.js +5 -3
  51. package/lib/react-qw/index.ts +8 -3
  52. package/lib/react-qw/nmhdr.js +3 -24
  53. package/lib/react-qw/nmhdr.ts +5 -30
  54. package/lib/react-qw/props.js +7 -2
  55. package/lib/react-qw/props.ts +7 -3
  56. package/lib/react-qw/reconciler.js +23 -13
  57. package/lib/react-qw/reconciler.ts +22 -13
  58. package/lib/text-measure.js +20 -23
  59. package/lib/text-measure.ts +22 -26
  60. package/lib/websocket.js +44 -4
  61. package/lib/websocket.ts +40 -4
  62. package/lib/windows/advapi32.js +53 -0
  63. package/lib/windows/advapi32.ts +64 -0
  64. package/lib/windows/comctl32.js +18 -0
  65. package/lib/windows/comctl32.ts +19 -0
  66. package/lib/windows/comdlg32.js +8 -0
  67. package/lib/windows/comdlg32.ts +10 -0
  68. package/lib/windows/gdi32.js +392 -0
  69. package/lib/windows/gdi32.ts +420 -0
  70. package/lib/windows/kernel32.js +262 -0
  71. package/lib/windows/kernel32.ts +291 -0
  72. package/lib/windows/msimg32.js +38 -0
  73. package/lib/windows/msimg32.ts +45 -0
  74. package/lib/windows/ntdll.js +9 -0
  75. package/lib/windows/ntdll.ts +11 -0
  76. package/lib/windows/ole32.js +7 -0
  77. package/lib/windows/ole32.ts +9 -0
  78. package/lib/windows/psapi.js +32 -0
  79. package/lib/windows/psapi.ts +37 -0
  80. package/lib/windows/shell32.js +13 -0
  81. package/lib/windows/shell32.ts +16 -0
  82. package/lib/windows/structs.js +519 -0
  83. package/lib/windows/structs.ts +566 -0
  84. package/lib/windows/user32.js +572 -0
  85. package/lib/windows/user32.ts +607 -0
  86. package/lib/windows/version.js +29 -0
  87. package/lib/windows/version.ts +35 -0
  88. package/lib/windows/winspool.js +71 -0
  89. package/lib/windows/winspool.ts +80 -0
  90. package/package.json +1 -1
  91. package/quickwin.d.ts +31 -40
  92. package/quickwin_const.d.ts +137 -0
  93. package/qwin-nowasm-x86.exe +0 -0
  94. package/qwin-nowasm.exe +0 -0
  95. package/qwin-x86.exe +0 -0
  96. package/qwin.exe +0 -0
  97. package/test/bench_ffi_callraw.js +236 -0
  98. package/test/bench_ffi_callraw.ts +236 -0
  99. package/test/bench_ffi_overhead.js +139 -0
  100. package/test/bench_ffi_overhead.ts +141 -0
  101. package/test/bench_sendmessage.js +104 -0
  102. package/test/bench_sendmessage.ts +100 -0
  103. package/test/bench_sendmessage_nonnull.js +187 -0
  104. package/test/bench_sendmessage_nonnull.ts +188 -0
  105. package/test/run.js +19 -4
  106. package/test/run.ts +20 -5
  107. package/test/test_basic_fetch.js +29 -0
  108. package/test/test_basic_fetch.ts +26 -0
  109. package/test/test_ffi.js +27 -45
  110. package/test/test_ffi.ts +35 -54
  111. package/test/test_ffi_abi.js +290 -0
  112. package/test/test_ffi_abi.ts +274 -0
  113. package/test/test_ffi_array.js +116 -0
  114. package/test/test_ffi_array.ts +141 -0
  115. package/test/test_ffi_bind.js +620 -8
  116. package/test/test_ffi_bind.ts +630 -8
  117. package/test/test_ffi_struct.js +632 -88
  118. package/test/test_ffi_struct.ts +666 -91
  119. package/test/test_ffi_struct_layout.js +495 -0
  120. package/test/test_ffi_struct_layout.ts +543 -0
  121. package/test/test_ffi_user32.js +103 -0
  122. package/test/test_ffi_user32.ts +113 -0
  123. package/test/test_ffi_windows.js +101 -0
  124. package/test/test_ffi_windows.ts +113 -0
  125. package/test/test_files.js +102 -0
  126. package/test/test_files.ts +121 -0
  127. package/test/test_gdi_draw.js +681 -0
  128. package/test/test_gdi_draw.ts +725 -0
  129. package/test/test_helper.js +8 -1
  130. package/test/test_helper.ts +9 -1
  131. package/test/test_http_import.js +18 -0
  132. package/test/test_http_import.ts +19 -0
  133. package/test/test_http_server.js +73 -1
  134. package/test/test_http_server.ts +75 -1
  135. package/test/test_ipv6.js +2 -2
  136. package/test/test_ipv6.ts +2 -2
  137. package/test/test_net_fetch.js +74 -11
  138. package/test/test_net_fetch.ts +73 -10
  139. package/test/test_net_websocket.js +1 -1
  140. package/test/test_net_websocket.ts +1 -1
  141. package/test/test_printer.js +137 -0
  142. package/test/test_printer.ts +148 -0
  143. package/test/test_proc.js +141 -0
  144. package/test/test_proc.ts +163 -0
  145. package/test/test_react_complex.js +1401 -1069
  146. package/test/test_react_counter.js +1391 -1059
  147. package/test/test_react_flex.js +1411 -1072
  148. package/test/test_react_hidden.js +1394 -1062
  149. package/test/test_react_listview_link.js +1391 -1059
  150. package/test/test_react_notify.js +18638 -0
  151. package/test/test_react_render.js +1391 -1059
  152. package/test/test_registry.js +74 -0
  153. package/test/test_registry.ts +95 -0
  154. package/test/test_sysinfo.js +122 -0
  155. package/test/test_sysinfo.ts +141 -0
  156. package/test/test_wolfssl_read.js +45 -43
  157. package/test/test_wolfssl_read.ts +42 -40
  158. package/test/test_worker_net.js +35 -17
  159. package/test/test_worker_net.ts +27 -15
  160. package/tsconfig.json +1 -1
  161. package/examples/exec_server.ts +0 -80
  162. package/lib/ffi-bind.js +0 -85
  163. package/lib/ffi-bind.ts +0 -170
  164. package/lib/ffi-struct.js +0 -224
  165. package/lib/ffi-struct.ts +0 -239
  166. package/lib/win-common-structs.js +0 -39
  167. package/lib/win-common-structs.ts +0 -41
@@ -1,63 +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
- import { OPENFILENAMEW } from '../lib/win-common-structs.js'
9
-
10
- const FFI_PTR = ffi.FFI_TYPE_POINTER
11
- const FFI_U32 = ffi.FFI_TYPE_UINT32
12
- const FFI_S32 = ffi.FFI_TYPE_SINT32
13
-
14
- const _user32 = win.LoadLibrary('user32.dll')
15
- const _gdi32 = win.LoadLibrary('gdi32.dll')
16
- 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'
17
12
 
18
13
  type MuPdf = typeof import('../vendor/mupdf-wasm/mupdf.js')
19
- if (!(_user32 && _gdi32 && _comdlg32)) std.exit(0)
20
14
 
21
- function loadProc(lib: win.HMODULE, name: string): number {
22
- const ptr = win.GetProcAddress(lib, name)
23
- if (!ptr) { std.printf('Error: cannot load %s\n', name); std.exit(1) }
24
- return ptr
25
- }
26
-
27
- const GetOpenFileNameW = loadProc(_comdlg32, 'GetOpenFileNameW')
28
- const SetDIBitsToDevice = loadProc(_gdi32, 'SetDIBitsToDevice')
29
- const GetDC = loadProc(_user32, 'GetDC')
30
- const ReleaseDC = loadProc(_user32, 'ReleaseDC')
31
- const PatBlt = loadProc(_gdi32, 'PatBlt')
32
15
  const WHITENESS = 0x00FF0062
33
16
 
34
- function makeBitmapInfo(w: number, h: number): ArrayBuffer {
35
- const bmi = new ArrayBuffer(40)
36
- const bv = new DataView(bmi)
37
- bv.setUint32(0, 40, true)
38
- bv.setInt32(4, w, true)
39
- bv.setInt32(8, -h, true)
40
- bv.setUint16(12, 1, true)
41
- bv.setUint16(14, 24, true)
42
- return bmi
43
- }
44
-
45
- function strToWide(str: string): ArrayBuffer {
46
- return new TextEncoder('utf-16le').encode(str + '\0').buffer
47
- }
48
-
49
- function wideToStr(buf: ArrayBuffer): string {
50
- const dv = new DataView(buf)
51
- const chars: number[] = []
52
- for (let i = 0; i < buf.byteLength; i += 2) {
53
- const c = dv.getUint16(i, true); if (c === 0) break
54
- chars.push(c)
55
- }
56
- return String.fromCharCode(...chars)
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 })
57
20
  }
58
21
 
59
22
  interface PixmapInfo {
60
- data: ArrayBuffer; w: number; h: number
23
+ data: PtrArrayBuffer<string>; w: number; h: number
61
24
  }
62
25
 
63
26
  let hwndMain: gui.HWND | null = null
@@ -113,7 +76,8 @@ function renderPdfPage(mupdf: MuPdf, filePath: string, pageIndex: number): Pixma
113
76
  const srcStride = pixmap.getStride()
114
77
  const w = pixmap.getWidth(), h = pixmap.getHeight()
115
78
  const dibStride = Math.floor((w * 3 + 3) / 4) * 4
116
- const dib = new Uint8Array(h * dibStride)
79
+ const dibBuffer = new PtrArrayBuffer(h * dibStride)
80
+ const dib = new Uint8Array(dibBuffer)
117
81
  for (let y = 0; y < h; y++) {
118
82
  const srcOff = y * srcStride, dstOff = y * dibStride
119
83
  for (let x = 0; x < w; x++) {
@@ -122,43 +86,27 @@ function renderPdfPage(mupdf: MuPdf, filePath: string, pageIndex: number): Pixma
122
86
  }
123
87
  }
124
88
  const totalPages = cachedDoc.countPages()
125
- return { data: dib.buffer, w, h, totalPages }
89
+ return { data: dibBuffer, w, h, totalPages }
126
90
  } catch (e) { std.printf('Error rendering: %s\n', String(e)); clearCachedDoc(); return null }
127
91
  finally { if (pixmap) try { pixmap.destroy() } catch {}; if (page) try { page.destroy() } catch {} }
128
92
  }
129
93
 
130
94
  function openPdfFileDialog(): string | null {
131
95
  assertNonNullable(hwndMain)
132
- const fileBuf = new ArrayBuffer(260 * 2)
133
- const filterWide = strToWide('PDF Files\0*.pdf\0All Files\0*.*\0\0')
134
- const ofn: ArrayBuffer & { __keep?: ArrayBuffer[] } = OPENFILENAMEW.write({
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({
135
100
  lStructSize: OPENFILENAMEW.size,
136
101
  hwndOwner: hwndMain,
137
- hInstance: 0,
138
- lpstrFilter: ffi.bufferPtr(filterWide),
139
- lpstrCustomFilter: 0,
140
- nMaxCustFilter: 0,
141
- nFilterIndex: 0,
142
- lpstrFile: ffi.bufferPtr(fileBuf),
102
+ lpstrFilter: filterWide.ptr,
103
+ lpstrFile: fileBuf.ptr,
143
104
  nMaxFile: 260,
144
- lpstrFileTitle: 0,
145
- nMaxFileTitle: 0,
146
- lpstrInitialDir: 0,
147
- lpstrTitle: 0,
148
105
  Flags: 0x1000 | 0x0800 | 0x0004,
149
- nFileOffset: 0,
150
- nFileExtension: 0,
151
- lpstrDefExt: 0,
152
- lCustData: 0,
153
- lpfnHook: 0,
154
- lpTemplateName: 0,
155
- pvReserved: 0,
156
- dwReserved: 0,
157
- FlagsEx: 0,
158
106
  })
159
107
  ofn.__keep = [fileBuf, filterWide]
160
- const ret = ffi.ffiCall(GetOpenFileNameW, [FFI_PTR], [ofn], FFI_U32)
161
- return ret ? wideToStr(fileBuf) : null
108
+ const ret = GetOpenFileName(ofn.ptr)
109
+ return ret ? WCHAR.decode(fileBuf) : null
162
110
  }
163
111
 
164
112
  function updateScrollRange(): void {
@@ -313,15 +261,11 @@ let hwndBtnNext: gui.HWND | null = null
313
261
  gui.DefWindowProc(hwnd, msg, wParam, lParam)
314
262
  const pm = currentPixmap
315
263
  if (!pm) return 0
316
- const hdc = ffi.ffiCall(GetDC, [ffi.FFI_TYPE_POINTER], [hwnd], ffi.FFI_TYPE_POINTER)
264
+ const hdc = GetDC(hwnd)
317
265
  if (hdc) {
318
266
  const bmi = makeBitmapInfo(pm.w, pm.h)
319
- ffi.ffiCall(SetDIBitsToDevice, [
320
- ffi.FFI_TYPE_POINTER, FFI_S32, FFI_S32, FFI_U32, FFI_U32,
321
- FFI_S32, FFI_S32, FFI_U32, FFI_U32,
322
- FFI_PTR, FFI_PTR, FFI_U32
323
- ], [hdc, 0, 0, pm.w, pm.h, 0, 0, 0, pm.h, pm.data, bmi, 0], FFI_S32)
324
- ffi.ffiCall(ReleaseDC, [ffi.FFI_TYPE_POINTER, ffi.FFI_TYPE_POINTER], [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)
325
269
  }
326
270
  return 0
327
271
  }
@@ -335,11 +279,10 @@ let hwndBtnNext: gui.HWND | null = null
335
279
  const cr = gui.GetClientRect(hwnd)
336
280
  if (cr) {
337
281
  const cw = cr.right - cr.left, ch = cr.bottom - cr.top
338
- const hdc = ffi.ffiCall(GetDC, [ffi.FFI_TYPE_POINTER], [hwnd], ffi.FFI_TYPE_POINTER)
282
+ const hdc = GetDC(hwnd)
339
283
  if (hdc) {
340
- ffi.ffiCall(PatBlt, [ffi.FFI_TYPE_POINTER, FFI_S32, FFI_S32, FFI_S32, FFI_S32, FFI_U32],
341
- [hdc, 0, 0, cw, ch, WHITENESS], FFI_U32)
342
- ffi.ffiCall(ReleaseDC, [ffi.FFI_TYPE_POINTER, ffi.FFI_TYPE_POINTER], [hwnd, hdc], FFI_S32)
284
+ PatBlt(hdc, 0, 0, cw, ch, WHITENESS)
285
+ ReleaseDC(hwnd, hdc)
343
286
  }
344
287
  }
345
288
  gui.DefWindowProc(hwnd, msg, wParam, lParam)