winapi_easy/ui/
message_box.rs1use std::io;
2
3use num_enum::{
4 FromPrimitive,
5 IntoPrimitive,
6};
7use windows::Win32::UI::WindowsAndMessaging::{
8 IDABORT,
9 IDCANCEL,
10 IDCONTINUE,
11 IDIGNORE,
12 IDNO,
13 IDOK,
14 IDRETRY,
15 IDTRYAGAIN,
16 IDYES,
17 MB_ABORTRETRYIGNORE,
18 MB_CANCELTRYCONTINUE,
19 MB_ICONERROR,
20 MB_ICONINFORMATION,
21 MB_ICONQUESTION,
22 MB_ICONWARNING,
23 MB_OK,
24 MB_OKCANCEL,
25 MB_RETRYCANCEL,
26 MB_YESNO,
27 MB_YESNOCANCEL,
28 MESSAGEBOX_STYLE,
29 MessageBoxExW,
30};
31
32use crate::internal::ReturnValue;
33use crate::string::ZeroTerminatedWideString;
34use crate::ui::WindowHandle;
35
36#[derive(Copy, Clone, Default, Debug)]
37pub struct MessageBoxOptions<'a> {
38 pub message: Option<&'a str>,
39 pub caption: Option<&'a str>,
40 pub buttons: MessageBoxButtons,
41 pub icon: Option<MessageBoxIcon>,
42}
43
44#[derive(IntoPrimitive, Copy, Clone, Eq, PartialEq, Default, Debug)]
45#[repr(u32)]
46pub enum MessageBoxButtons {
47 #[default]
48 Ok = MB_OK.0,
49 OkCancel = MB_OKCANCEL.0,
50 RetryCancel = MB_RETRYCANCEL.0,
51 YesNo = MB_YESNO.0,
52 YesNoCancel = MB_YESNOCANCEL.0,
53 AbortRetryIgnore = MB_ABORTRETRYIGNORE.0,
54 CancelTryContinue = MB_CANCELTRYCONTINUE.0,
55}
56
57impl From<MessageBoxButtons> for MESSAGEBOX_STYLE {
58 fn from(value: MessageBoxButtons) -> Self {
59 MESSAGEBOX_STYLE(value.into())
60 }
61}
62
63#[derive(IntoPrimitive, Copy, Clone, Eq, PartialEq, Default, Debug)]
64#[repr(u32)]
65pub enum MessageBoxIcon {
66 #[default]
67 Information = MB_ICONINFORMATION.0,
68 QuestionMark = MB_ICONQUESTION.0,
69 Warning = MB_ICONWARNING.0,
70 Error = MB_ICONERROR.0,
71}
72
73impl From<MessageBoxIcon> for MESSAGEBOX_STYLE {
74 fn from(value: MessageBoxIcon) -> Self {
75 MESSAGEBOX_STYLE(value.into())
76 }
77}
78
79#[derive(FromPrimitive, Copy, Clone, Eq, PartialEq, Debug)]
80#[repr(i32)]
81pub enum PressedMessageBoxButton {
82 Ok = IDOK.0,
83 Cancel = IDCANCEL.0,
84 Abort = IDABORT.0,
85 Retry = IDRETRY.0,
86 Ignore = IDIGNORE.0,
87 Yes = IDYES.0,
88 No = IDNO.0,
89 TryAgain = IDTRYAGAIN.0,
90 Continue = IDCONTINUE.0,
91 #[num_enum(catch_all)]
92 Other(i32),
93}
94
95pub fn show_message_box(
96 window_handle: WindowHandle,
97 options: MessageBoxOptions,
98) -> io::Result<PressedMessageBoxButton> {
99 let message = options.message.map(ZeroTerminatedWideString::from_os_str);
100 let caption = options.caption.map(ZeroTerminatedWideString::from_os_str);
101 let result = unsafe {
102 MessageBoxExW(
103 Some(window_handle.into()),
104 message.map(|x| x.as_raw_pcwstr()).as_ref(),
105 caption.map(|x| x.as_raw_pcwstr()).as_ref(),
106 MESSAGEBOX_STYLE::from(options.buttons)
107 | options.icon.map(MESSAGEBOX_STYLE::from).unwrap_or_default(),
108 0,
109 )
110 };
111 let _ = result.0.if_null_get_last_error()?;
112 Ok(result.0.into())
113}