【问题标题】:Using winapi in Rust to get a bitmap from a window在 Rust 中使用 winapi 从窗口获取位图
【发布时间】: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 时。” 一旦你的代码编译好了,这就是你正在做的事情。

标签: winapi rust


【解决方案1】:

添加:

use winapi::shared::windef::{HBITMAP, HBITMAP__, HGDIOBJ, HWND, POINT, RECT, SIZE};
...

unsafe {SelectObject(mem_dc, bmp as HGDIOBJ)};            
unsafe {DeleteObject(bmp as HGDIOBJ)}; 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    • 2015-09-27
    相关资源
    最近更新 更多