Skip to main content

windows_erg/desktop/
types.rs

1use std::ffi::c_void;
2use std::fmt;
3
4use windows::Win32::Foundation::{HWND, RECT};
5
6use crate::types::ProcessId;
7
8/// Strongly-typed window handle wrapper.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub struct WindowHandle(pub *mut c_void);
11
12impl WindowHandle {
13    /// Create a new window handle.
14    pub fn new(raw: *mut c_void) -> Self {
15        Self(raw)
16    }
17
18    /// Get the raw HWND value.
19    pub fn as_ptr(self) -> *mut c_void {
20        self.0
21    }
22}
23
24impl From<HWND> for WindowHandle {
25    fn from(value: HWND) -> Self {
26        Self(value.0)
27    }
28}
29
30impl From<WindowHandle> for HWND {
31    fn from(value: WindowHandle) -> Self {
32        HWND(value.0)
33    }
34}
35
36impl fmt::Display for WindowHandle {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        write!(f, "{:p}", self.0)
39    }
40}
41
42/// Strongly-typed tray icon identifier.
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
44pub struct TrayIconId(pub u32);
45
46impl TrayIconId {
47    /// Create a new tray icon ID.
48    pub fn new(id: u32) -> Self {
49        Self(id)
50    }
51
52    /// Get the raw tray icon identifier.
53    pub fn as_u32(self) -> u32 {
54        self.0
55    }
56}
57
58impl fmt::Display for TrayIconId {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        write!(f, "{}", self.0)
61    }
62}
63
64/// Rectangle coordinates for a window.
65#[derive(Debug, Clone, Copy, PartialEq, Eq)]
66pub struct WindowRect {
67    /// Left coordinate in screen space.
68    pub left: i32,
69    /// Top coordinate in screen space.
70    pub top: i32,
71    /// Right coordinate in screen space.
72    pub right: i32,
73    /// Bottom coordinate in screen space.
74    pub bottom: i32,
75}
76
77impl WindowRect {
78    /// Width of the rectangle.
79    pub fn width(self) -> i32 {
80        self.right - self.left
81    }
82
83    /// Height of the rectangle.
84    pub fn height(self) -> i32 {
85        self.bottom - self.top
86    }
87}
88
89impl From<RECT> for WindowRect {
90    fn from(value: RECT) -> Self {
91        Self {
92            left: value.left,
93            top: value.top,
94            right: value.right,
95            bottom: value.bottom,
96        }
97    }
98}
99
100/// DWM cloaking state for a window.
101#[derive(Debug, Clone, Copy, PartialEq, Eq)]
102pub enum CloakState {
103    /// Window is not cloaked.
104    NotCloaked,
105    /// Cloaked by application logic.
106    App,
107    /// Cloaked by the shell.
108    Shell,
109    /// Cloaked by inherited state.
110    Inherited,
111    /// Unknown cloaking bitmask.
112    Unknown(u32),
113}
114
115impl CloakState {
116    /// Convert a DWM cloaking bitmask to the ergonomic cloak state.
117    pub fn from_raw(raw: u32) -> Self {
118        if raw == 0 {
119            return CloakState::NotCloaked;
120        }
121
122        if raw & 0x1 != 0 {
123            return CloakState::App;
124        }
125
126        if raw & 0x2 != 0 {
127            return CloakState::Shell;
128        }
129
130        if raw & 0x4 != 0 {
131            return CloakState::Inherited;
132        }
133
134        CloakState::Unknown(raw)
135    }
136
137    /// Returns true when the window is cloaked.
138    pub fn is_cloaked(self) -> bool {
139        !matches!(self, CloakState::NotCloaked)
140    }
141}
142
143/// Icon style for tray balloon notifications.
144#[derive(Debug, Clone, Copy, PartialEq, Eq)]
145pub enum BalloonIcon {
146    /// No icon.
147    None,
148    /// Information icon.
149    Info,
150    /// Warning icon.
151    Warning,
152    /// Error icon.
153    Error,
154}
155
156/// Snapshot of a desktop window.
157#[derive(Debug, Clone)]
158pub struct WindowInfo {
159    /// Window handle.
160    pub handle: WindowHandle,
161    /// Parent handle if available.
162    pub parent: Option<WindowHandle>,
163    /// Owning process ID.
164    pub process_id: ProcessId,
165    /// Window class name.
166    pub class_name: String,
167    /// Window title text.
168    pub title: String,
169    /// Window rectangle in screen coordinates.
170    pub rect: WindowRect,
171    /// Whether the window is visible.
172    pub is_visible: bool,
173    /// DWM cloaked state.
174    pub cloak_state: CloakState,
175}