use super::base_helper::to_utf16;
use crate::controls::ControlHandle;
use std::ptr;
use winapi::shared::windef::HWND;
#[derive(Clone, PartialEq, Debug)]
pub enum MessageButtons {
AbortTryIgnore,
CancelTryContinue,
Ok,
OkCancel,
RetryCancel,
YesNo,
YesNoCancel,
}
#[derive(Clone, PartialEq, Debug)]
pub enum MessageIcons {
Warning,
Info,
Question,
Error,
None,
}
#[derive(Clone, PartialEq, Debug)]
pub enum MessageChoice {
Abort,
Cancel,
Continue,
Ignore,
No,
Ok,
Retry,
TryAgain,
Yes,
}
#[derive(Clone, PartialEq, Debug)]
pub struct MessageParams<'a> {
pub title: &'a str,
pub content: &'a str,
pub buttons: MessageButtons,
pub icons: MessageIcons,
}
fn inner_message(parent: HWND, params: &MessageParams) -> MessageChoice {
use winapi::um::winuser::{
MB_ABORTRETRYIGNORE, MB_CANCELTRYCONTINUE, MB_ICONEXCLAMATION, MB_ICONINFORMATION,
MB_ICONQUESTION, MB_ICONSTOP, MB_OK, MB_OKCANCEL, MB_RETRYCANCEL, MB_YESNO, MB_YESNOCANCEL,
};
use winapi::um::winuser::MessageBoxW;
use winapi::um::winuser::{
IDABORT, IDCANCEL, IDCONTINUE, IDIGNORE, IDNO, IDOK, IDRETRY, IDTRYAGAIN, IDYES,
};
let text = to_utf16(params.content);
let title = to_utf16(params.title);
let buttons = match params.buttons {
MessageButtons::AbortTryIgnore => MB_ABORTRETRYIGNORE,
MessageButtons::CancelTryContinue => MB_CANCELTRYCONTINUE,
MessageButtons::Ok => MB_OK,
MessageButtons::OkCancel => MB_OKCANCEL,
MessageButtons::RetryCancel => MB_RETRYCANCEL,
MessageButtons::YesNo => MB_YESNO,
MessageButtons::YesNoCancel => MB_YESNOCANCEL,
};
let icons = match params.icons {
MessageIcons::Error => MB_ICONSTOP,
MessageIcons::Info => MB_ICONINFORMATION,
MessageIcons::None => 0,
MessageIcons::Question => MB_ICONQUESTION,
MessageIcons::Warning => MB_ICONEXCLAMATION,
};
let answer = unsafe { MessageBoxW(parent, text.as_ptr(), title.as_ptr(), buttons | icons) };
match answer {
IDABORT => MessageChoice::Abort,
IDCANCEL => MessageChoice::Cancel,
IDCONTINUE => MessageChoice::Continue,
IDIGNORE => MessageChoice::Ignore,
IDNO => MessageChoice::No,
IDOK => MessageChoice::Ok,
IDRETRY => MessageChoice::Retry,
IDTRYAGAIN => MessageChoice::TryAgain,
IDYES => MessageChoice::Yes,
_ => MessageChoice::Cancel,
}
}
pub fn message<'a>(params: &MessageParams) -> MessageChoice {
inner_message(ptr::null_mut(), params)
}
pub fn modal_message<'a, P: Into<ControlHandle>>(
parent: P,
params: &MessageParams,
) -> MessageChoice {
let control_handle = parent.into();
let hwnd = control_handle.hwnd().expect("expected window like control");
inner_message(hwnd, params)
}
pub fn fatal_message<'a>(title: &'a str, content: &'a str) -> ! {
error_message(title, content);
panic!("{} - {}", title, content);
}
pub fn modal_fatal_message<'a, P: Into<ControlHandle>>(
parent: P,
title: &'a str,
content: &'a str,
) -> ! {
modal_error_message(parent, title, content);
panic!("{} - {}", title, content);
}
pub fn error_message<'a>(title: &'a str, content: &'a str) -> MessageChoice {
let params = MessageParams {
title,
content,
buttons: MessageButtons::Ok,
icons: MessageIcons::Error,
};
message(¶ms)
}
pub fn modal_error_message<'a, P: Into<ControlHandle>>(
parent: P,
title: &'a str,
content: &'a str,
) -> MessageChoice {
let params = MessageParams {
title,
content,
buttons: MessageButtons::Ok,
icons: MessageIcons::Error,
};
modal_message(parent, ¶ms)
}
pub fn simple_message<'a>(title: &'a str, content: &'a str) -> MessageChoice {
let params = MessageParams {
title,
content,
buttons: MessageButtons::Ok,
icons: MessageIcons::Info,
};
message(¶ms)
}
pub fn modal_info_message<'a, P: Into<ControlHandle>>(
parent: P,
title: &'a str,
content: &'a str,
) -> MessageChoice {
let params = MessageParams {
title,
content,
buttons: MessageButtons::Ok,
icons: MessageIcons::Info,
};
modal_message(parent, ¶ms)
}