Skip to content

Commit 642d648

Browse files
committed
Fix windows hInstance for raw window handle.
..and make windows' hwnd a non-option, removing lots of 'unwrap'
1 parent b20aaa9 commit 642d648

File tree

1 file changed

+90
-105
lines changed

1 file changed

+90
-105
lines changed

src/os/windows/mod.rs

Lines changed: 90 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ use winapi::{
2727
fileapi::GetFullPathNameW,
2828
libloaderapi, wingdi,
2929
winuser::{
30-
self, GetWindowLongPtrW, GWLP_HINSTANCE, ICON_BIG, ICON_SMALL, IMAGE_ICON,
31-
LR_DEFAULTSIZE, LR_LOADFROMFILE, WM_SETICON,
30+
self, ICON_BIG, ICON_SMALL, IMAGE_ICON, LR_DEFAULTSIZE, LR_LOADFROMFILE, WM_SETICON,
3231
},
3332
},
3433
};
@@ -494,7 +493,8 @@ impl Default for DrawParameters {
494493

495494
#[repr(C)]
496495
pub struct Window {
497-
window: Option<windef::HWND>,
496+
hwnd: windef::HWND,
497+
hinstance: minwindef::HINSTANCE,
498498
dc: windef::HDC,
499499
clear_brush: windef::HBRUSH,
500500
is_open: bool,
@@ -514,17 +514,9 @@ pub struct Window {
514514

515515
impl HasWindowHandle for Window {
516516
fn window_handle(&self) -> std::result::Result<WindowHandle, HandleError> {
517-
let raw_hwnd = self.window.unwrap();
518-
let hwnd = match NonZeroIsize::new(raw_hwnd as isize) {
519-
Some(hwnd) => hwnd,
520-
None => unimplemented!("invalid hwnd"),
521-
};
522-
523-
let raw_hinstance = unsafe { GetWindowLongPtrW(raw_hwnd, GWLP_HINSTANCE) };
524-
let hinstance = NonZeroIsize::new(raw_hinstance);
525-
517+
let hwnd = NonZeroIsize::new(self.hwnd as isize).ok_or(HandleError::Unavailable)?;
526518
let mut handle = Win32WindowHandle::new(hwnd);
527-
handle.hinstance = hinstance;
519+
handle.hinstance = NonZeroIsize::new(self.hinstance as _);
528520

529521
let raw_handle = RawWindowHandle::Win32(handle);
530522
unsafe { Ok(WindowHandle::borrow_raw(raw_handle)) }
@@ -546,35 +538,12 @@ impl Window {
546538
height: usize,
547539
opts: WindowOptions,
548540
scale_factor: i32,
549-
) -> Option<windef::HWND> {
550-
unsafe {
551-
let class_name = to_wstring("minifb_window");
552-
let class = winuser::WNDCLASSW {
553-
style: winuser::CS_HREDRAW | winuser::CS_VREDRAW | winuser::CS_OWNDC,
554-
lpfnWndProc: Some(wnd_proc),
555-
cbClsExtra: 0,
556-
cbWndExtra: 0,
557-
hInstance: libloaderapi::GetModuleHandleA(std::ptr::null()),
558-
hIcon: std::ptr::null_mut(),
559-
hCursor: winuser::LoadCursorW(std::ptr::null_mut(), winuser::IDC_ARROW),
560-
hbrBackground: std::ptr::null_mut(),
561-
lpszMenuName: std::ptr::null(),
562-
lpszClassName: class_name.as_ptr(),
563-
};
564-
565-
if winuser::RegisterClassW(&class) == 0 {
566-
// ignore the "Class already exists" error for multiple windows
567-
if errhandlingapi::GetLastError() as u32 != 1410 {
568-
println!(
569-
"Unable to register class, error {}",
570-
errhandlingapi::GetLastError() as u32
571-
);
572-
return None;
573-
}
574-
}
575-
576-
let window_name = to_wstring(name);
541+
) -> Option<(windef::HWND, minwindef::HINSTANCE)> {
542+
let hinstance = unsafe { libloaderapi::GetModuleHandleA(std::ptr::null()) };
577543

544+
let class_name = to_wstring("minifb_window");
545+
let window_name = to_wstring(name);
546+
let flags = {
578547
let mut flags = 0;
579548

580549
if opts.title {
@@ -602,6 +571,34 @@ impl Window {
602571
flags = winuser::WS_VISIBLE | winuser::WS_POPUP;
603572
}
604573

574+
flags
575+
};
576+
577+
let handle = unsafe {
578+
let class = winuser::WNDCLASSW {
579+
style: winuser::CS_HREDRAW | winuser::CS_VREDRAW | winuser::CS_OWNDC,
580+
lpfnWndProc: Some(wnd_proc),
581+
cbClsExtra: 0,
582+
cbWndExtra: 0,
583+
hInstance: hinstance,
584+
hIcon: std::ptr::null_mut(),
585+
hCursor: winuser::LoadCursorW(std::ptr::null_mut(), winuser::IDC_ARROW),
586+
hbrBackground: std::ptr::null_mut(),
587+
lpszMenuName: std::ptr::null(),
588+
lpszClassName: class_name.as_ptr(),
589+
};
590+
591+
if winuser::RegisterClassW(&class) == 0 {
592+
// ignore the "Class already exists" error for multiple windows
593+
if errhandlingapi::GetLastError() as u32 != 1410 {
594+
println!(
595+
"Unable to register class, error {}",
596+
errhandlingapi::GetLastError() as u32
597+
);
598+
return None;
599+
}
600+
}
601+
605602
let new_width = width * scale_factor as usize;
606603
let new_height = height * scale_factor as usize;
607604

@@ -613,11 +610,10 @@ impl Window {
613610
};
614611

615612
winuser::AdjustWindowRect(&mut rect, flags, 0);
616-
617613
rect.right -= rect.left;
618614
rect.bottom -= rect.top;
619615

620-
let handle = winuser::CreateWindowExW(
616+
winuser::CreateWindowExW(
621617
0,
622618
class_name.as_ptr(),
623619
window_name.as_ptr(),
@@ -630,35 +626,36 @@ impl Window {
630626
std::ptr::null_mut(),
631627
std::ptr::null_mut(),
632628
std::ptr::null_mut(),
633-
);
634-
if handle.is_null() {
635-
println!(
636-
"Unable to create window, error {}",
637-
errhandlingapi::GetLastError() as u32
638-
);
639-
return None;
640-
}
641-
642-
winuser::ShowWindow(handle, winuser::SW_NORMAL);
629+
)
630+
};
643631

644-
Some(handle)
632+
if handle.is_null() {
633+
println!(
634+
"Unable to create window, error {}",
635+
unsafe { errhandlingapi::GetLastError() } as u32
636+
);
637+
None
638+
} else {
639+
unsafe { winuser::ShowWindow(handle, winuser::SW_NORMAL) };
640+
Some((handle, hinstance))
645641
}
646642
}
647643

648644
pub fn new(name: &str, width: usize, height: usize, opts: WindowOptions) -> Result<Window> {
649-
unsafe {
650-
let scale_factor = Self::get_scale_factor(width, height, opts.scale);
645+
let scale_factor = Self::get_scale_factor(width, height, opts.scale);
651646

652-
let handle = Self::open_window(name, width, height, opts, scale_factor);
653-
654-
if handle.is_none() {
655-
return Err(Error::WindowCreate("Unable to create Window".to_owned()));
656-
}
647+
let Some((window_handle, hinstance)) =
648+
Self::open_window(name, width, height, opts, scale_factor)
649+
else {
650+
return Err(Error::WindowCreate("Unable to create Window".to_owned()));
651+
};
657652

653+
unsafe {
658654
let window = Window {
659655
mouse: MouseData::default(),
660-
dc: winuser::GetDC(handle.unwrap()),
661-
window: Some(handle.unwrap()),
656+
dc: winuser::GetDC(window_handle),
657+
hwnd: window_handle,
658+
hinstance,
662659
key_handler: KeyHandler::new(),
663660
update_rate: UpdateRate::new(),
664661
is_open: true,
@@ -698,7 +695,7 @@ impl Window {
698695
pub fn set_title(&mut self, title: &str) {
699696
unsafe {
700697
let title_name = to_wstring(title);
701-
winuser::SetWindowTextW(self.window.unwrap(), title_name.as_ptr());
698+
winuser::SetWindowTextW(self.hwnd, title_name.as_ptr());
702699
}
703700
}
704701

@@ -734,35 +731,33 @@ impl Window {
734731
LR_DEFAULTSIZE | LR_LOADFROMFILE,
735732
);
736733

737-
if let Some(handle) = self.window {
738-
winapi::um::winuser::SendMessageW(
739-
handle,
740-
WM_SETICON,
741-
ICON_SMALL as WPARAM,
742-
icon as LPARAM,
743-
);
734+
winapi::um::winuser::SendMessageW(
735+
self.hwnd,
736+
WM_SETICON,
737+
ICON_SMALL as WPARAM,
738+
icon as LPARAM,
739+
);
744740

745-
winapi::um::winuser::SendMessageW(
746-
handle,
747-
WM_SETICON,
748-
ICON_BIG as WPARAM,
749-
icon as LPARAM,
750-
);
751-
}
741+
winapi::um::winuser::SendMessageW(
742+
self.hwnd,
743+
WM_SETICON,
744+
ICON_BIG as WPARAM,
745+
icon as LPARAM,
746+
);
752747
}
753748
}
754749
}
755750

756751
#[inline]
757752
pub fn get_window_handle(&self) -> *mut c_void {
758-
self.window.unwrap() as *mut c_void
753+
self.hwnd as *mut c_void
759754
}
760755

761756
#[inline]
762757
pub fn set_position(&mut self, x: isize, y: isize) {
763758
unsafe {
764759
winuser::SetWindowPos(
765-
self.window.unwrap(),
760+
self.hwnd,
766761
std::ptr::null_mut(),
767762
x as i32,
768763
y as i32,
@@ -784,7 +779,7 @@ impl Window {
784779
top: 0,
785780
bottom: 0,
786781
};
787-
if winuser::GetWindowRect(self.window.unwrap(), &mut rect) != 0 {
782+
if winuser::GetWindowRect(self.hwnd, &mut rect) != 0 {
788783
x = rect.left;
789784
y = rect.top;
790785
}
@@ -796,7 +791,7 @@ impl Window {
796791
pub fn topmost(&self, topmost: bool) {
797792
unsafe {
798793
winuser::SetWindowPos(
799-
self.window.unwrap(),
794+
self.hwnd,
800795
if topmost {
801796
winuser::HWND_TOPMOST
802797
} else {
@@ -979,7 +974,7 @@ impl Window {
979974
buf_height: usize,
980975
buf_stride: usize,
981976
) -> Result<()> {
982-
let window = self.window.unwrap();
977+
let window = self.hwnd;
983978

984979
self.generic_update(window);
985980

@@ -1002,24 +997,17 @@ impl Window {
1002997

1003998
#[inline]
1004999
pub fn update(&mut self) {
1005-
let window = self.window.unwrap();
1006-
1007-
self.generic_update(window);
1008-
self.message_loop(window);
1000+
self.generic_update(self.hwnd);
1001+
self.message_loop(self.hwnd);
10091002
}
10101003

10111004
#[inline]
10121005
pub fn is_active(&mut self) -> bool {
1013-
match self.window {
1014-
Some(hwnd) => {
1015-
let active = unsafe { winapi::um::winuser::GetActiveWindow() };
1016-
!active.is_null() && active == hwnd
1017-
}
1018-
None => false,
1019-
}
1006+
let active = unsafe { winapi::um::winuser::GetActiveWindow() };
1007+
!active.is_null() && active == self.hwnd
10201008
}
10211009

1022-
unsafe fn get_scale_factor(width: usize, height: usize, scale: Scale) -> i32 {
1010+
fn get_scale_factor(width: usize, height: usize, scale: Scale) -> i32 {
10231011
let factor: i32 = match scale {
10241012
Scale::X1 => 1,
10251013
Scale::X2 => 2,
@@ -1028,8 +1016,8 @@ impl Window {
10281016
Scale::X16 => 16,
10291017
Scale::X32 => 32,
10301018
Scale::FitScreen => {
1031-
let screen_x = winuser::GetSystemMetrics(winuser::SM_CXSCREEN) as i32;
1032-
let screen_y = winuser::GetSystemMetrics(winuser::SM_CYSCREEN) as i32;
1019+
let screen_x = unsafe { winuser::GetSystemMetrics(winuser::SM_CXSCREEN) } as i32;
1020+
let screen_y = unsafe { winuser::GetSystemMetrics(winuser::SM_CYSCREEN) } as i32;
10331021

10341022
let mut scale = 1i32;
10351023

@@ -1092,7 +1080,7 @@ impl Window {
10921080

10931081
pub fn add_menu(&mut self, menu: &Menu) -> MenuHandle {
10941082
unsafe {
1095-
let window = self.window.unwrap();
1083+
let window = self.hwnd;
10961084
let mut main_menu = winuser::GetMenu(window);
10971085

10981086
if main_menu.is_null() {
@@ -1123,7 +1111,7 @@ impl Window {
11231111
}
11241112

11251113
pub fn remove_menu(&mut self, handle: MenuHandle) {
1126-
let window = self.window.unwrap();
1114+
let window = self.hwnd;
11271115
let main_menu = unsafe { winuser::GetMenu(window) };
11281116
for i in 0..self.menus.len() {
11291117
if self.menus[i].menu_handle == handle.0 as windef::HMENU {
@@ -1133,7 +1121,7 @@ impl Window {
11331121
i as minwindef::UINT,
11341122
winuser::MF_BYPOSITION,
11351123
);
1136-
winuser::DrawMenuBar(self.window.unwrap());
1124+
winuser::DrawMenuBar(self.hwnd);
11371125
}
11381126
self.menus.swap_remove(i);
11391127
return;
@@ -1412,11 +1400,8 @@ impl Menu {
14121400
impl Drop for Window {
14131401
fn drop(&mut self) {
14141402
unsafe {
1415-
winuser::ReleaseDC(self.window.unwrap(), self.dc);
1416-
1417-
if self.window.is_some() {
1418-
winuser::DestroyWindow(self.window.unwrap());
1419-
}
1403+
winuser::ReleaseDC(self.hwnd, self.dc);
1404+
winuser::DestroyWindow(self.hwnd);
14201405
}
14211406
}
14221407
}

0 commit comments

Comments
 (0)