native_windows_gui/controls/
control_handle.rs

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