native_windows_gui2/win32/message_box.rs
1use super::base_helper::to_utf16;
2use crate::controls::ControlHandle;
3use std::ptr;
4use winapi::shared::windef::HWND;
5
6/**
7 Enum of message box buttons (to use with `MessageParams` )
8*/
9#[derive(Clone, PartialEq, Debug)]
10pub enum MessageButtons {
11 AbortTryIgnore,
12 CancelTryContinue,
13 Ok,
14 OkCancel,
15 RetryCancel,
16 YesNo,
17 YesNoCancel,
18}
19
20/**
21 Enum of message box icons (to use with `MessageParams` )
22*/
23#[derive(Clone, PartialEq, Debug)]
24pub enum MessageIcons {
25 Warning,
26 Info,
27 Question,
28 Error,
29 None,
30}
31
32/**
33 Return value of `message`. Define the button that the user clicked. If the user
34 cancelled the message box by clicking on X button of the window, `MessageChoice::Cancel` is returned.
35*/
36#[derive(Clone, PartialEq, Debug)]
37pub enum MessageChoice {
38 Abort,
39 Cancel,
40 Continue,
41 Ignore,
42 No,
43 Ok,
44 Retry,
45 TryAgain,
46 Yes,
47}
48
49/**
50 A structure that defines how a messagebox should look and behave.
51
52 Members:
53 * `title`: The title of the message box
54 * `content`: The message of the message box
55 * `buttons`: The button of the message box
56 * `icons`: The message box icon
57*/
58#[derive(Clone, PartialEq, Debug)]
59pub struct MessageParams<'a> {
60 pub title: &'a str,
61 pub content: &'a str,
62 pub buttons: MessageButtons,
63 pub icons: MessageIcons,
64}
65
66/// Inner function used by the message box function
67fn inner_message(parent: HWND, params: &MessageParams) -> MessageChoice {
68 use winapi::um::winuser::{
69 MB_ABORTRETRYIGNORE, MB_CANCELTRYCONTINUE, MB_ICONEXCLAMATION, MB_ICONINFORMATION,
70 MB_ICONQUESTION, MB_ICONSTOP, MB_OK, MB_OKCANCEL, MB_RETRYCANCEL, MB_YESNO, MB_YESNOCANCEL,
71 };
72
73 use winapi::um::winuser::MessageBoxW;
74 use winapi::um::winuser::{
75 IDABORT, IDCANCEL, IDCONTINUE, IDIGNORE, IDNO, IDOK, IDRETRY, IDTRYAGAIN, IDYES,
76 };
77
78 let text = to_utf16(params.content);
79 let title = to_utf16(params.title);
80
81 let buttons = match params.buttons {
82 MessageButtons::AbortTryIgnore => MB_ABORTRETRYIGNORE,
83 MessageButtons::CancelTryContinue => MB_CANCELTRYCONTINUE,
84 MessageButtons::Ok => MB_OK,
85 MessageButtons::OkCancel => MB_OKCANCEL,
86 MessageButtons::RetryCancel => MB_RETRYCANCEL,
87 MessageButtons::YesNo => MB_YESNO,
88 MessageButtons::YesNoCancel => MB_YESNOCANCEL,
89 };
90
91 let icons = match params.icons {
92 MessageIcons::Error => MB_ICONSTOP,
93 MessageIcons::Info => MB_ICONINFORMATION,
94 MessageIcons::None => 0,
95 MessageIcons::Question => MB_ICONQUESTION,
96 MessageIcons::Warning => MB_ICONEXCLAMATION,
97 };
98
99 let answer = unsafe { MessageBoxW(parent, text.as_ptr(), title.as_ptr(), buttons | icons) };
100 match answer {
101 IDABORT => MessageChoice::Abort,
102 IDCANCEL => MessageChoice::Cancel,
103 IDCONTINUE => MessageChoice::Continue,
104 IDIGNORE => MessageChoice::Ignore,
105 IDNO => MessageChoice::No,
106 IDOK => MessageChoice::Ok,
107 IDRETRY => MessageChoice::Retry,
108 IDTRYAGAIN => MessageChoice::TryAgain,
109 IDYES => MessageChoice::Yes,
110 _ => MessageChoice::Cancel,
111 }
112}
113
114/**
115 Create an application wide message box.
116 It is recommended to use `modal_message` because it locks the window that creates the message box.
117 This method may be deprecated in the future
118
119 Parameters:
120 * params: A `MessageParams` structure that defines how the message box should look
121
122 ```rust
123 use native_windows_gui2 as nwg;
124 fn test_message() {
125 let p = nwg::MessageParams {
126 title: "Hey",
127 content: "Cats are cute",
128 buttons: nwg::MessageButtons::Ok,
129 icons: nwg::MessageIcons::Warning
130 };
131
132 assert!(nwg::message(&p) == nwg::MessageChoice::Ok)
133 }
134 ```
135*/
136pub fn message<'a>(params: &MessageParams) -> MessageChoice {
137 inner_message(ptr::null_mut(), params)
138}
139
140/**
141 Create a message box for a selected window. The window will be locked until the user close the message box.
142
143 This functions panics if a non window control is used as parent (ex: a menu)
144
145 Parameters:
146 * parent: The reference to a window-like control
147 * params: A `MessageParams` structure that defines how the message box should look
148
149 ```rust
150 use native_windows_gui2 as nwg;
151 fn test_message(parent: &nwg::Window) {
152 let p = nwg::MessageParams {
153 title: "Hey",
154 content: "Cats are cute",
155 buttons: nwg::MessageButtons::Ok,
156 icons: nwg::MessageIcons::Warning
157 };
158
159 assert!(nwg::modal_message(parent, &p) == nwg::MessageChoice::Ok)
160 }
161 ```
162*/
163pub fn modal_message<'a, P: Into<ControlHandle>>(
164 parent: P,
165 params: &MessageParams,
166) -> MessageChoice {
167 let control_handle = parent.into();
168 let hwnd = control_handle.hwnd().expect("expected window like control");
169 inner_message(hwnd, params)
170}
171
172/**
173 Display a message box and then panic. The message box has for style `MessageButtons::Ok` and `MessageIcons::Error` .
174 It is recommended to use `modal_fatal_message` because it locks the window that creates the message box.
175 This method may be deprecated in the future
176
177 Parameters:
178 * title: The message box title
179 * content: The message box message
180*/
181pub fn fatal_message<'a>(title: &'a str, content: &'a str) -> ! {
182 error_message(title, content);
183 panic!("{} - {}", title, content);
184}
185
186/**
187 Display a message box and then panic. The message box has for style `MessageButtons::Ok` and `MessageIcons::Error` .
188
189 This functions panics if a non window control is used as parent (ex: a menu)
190
191 Parameters:
192 * parent: Parent window to lock for the duration of the message box
193 * title: The message box title
194 * content: The message box message
195*/
196pub fn modal_fatal_message<'a, P: Into<ControlHandle>>(
197 parent: P,
198 title: &'a str,
199 content: &'a str,
200) -> ! {
201 modal_error_message(parent, title, content);
202 panic!("{} - {}", title, content);
203}
204
205/**
206 Display a simple error message box. The message box has for style `MessageButtons::Ok` and `MessageIcons::Error`.
207 It is recommended to use `modal_error_message` because it locks the window that creates the message box.
208 This method may be deprecated in the future
209
210 Parameters:
211 * title: The message box title
212 * content: The message box message
213*/
214pub fn error_message<'a>(title: &'a str, content: &'a str) -> MessageChoice {
215 let params = MessageParams {
216 title,
217 content,
218 buttons: MessageButtons::Ok,
219 icons: MessageIcons::Error,
220 };
221
222 message(¶ms)
223}
224
225/**
226 Display a simple error message box. The message box has for style `MessageButtons::Ok` and `MessageIcons::Error`.
227
228 This functions panics if a non window control is used as parent (ex: a menu)
229
230 Parameters:
231 * parent: Parent window to lock for the duration of the message box
232 * title: The message box title
233 * content: The message box message
234*/
235pub fn modal_error_message<'a, P: Into<ControlHandle>>(
236 parent: P,
237 title: &'a str,
238 content: &'a str,
239) -> MessageChoice {
240 let params = MessageParams {
241 title,
242 content,
243 buttons: MessageButtons::Ok,
244 icons: MessageIcons::Error,
245 };
246
247 modal_message(parent, ¶ms)
248}
249
250/**
251 Display a simple message box. The message box has for style `MessageButtons::Ok` and `MessageIcons::Info`.
252 It is recommended to use `modal_info_message` because it locks the window that creates the message box.
253 This method may be deprecated in the future
254
255 Parameters:
256 * title: The message box title
257 * content: The message box message
258*/
259pub fn simple_message<'a>(title: &'a str, content: &'a str) -> MessageChoice {
260 let params = MessageParams {
261 title,
262 content,
263 buttons: MessageButtons::Ok,
264 icons: MessageIcons::Info,
265 };
266
267 message(¶ms)
268}
269
270/**
271 Display a simple message box. The message box has for style `MessageButtons::Ok` and `MessageIcons::Info`.
272
273 This functions panics if a non window control is used as parent (ex: a menu)
274
275 Parameters:
276 * parent: Parent window to lock for the duration of the message box
277 * title: The message box title
278 * content: The message box message
279*/
280pub fn modal_info_message<'a, P: Into<ControlHandle>>(
281 parent: P,
282 title: &'a str,
283 content: &'a str,
284) -> MessageChoice {
285 let params = MessageParams {
286 title,
287 content,
288 buttons: MessageButtons::Ok,
289 icons: MessageIcons::Info,
290 };
291
292 modal_message(parent, ¶ms)
293}