#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
#![forbid(unsafe_op_in_unsafe_fn)]
use hwnd::*;
use abistr::cstr16;
use bytemuck::*;
use winapi::um::winuser::*;
use winresult::ERROR;
use std::ptr::*;
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};
fn main() {
std::process::exit(main_imp())
}
fn main_imp() -> i32 {
let hinstance = get_module_handle_entry_exe().unwrap();
let hcursor = load_cursor_w(None, IDC::ARROW).unwrap();
let hicon = load_icon_w(None, IDI::APPLICATION).unwrap();
let wc = WndClassW {
wnd_proc: Some(window_proc),
hinstance,
hcursor,
hicon,
class_name: cstr16!("SampleWndClass").into(),
.. WndClassW::zeroed()
};
let wc = unsafe { register_class_w(&wc) }.unwrap();
let ex_style = 0;
let style = WS::OVERLAPPEDWINDOW;
let size = adjust_window_rect_ex_copy(
Rect { left: 0, right: 800, top: 0, bottom: 600 },
style, false, ex_style
).unwrap();
let hwnd = unsafe { create_window_ex_w(
ex_style,
wc,
cstr16!("hello-world"),
style,
CW_USEDEFAULT,
CW_USEDEFAULT,
size.right - size.left,
size.bottom - size.top,
null_mut(),
null_mut(),
hinstance,
null_mut(),
)}.unwrap();
show_window_async(hwnd, SW::SHOWNORMAL).unwrap();
let mut msg = Msg::zeroed();
while get_message_w(&mut msg, HWnd::NULL, 0, 0).unwrap() {
translate_message(&msg);
let _ = unsafe { dispatch_message_w(&msg) };
}
if msg.message == WM::QUIT { return msg.wparam as _ }
0 }
unsafe extern "system" fn window_proc(hwnd: HWnd, umsg: WM32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
if umsg == WM::GETMINMAXINFO {
EARLY.set(hwnd, "early").unwrap();
LATE .set(hwnd, "late" ).unwrap();
}
eprintln!("window_proc({hwnd:?}, {umsg:?}");
eprintln!(" early: {:?}", EARLY.get_copy(hwnd));
eprintln!(" late: {:?}", LATE .get_copy(hwnd));
match umsg {
WM::LBUTTONDOWN => {
unsafe { MessageBoxA(null_mut(), "Message Box\0".as_ptr().cast(), "Caption\0".as_ptr().cast(), MB_OK) };
0
},
WM::RBUTTONDOWN => {
unsafe { destroy_window(hwnd) }.unwrap();
assert_eq!(ERROR::INVALID_WINDOW_HANDLE, unsafe { destroy_window(hwnd) }.unwrap_err());
0
},
WM::DESTROY => {
assert!(is_window(hwnd));
assert_eq!(ERROR::INVALID_WINDOW_HANDLE, EARLY.set(hwnd, "early").unwrap_err()); LATE.set(hwnd, "late").unwrap();
static DESTROY : AtomicBool = AtomicBool::new(false);
if !DESTROY.load(Relaxed) {
DESTROY.store(true, Relaxed);
unsafe { destroy_window(hwnd) }.unwrap();
assert_eq!(ERROR::INVALID_WINDOW_HANDLE, LATE.set(hwnd, "late").unwrap_err()); }
post_quit_message(0);
0
},
_ => unsafe { def_window_proc_w(hwnd, umsg, wparam, lparam) },
}
}
static EARLY : assoc::local::Slot<&'static str> = assoc::local::Slot::new_drop_early();
static LATE : assoc::local::Slot<&'static str> = assoc::local::Slot::new_drop_late();