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.
Files changed (137) hide show
  1. package/README.en.md +3 -3
  2. package/README.md +21 -24
  3. package/examples/PdfCanvas.js +8 -37
  4. package/examples/PdfCanvas.tsx +11 -41
  5. package/examples/exec_server.js +20054 -1423
  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 +31 -73
  10. package/examples/pdf_preview2.ts +33 -76
  11. package/examples/pdf_viewer.js +1496 -616
  12. package/examples/pdf_viewer.tsx +23 -64
  13. package/examples/setres.js +22 -47
  14. package/examples/setres.ts +23 -57
  15. package/examples/test_gallery.js +1491 -525
  16. package/examples/test_react_lazy.js +1455 -500
  17. package/examples/test_react_listbox.js +1454 -499
  18. package/examples/test_root_window.js +1450 -495
  19. package/examples/test_tab.js +1455 -500
  20. package/lib/abort.js +70 -0
  21. package/lib/abort.ts +69 -0
  22. package/lib/certs.js +214 -0
  23. package/lib/certs.ts +224 -0
  24. package/lib/exec-log.js +15 -0
  25. package/lib/exec-log.ts +30 -0
  26. package/lib/fetch.js +37 -4
  27. package/lib/fetch.ts +35 -4
  28. package/lib/ffi/bind.js +352 -0
  29. package/lib/ffi/bind.ts +442 -0
  30. package/lib/ffi/ctype.js +168 -0
  31. package/lib/ffi/ctype.ts +331 -0
  32. package/lib/ffi/index.js +6 -0
  33. package/lib/ffi/index.ts +6 -0
  34. package/lib/ffi/struct.js +412 -0
  35. package/lib/ffi/struct.ts +664 -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 +20 -33
  41. package/lib/react-qw/components/Input.js +3 -10
  42. package/lib/react-qw/components/Link.js +7 -22
  43. package/lib/react-qw/components/ListView.js +80 -141
  44. package/lib/react-qw/components/PathPicker.js +36 -80
  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 +15 -20
  48. package/lib/react-qw/components/Tooltip.js +21 -20
  49. package/lib/react-qw/components/TreeView.js +14 -47
  50. package/lib/react-qw/index.js +4 -2
  51. package/lib/react-qw/index.ts +4 -2
  52. package/lib/react-qw/nmhdr.js +5 -0
  53. package/lib/react-qw/nmhdr.ts +7 -0
  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 +18 -35
  59. package/lib/text-measure.ts +20 -37
  60. package/lib/websocket.js +12 -2
  61. package/lib/websocket.ts +15 -2
  62. package/lib/windows/comctl32.js +18 -0
  63. package/lib/windows/comctl32.ts +20 -0
  64. package/lib/windows/comdlg32.js +7 -0
  65. package/lib/windows/comdlg32.ts +9 -0
  66. package/lib/windows/gdi32.js +90 -0
  67. package/lib/windows/gdi32.ts +97 -0
  68. package/lib/windows/kernel32.js +66 -0
  69. package/lib/windows/kernel32.ts +76 -0
  70. package/lib/windows/ntdll.js +8 -0
  71. package/lib/windows/ntdll.ts +10 -0
  72. package/lib/windows/ole32.js +7 -0
  73. package/lib/windows/ole32.ts +9 -0
  74. package/lib/windows/shell32.js +11 -0
  75. package/lib/windows/shell32.ts +14 -0
  76. package/lib/windows/structs.js +384 -0
  77. package/lib/windows/structs.ts +422 -0
  78. package/lib/windows/user32.js +469 -0
  79. package/lib/windows/user32.ts +502 -0
  80. package/package.json +1 -1
  81. package/quickwin.d.ts +22 -33
  82. package/quickwin_const.d.ts +1 -0
  83. package/qwin-nowasm-x86.exe +0 -0
  84. package/qwin-nowasm.exe +0 -0
  85. package/qwin-x86.exe +0 -0
  86. package/qwin.exe +0 -0
  87. package/test/bench_ffi_callraw.js +236 -0
  88. package/test/bench_ffi_callraw.ts +236 -0
  89. package/test/bench_ffi_overhead.js +139 -0
  90. package/test/bench_ffi_overhead.ts +141 -0
  91. package/test/bench_sendmessage.js +104 -0
  92. package/test/bench_sendmessage.ts +100 -0
  93. package/test/bench_sendmessage_nonnull.js +187 -0
  94. package/test/bench_sendmessage_nonnull.ts +188 -0
  95. package/test/run.js +14 -4
  96. package/test/run.ts +15 -5
  97. package/test/test_basic_fetch.js +8 -0
  98. package/test/test_basic_fetch.ts +9 -0
  99. package/test/test_ffi.js +33 -47
  100. package/test/test_ffi.ts +41 -60
  101. package/test/test_ffi_abi.js +235 -0
  102. package/test/test_ffi_abi.ts +218 -0
  103. package/test/test_ffi_bind.js +572 -0
  104. package/test/test_ffi_bind.ts +597 -0
  105. package/test/test_ffi_struct.js +745 -0
  106. package/test/test_ffi_struct.ts +798 -0
  107. package/test/test_ffi_struct_layout.js +495 -0
  108. package/test/test_ffi_struct_layout.ts +543 -0
  109. package/test/test_ffi_user32.js +103 -0
  110. package/test/test_ffi_user32.ts +113 -0
  111. package/test/test_ffi_windows.js +101 -0
  112. package/test/test_ffi_windows.ts +113 -0
  113. package/test/test_helper.js +8 -1
  114. package/test/test_helper.ts +9 -1
  115. package/test/test_http_import.js +18 -0
  116. package/test/test_http_import.ts +19 -0
  117. package/test/test_http_server.js +73 -1
  118. package/test/test_http_server.ts +75 -1
  119. package/test/test_ipv6.js +2 -2
  120. package/test/test_ipv6.ts +2 -2
  121. package/test/test_net_fetch.js +70 -8
  122. package/test/test_net_fetch.ts +69 -7
  123. package/test/test_net_websocket.js +1 -1
  124. package/test/test_net_websocket.ts +1 -1
  125. package/test/test_react_complex.js +1465 -510
  126. package/test/test_react_counter.js +1455 -500
  127. package/test/test_react_flex.js +1475 -513
  128. package/test/test_react_hidden.js +1458 -503
  129. package/test/test_react_listview_link.js +1455 -500
  130. package/test/test_react_notify.js +18534 -0
  131. package/test/test_react_render.js +1455 -500
  132. package/test/test_wolfssl_read.js +3 -2
  133. package/test/test_wolfssl_read.ts +3 -1
  134. package/test/test_worker_net.js +35 -17
  135. package/test/test_worker_net.ts +27 -15
  136. package/tsconfig.json +1 -1
  137. package/examples/exec_server.ts +0 -80
package/README.en.md CHANGED
@@ -13,10 +13,11 @@ Install:
13
13
  ```bash
14
14
  # Option 1: npm local install (recommended)
15
15
  npm install quickwin
16
- npx quickwin script.js
16
+ npx quickwin node_modules/quickwin/main.js # bundled main.js demo; use npx quickwin script.js for your own scripts
17
17
 
18
18
  # Option 2: download directly from GitHub Release
19
19
  iwr https://github.com/xna00/quickwin/releases/latest/download/qwin.exe -OutFile qwin.exe
20
+ iwr https://github.com/xna00/quickwin/releases/latest/download/main.js -OutFile main.js
20
21
  .\qwin.exe main.js
21
22
  ```
22
23
 
@@ -29,7 +30,7 @@ The npm package ships 4 executables: `qwin.exe` (64-bit) / `qwin-x86.exe` (32-bi
29
30
  - **HTTP/HTTPS** — `fetch()` API, Brotli decompression, chunked transfer, conditional caching
30
31
  - **WebSocket** — full RFC 6455 implementation, ws:// + wss://
31
32
  - **WebAssembly** — WAMR-based, supports `WebAssembly.*` standard API
32
- - **FFI** — call any DLL function via libffi
33
+ - **FFI** — call any DLL function via a built-in asm stub and declarative `bind()` signatures (no third-party dependency)
33
34
  - **Polyfills** — `TextEncoder`, `URL`, `URLSearchParams`, `btoa`/`atob`, `crypto.subtle`, `setTimeout`
34
35
  - **Dynamic import** — `import('https://esm.sh/...')`, no dependency installation needed
35
36
 
@@ -104,7 +105,6 @@ When run without a script file argument, `qwin.exe` checks for embedded JS at th
104
105
  | `fetch` | `import './lib/fetch.js'` | adds `fetch()`, `Response`, `Headers` to globalThis |
105
106
  | `websocket` | `import './lib/websocket.js'` | adds `WebSocket` to globalThis |
106
107
  | `polyfill` | `import './lib/polyfill.js'` | adds `TextEncoder`, `URL`, `btoa`/`atob`, `setTimeout` to globalThis |
107
- | `preact` | `lib/preact/...` | JSX → Win32 renderer (`render`, `useState`, `useEffect`) |
108
108
  | `react-qw` | `lib/react-qw/` | React Custom Renderer for Win32 GUI ([docs](lib/react-qw/)) |
109
109
 
110
110
  ## Worker
package/README.md CHANGED
@@ -13,10 +13,11 @@ Windows 平台上的 QuickJS 运行时,支持原生 GUI、网络、WASM、FFI
13
13
  ```bash
14
14
  # 方式一:npm 本地安装(推荐)
15
15
  npm install quickwin
16
- npx quickwin script.js
16
+ npx quickwin node_modules/quickwin/main.js # 包自带 main.js 示例;用 npx quickwin script.js 运行你自己的脚本
17
17
 
18
18
  # 方式二:直接从 GitHub Release 下载
19
19
  iwr https://github.com/xna00/quickwin/releases/latest/download/qwin.exe -OutFile qwin.exe
20
+ iwr https://github.com/xna00/quickwin/releases/latest/download/main.js -OutFile main.js
20
21
  .\qwin.exe main.js
21
22
  ```
22
23
 
@@ -29,7 +30,7 @@ npm 包自带 4 个可执行文件:`qwin.exe`(64 位)/ `qwin-x86.exe`(32
29
30
  - **HTTP/HTTPS** —— `fetch()` API、Brotli 解压、chunked 传输、条件缓存
30
31
  - **WebSocket** —— 完整的 RFC 6455 实现,支持 ws:// 与 wss://
31
32
  - **WebAssembly** —— 基于 WAMR,支持标准 `WebAssembly.*` API
32
- - **FFI** —— 通过 libffi 调用任意 DLL 函数
33
+ - **FFI** —— 内置汇编调用桩,用 `bind()` 声明式签名调用任意 DLL 函数(无第三方依赖)
33
34
  - **Polyfills** —— `TextEncoder`、`URL`、`URLSearchParams`、`btoa`/`atob`、`crypto.subtle`、`setTimeout`
34
35
  - **动态导入** —— `import('https://esm.sh/...')`,无需安装任何依赖
35
36
 
@@ -103,7 +104,6 @@ _build/exec_server.exe
103
104
  | `fetch` | `import './lib/fetch.js'` | 向 globalThis 添加 `fetch()`、`Response`、`Headers` |
104
105
  | `websocket` | `import './lib/websocket.js'` | 向 globalThis 添加 `WebSocket` |
105
106
  | `polyfill` | `import './lib/polyfill.js'` | 向 globalThis 添加 `TextEncoder`、`URL`、`btoa`/`atob`、`setTimeout` |
106
- | `preact` | `lib/preact/...` | JSX → Win32 渲染器(`render`、`useState`、`useEffect`) |
107
107
  | `react-qw` | `lib/react-qw/` | 面向 Win32 GUI 的 React 自定义渲染器([文档](lib/react-qw/)) |
108
108
 
109
109
  ## Worker
@@ -167,48 +167,45 @@ parent.onmessage = (e) => {
167
167
 
168
168
  ### 前置依赖
169
169
 
170
- - MSYS2 UCRT64 或 MINGW64
171
- - Node.js(用于通过 tsc 编译 TypeScript)
170
+ - **podman**(开发容器;构建/测试/QEMU 验证都在容器内完成,与 CI 一致)
172
171
  - Git(用于子模块)
173
172
 
173
+ > 也支持 MSYS2 原生直接 `make`,详见 `.agents/DEVELOPMENT_WORKFLOW.md`。
174
+
174
175
  ### 构建
175
176
 
176
177
  ```bash
177
178
  git clone --recursive https://github.com/xna00/quickwin.git
178
179
  cd quickwin
179
180
 
180
- .\run.ps1 "make wamr" # 构建 WAMR 库(仅首次)
181
- .\run.ps1 "make small" # 构建 qwin.exe(-Os + LTO,约 1.5MB)
182
- .\run.ps1 "make js" # 编译 TypeScript
183
- .\run.ps1 "make test" # 运行全部测试
181
+ ./docker/dev-podman.sh up # 启动开发容器(复用 ghcr.io/xna00/quickwin-dev)
182
+ podman exec quickwin-dev bash -lc 'cd /workspace && make js && make cc64 && make test TEST=-net'
184
183
  ```
185
184
 
186
- `make nowasm` 会产出更小的 `_build/qwin-nowasm.exe`,不含 WASM/WAMR
187
- (没有 `WebAssembly` 全局对象);对这种版本运行 `make test TEST=-wasm` 跳过 WASM 测试。
185
+ `make cc64` 产出 `_build/qwin.exe`。`cc64-nowasm` 会产出更小的
186
+ `_build/qwin-nowasm.exe`,不含 WASM/WAMR(没有 `WebAssembly` 全局对象);
187
+ 对这种版本运行 `make test TEST=-wasm` 跳过 WASM 测试。
188
188
 
189
189
  ### 构建目标
190
190
 
191
191
  | Target | Description |
192
192
  |--------|-------------|
193
- | `make` / `make nodebug` | 快速构建 |
194
- | `make small` | `-Os` + LTO + strip,约 1.5MB(推荐) |
195
- | `make minimal` | `small` + UPX 压缩 |
196
- | `make release` | `-O2` + LTO + strip(未做 `-Os` 优化) |
197
- | `make debug` | 带 bridge 日志的调试构建 |
198
- | `make nowasm` | 无 WASM/WAMR 构建 → `_build/qwin-nowasm.exe`(约 1.2MB,无 `WebAssembly` 全局) |
199
- | `make cc64-small` | 交叉编译 x86_64 `_build/qwin.exe`(`-Os`,CI 用) |
200
- | `make cc32-small` | 交叉编译 i686 `_build/qwin-x86.exe`(`-Os`,兼容 XP,CI 用) |
193
+ | `make cc64` | 交叉编译 x86_64 → `_build/qwin.exe`(默认目标,`BUILD=fast`) |
194
+ | `make cc32` | 交叉编译 i686/XP → `_build/qwin-x86.exe` |
195
+ | `make cc64-nowasm` / `cc32-nowasm` | 无 WASM/WAMR 版 |
196
+ | `BUILD=fast\|small\|debug` | 构建 flavor:`make cc64 BUILD=small` = `-Os`+LTO(约 1.5MB,CI 用) |
201
197
  | `make js` | 通过 tsc 编译 TypeScript |
202
- | `make wasm` | 编译 WAT → WASM fixtures |
198
+ | `make wasm` / `make wat` | 编译 WAT → WASM fixtures |
203
199
  | `make test` | 运行全部测试 |
204
200
  | `make test TEST=-net` | 跳过网络测试(快速) |
205
201
  | `make test TEST=wasm` | 仅运行 WASM 测试 |
206
- | `make wamr` | 重建 WAMR 库 |
207
- | `make embed-js` | 把 `embed.js` 内嵌进 exe(用 `JS_EMBED=file.js`) |
208
- | `make embed-js-br` | 把 Brotli 压缩的 JS 内嵌进 exe |
209
202
  | `make exec_server` | 打包 `examples/exec_server.ts` 并 Brotli 内嵌进 `_build/exec_server.exe` |
203
+ | `make embed-js` / `embed-js-br` | 把 JS(Brotli 压缩)内嵌进 exe |
210
204
  | `make npm-pkg` | 打包到 `dist/quickwin/` |
211
- | `make clean` | 清理构建产物 |
205
+ | `make gen-const` | 重新生成 `quickwin_const.d.ts` |
206
+ | `make clean` / `distclean` | 清理(会清掉整个 `_build/`,之后需 `make js wasm`) |
207
+
208
+ 构建与排错细节见 `.agents/DEVELOPMENT_WORKFLOW.md`。
212
209
 
213
210
  ## 许可证
214
211
 
@@ -1,32 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { forwardRef, useRef } from 'react';
3
- import * as win from 'win';
4
- import * as ffi from 'ffi';
5
- const _user32 = win.LoadLibrary('user32.dll');
6
- const _gdi32 = win.LoadLibrary('gdi32.dll');
7
- if (!_user32 || !_gdi32)
8
- throw new Error('Failed to load user32/gdi32');
9
- function loadProc(lib, name) {
10
- const ptr = win.GetProcAddress(lib, name);
11
- if (!ptr)
12
- throw new Error('Failed to load ' + name);
13
- return ptr;
14
- }
15
- const GetDC_ = loadProc(_user32, 'GetDC');
16
- const ReleaseDC_ = loadProc(_user32, 'ReleaseDC');
17
- const SetDIBitsToDevice_ = loadProc(_gdi32, 'SetDIBitsToDevice');
18
- const FFI_PTR = ffi.FFI_TYPE_POINTER;
19
- const FFI_U32 = ffi.FFI_TYPE_UINT32;
20
- const FFI_S32 = ffi.FFI_TYPE_SINT32;
3
+ import { GetDC, ReleaseDC } from '../lib/windows/user32.js';
4
+ import { SetDIBitsToDevice } from '../lib/windows/gdi32.js';
5
+ import { BITMAPINFOHEADER } from '../lib/windows/structs.js';
21
6
  function makeBitmapInfo(w, h) {
22
- const bmi = new ArrayBuffer(40);
23
- const bv = new DataView(bmi);
24
- bv.setUint32(0, 40, true);
25
- bv.setInt32(4, w, true);
26
- bv.setInt32(8, -h, true);
27
- bv.setUint16(12, 1, true);
28
- bv.setUint16(14, 24, true);
29
- return bmi;
7
+ // biHeight 负 = 自顶向下(DIB 原点左上);biCompression 缺省 0 = BI_RGB 无压缩
8
+ return BITMAPINFOHEADER.encode({ biSize: BITMAPINFOHEADER.size, biWidth: w, biHeight: -h, biPlanes: 1, biBitCount: 24 });
30
9
  }
31
10
  export const PdfCanvas = forwardRef(({ pixmap, style }, ref) => {
32
11
  const canvasRef = useRef(null);
@@ -46,19 +25,11 @@ export const PdfCanvas = forwardRef(({ pixmap, style }, ref) => {
46
25
  const pm = pixmapRef.current;
47
26
  if (!pm)
48
27
  return 0;
49
- const hdc = ffi.ffiCall(GetDC_, [ffi.FFI_TYPE_UINT64], [hwnd], ffi.FFI_TYPE_UINT64);
28
+ const hdc = GetDC(hwnd);
50
29
  if (hdc) {
51
30
  const bmi = makeBitmapInfo(pm.w, pm.h);
52
- ffi.ffiCall(SetDIBitsToDevice_, [
53
- ffi.FFI_TYPE_UINT64, FFI_S32, FFI_S32, FFI_U32, FFI_U32,
54
- FFI_S32, FFI_S32, FFI_U32, FFI_U32,
55
- FFI_PTR, FFI_PTR, FFI_U32
56
- ], [
57
- hdc, 0, 0, pm.w, pm.h,
58
- 0, 0, 0, pm.h,
59
- pm.data, bmi, 0
60
- ], FFI_S32);
61
- ffi.ffiCall(ReleaseDC_, [ffi.FFI_TYPE_UINT64, ffi.FFI_TYPE_UINT64], [hwnd, hdc], FFI_S32);
31
+ SetDIBitsToDevice(hdc, 0, 0, pm.w, pm.h, 0, 0, 0, pm.h, pm.data, bmi, 0);
32
+ ReleaseDC(hwnd, hdc);
62
33
  }
63
34
  return 0;
64
35
  }
@@ -1,40 +1,18 @@
1
+ import { PtrArrayBuffer } from '../lib/ffi/ctype.js'
1
2
  import { forwardRef, useRef } from 'react'
2
3
  import * as gui from 'gui'
3
- import * as win from 'win'
4
- import * as ffi from 'ffi'
4
+ import { GetDC, ReleaseDC } from '../lib/windows/user32.js'
5
+ import { SetDIBitsToDevice } from '../lib/windows/gdi32.js'
6
+ import { BITMAPINFOHEADER } from '../lib/windows/structs.js'
5
7
  import type { WStyle } from '../lib/react-qw/jsx.d.ts'
6
8
 
7
- const _user32 = win.LoadLibrary('user32.dll')
8
- const _gdi32 = win.LoadLibrary('gdi32.dll')
9
- if (!_user32 || !_gdi32) throw new Error('Failed to load user32/gdi32')
10
-
11
- function loadProc(lib: win.HMODULE, name: string): number {
12
- const ptr = win.GetProcAddress(lib, name)
13
- if (!ptr) throw new Error('Failed to load ' + name)
14
- return ptr
15
- }
16
-
17
- const GetDC_ = loadProc(_user32, 'GetDC')
18
- const ReleaseDC_ = loadProc(_user32, 'ReleaseDC')
19
- const SetDIBitsToDevice_ = loadProc(_gdi32, 'SetDIBitsToDevice')
20
-
21
- const FFI_PTR = ffi.FFI_TYPE_POINTER
22
- const FFI_U32 = ffi.FFI_TYPE_UINT32
23
- const FFI_S32 = ffi.FFI_TYPE_SINT32
24
-
25
- function makeBitmapInfo(w: number, h: number): ArrayBuffer {
26
- const bmi = new ArrayBuffer(40)
27
- const bv = new DataView(bmi)
28
- bv.setUint32(0, 40, true)
29
- bv.setInt32(4, w, true)
30
- bv.setInt32(8, -h, true)
31
- bv.setUint16(12, 1, true)
32
- bv.setUint16(14, 24, true)
33
- return bmi
9
+ function makeBitmapInfo(w: number, h: number) {
10
+ // biHeight 负 = 自顶向下(DIB 原点左上);biCompression 缺省 0 = BI_RGB 无压缩
11
+ return BITMAPINFOHEADER.encode({ biSize: BITMAPINFOHEADER.size, biWidth: w, biHeight: -h, biPlanes: 1, biBitCount: 24 })
34
12
  }
35
13
 
36
14
  export interface PdfCanvasProps {
37
- pixmap?: { data: ArrayBuffer; w: number; h: number }
15
+ pixmap?: { data: PtrArrayBuffer<string>; w: number; h: number }
38
16
  style?: WStyle
39
17
  }
40
18
 
@@ -59,19 +37,11 @@ export const PdfCanvas = forwardRef<gui.HWND, PdfCanvasProps>(
59
37
  if (e.msg === gui.WmMsg.PAINT) {
60
38
  const pm = pixmapRef.current
61
39
  if (!pm) return 0
62
- const hdc = ffi.ffiCall(GetDC_, [ffi.FFI_TYPE_UINT64], [hwnd], ffi.FFI_TYPE_UINT64)
40
+ const hdc = GetDC(hwnd)
63
41
  if (hdc) {
64
42
  const bmi = makeBitmapInfo(pm.w, pm.h)
65
- ffi.ffiCall(SetDIBitsToDevice_, [
66
- ffi.FFI_TYPE_UINT64, FFI_S32, FFI_S32, FFI_U32, FFI_U32,
67
- FFI_S32, FFI_S32, FFI_U32, FFI_U32,
68
- FFI_PTR, FFI_PTR, FFI_U32
69
- ], [
70
- hdc, 0, 0, pm.w, pm.h,
71
- 0, 0, 0, pm.h,
72
- pm.data, bmi, 0
73
- ], FFI_S32)
74
- ffi.ffiCall(ReleaseDC_, [ffi.FFI_TYPE_UINT64, ffi.FFI_TYPE_UINT64], [hwnd, hdc], FFI_S32)
43
+ SetDIBitsToDevice(hdc, 0, 0, pm.w, pm.h, 0, 0, 0, pm.h, pm.data, bmi, 0)
44
+ ReleaseDC(hwnd, hdc)
75
45
  }
76
46
  return 0
77
47
  }