emoon / rust_minifb

Cross platfrom window and framebuffer crate for Rust
MIT License
1.04k stars 99 forks source link

Windows 11 cant make window transperant. #330

Open jonatino opened 1 year ago

jonatino commented 1 year ago

I'm trying to run the example from https://github.com/emoon/rust_minifb/blob/master/examples/transparent.rs on Windows but my window is just one solid color, not transparent.

Is it supported on windows?

jonatino commented 1 year ago

Was able to get it working with the following code.

    let mut window = Window::new("Raqote", BS_WIDTH as usize, BS_HEIGHT as usize, WindowOptions {
        transparency: false,
        borderless: true,
        scale_mode: ScaleMode::Center,
        none: true,
        title: false,
        resize: false,
        scale: Scale::X1,
        topmost: true,
    }).unwrap();
    let font = SystemSource::new()
        .select_best_match(&[FamilyName::SansSerif], &Properties::new())
        .unwrap()
        .load()
        .unwrap();

    let size = window.get_size();

    let hwnd: HWND = window.get_window_handle() as isize;
    println!("{:?}", hwnd);
    unsafe { SetWindowLongA(hwnd, GWL_EXSTYLE, (WS_EX_LAYERED | WS_EX_TRANSPARENT) as i32) };
    let mut margs = MARGINS {
        cxLeftWidth: -1,
        cxRightWidth: -1,
        cyTopHeight: -1,
        cyBottomHeight: -1,
    };
    unsafe { DwmExtendFrameIntoClientArea(hwnd, &mut margs) };
    unsafe { UpdateWindow(hwnd) };
    unsafe { SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, size.0 as i32, size.1 as i32, SWP_SHOWWINDOW) };

    let mut dt = DrawTarget::new(size.0 as i32, size.1 as i32);
    loop {
        dt.clear(SolidSource::from_unpremultiplied_argb(0, 0, 0, 0));

        let mut pb = PathBuilder::new();
        if let Some(pos) = window.get_mouse_pos(MouseMode::Clamp) {
            pb.rect(pos.0, pos.1, 100., 130.);
            let path = pb.finish();
            dt.fill(&path, &Source::Solid(SolidSource::from_unpremultiplied_argb(50, 0, 0xff, 0)), &DrawOptions::default());

            let pos_string = format!("{:?}", pos);
            dt.draw_text(&font, 36., &pos_string, Point::new(0., 100.),
                         &Source::Solid(SolidSource::from_unpremultiplied_argb(0xff, 255, 0, 0)),
                         &DrawOptions::default(),
            );
        }

        window.update_with_buffer(dt.get_data(), size.0, size.1).unwrap();
    }
emoon commented 1 year ago

There is an open issue for it here https://github.com/emoon/rust_minifb/issues/133 I haven't added any of this support myself and I have only accepted PR for it, so if you are willing to do that it would be great!

jonatino commented 1 year ago

@emoon I'll try to make a PR for it. While I'm at it, do you have any objections to me replacing the winapi crate with the microsoft official windows-sys crate?

emoon commented 1 year ago

Both sound good to me! :+1: