quickwin 1.3.0 → 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 +1 -2
- package/README.md +19 -23
- 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 +25 -82
- package/examples/pdf_preview2.ts +27 -84
- package/examples/pdf_viewer.js +1318 -1178
- package/examples/pdf_viewer.tsx +16 -67
- package/examples/setres.js +22 -47
- package/examples/setres.ts +23 -57
- package/examples/test_gallery.js +1313 -1074
- package/examples/test_react_lazy.js +1284 -1056
- package/examples/test_react_listbox.js +1283 -1055
- package/examples/test_root_window.js +1279 -1051
- package/examples/test_tab.js +1284 -1056
- 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 +18 -37
- package/lib/react-qw/components/Input.js +3 -10
- package/lib/react-qw/components/Link.js +6 -19
- package/lib/react-qw/components/ListView.js +49 -154
- package/lib/react-qw/components/PathPicker.js +28 -88
- 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 +6 -22
- package/lib/react-qw/components/Tooltip.js +10 -21
- package/lib/react-qw/components/TreeView.js +8 -31
- package/lib/react-qw/index.js +4 -2
- package/lib/react-qw/index.ts +4 -2
- package/lib/react-qw/nmhdr.js +3 -24
- package/lib/react-qw/nmhdr.ts +5 -30
- 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 -23
- package/lib/text-measure.ts +20 -25
- 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 -37
- 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 +12 -4
- package/test/run.ts +13 -5
- package/test/test_basic_fetch.js +8 -0
- package/test/test_basic_fetch.ts +9 -0
- package/test/test_ffi.js +25 -43
- package/test/test_ffi.ts +33 -52
- package/test/test_ffi_abi.js +235 -0
- package/test/test_ffi_abi.ts +218 -0
- package/test/test_ffi_bind.js +538 -8
- package/test/test_ffi_bind.ts +559 -8
- package/test/test_ffi_struct.js +632 -88
- package/test/test_ffi_struct.ts +666 -91
- 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 +1294 -1066
- package/test/test_react_counter.js +1284 -1056
- package/test/test_react_flex.js +1304 -1069
- package/test/test_react_hidden.js +1287 -1059
- package/test/test_react_listview_link.js +1284 -1056
- package/test/test_react_notify.js +18534 -0
- package/test/test_react_render.js +1284 -1056
- 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/lib/ffi-bind.js +0 -85
- package/lib/ffi-bind.ts +0 -170
- package/lib/ffi-struct.js +0 -224
- package/lib/ffi-struct.ts +0 -239
- package/lib/win-common-structs.js +0 -39
- package/lib/win-common-structs.ts +0 -41
package/README.en.md
CHANGED
|
@@ -30,7 +30,7 @@ The npm package ships 4 executables: `qwin.exe` (64-bit) / `qwin-x86.exe` (32-bi
|
|
|
30
30
|
- **HTTP/HTTPS** — `fetch()` API, Brotli decompression, chunked transfer, conditional caching
|
|
31
31
|
- **WebSocket** — full RFC 6455 implementation, ws:// + wss://
|
|
32
32
|
- **WebAssembly** — WAMR-based, supports `WebAssembly.*` standard API
|
|
33
|
-
- **FFI** — call any DLL function via
|
|
33
|
+
- **FFI** — call any DLL function via a built-in asm stub and declarative `bind()` signatures (no third-party dependency)
|
|
34
34
|
- **Polyfills** — `TextEncoder`, `URL`, `URLSearchParams`, `btoa`/`atob`, `crypto.subtle`, `setTimeout`
|
|
35
35
|
- **Dynamic import** — `import('https://esm.sh/...')`, no dependency installation needed
|
|
36
36
|
|
|
@@ -105,7 +105,6 @@ When run without a script file argument, `qwin.exe` checks for embedded JS at th
|
|
|
105
105
|
| `fetch` | `import './lib/fetch.js'` | adds `fetch()`, `Response`, `Headers` to globalThis |
|
|
106
106
|
| `websocket` | `import './lib/websocket.js'` | adds `WebSocket` to globalThis |
|
|
107
107
|
| `polyfill` | `import './lib/polyfill.js'` | adds `TextEncoder`, `URL`, `btoa`/`atob`, `setTimeout` to globalThis |
|
|
108
|
-
| `preact` | `lib/preact/...` | JSX → Win32 renderer (`render`, `useState`, `useEffect`) |
|
|
109
108
|
| `react-qw` | `lib/react-qw/` | React Custom Renderer for Win32 GUI ([docs](lib/react-qw/)) |
|
|
110
109
|
|
|
111
110
|
## Worker
|
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ npm 包自带 4 个可执行文件:`qwin.exe`(64 位)/ `qwin-x86.exe`(32
|
|
|
30
30
|
- **HTTP/HTTPS** —— `fetch()` API、Brotli 解压、chunked 传输、条件缓存
|
|
31
31
|
- **WebSocket** —— 完整的 RFC 6455 实现,支持 ws:// 与 wss://
|
|
32
32
|
- **WebAssembly** —— 基于 WAMR,支持标准 `WebAssembly.*` API
|
|
33
|
-
- **FFI** ——
|
|
33
|
+
- **FFI** —— 内置汇编调用桩,用 `bind()` 声明式签名调用任意 DLL 函数(无第三方依赖)
|
|
34
34
|
- **Polyfills** —— `TextEncoder`、`URL`、`URLSearchParams`、`btoa`/`atob`、`crypto.subtle`、`setTimeout`
|
|
35
35
|
- **动态导入** —— `import('https://esm.sh/...')`,无需安装任何依赖
|
|
36
36
|
|
|
@@ -104,7 +104,6 @@ _build/exec_server.exe
|
|
|
104
104
|
| `fetch` | `import './lib/fetch.js'` | 向 globalThis 添加 `fetch()`、`Response`、`Headers` |
|
|
105
105
|
| `websocket` | `import './lib/websocket.js'` | 向 globalThis 添加 `WebSocket` |
|
|
106
106
|
| `polyfill` | `import './lib/polyfill.js'` | 向 globalThis 添加 `TextEncoder`、`URL`、`btoa`/`atob`、`setTimeout` |
|
|
107
|
-
| `preact` | `lib/preact/...` | JSX → Win32 渲染器(`render`、`useState`、`useEffect`) |
|
|
108
107
|
| `react-qw` | `lib/react-qw/` | 面向 Win32 GUI 的 React 自定义渲染器([文档](lib/react-qw/)) |
|
|
109
108
|
|
|
110
109
|
## Worker
|
|
@@ -168,48 +167,45 @@ parent.onmessage = (e) => {
|
|
|
168
167
|
|
|
169
168
|
### 前置依赖
|
|
170
169
|
|
|
171
|
-
-
|
|
172
|
-
- Node.js(用于通过 tsc 编译 TypeScript)
|
|
170
|
+
- **podman**(开发容器;构建/测试/QEMU 验证都在容器内完成,与 CI 一致)
|
|
173
171
|
- Git(用于子模块)
|
|
174
172
|
|
|
173
|
+
> 也支持 MSYS2 原生直接 `make`,详见 `.agents/DEVELOPMENT_WORKFLOW.md`。
|
|
174
|
+
|
|
175
175
|
### 构建
|
|
176
176
|
|
|
177
177
|
```bash
|
|
178
178
|
git clone --recursive https://github.com/xna00/quickwin.git
|
|
179
179
|
cd quickwin
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
.\run.ps1 "make js" # 编译 TypeScript
|
|
184
|
-
.\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'
|
|
185
183
|
```
|
|
186
184
|
|
|
187
|
-
`make
|
|
188
|
-
(没有 `WebAssembly`
|
|
185
|
+
`make cc64` 产出 `_build/qwin.exe`。`cc64-nowasm` 会产出更小的
|
|
186
|
+
`_build/qwin-nowasm.exe`,不含 WASM/WAMR(没有 `WebAssembly` 全局对象);
|
|
187
|
+
对这种版本运行 `make test TEST=-wasm` 跳过 WASM 测试。
|
|
189
188
|
|
|
190
189
|
### 构建目标
|
|
191
190
|
|
|
192
191
|
| Target | Description |
|
|
193
192
|
|--------|-------------|
|
|
194
|
-
| `make`
|
|
195
|
-
| `make
|
|
196
|
-
| `make
|
|
197
|
-
| `
|
|
198
|
-
| `make debug` | 带 bridge 日志的调试构建 |
|
|
199
|
-
| `make nowasm` | 无 WASM/WAMR 构建 → `_build/qwin-nowasm.exe`(约 1.2MB,无 `WebAssembly` 全局) |
|
|
200
|
-
| `make cc64-small` | 交叉编译 x86_64 `_build/qwin.exe`(`-Os`,CI 用) |
|
|
201
|
-
| `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 用) |
|
|
202
197
|
| `make js` | 通过 tsc 编译 TypeScript |
|
|
203
|
-
| `make wasm` | 编译 WAT → WASM fixtures |
|
|
198
|
+
| `make wasm` / `make wat` | 编译 WAT → WASM fixtures |
|
|
204
199
|
| `make test` | 运行全部测试 |
|
|
205
200
|
| `make test TEST=-net` | 跳过网络测试(快速) |
|
|
206
201
|
| `make test TEST=wasm` | 仅运行 WASM 测试 |
|
|
207
|
-
| `make wamr` | 重建 WAMR 库 |
|
|
208
|
-
| `make embed-js` | 把 `embed.js` 内嵌进 exe(用 `JS_EMBED=file.js`) |
|
|
209
|
-
| `make embed-js-br` | 把 Brotli 压缩的 JS 内嵌进 exe |
|
|
210
202
|
| `make exec_server` | 打包 `examples/exec_server.ts` 并 Brotli 内嵌进 `_build/exec_server.exe` |
|
|
203
|
+
| `make embed-js` / `embed-js-br` | 把 JS(Brotli 压缩)内嵌进 exe |
|
|
211
204
|
| `make npm-pkg` | 打包到 `dist/quickwin/` |
|
|
212
|
-
| `make
|
|
205
|
+
| `make gen-const` | 重新生成 `quickwin_const.d.ts` |
|
|
206
|
+
| `make clean` / `distclean` | 清理(会清掉整个 `_build/`,之后需 `make js wasm`) |
|
|
207
|
+
|
|
208
|
+
构建与排错细节见 `.agents/DEVELOPMENT_WORKFLOW.md`。
|
|
213
209
|
|
|
214
210
|
## 许可证
|
|
215
211
|
|
package/examples/PdfCanvas.js
CHANGED
|
@@ -1,32 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useRef } from 'react';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
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
|
-
|
|
23
|
-
|
|
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 =
|
|
28
|
+
const hdc = GetDC(hwnd);
|
|
50
29
|
if (hdc) {
|
|
51
30
|
const bmi = makeBitmapInfo(pm.w, pm.h);
|
|
52
|
-
|
|
53
|
-
|
|
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_POINTER, ffi.FFI_TYPE_POINTER], [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
|
}
|
package/examples/PdfCanvas.tsx
CHANGED
|
@@ -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
|
|
4
|
-
import
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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:
|
|
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 =
|
|
40
|
+
const hdc = GetDC(hwnd)
|
|
63
41
|
if (hdc) {
|
|
64
42
|
const bmi = makeBitmapInfo(pm.w, pm.h)
|
|
65
|
-
|
|
66
|
-
|
|
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_POINTER, ffi.FFI_TYPE_POINTER], [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
|
}
|