use crate::co;
use crate::decl::*;
use crate::gui::privs::*;
use crate::msg::*;
use crate::prelude::*;
pub(in crate::gui) struct DlgBase {
base: BaseWnd,
dlg_id: u16,
}
impl Drop for DlgBase {
fn drop(&mut self) {
if *self.base.hwnd() != HWND::NULL {
unsafe {
self.base.hwnd().SetWindowLongPtr(co::GWLP::DWLP_USER, 0); }
}
}
}
impl DlgBase {
#[must_use]
pub(in crate::gui) fn new(dlg_id: u16) -> Self {
Self { base: BaseWnd::new(WndTy::Dlg), dlg_id }
}
#[must_use]
pub(in crate::gui) const fn base(&self) -> &BaseWnd {
&self.base
}
pub(in crate::gui) fn create_dialog_param(&self, hinst: &HINSTANCE, hparent: Option<&HWND>) {
if *self.base.hwnd() != HWND::NULL {
panic!("Cannot create dialog twice.");
}
unsafe {
hinst.CreateDialogParam(
IdStr::Id(self.dlg_id),
hparent,
Self::dlg_proc,
Some(self as *const _ as _), )
}
.expect(DONTFAIL);
}
pub(in crate::gui) fn dialog_box_param(&self, hinst: &HINSTANCE, hparent: Option<&HWND>) {
if *self.base.hwnd() != HWND::NULL {
panic!("Cannot create dialog twice.");
}
unsafe {
hinst.DialogBoxParam(
IdStr::Id(self.dlg_id),
hparent,
Self::dlg_proc,
Some(self as *const _ as _), )
}
.expect(DONTFAIL);
}
pub(in crate::gui) fn set_icon(&self, hinst: &HINSTANCE, icon_id: u16) -> SysResult<()> {
unsafe {
self.base.hwnd().SendMessage(wm::SetIcon {
hicon: hinst
.LoadImageIcon(IdOicStr::Id(icon_id), SIZE::with(16, 16), co::LR::DEFAULTCOLOR)?
.leak(),
size: co::ICON_SZ::SMALL,
});
self.base.hwnd().SendMessage(wm::SetIcon {
hicon: hinst
.LoadImageIcon(IdOicStr::Id(icon_id), SIZE::with(32, 32), co::LR::DEFAULTCOLOR)?
.leak(),
size: co::ICON_SZ::BIG,
});
}
Ok(())
}
extern "system" fn dlg_proc(hwnd: HWND, msg: co::WM, wparam: usize, lparam: isize) -> isize {
let wm_any = WndMsg::new(msg, wparam, lparam);
Self::dlg_proc_proc(hwnd, wm_any).unwrap_or_else(|err| {
quit_error::post_quit_error(wm_any, err);
true as _
})
}
fn dlg_proc_proc(hwnd: HWND, p: WndMsg) -> AnyResult<isize> {
let ptr_self = match p.msg_id {
co::WM::INITDIALOG => {
let msg = unsafe { wm::InitDialog::from_generic_wm(p) };
let ptr_self = msg.additional_data as *const Self;
unsafe {
hwnd.SetWindowLongPtr(co::GWLP::DWLP_USER, ptr_self as _); }
let ref_self = unsafe { &*ptr_self };
ref_self.base.set_hwnd(unsafe { hwnd.raw_copy() }); ptr_self
},
_ => hwnd.GetWindowLongPtr(co::GWLP::DWLP_USER) as *const Self, };
if ptr_self.is_null() {
Ok(0) } else {
let ref_self = unsafe { &*ptr_self };
Self::dlg_proc_proc2(&ref_self.base, hwnd, p)
}
}
pub(in crate::gui) fn dlg_proc_proc2(
base: &BaseWnd,
hwnd: HWND,
p: WndMsg,
) -> AnyResult<isize> {
let (at_least_one_before, user_ret, at_least_one_after) = base.process_msgs(p)?;
if p.msg_id == co::WM::NCDESTROY {
unsafe {
hwnd.SetWindowLongPtr(co::GWLP::DWLP_USER, 0); }
base.set_hwnd(HWND::NULL); base.clear_messages(); }
if let Some(user_ret) = user_ret {
match p.msg_id {
co::WM::GETDLGCODE | co::WM::SETCURSOR => unsafe {
hwnd.SetWindowLongPtr(co::GWLP::DWLP_MSGRESULT, user_ret); Ok(1) },
_ => Ok(user_ret),
}
} else if at_least_one_before || at_least_one_after {
Ok(1) } else {
Ok(0) }
}
}