mod data;
mod handle;
mod proc;
mod window_class;
use data::WindowData;
pub use handle::HWnd;
pub use proc::wnd_proc;
use std::ptr::null_mut;
use std::rc::Rc;
use window_class::RegisteredClass;
use windows_core::{Error, Result, HSTRING};
use crate::wrappers::win32::h_instance::HInstance;
use crate::wrappers::win32::style::WindowStyle;
use crate::PhySize;
use windows_sys::Win32::Foundation::{HWND, LPARAM, LRESULT, WPARAM};
use windows_sys::Win32::UI::WindowsAndMessaging::CreateWindowExW;
pub trait WindowImpl: 'static {
fn after_create(&self, window: HWnd) -> Result<()>;
unsafe fn handle_message(
&self, window: HWnd, message_code: u32, w_param: WPARAM, l_param: LPARAM,
) -> Option<LRESULT>;
fn before_destroy(&self, window: HWnd);
}
pub fn create_window<W: WindowImpl>(
title: &HSTRING, style: WindowStyle, nc_size: PhySize, parent: HWND,
initializer: impl FnOnce(HWnd) -> W + 'static,
) -> Result<HWND> {
let instance = HInstance::get();
let window_class = RegisteredClass::register_new(instance, Some(wnd_proc::<W>))?;
let data = WindowData::new(initializer, window_class.clone());
let hwnd = unsafe {
CreateWindowExW(
style.style_ex,
window_class.as_atom_ptr(),
title.as_ptr(),
style.style,
0,
0,
nc_size.width.try_into().unwrap_or(i32::MAX),
nc_size.height.try_into().unwrap_or(i32::MAX),
parent,
null_mut(),
instance.as_raw(),
Rc::into_raw(data).cast(),
)
};
if hwnd.is_null() {
return Err(Error::from_win32());
}
Ok(hwnd)
}