Skip to main content

native_windows_gui2/controls/
control_handle.rs

1use crate::win32::window_helper as wh;
2use winapi::shared::windef::{HMENU, HWND};
3
4/**
5    Inner handle type used internally by each control.
6*/
7#[derive(Debug, Clone, Copy)]
8pub enum ControlHandle {
9    NoHandle,
10    Hwnd(HWND),
11
12    /// (Parent menu / Menu).
13    /// Parent menu must be there as WINAPI does not have any function to fetch the parent
14    Menu(HMENU, HMENU),
15
16    /// (Parent window / Menu).
17    PopMenu(HWND, HMENU),
18
19    /// (Parent menu / Unique ID).
20    MenuItem(HMENU, u32),
21
22    /// Notice control
23    Notice(HWND, u32),
24
25    /// Timer control
26    Timer(HWND, u32),
27
28    /// System tray control
29    SystemTray(HWND),
30}
31
32impl ControlHandle {
33    /// Destroy the underlying object and set the handle to `NoHandle`
34    /// Can be used to "reset" a UI component
35    pub fn destroy(&mut self) {
36        match self {
37            &mut ControlHandle::Hwnd(h) => wh::destroy_window(h),
38            &mut ControlHandle::Menu(_parent, m) => wh::destroy_menu(m),
39            &mut ControlHandle::MenuItem(parent, id) => wh::destroy_menu_item(parent, id),
40            &mut ControlHandle::PopMenu(_parent, m) => wh::destroy_menu(m),
41            _ => {}
42        }
43
44        *self = ControlHandle::NoHandle;
45    }
46
47    pub fn blank(&self) -> bool {
48        match self {
49            &ControlHandle::NoHandle => true,
50            _ => false,
51        }
52    }
53
54    pub fn hwnd(&self) -> Option<HWND> {
55        match self {
56            &ControlHandle::Hwnd(h) => Some(h),
57            _ => None,
58        }
59    }
60
61    pub fn hmenu(&self) -> Option<(HMENU, HMENU)> {
62        match self {
63            &ControlHandle::Menu(h1, h2) => Some((h1, h2)),
64            _ => None,
65        }
66    }
67
68    pub fn pop_hmenu(&self) -> Option<(HWND, HMENU)> {
69        match self {
70            &ControlHandle::PopMenu(h1, h2) => Some((h1, h2)),
71            _ => None,
72        }
73    }
74
75    pub fn hmenu_item(&self) -> Option<(HMENU, u32)> {
76        match self {
77            &ControlHandle::MenuItem(h, i) => Some((h, i)),
78            _ => None,
79        }
80    }
81
82    pub fn timer(&self) -> Option<(HWND, u32)> {
83        match self {
84            &ControlHandle::Timer(h, i) => Some((h, i)),
85            _ => None,
86        }
87    }
88
89    pub fn notice(&self) -> Option<(HWND, u32)> {
90        match self {
91            &ControlHandle::Notice(h, i) => Some((h, i)),
92            _ => None,
93        }
94    }
95
96    pub fn tray(&self) -> Option<HWND> {
97        match self {
98            &ControlHandle::SystemTray(h) => Some(h),
99            _ => None,
100        }
101    }
102}
103
104impl Default for ControlHandle {
105    fn default() -> ControlHandle {
106        ControlHandle::NoHandle
107    }
108}
109
110impl PartialEq for ControlHandle {
111    fn eq(&self, other: &Self) -> bool {
112        match self {
113            // NoHandle
114            &ControlHandle::NoHandle => match other {
115                &ControlHandle::NoHandle => true,
116                _ => false,
117            },
118            // HWND
119            &ControlHandle::Hwnd(hwnd1) => match other {
120                &ControlHandle::Hwnd(hwnd2) => hwnd1 == hwnd2,
121                _ => false,
122            },
123            // HMENU
124            &ControlHandle::Menu(_, h1) => match other {
125                &ControlHandle::Menu(_, h2) => h1 == h2,
126                _ => false,
127            },
128            // HMENU
129            &ControlHandle::PopMenu(_, h1) => match other {
130                &ControlHandle::PopMenu(_, h2) => h1 == h2,
131                _ => false,
132            },
133            // HMENU / ITEM
134            &ControlHandle::MenuItem(_, id1) => match other {
135                &ControlHandle::MenuItem(_, id2) => id1 == id2,
136                _ => false,
137            },
138            // TIMER
139            &ControlHandle::Timer(hwnd1, id1) => match other {
140                &ControlHandle::Timer(hwnd2, id2) => hwnd1 == hwnd2 && id1 == id2,
141                _ => false,
142            },
143            // Notice
144            &ControlHandle::Notice(hwnd1, id1) => match other {
145                &ControlHandle::Notice(hwnd2, id2) => hwnd1 == hwnd2 && id1 == id2,
146                _ => false,
147            },
148            // System tray
149            &ControlHandle::SystemTray(hwnd1) => match other {
150                &ControlHandle::SystemTray(hwnd2) => hwnd1 == hwnd2,
151                _ => false,
152            },
153        }
154    }
155}
156
157impl Eq for ControlHandle {}
158
159impl From<&ControlHandle> for ControlHandle {
160    fn from(control: &ControlHandle) -> Self {
161        *control
162    }
163}