@@ -30,7 +30,7 @@ pub(super) struct NativeWindowHandle {
3030impl NativeWindowHandle {
3131 pub ( super ) fn new ( window : & dyn Window ) -> NativeWindowHandle {
3232 // Extract Win32 HWND from winit.
33- let hwnd = match window. window_handle ( ) . expect ( "No window handle" ) . as_raw ( ) {
33+ let main = match window. window_handle ( ) . expect ( "No window handle" ) . as_raw ( ) {
3434 RawWindowHandle :: Win32 ( h) => HWND ( h. hwnd . get ( ) as * mut std:: ffi:: c_void ) ,
3535 _ => panic ! ( "Not a Win32 window" ) ,
3636 } ;
@@ -57,55 +57,69 @@ impl NativeWindowHandle {
5757 None ,
5858 HINSTANCE ( std:: ptr:: null_mut ( ) ) ,
5959 // Pass the main window's HWND to WM_NCCREATE so the helper can store it.
60- Some ( & hwnd as * const _ as _ ) ,
60+ Some ( & main as * const _ as _ ) ,
6161 )
6262 }
6363 . expect ( "CreateWindowExW failed" ) ;
6464
6565 // Subclass the main window.
6666 // https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-setwindowlongptra
67- let prev_window_message_handler = unsafe { SetWindowLongPtrW ( hwnd , GWLP_WNDPROC , main_window_handle_message as isize ) } ;
67+ let prev_window_message_handler = unsafe { SetWindowLongPtrW ( main , GWLP_WNDPROC , main_window_handle_message as isize ) } ;
6868 if prev_window_message_handler == 0 {
6969 let _ = unsafe { DestroyWindow ( helper) } ;
7070 panic ! ( "SetWindowLongPtrW failed" ) ;
7171 }
7272
73- let inner = NativeWindowHandle {
74- main : hwnd ,
73+ let native_handle = NativeWindowHandle {
74+ main,
7575 helper,
7676 prev_window_message_handler,
7777 } ;
78- registry:: insert ( & inner ) ;
78+ registry:: insert ( & native_handle ) ;
7979
8080 // Place the helper over the main window and show it without activation.
81- unsafe { position_helper ( hwnd , helper) } ;
81+ unsafe { position_helper ( main , helper) } ;
8282 let _ = unsafe { ShowWindow ( helper, SW_SHOWNOACTIVATE ) } ;
8383
8484 // DwmExtendFrameIntoClientArea is needed to keep native window frame (but no titlebar).
8585 // https://learn.microsoft.com/windows/win32/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea
8686 // https://learn.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
8787 let mut boarder_size: u32 = 1 ;
88- let _ = unsafe { DwmGetWindowAttribute ( hwnd , DWMWA_VISIBLE_FRAME_BORDER_THICKNESS , & mut boarder_size as * mut _ as * mut _ , size_of :: < u32 > ( ) as u32 ) } ;
88+ let _ = unsafe { DwmGetWindowAttribute ( main , DWMWA_VISIBLE_FRAME_BORDER_THICKNESS , & mut boarder_size as * mut _ as * mut _ , size_of :: < u32 > ( ) as u32 ) } ;
8989 let margins = MARGINS {
9090 cxLeftWidth : 0 ,
9191 cxRightWidth : 0 ,
9292 cyBottomHeight : 0 ,
9393 cyTopHeight : boarder_size as i32 ,
9494 } ;
95- let _ = unsafe { DwmExtendFrameIntoClientArea ( hwnd, & margins) } ;
95+ let _ = unsafe { DwmExtendFrameIntoClientArea ( main, & margins) } ;
96+
97+ let hinst = unsafe { GetModuleHandleW ( None ) } . unwrap ( ) ;
98+
99+ // Set taskbar icon
100+ if let Ok ( big) = unsafe { LoadImageW ( hinst, PCWSTR ( 1usize as * const u16 ) , IMAGE_ICON , GetSystemMetrics ( SM_CXICON ) , GetSystemMetrics ( SM_CYICON ) , LR_SHARED ) } {
101+ unsafe { SetClassLongPtrW ( main, GCLP_HICON , big. 0 as isize ) } ;
102+ unsafe { SendMessageW ( main, WM_SETICON , WPARAM ( ICON_BIG as usize ) , LPARAM ( big. 0 as isize ) ) } ;
103+ }
104+
105+ // Set window icon
106+ if let Ok ( small) = unsafe { LoadImageW ( hinst, PCWSTR ( 1usize as * const u16 ) , IMAGE_ICON , GetSystemMetrics ( SM_CXSMICON ) , GetSystemMetrics ( SM_CYSMICON ) , LR_SHARED ) } {
107+ unsafe { SetClassLongPtrW ( main, GCLP_HICONSM , small. 0 as isize ) } ;
108+ unsafe { SendMessageW ( main, WM_SETICON , WPARAM ( ICON_SMALL as usize ) , LPARAM ( small. 0 as isize ) ) } ;
109+ }
96110
97111 // Force window update
98- let _ = unsafe { SetWindowPos ( hwnd , None , 0 , 0 , 0 , 0 , SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER ) } ;
112+ let _ = unsafe { SetWindowPos ( main , None , 0 , 0 , 0 , 0 , SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER ) } ;
99113
100- inner
114+ native_handle
101115 }
102116
103117 pub ( super ) fn destroy ( & self ) {
104118 registry:: remove_by_main ( self . main ) ;
105119
106120 // Undo subclassing and destroy the helper window.
107121 let _ = unsafe { SetWindowLongPtrW ( self . main , GWLP_WNDPROC , self . prev_window_message_handler ) } ;
108- if self . helper . 0 != std :: ptr :: null_mut ( ) {
122+ if ! self . helper . is_invalid ( ) {
109123 let _ = unsafe { DestroyWindow ( self . helper ) } ;
110124 }
111125 }
@@ -264,16 +278,17 @@ unsafe extern "system" fn helper_window_handle_message(hwnd: HWND, msg: u32, wpa
264278 unsafe { DefWindowProcW ( hwnd, msg, wparam, lparam) }
265279}
266280
281+ const RESIZE_BAND_THICKNESS : i32 = 8 ;
282+
267283// Position the helper window to match the main window's location and size (plus the resize band size).
268284unsafe fn position_helper ( main : HWND , helper : HWND ) {
269285 let mut r = RECT :: default ( ) ;
270286 let _ = unsafe { GetWindowRect ( main, & mut r) } ;
271287
272- const RESIZE_BAND_SIZE : i32 = 8 ;
273- let x = r. left - RESIZE_BAND_SIZE ;
274- let y = r. top - RESIZE_BAND_SIZE ;
275- let w = ( r. right - r. left ) + RESIZE_BAND_SIZE * 2 ;
276- let h = ( r. bottom - r. top ) + RESIZE_BAND_SIZE * 2 ;
288+ let x = r. left - RESIZE_BAND_THICKNESS ;
289+ let y = r. top - RESIZE_BAND_THICKNESS ;
290+ let w = ( r. right - r. left ) + RESIZE_BAND_THICKNESS * 2 ;
291+ let h = ( r. bottom - r. top ) + RESIZE_BAND_THICKNESS * 2 ;
277292
278293 let _ = unsafe { SetWindowPos ( helper, main, x, y, w, h, SWP_NOACTIVATE ) } ;
279294}
@@ -285,7 +300,6 @@ unsafe fn calculate_hit(helper: HWND, lparam: LPARAM) -> u32 {
285300 let mut r = RECT :: default ( ) ;
286301 let _ = unsafe { GetWindowRect ( helper, & mut r) } ;
287302
288- const RESIZE_BAND_THICKNESS : i32 = 8 ;
289303 let on_top = y < ( r. top + RESIZE_BAND_THICKNESS ) as u32 ;
290304 let on_right = x >= ( r. right - RESIZE_BAND_THICKNESS ) as u32 ;
291305 let on_bottom = y >= ( r. bottom - RESIZE_BAND_THICKNESS ) as u32 ;
0 commit comments