use std::mem;
use std::ptr;
use winapi::shared::minwindef::HINSTANCE;
use winapi::shared::ntdef::LPCWSTR;
use winapi::shared::windef::HCURSOR;
use winapi::um::shellscalingapi::PROCESS_SYSTEM_DPI_AWARE;
use winapi::um::wingdi::CreateSolidBrush;
use winapi::um::winuser::{
DispatchMessageW, GetAncestor, GetMessageW, LoadIconW, PostQuitMessage, RegisterClassW,
TranslateAcceleratorW, TranslateMessage, GA_ROOT, IDI_APPLICATION, MSG, WNDCLASSW,
};
use crate::application::AppHandler;
use super::accels;
use super::clipboard::Clipboard;
use super::util::{self, ToWide, CLASS_NAME, OPTIONAL_FUNCTIONS};
use super::window::win_proc_dispatch;
pub struct Application;
impl Application {
pub fn new(_handler: Option<Box<dyn AppHandler>>) -> Application {
Application::init();
Application
}
pub fn run(&mut self) {
unsafe {
loop {
let mut msg = mem::MaybeUninit::uninit();
let res = GetMessageW(msg.as_mut_ptr(), ptr::null_mut(), 0, 0);
if res <= 0 {
return;
}
let mut msg: MSG = msg.assume_init();
let accels = accels::find_accels(GetAncestor(msg.hwnd, GA_ROOT));
let translated = accels.map_or(false, |it| {
TranslateAcceleratorW(msg.hwnd, it.handle(), &mut msg) != 0
});
if !translated {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
}
}
fn init() {
util::attach_console();
if let Some(func) = OPTIONAL_FUNCTIONS.SetProcessDpiAwareness {
unsafe {
func(PROCESS_SYSTEM_DPI_AWARE); }
}
unsafe {
let class_name = CLASS_NAME.to_wide();
let icon = LoadIconW(0 as HINSTANCE, IDI_APPLICATION);
let brush = CreateSolidBrush(0xff_ff_ff);
let wnd = WNDCLASSW {
style: 0,
lpfnWndProc: Some(win_proc_dispatch),
cbClsExtra: 0,
cbWndExtra: 0,
hInstance: 0 as HINSTANCE,
hIcon: icon,
hCursor: 0 as HCURSOR,
hbrBackground: brush,
lpszMenuName: 0 as LPCWSTR,
lpszClassName: class_name.as_ptr(),
};
let class_atom = RegisterClassW(&wnd);
if class_atom == 0 {
panic!("Error registering class");
}
}
}
pub fn quit() {
unsafe {
PostQuitMessage(0);
}
}
pub fn clipboard() -> Clipboard {
Clipboard
}
pub fn get_locale() -> String {
"en-US".into()
}
}