quickwin 3.0.0 → 3.0.2

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 (253) hide show
  1. package/README.en.md +3 -0
  2. package/README.md +2 -0
  3. package/lib/abort.d.ts +21 -0
  4. package/lib/assert.d.ts +2 -0
  5. package/lib/bitmap.d.ts +7 -0
  6. package/lib/cache-utils.d.ts +6 -0
  7. package/lib/certs.d.ts +1 -0
  8. package/lib/dpi.d.ts +9 -0
  9. package/lib/dumpRects.d.ts +2 -0
  10. package/lib/exec-log.d.ts +23 -0
  11. package/lib/fetch.d.ts +4 -0
  12. package/lib/ffi/bind.d.ts +70 -0
  13. package/lib/ffi/ctype.d.ts +117 -0
  14. package/lib/ffi/index.d.ts +2 -0
  15. package/lib/ffi/struct.d.ts +174 -0
  16. package/lib/http-common.d.ts +143 -0
  17. package/lib/http-server.d.ts +59 -0
  18. package/lib/polyfill.d.ts +22 -0
  19. package/lib/react-qw/components/Button.d.ts +9 -0
  20. package/lib/react-qw/components/CheckBox.d.ts +11 -0
  21. package/lib/react-qw/components/ComboBox.d.ts +11 -0
  22. package/lib/react-qw/components/DateTimePicker.d.ts +15 -0
  23. package/lib/react-qw/components/Input.d.ts +15 -0
  24. package/lib/react-qw/components/Link.d.ts +12 -0
  25. package/lib/react-qw/components/ListBox.d.ts +13 -0
  26. package/lib/react-qw/components/ListView.d.ts +37 -0
  27. package/lib/react-qw/components/PathPicker.d.ts +23 -0
  28. package/lib/react-qw/components/ProgressBar.d.ts +9 -0
  29. package/lib/react-qw/components/RadioButton.d.ts +11 -0
  30. package/lib/react-qw/components/ScrollView.d.ts +9 -0
  31. package/lib/react-qw/components/Slider.d.ts +12 -0
  32. package/lib/react-qw/components/Tab.d.ts +14 -0
  33. package/lib/react-qw/components/Tooltip.d.ts +7 -0
  34. package/lib/react-qw/components/TreeView.d.ts +18 -0
  35. package/lib/react-qw/components/index.d.ts +16 -0
  36. package/lib/react-qw/index.d.ts +24 -0
  37. package/lib/react-qw/layout.d.ts +29 -0
  38. package/lib/react-qw/nmhdr.d.ts +1 -0
  39. package/lib/react-qw/props.d.ts +2 -0
  40. package/lib/react-qw/reconciler.d.ts +21 -0
  41. package/lib/stream.d.ts +20 -0
  42. package/lib/text-codec.d.ts +39 -0
  43. package/lib/text-measure.d.ts +14 -0
  44. package/lib/url.d.ts +54 -0
  45. package/lib/websocket.d.ts +73 -0
  46. package/lib/windows/{advapi32.ts → advapi32.d.ts} +6 -21
  47. package/lib/windows/comctl32.d.ts +14 -0
  48. package/lib/windows/comdlg32.d.ts +4 -0
  49. package/lib/windows/{gdi32.ts → gdi32.d.ts} +161 -98
  50. package/lib/windows/{kernel32.ts → kernel32.d.ts} +138 -115
  51. package/lib/windows/{msimg32.ts → msimg32.d.ts} +11 -14
  52. package/lib/windows/ntdll.d.ts +5 -0
  53. package/lib/windows/ole32.d.ts +3 -0
  54. package/lib/windows/{psapi.ts → psapi.d.ts} +9 -18
  55. package/lib/windows/{shell32.ts → shell32.d.ts} +25 -24
  56. package/lib/windows/structs.d.ts +3141 -0
  57. package/lib/windows/{user32.ts → user32.d.ts} +196 -193
  58. package/lib/windows/version.d.ts +27 -0
  59. package/lib/windows/{winspool.ts → winspool.d.ts} +18 -32
  60. package/package.json +15 -8
  61. package/qwin-nowasm-x86.exe +0 -0
  62. package/qwin-nowasm.exe +0 -0
  63. package/qwin-x86.exe +0 -0
  64. package/qwin.exe +0 -0
  65. package/examples/PdfCanvas.js +0 -38
  66. package/examples/PdfCanvas.tsx +0 -54
  67. package/examples/execd/main.js +0 -23379
  68. package/examples/execd/tray.js +0 -192
  69. package/examples/execd/worker.js +0 -122
  70. package/examples/pdf_preview2.js +0 -398
  71. package/examples/pdf_preview2.ts +0 -353
  72. package/examples/pdf_viewer.js +0 -22515
  73. package/examples/pdf_viewer.tsx +0 -228
  74. package/examples/test_gallery.js +0 -18692
  75. package/examples/test_gallery.tsx +0 -291
  76. package/examples/test_react_lazy.js +0 -18560
  77. package/examples/test_react_lazy.tsx +0 -65
  78. package/examples/test_react_listbox.js +0 -18562
  79. package/examples/test_react_listbox.tsx +0 -73
  80. package/examples/test_root_window.js +0 -18532
  81. package/examples/test_root_window.tsx +0 -41
  82. package/examples/test_tab.js +0 -18563
  83. package/examples/test_tab.tsx +0 -77
  84. package/examples/tray_demo.js +0 -86
  85. package/examples/tray_demo.tsx +0 -89
  86. package/lib/abort.ts +0 -69
  87. package/lib/assert.ts +0 -7
  88. package/lib/bitmap.ts +0 -39
  89. package/lib/cache-utils.ts +0 -40
  90. package/lib/certs.ts +0 -258
  91. package/lib/dpi.ts +0 -31
  92. package/lib/dumpRects.ts +0 -34
  93. package/lib/exec-log.ts +0 -30
  94. package/lib/fetch.ts +0 -589
  95. package/lib/ffi/bind.ts +0 -540
  96. package/lib/ffi/ctype.ts +0 -371
  97. package/lib/ffi/index.ts +0 -6
  98. package/lib/ffi/struct.ts +0 -780
  99. package/lib/http-common.ts +0 -441
  100. package/lib/http-server.ts +0 -604
  101. package/lib/polyfill.ts +0 -171
  102. package/lib/react-qw/components/index.ts +0 -17
  103. package/lib/react-qw/index.ts +0 -96
  104. package/lib/react-qw/layout.ts +0 -111
  105. package/lib/react-qw/nmhdr.ts +0 -7
  106. package/lib/react-qw/props.ts +0 -41
  107. package/lib/react-qw/reconciler.ts +0 -379
  108. package/lib/stream.ts +0 -22
  109. package/lib/text-codec.ts +0 -171
  110. package/lib/text-measure.ts +0 -44
  111. package/lib/url.ts +0 -201
  112. package/lib/websocket.ts +0 -600
  113. package/lib/windows/comctl32.ts +0 -20
  114. package/lib/windows/comdlg32.ts +0 -10
  115. package/lib/windows/ntdll.ts +0 -11
  116. package/lib/windows/ole32.ts +0 -9
  117. package/lib/windows/structs.ts +0 -807
  118. package/lib/windows/version.ts +0 -35
  119. package/test/add.wasm +0 -0
  120. package/test/bench_ffi_callraw.js +0 -235
  121. package/test/bench_ffi_callraw.ts +0 -235
  122. package/test/bench_ffi_overhead.js +0 -139
  123. package/test/bench_ffi_overhead.ts +0 -141
  124. package/test/bench_sendmessage.js +0 -104
  125. package/test/bench_sendmessage.ts +0 -100
  126. package/test/bench_sendmessage_nonnull.js +0 -187
  127. package/test/bench_sendmessage_nonnull.ts +0 -188
  128. package/test/complex.wasm +0 -0
  129. package/test/complex_imports.wasm +0 -0
  130. package/test/debug/http_server_e2e.js +0 -31
  131. package/test/debug/minwasm.js +0 -52
  132. package/test/debug/mupdf_debug.js +0 -86
  133. package/test/debug/wasm.js +0 -122
  134. package/test/debug/wasm_export_debug.js +0 -54
  135. package/test/debug/wasm_names.js +0 -36
  136. package/test/example.pdf +0 -0
  137. package/test/global_imports.wasm +0 -0
  138. package/test/import_func.wasm +0 -0
  139. package/test/imports.wasm +0 -0
  140. package/test/mupdf-cdn.js +0 -40
  141. package/test/mupdf-cdn.ts +0 -43
  142. package/test/run.js +0 -111
  143. package/test/run.ts +0 -116
  144. package/test/sjlj.wasm +0 -0
  145. package/test/test_basic.js +0 -7
  146. package/test/test_basic.ts +0 -9
  147. package/test/test_basic_fetch.js +0 -63
  148. package/test/test_basic_fetch.ts +0 -59
  149. package/test/test_brotli.js +0 -48
  150. package/test/test_brotli.ts +0 -52
  151. package/test/test_fetch_cache.js +0 -169
  152. package/test/test_fetch_cache.ts +0 -187
  153. package/test/test_ffi.js +0 -157
  154. package/test/test_ffi.ts +0 -170
  155. package/test/test_ffi_abi.js +0 -290
  156. package/test/test_ffi_abi.ts +0 -274
  157. package/test/test_ffi_array.js +0 -116
  158. package/test/test_ffi_array.ts +0 -141
  159. package/test/test_ffi_bind.js +0 -656
  160. package/test/test_ffi_bind.ts +0 -670
  161. package/test/test_ffi_struct.js +0 -779
  162. package/test/test_ffi_struct.ts +0 -828
  163. package/test/test_ffi_struct_layout.js +0 -495
  164. package/test/test_ffi_struct_layout.ts +0 -543
  165. package/test/test_ffi_user32.js +0 -103
  166. package/test/test_ffi_user32.ts +0 -113
  167. package/test/test_ffi_windows.js +0 -172
  168. package/test/test_ffi_windows.ts +0 -187
  169. package/test/test_files.js +0 -102
  170. package/test/test_files.ts +0 -121
  171. package/test/test_frame_encoding.js +0 -128
  172. package/test/test_frame_encoding.ts +0 -132
  173. package/test/test_gdi_draw.js +0 -681
  174. package/test/test_gdi_draw.ts +0 -725
  175. package/test/test_helper.js +0 -91
  176. package/test/test_helper.ts +0 -88
  177. package/test/test_http_import.js +0 -96
  178. package/test/test_http_import.ts +0 -93
  179. package/test/test_http_server.js +0 -214
  180. package/test/test_http_server.ts +0 -211
  181. package/test/test_import_dir.js +0 -4
  182. package/test/test_import_dir.ts +0 -5
  183. package/test/test_ipv6.js +0 -134
  184. package/test/test_ipv6.ts +0 -130
  185. package/test/test_jsx.js +0 -1314
  186. package/test/test_meta_url.js +0 -3
  187. package/test/test_meta_url.ts +0 -4
  188. package/test/test_mupdf_render.js +0 -51
  189. package/test/test_mupdf_render.ts +0 -55
  190. package/test/test_mupdf_twice.js +0 -62
  191. package/test/test_mupdf_twice.ts +0 -65
  192. package/test/test_mupdf_wasm.js +0 -39
  193. package/test/test_mupdf_wasm.ts +0 -32
  194. package/test/test_net_event.js +0 -57
  195. package/test/test_net_event.ts +0 -56
  196. package/test/test_net_fetch.js +0 -384
  197. package/test/test_net_fetch.ts +0 -373
  198. package/test/test_net_websocket.js +0 -180
  199. package/test/test_net_websocket.ts +0 -164
  200. package/test/test_polyfill.js +0 -144
  201. package/test/test_polyfill.ts +0 -159
  202. package/test/test_printer.js +0 -137
  203. package/test/test_printer.ts +0 -148
  204. package/test/test_proc.js +0 -141
  205. package/test/test_proc.ts +0 -163
  206. package/test/test_react_complex.js +0 -18678
  207. package/test/test_react_counter.js +0 -18555
  208. package/test/test_react_flex.js +0 -18871
  209. package/test/test_react_hidden.js +0 -18560
  210. package/test/test_react_listview_link.js +0 -18590
  211. package/test/test_react_notify.js +0 -18797
  212. package/test/test_react_render.js +0 -18550
  213. package/test/test_registry.js +0 -74
  214. package/test/test_registry.ts +0 -95
  215. package/test/test_sysinfo.js +0 -122
  216. package/test/test_sysinfo.ts +0 -141
  217. package/test/test_url.js +0 -173
  218. package/test/test_url.ts +0 -183
  219. package/test/test_wasm_basic.js +0 -85
  220. package/test/test_wasm_basic.ts +0 -73
  221. package/test/test_wasm_import_global.js +0 -41
  222. package/test/test_wasm_import_global.ts +0 -45
  223. package/test/test_wasm_sjlj.js +0 -145
  224. package/test/test_wasm_sjlj.ts +0 -125
  225. package/test/test_wasm_types.js +0 -97
  226. package/test/test_wasm_types.ts +0 -124
  227. package/test/test_wolfssl_read.js +0 -203
  228. package/test/test_wolfssl_read.ts +0 -184
  229. package/test/test_worker.js +0 -21
  230. package/test/test_worker.ts +0 -24
  231. package/test/test_worker_concurrent.js +0 -45
  232. package/test/test_worker_concurrent.ts +0 -56
  233. package/test/test_worker_data_url.js +0 -46
  234. package/test/test_worker_data_url.ts +0 -51
  235. package/test/test_worker_fetch.js +0 -26
  236. package/test/test_worker_fetch.ts +0 -27
  237. package/test/test_worker_net.js +0 -69
  238. package/test/test_worker_net.ts +0 -66
  239. package/test/test_worker_wasm_concurrent.js +0 -44
  240. package/test/test_worker_wasm_concurrent.ts +0 -45
  241. package/test/types.wasm +0 -0
  242. package/test/worker_fetch.js +0 -13
  243. package/test/worker_fetch.ts +0 -13
  244. package/test/worker_helper.js +0 -1
  245. package/test/worker_helper.ts +0 -1
  246. package/test/worker_http.js +0 -18
  247. package/test/worker_http.ts +0 -20
  248. package/test/worker_import_lib.js +0 -12
  249. package/test/worker_import_lib.ts +0 -13
  250. package/test/worker_module.js +0 -16
  251. package/test/worker_module.ts +0 -17
  252. package/test/worker_wasm_concurrent.js +0 -22
  253. package/test/worker_wasm_concurrent.ts +0 -22
@@ -1,398 +0,0 @@
1
- import { PtrArrayBuffer, NULL } from '../lib/ffi/ctype.js';
2
- import '../lib/polyfill.js';
3
- import * as std from 'std';
4
- import * as gui from 'gui';
5
- import { MUPDF_JS_URL, preloadMupdfWasm } from '../test/mupdf-cdn.js';
6
- import { assertNonNullable } from '../lib/assert.js';
7
- import { WCHAR } from '../lib/ffi/bind.js';
8
- import { BITMAPINFOHEADER, OPENFILENAMEW, RECT, SCROLLINFO } from '../lib/windows/structs.js';
9
- import { GetOpenFileName } from '../lib/windows/comdlg32.js';
10
- import { GetClientRect, GetDC, GetScrollInfo, GetWindowLongPtr, GetWindowText, GetWindowTextLength, InvalidateRect, MessageBox, PostQuitMessage, ReleaseDC, SetScrollInfo, SetWindowPos, SetWindowLongPtr, SetWindowText, ShowScrollBar, ShowWindow } from '../lib/windows/user32.js';
11
- import { PatBlt, SetDIBitsToDevice } from '../lib/windows/gdi32.js';
12
- const WHITENESS = 0x00FF0062;
13
- function makeBitmapInfo(w, h) {
14
- // biHeight 负 = 自顶向下(DIB 原点左上);biCompression 缺省 0 = BI_RGB 无压缩
15
- return BITMAPINFOHEADER.encode({ biSize: BITMAPINFOHEADER.size, biWidth: w, biHeight: -h, biPlanes: 1, biBitCount: 24 });
16
- }
17
- let hwndMain = null;
18
- let hwndEdit = null;
19
- let hwndCanvas = null;
20
- let hwndContent = null;
21
- let currentPixmap = null;
22
- let currentPage = 0, totalPages = 0;
23
- let scrollX = 0, scrollY = 0;
24
- let cachedPath = '';
25
- let cachedDoc = null;
26
- function clearCachedDoc() {
27
- if (cachedDoc) {
28
- try {
29
- cachedDoc.destroy();
30
- }
31
- catch { }
32
- }
33
- cachedDoc = null;
34
- cachedPath = '';
35
- }
36
- async function loadMupdf() {
37
- try {
38
- await preloadMupdfWasm();
39
- return await import(MUPDF_JS_URL);
40
- }
41
- catch (e) {
42
- std.printf('Error: mupdf load failed: %s\n', String(e));
43
- return null;
44
- }
45
- }
46
- function renderPdfPage(mupdf, filePath, pageIndex) {
47
- if (filePath !== cachedPath) {
48
- clearCachedDoc();
49
- const fp = std.open(filePath, 'rb');
50
- if (!fp) {
51
- std.printf('Error: cannot open %s\n', filePath);
52
- return null;
53
- }
54
- let buf = null;
55
- try {
56
- fp.seek(0, 2);
57
- const size = fp.tell();
58
- fp.seek(0, 0);
59
- buf = new ArrayBuffer(size);
60
- fp.read(buf, 0, size);
61
- }
62
- finally {
63
- fp.close();
64
- }
65
- if (!buf)
66
- return null;
67
- try {
68
- cachedDoc = mupdf.Document.openDocument(new Uint8Array(buf), 'application/pdf');
69
- cachedPath = filePath;
70
- }
71
- catch (e) {
72
- std.printf('Error opening document: %s\n', String(e));
73
- return null;
74
- }
75
- }
76
- if (!cachedDoc)
77
- return null;
78
- let page = null;
79
- let pixmap = null;
80
- try {
81
- page = cachedDoc.loadPage(pageIndex);
82
- pixmap = page.toPixmap(mupdf.Matrix.scale(1.5, 1.5), mupdf.ColorSpace.DeviceRGB, false);
83
- if (!pixmap)
84
- return null;
85
- const srcPixels = pixmap.getPixels();
86
- const srcStride = pixmap.getStride();
87
- const w = pixmap.getWidth(), h = pixmap.getHeight();
88
- const dibStride = Math.floor((w * 3 + 3) / 4) * 4;
89
- const dibBuffer = new PtrArrayBuffer(h * dibStride);
90
- const dib = new Uint8Array(dibBuffer);
91
- for (let y = 0; y < h; y++) {
92
- const srcOff = y * srcStride, dstOff = y * dibStride;
93
- for (let x = 0; x < w; x++) {
94
- const sx = srcOff + x * 3, dx = dstOff + x * 3;
95
- dib[dx] = srcPixels[sx + 2];
96
- dib[dx + 1] = srcPixels[sx + 1];
97
- dib[dx + 2] = srcPixels[sx];
98
- }
99
- }
100
- const totalPages = cachedDoc.countPages();
101
- return { data: dibBuffer, w, h, totalPages };
102
- }
103
- catch (e) {
104
- std.printf('Error rendering: %s\n', String(e));
105
- clearCachedDoc();
106
- return null;
107
- }
108
- finally {
109
- if (pixmap)
110
- try {
111
- pixmap.destroy();
112
- }
113
- catch { }
114
- ;
115
- if (page)
116
- try {
117
- page.destroy();
118
- }
119
- catch { }
120
- }
121
- }
122
- function openPdfFileDialog() {
123
- assertNonNullable(hwndMain);
124
- const fileBuf = WCHAR.alloc(260);
125
- const filterWide = WCHAR.encode('PDF Files\0*.pdf\0All Files\0*.*\0\0');
126
- // 缺省字段跳过 = fresh buffer 上留 0
127
- const ofn = OPENFILENAMEW.encode({
128
- lStructSize: OPENFILENAMEW.size,
129
- hwndOwner: hwndMain,
130
- lpstrFilter: filterWide.ptr,
131
- lpstrFile: fileBuf.ptr,
132
- nMaxFile: 260,
133
- Flags: 0x1000 | 0x0800 | 0x0004,
134
- });
135
- ofn.__keep = [fileBuf, filterWide];
136
- const ret = GetOpenFileName(ofn.ptr);
137
- return ret ? WCHAR.decode(fileBuf) : null;
138
- }
139
- function updateScrollRange() {
140
- assertNonNullable(hwndCanvas);
141
- assertNonNullable(hwndContent);
142
- if (!currentPixmap)
143
- return;
144
- const crBuf = RECT.alloc();
145
- if (!GetClientRect(hwndCanvas, crBuf.ptr))
146
- return;
147
- const { left, top, right, bottom } = RECT.decode(crBuf);
148
- const cw = right - left, ch = bottom - top;
149
- const maxX = Math.max(0, currentPixmap.w - cw);
150
- const maxY = Math.max(0, currentPixmap.h - ch);
151
- scrollX = Math.min(scrollX, maxX);
152
- scrollY = Math.min(scrollY, maxY);
153
- if (currentPixmap.w > cw) {
154
- const style = GetWindowLongPtr(hwndCanvas, -16 /* Gwlp.STYLE */);
155
- if (!(style & 1048576 /* WindowStyle.HSCROLL */)) {
156
- SetWindowLongPtr(hwndCanvas, -16 /* Gwlp.STYLE */, style | 1048576 /* WindowStyle.HSCROLL */);
157
- SetWindowPos(hwndCanvas, 0 /* SetWindowPosHwnd.TOP */, 0, 0, 0, 0, 2 /* SetWindowPosFlag.SWP_NOMOVE */ | 1 /* SetWindowPosFlag.SWP_NOSIZE */ | 4 /* SetWindowPosFlag.SWP_NOZORDER */ | 32 /* SetWindowPosFlag.SWP_FRAMECHANGED */);
158
- }
159
- SetScrollInfo(hwndCanvas, 0 /* ScrollBar.HORZ */, {
160
- cbSize: SCROLLINFO.size, fMask: 1 /* ScrollInfoFlag.RANGE */ | 2 /* ScrollInfoFlag.PAGE */ | 4 /* ScrollInfoFlag.POS */,
161
- nMin: 0, nMax: currentPixmap.w - 1, nPage: cw, nPos: scrollX,
162
- }, 1);
163
- ShowScrollBar(hwndCanvas, 0 /* ScrollBar.HORZ */, 1);
164
- }
165
- else {
166
- scrollX = 0;
167
- const style = GetWindowLongPtr(hwndCanvas, -16 /* Gwlp.STYLE */);
168
- if (style & 1048576 /* WindowStyle.HSCROLL */) {
169
- SetWindowLongPtr(hwndCanvas, -16 /* Gwlp.STYLE */, style & ~1048576 /* WindowStyle.HSCROLL */);
170
- SetWindowPos(hwndCanvas, 0 /* SetWindowPosHwnd.TOP */, 0, 0, 0, 0, 2 /* SetWindowPosFlag.SWP_NOMOVE */ | 1 /* SetWindowPosFlag.SWP_NOSIZE */ | 4 /* SetWindowPosFlag.SWP_NOZORDER */ | 32 /* SetWindowPosFlag.SWP_FRAMECHANGED */);
171
- }
172
- ShowScrollBar(hwndCanvas, 0 /* ScrollBar.HORZ */, 0);
173
- }
174
- if (currentPixmap.h > ch) {
175
- SetScrollInfo(hwndCanvas, 1 /* ScrollBar.VERT */, {
176
- cbSize: SCROLLINFO.size, fMask: 1 /* ScrollInfoFlag.RANGE */ | 2 /* ScrollInfoFlag.PAGE */ | 4 /* ScrollInfoFlag.POS */,
177
- nMin: 0, nMax: currentPixmap.h - 1, nPage: ch, nPos: scrollY,
178
- }, 1);
179
- ShowScrollBar(hwndCanvas, 1 /* ScrollBar.VERT */, 1);
180
- }
181
- else {
182
- scrollY = 0;
183
- ShowScrollBar(hwndCanvas, 1 /* ScrollBar.VERT */, 0);
184
- }
185
- SetWindowPos(hwndContent, 0 /* SetWindowPosHwnd.TOP */, -scrollX, -scrollY, 0, 0, 1 /* SetWindowPosFlag.SWP_NOSIZE */ | 4 /* SetWindowPosFlag.SWP_NOZORDER */);
186
- }
187
- function showPdf(mupdf, path, pageIdx) {
188
- assertNonNullable(hwndMain);
189
- assertNonNullable(hwndContent);
190
- const pix = renderPdfPage(mupdf, path, pageIdx);
191
- if (!pix) {
192
- MessageBox(NULL, '渲染 PDF 失败', 'JS Alert', 0);
193
- return;
194
- }
195
- currentPixmap = pix;
196
- currentPage = pageIdx;
197
- totalPages = pix.totalPages;
198
- SetWindowText(hwndMain, 'PDF 预览 - 第 ' + (pageIdx + 1) + '/' + totalPages + ' 页');
199
- scrollX = 0;
200
- scrollY = 0;
201
- SetWindowPos(hwndContent, 0 /* SetWindowPosHwnd.TOP */, 0, 0, pix.w, pix.h, 4 /* SetWindowPosFlag.SWP_NOZORDER */ | 2 /* SetWindowPosFlag.SWP_NOMOVE */);
202
- updateScrollRange();
203
- InvalidateRect(hwndContent, NULL, 1);
204
- }
205
- function doScroll(dx, dy) {
206
- assertNonNullable(hwndCanvas);
207
- assertNonNullable(hwndContent);
208
- const crBuf = RECT.alloc();
209
- if (!GetClientRect(hwndCanvas, crBuf.ptr) || !currentPixmap)
210
- return;
211
- const { left, top, right, bottom } = RECT.decode(crBuf);
212
- const cw = right - left, ch = bottom - top;
213
- const maxX = Math.max(0, currentPixmap.w - cw);
214
- const maxY = Math.max(0, currentPixmap.h - ch);
215
- scrollX = Math.max(0, Math.min(maxX, scrollX + dx));
216
- scrollY = Math.max(0, Math.min(maxY, scrollY + dy));
217
- SetWindowPos(hwndContent, 0 /* SetWindowPosHwnd.TOP */, -scrollX, -scrollY, 0, 0, 1 /* SetWindowPosFlag.SWP_NOSIZE */ | 4 /* SetWindowPosFlag.SWP_NOZORDER */);
218
- SetScrollInfo(hwndCanvas, 0 /* ScrollBar.HORZ */, { cbSize: SCROLLINFO.size, fMask: 4 /* ScrollInfoFlag.POS */, nPos: scrollX }, 1);
219
- SetScrollInfo(hwndCanvas, 1 /* ScrollBar.VERT */, { cbSize: SCROLLINFO.size, fMask: 4 /* ScrollInfoFlag.POS */, nPos: scrollY }, 1);
220
- }
221
- async function main() {
222
- const mupdf = await loadMupdf();
223
- if (!mupdf) {
224
- MessageBox(NULL, '加载 mupdf WASM 失败', 'JS Alert', 0);
225
- return;
226
- }
227
- const WS_CHILD = 1073741824 /* WindowStyle.CHILD */;
228
- const WS_VIS = 268435456 /* WindowStyle.VISIBLE */;
229
- const WS_BORDER = 8388608 /* WindowStyle.BORDER */;
230
- const ctrlY = 12, ctrlH = 26, gap = 4, btnW = 80, btnPageW = 72;
231
- let hwndBtnOpen = null;
232
- let hwndBtnPrev = null;
233
- let hwndBtnNext = null;
234
- gui.RegisterClass('PdfViewer2', (hwnd, msg, wParam, lParam) => {
235
- assertNonNullable(hwndCanvas);
236
- assertNonNullable(hwndEdit);
237
- assertNonNullable(hwndBtnOpen);
238
- assertNonNullable(hwndBtnPrev);
239
- assertNonNullable(hwndBtnNext);
240
- if (msg === 2 /* WmMsg.DESTROY */) {
241
- PostQuitMessage(0);
242
- return 0;
243
- }
244
- if (msg === 5 /* WmMsg.SIZE */) {
245
- const crBuf = RECT.alloc();
246
- if (GetClientRect(hwnd, crBuf.ptr)) {
247
- const { left, top, right, bottom } = RECT.decode(crBuf);
248
- const cw = right - left, ch = bottom - top;
249
- SetWindowPos(hwndCanvas, 0 /* SetWindowPosHwnd.TOP */, 0, 50, cw, Math.max(1, ch - 50), 4 /* SetWindowPosFlag.SWP_NOZORDER */);
250
- SetWindowPos(hwndEdit, 0 /* SetWindowPosHwnd.TOP */, 0, 0, Math.max(100, cw - 320), 0, 2 /* SetWindowPosFlag.SWP_NOMOVE */ | 4 /* SetWindowPosFlag.SWP_NOZORDER */);
251
- }
252
- return gui.DefWindowProc(hwnd, msg, wParam, lParam);
253
- }
254
- if (msg === 273 /* WmMsg.COMMAND */) {
255
- const hCtrl = lParam;
256
- if (hCtrl === hwndBtnOpen) {
257
- const path = openPdfFileDialog();
258
- if (path) {
259
- SetWindowText(hwndEdit, path);
260
- showPdf(mupdf, path, 0);
261
- }
262
- }
263
- else if (hCtrl === hwndBtnPrev) {
264
- const cap = GetWindowTextLength(hwndEdit) + 1;
265
- const buf = WCHAR.alloc(cap);
266
- GetWindowText(hwndEdit, buf, cap);
267
- const path = WCHAR.decode(buf);
268
- if (path && currentPage > 0)
269
- showPdf(mupdf, path, currentPage - 1);
270
- }
271
- else if (hCtrl === hwndBtnNext) {
272
- const cap = GetWindowTextLength(hwndEdit) + 1;
273
- const buf = WCHAR.alloc(cap);
274
- GetWindowText(hwndEdit, buf, cap);
275
- const path = WCHAR.decode(buf);
276
- if (path && currentPage < totalPages - 1)
277
- showPdf(mupdf, path, currentPage + 1);
278
- }
279
- return 0;
280
- }
281
- return gui.DefWindowProc(hwnd, msg, wParam, lParam);
282
- });
283
- hwndMain = gui.CreateWindow('PdfViewer2', 'PDF 预览 2', 13565952 /* WindowStyle.OVERLAPPEDWINDOW */ | 33554432 /* WindowStyle.CLIPCHILDREN */, 100, 100, 1100, 800, null, null);
284
- if (!hwndMain) {
285
- MessageBox(NULL, '创建主窗口失败', 'JS Alert', 0);
286
- return;
287
- }
288
- // 控件直接挂在主窗口上
289
- hwndEdit = gui.CreateWindow('EDIT', '', WS_CHILD | WS_VIS | WS_BORDER, ctrlY + btnW + gap, ctrlY, 480, ctrlH, hwndMain, null);
290
- hwndBtnOpen = gui.CreateWindow('BUTTON', '打开 PDF', WS_CHILD | WS_VIS, ctrlY, ctrlY, btnW, ctrlH, hwndMain, null);
291
- hwndBtnPrev = gui.CreateWindow('BUTTON', '上一页', WS_CHILD | WS_VIS, ctrlY + btnW + gap + 480 + gap, ctrlY, btnPageW, ctrlH, hwndMain, null);
292
- hwndBtnNext = gui.CreateWindow('BUTTON', '下一页', WS_CHILD | WS_VIS, ctrlY + btnW + gap + 480 + gap + btnPageW + gap, ctrlY, btnPageW, ctrlH, hwndMain, null);
293
- // 画布(带滚动条)
294
- hwndCanvas = gui.CreateWindow('STATIC', '', WS_CHILD | WS_VIS | 33554432 /* WindowStyle.CLIPCHILDREN */ | 2097152 /* WindowStyle.VSCROLL */ | 1048576 /* WindowStyle.HSCROLL */, 0, 50, 1100, 750, hwndMain, null);
295
- // 内容窗口(画 pixmap)
296
- hwndContent = gui.CreateWindow('STATIC', '', WS_CHILD | WS_VIS, 0, 0, 100, 100, hwndCanvas, null);
297
- assertNonNullable(hwndMain);
298
- assertNonNullable(hwndEdit);
299
- assertNonNullable(hwndCanvas);
300
- assertNonNullable(hwndContent);
301
- assertNonNullable(hwndBtnOpen);
302
- assertNonNullable(hwndBtnPrev);
303
- assertNonNullable(hwndBtnNext);
304
- // 内容窗口 PAINT
305
- gui.SetWindowProc(hwndContent, (hwnd, msg, wParam, lParam) => {
306
- if (msg === 20 /* WmMsg.ERASEBKGND */)
307
- return 1;
308
- if (msg === 15 /* WmMsg.PAINT */) {
309
- gui.DefWindowProc(hwnd, msg, wParam, lParam);
310
- const pm = currentPixmap;
311
- if (!pm)
312
- return 0;
313
- const hdc = GetDC(hwnd);
314
- if (hdc) {
315
- const bmi = makeBitmapInfo(pm.w, pm.h);
316
- SetDIBitsToDevice(hdc, 0, 0, pm.w, pm.h, 0, 0, 0, pm.h, pm.data, bmi, 0 /* ColorUse.RGB_COLORS */);
317
- ReleaseDC(hwnd, hdc);
318
- }
319
- return 0;
320
- }
321
- return gui.DefWindowProc(hwnd, msg, wParam, lParam);
322
- });
323
- // 画布消息处理(PAINT 填白、滚动条、滚轮)
324
- gui.SetWindowProc(hwndCanvas, (hwnd, msg, wParam, lParam) => {
325
- if (msg === 20 /* WmMsg.ERASEBKGND */)
326
- return 1;
327
- if (msg === 15 /* WmMsg.PAINT */) {
328
- const crBuf = RECT.alloc();
329
- if (GetClientRect(hwnd, crBuf.ptr)) {
330
- const { left, top, right, bottom } = RECT.decode(crBuf);
331
- const cw = right - left, ch = bottom - top;
332
- const hdc = GetDC(hwnd);
333
- if (hdc) {
334
- PatBlt(hdc, 0, 0, cw, ch, WHITENESS);
335
- ReleaseDC(hwnd, hdc);
336
- }
337
- }
338
- gui.DefWindowProc(hwnd, msg, wParam, lParam);
339
- return 0;
340
- }
341
- if (msg === 277 /* WmMsg.VSCROLL */ || msg === 276 /* WmMsg.HSCROLL */) {
342
- const bar = msg === 277 /* WmMsg.VSCROLL */ ? 1 /* ScrollBar.VERT */ : 0 /* ScrollBar.HORZ */;
343
- const si = SCROLLINFO.encode({ cbSize: SCROLLINFO.size, fMask: 23 /* ScrollInfoFlag.ALL */ });
344
- GetScrollInfo(hwnd, bar, si.ptr);
345
- const info = SCROLLINFO.decode(si);
346
- const maxPos = info.nMax - info.nPage + 1;
347
- const code = wParam & 0xFFFF;
348
- let newPos = bar === 1 /* ScrollBar.VERT */ ? scrollY : scrollX;
349
- if (code === 5 /* ScrollCmd.THUMBTRACK */ || code === 4 /* ScrollCmd.THUMBPOSITION */)
350
- newPos = Math.max(0, Math.min(maxPos, (wParam >> 16) & 0xFFFF));
351
- else if (code === 0 /* ScrollCmd.LINEUP */)
352
- newPos -= 20;
353
- else if (code === 1 /* ScrollCmd.LINEDOWN */)
354
- newPos += 20;
355
- else if (code === 2 /* ScrollCmd.PAGEUP */)
356
- newPos -= info.nPage;
357
- else if (code === 3 /* ScrollCmd.PAGEDOWN */)
358
- newPos += info.nPage;
359
- else
360
- return 0;
361
- newPos = Math.max(0, Math.min(maxPos, newPos));
362
- if (bar === 1 /* ScrollBar.VERT */)
363
- doScroll(0, newPos - scrollY);
364
- else
365
- doScroll(newPos - scrollX, 0);
366
- return 0;
367
- }
368
- if (msg === 522 /* WmMsg.MOUSEWHEEL */) {
369
- const raw = (wParam >>> 16) & 0xFFFF;
370
- const wheel = raw >= 0x8000 ? raw - 0x10000 : raw;
371
- const isHorz = (wParam & 4 /* MouseKeyFlag.MK_SHIFT */) !== 0;
372
- const bar = isHorz ? 0 /* ScrollBar.HORZ */ : 1 /* ScrollBar.VERT */;
373
- const si = SCROLLINFO.encode({ cbSize: SCROLLINFO.size, fMask: 23 /* ScrollInfoFlag.ALL */ });
374
- GetScrollInfo(hwnd, bar, si.ptr);
375
- const info = SCROLLINFO.decode(si);
376
- const maxPos = info.nMax - info.nPage + 1;
377
- let newPos = (isHorz ? scrollX : scrollY) - Math.round(wheel * 40 / 120);
378
- newPos = Math.max(0, Math.min(maxPos, newPos));
379
- if (isHorz)
380
- doScroll(newPos - scrollX, 0);
381
- else
382
- doScroll(0, newPos - scrollY);
383
- return 0;
384
- }
385
- if (msg === 5 /* WmMsg.SIZE */) {
386
- updateScrollRange();
387
- return gui.DefWindowProc(hwnd, msg, wParam, lParam);
388
- }
389
- return gui.DefWindowProc(hwnd, msg, wParam, lParam);
390
- });
391
- ShowWindow(hwndMain, 1 /* ShowWindowCmd.SHOWNORMAL */);
392
- const test = std.open('test/example.pdf', 'rb');
393
- if (test) {
394
- test.close();
395
- showPdf(mupdf, 'test/example.pdf', 0);
396
- }
397
- }
398
- main();