windows_win/ui/
msg_box.rsuse crate::sys::{HWND, MessageBoxW};
use crate::utils::Result;
use std::os::windows::ffi::OsStrExt;
use std::ffi;
use std::ptr;
use std::os::raw::{c_int, c_uint};
use crate::utils;
pub mod flags {
pub use crate::sys::{
MB_ABORTRETRYIGNORE,
MB_CANCELTRYCONTINUE,
MB_HELP,
MB_OK,
MB_OKCANCEL,
MB_RETRYCANCEL,
MB_YESNO,
MB_YESNOCANCEL,
MB_ICONEXCLAMATION,
MB_ICONWARNING,
MB_ICONINFORMATION,
MB_ICONASTERISK,
MB_ICONQUESTION,
MB_ICONSTOP,
MB_ICONERROR,
MB_ICONHAND,
MB_APPLMODAL,
MB_SYSTEMMODAL,
MB_TASKMODAL,
};
}
#[derive(Debug, PartialEq, Eq)]
pub enum MsgBoxResult {
Abort,
Cancel,
Continue,
Ignore,
No,
Ok,
Retry,
TryAgain,
Yes,
Ext(c_int),
}
impl From<c_int> for MsgBoxResult {
fn from(value: c_int) -> MsgBoxResult {
match value {
1 => MsgBoxResult::Ok,
2 => MsgBoxResult::Cancel,
3 => MsgBoxResult::Abort,
4 => MsgBoxResult::Retry,
5 => MsgBoxResult::Ignore,
6 => MsgBoxResult::Yes,
7 => MsgBoxResult::No,
10 => MsgBoxResult::TryAgain,
11 => MsgBoxResult::Continue,
value => MsgBoxResult::Ext(value),
}
}
}
pub struct MessageBox {
parent: HWND,
text: Vec<u16>,
caption: Option<Vec<u16>>,
flags: c_uint,
}
impl MessageBox {
pub fn new(text: &ffi::OsStr) -> Self {
let mut text: Vec<u16> = text.encode_wide().collect();
text.push(0);
Self {
parent: ptr::null_mut(),
text,
caption: None,
flags: flags::MB_OK,
}
}
#[inline]
pub fn info<T: AsRef<ffi::OsStr>>(text: T) -> Self {
let mut res = Self::new(text.as_ref());
res.flags |= flags::MB_ICONINFORMATION;
res
}
#[inline]
pub fn error<T: AsRef<ffi::OsStr>>(text: T) -> Self {
let mut res = Self::new(text.as_ref());
res.flags |= flags::MB_ICONERROR;
res
}
pub fn parent(&mut self, parent: HWND) -> &mut Self {
self.parent = parent;
self
}
pub fn set_flags(&mut self, flags: c_uint) -> &mut Self {
self.flags = flags;
self
}
pub fn flags(&mut self, flags: c_uint) -> &mut Self {
self.flags |= flags;
self
}
pub fn text<T: AsRef<ffi::OsStr>>(&mut self, text: T) -> &mut Self {
let text = text.as_ref();
self.text.truncate(0);
for ch in text.encode_wide() {
self.text.push(ch);
}
self.text.push(0);
self
}
pub fn title<T: AsRef<ffi::OsStr>>(&mut self, text: T) -> &mut Self {
let title = text.as_ref();
self.caption = match self.caption.take() {
Some(mut caption) => {
caption.truncate(0);
for ch in title.encode_wide() {
caption.push(ch);
}
caption.push(0);
Some(caption)
},
None => {
let mut title: Vec<u16> = title.encode_wide().collect();
title.push(0);
Some(title)
},
};
self
}
pub fn show(&self) -> Result<MsgBoxResult> {
let caption = self.caption.as_ref().map(|caption| caption.as_ptr()).unwrap_or_else(|| ptr::null());
match unsafe { MessageBoxW(self.parent, self.text.as_ptr(), caption, self.flags) } {
0 => Err(utils::get_last_error()),
n => Ok(MsgBoxResult::from(n)),
}
}
}