【发布时间】:2021-02-20 23:53:13
【问题描述】:
.. 嗨,我有这个代码:
#[cfg(windows)] extern crate winapi;
use winapi::um::winuser::{FindWindowW, GetClientRect, GetWindowDC, GetDC, ReleaseDC};
use winapi::um::wingdi::{CreateBitmap, CreateCompatibleBitmap, CreateCompatibleDC, SelectObject, GetObjectW, SaveDC, DeleteDC, DeleteObject};
use std::ptr::null_mut;
use std::mem::zeroed;
use std::ffi::OsStr;
use std::iter::once;
use std::os::windows::ffi::OsStrExt;
#[cfg(windows)]
fn find_window(name: &str) {
let window: Vec<u16> = OsStr::new(name).encode_wide().chain(once(0)).collect();
let hwnd = unsafe { FindWindowW(null_mut(), window.as_ptr()) };
if hwnd != null_mut() {
println!("Window found");
let mut my_rect = unsafe { zeroed::<winapi::shared::windef::RECT>() };
let _client_rect = unsafe { GetClientRect(hwnd, &mut my_rect) };
let w = my_rect.right - my_rect.left;
let h = my_rect.bottom - my_rect.top;
let hwnd_dc = unsafe { GetWindowDC(hwnd) };
let mem_dc = unsafe { CreateCompatibleDC(hwnd_dc) };
let bmp = unsafe { CreateCompatibleBitmap(mem_dc, w, h) };
//SelectObject(mem_dc, bmp); <== Problem is here
//DeleteObject(bmp); <== Same problem here
unsafe { DeleteDC(mem_dc) };
unsafe { ReleaseDC(hwnd, hwnd_dc) };
}
else {
println!("Window not found");
}
}
fn main() {
find_window("Firefox"); // just for test
}
如果我运行这个,我会得到:
SelectObject(mem_dc, bmp);
| ^^^ expected enum `std::ffi::c_void`, found enum `winapi::shared::windef::HBITMAP__`
所以我明白了,它不需要那个位图指针,但是在 win32 文档中,它说这个函数 (SelectObject) 接受一个设备上下文 (mem_dc) 和一个由 CreateCompatibleBitmap 等函数创建的对象。
https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-selectobject
Rust 中的绑定接受两个相同的参数,但它似乎想要 std::ffi::c_void 但查看 Rust 文档,我不明白它到底是什么。
你能帮我找出问题所在吗?谢谢。
【问题讨论】:
-
不相关,但DeleteObject 有这样的评论:“不要删除绘图对象(钢笔或画笔)当它仍被选入 DC 时。” 一旦你的代码编译好了,这就是你正在做的事情。