@@ -6,27 +6,25 @@ use std::{
66
77use compio:: driver:: syscall;
88use inherit_methods_macro:: inherit_methods;
9- use widestring:: U16CString ;
10- use windows_sys:: {
11- Win32 :: {
12- Foundation :: { ERROR_INVALID_HANDLE , HWND , LPARAM , LRESULT , POINT , SetLastError , WPARAM } ,
13- Graphics :: Gdi :: { GetStockObject , MapWindowPoints , WHITE_BRUSH } ,
14- System :: LibraryLoader :: GetModuleHandleW ,
15- UI :: {
16- Input :: KeyboardAndMouse :: { EnableWindow , IsWindowEnabled } ,
17- WindowsAndMessaging :: {
18- CW_USEDEFAULT , CloseWindow , CreateWindowExW , DestroyWindow , GWL_EXSTYLE , GWL_STYLE ,
19- GetClientRect , GetParent , GetWindowLongPtrW , GetWindowRect , GetWindowTextLengthW ,
20- GetWindowTextW , HICON , HWND_DESKTOP , ICON_BIG , IDC_ARROW , IMAGE_ICON ,
21- IsWindowVisible , LR_DEFAULTCOLOR , LR_DEFAULTSIZE , LR_SHARED , LoadCursorW ,
22- LoadImageW , RegisterClassExW , SW_HIDE , SW_SHOW , SWP_NOMOVE , SWP_NOSIZE ,
23- SWP_NOZORDER , SendMessageW , SetWindowLongPtrW , SetWindowPos , SetWindowTextW ,
24- ShowWindow , WM_CLOSE , WM_MOVE , WM_SETICON , WM_SIZE , WNDCLASSEXW , WS_CHILDWINDOW ,
25- WS_OVERLAPPEDWINDOW ,
26- } ,
9+ use widestring:: { U16CStr , U16CString , u16cstr} ;
10+ #[ cfg( feature = "ignore-class-conflict" ) ]
11+ use windows_sys:: Win32 :: Foundation :: ERROR_CLASS_ALREADY_EXISTS ;
12+ use windows_sys:: Win32 :: {
13+ Foundation :: { ERROR_INVALID_HANDLE , HWND , LPARAM , LRESULT , POINT , SetLastError , WPARAM } ,
14+ Graphics :: Gdi :: { GetStockObject , MapWindowPoints , WHITE_BRUSH } ,
15+ System :: LibraryLoader :: GetModuleHandleW ,
16+ UI :: {
17+ Input :: KeyboardAndMouse :: { EnableWindow , IsWindowEnabled } ,
18+ WindowsAndMessaging :: {
19+ CW_USEDEFAULT , CloseWindow , CreateWindowExW , DestroyWindow , GWL_EXSTYLE , GWL_STYLE ,
20+ GetClientRect , GetParent , GetWindowLongPtrW , GetWindowRect , GetWindowTextLengthW ,
21+ GetWindowTextW , HICON , HWND_DESKTOP , ICON_BIG , IDC_ARROW , IMAGE_ICON , IsWindowVisible ,
22+ LR_DEFAULTCOLOR , LR_DEFAULTSIZE , LR_SHARED , LoadCursorW , LoadImageW , RegisterClassExW ,
23+ SW_HIDE , SW_SHOW , SWP_NOMOVE , SWP_NOSIZE , SWP_NOZORDER , SendMessageW ,
24+ SetWindowLongPtrW , SetWindowPos , SetWindowTextW , ShowWindow , WM_CLOSE , WM_MOVE ,
25+ WM_SETICON , WM_SIZE , WNDCLASSEXW , WS_CHILDWINDOW , WS_OVERLAPPEDWINDOW ,
2726 } ,
2827 } ,
29- w,
3028} ;
3129use winio_handle:: { AsRawWindow , AsWindow , BorrowedWindow , RawWindow } ;
3230use winio_primitive:: { Point , Size } ;
@@ -321,7 +319,8 @@ impl AsRawWindow for Widget {
321319 }
322320}
323321
324- pub ( crate ) const WINDOW_CLASS_NAME : * const u16 = w ! ( "XamlWindow" ) ;
322+ pub ( crate ) const WINDOW_CLASS_NAME : & U16CStr =
323+ u16cstr ! ( concat!( "WinioWindowVersion" , env!( "CARGO_PKG_VERSION" ) ) ) ;
325324
326325fn register ( ) {
327326 unsafe {
@@ -338,10 +337,18 @@ fn register() {
338337 hCursor : unsafe { LoadCursorW ( null_mut ( ) , IDC_ARROW ) } ,
339338 hbrBackground : unsafe { GetStockObject ( WHITE_BRUSH ) } ,
340339 lpszMenuName : null ( ) ,
341- lpszClassName : WINDOW_CLASS_NAME ,
340+ lpszClassName : WINDOW_CLASS_NAME . as_ptr ( ) ,
342341 hIconSm : null_mut ( ) ,
343342 } ;
344- syscall ! ( BOOL , unsafe { RegisterClassExW ( & cls) } ) . unwrap ( ) ;
343+ match syscall ! ( BOOL , unsafe { RegisterClassExW ( & cls) } ) {
344+ Ok ( _) => { }
345+ #[ cfg( feature = "ignore-class-conflict" ) ]
346+ Err ( e) if e. raw_os_error ( ) == Some ( ERROR_CLASS_ALREADY_EXISTS as _ ) => {
347+ // The class is already registered. We choose to ignore this error,
348+ // and hope that the class is still valid.
349+ }
350+ Err ( e) => panic ! ( "{e:?}" ) ,
351+ }
345352}
346353
347354static REGISTER : Once = Once :: new ( ) ;
@@ -361,13 +368,18 @@ impl Window {
361368 register_once ( ) ;
362369 let handle = if let Some ( parent) = parent {
363370 Widget :: new (
364- WINDOW_CLASS_NAME ,
371+ WINDOW_CLASS_NAME . as_ptr ( ) ,
365372 WS_OVERLAPPEDWINDOW | WS_CHILDWINDOW ,
366373 0 ,
367374 parent. as_window ( ) . as_raw_window ( ) ,
368375 )
369376 } else {
370- Widget :: new ( WINDOW_CLASS_NAME , WS_OVERLAPPEDWINDOW , 0 , null_mut ( ) )
377+ Widget :: new (
378+ WINDOW_CLASS_NAME . as_ptr ( ) ,
379+ WS_OVERLAPPEDWINDOW ,
380+ 0 ,
381+ null_mut ( ) ,
382+ )
371383 } ;
372384 let this = Self { handle } ;
373385 unsafe { window_use_dark_mode ( this. as_raw_window ( ) ) } ;
0 commit comments