@@ -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 ) ]
496495pub 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
515515impl 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 {
14121400impl 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