winio_ui_windows_common/
backdrop.rs

1#![warn(missing_docs)]
2
3use windows::core::{Error, HRESULT};
4use windows_sys::Win32::{
5    Foundation::HWND,
6    Graphics::Dwm::{
7        DWMSBT_AUTO, DWMSBT_MAINWINDOW, DWMSBT_TABBEDWINDOW, DWMSBT_TRANSIENTWINDOW,
8        DWMWA_SYSTEMBACKDROP_TYPE, DwmGetWindowAttribute, DwmSetWindowAttribute,
9    },
10};
11
12use crate::Result;
13
14/// Backdrop effects for windows.
15#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
16#[non_exhaustive]
17pub enum Backdrop {
18    /// Default window style.
19    None,
20    /// Acrylic effect.
21    Acrylic,
22    /// Mica effect.
23    Mica,
24    /// Mica Alt effect.
25    MicaAlt,
26}
27
28/// Get the current backdrop effect of a window.
29/// # Safety
30/// The caller must ensure that `handle` is a valid window handle.
31pub unsafe fn get_backdrop(handle: HWND) -> Result<Backdrop> {
32    let mut style = 0;
33    let res = unsafe {
34        DwmGetWindowAttribute(
35            handle,
36            DWMWA_SYSTEMBACKDROP_TYPE as _,
37            &mut style as *mut _ as _,
38            4,
39        )
40    };
41    if res < 0 {
42        return Err(Error::from_hresult(HRESULT(res)));
43    }
44    let style = match style {
45        DWMSBT_TRANSIENTWINDOW => Backdrop::Acrylic,
46        DWMSBT_MAINWINDOW => Backdrop::Mica,
47        DWMSBT_TABBEDWINDOW => Backdrop::MicaAlt,
48        _ => Backdrop::None,
49    };
50    Ok(style)
51}
52
53/// Set the backdrop effect of a window.
54/// # Safety
55/// The caller must ensure that `handle` is a valid window handle.
56pub unsafe fn set_backdrop(handle: HWND, backdrop: Backdrop) -> Result<bool> {
57    let style = match backdrop {
58        Backdrop::Acrylic => DWMSBT_TRANSIENTWINDOW,
59        Backdrop::Mica => DWMSBT_MAINWINDOW,
60        Backdrop::MicaAlt => DWMSBT_TABBEDWINDOW,
61        _ => DWMSBT_AUTO,
62    };
63    let res = unsafe {
64        DwmSetWindowAttribute(
65            handle,
66            DWMWA_SYSTEMBACKDROP_TYPE as _,
67            &style as *const _ as _,
68            4,
69        )
70    };
71    if res >= 0 {
72        Ok(style > 0)
73    } else {
74        Err(Error::from_hresult(HRESULT(res)))
75    }
76}