Skip to content

Commit 67c295c

Browse files
authored
Merge pull request #37 from compio-rs/fix/win32-class-conflict
fix(win32): ignore ERROR_CLASS_ALREADY_EXISTS
2 parents 89f9f38 + 8492dd9 commit 67c295c

3 files changed

Lines changed: 38 additions & 24 deletions

File tree

winio-ui-win32/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,5 @@ sync-unsafe-cell = { version = "0.1", optional = true }
6565
embed-resource = "3"
6666

6767
[features]
68+
ignore-class-conflict = []
6869
dark-mode = ["dep:slim-detours-sys", "dep:sync-unsafe-cell"]

winio-ui-win32/src/ui/window.rs

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,25 @@ use std::{
66

77
use compio::driver::syscall;
88
use 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
};
3129
use winio_handle::{AsRawWindow, AsWindow, BorrowedWindow, RawWindow};
3230
use 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

326325
fn 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

347354
static 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()) };

winio/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ enable_log = ["compio/enable_log", "compio-log/enable_log"]
5858

5959
nightly = ["compio/nightly", "cyper/nightly"]
6060
win32-dark-mode = ["winio-ui-win32/dark-mode"]
61+
win32-ignore-class-conflict = ["winio-ui-win32/ignore-class-conflict"]
6162
objc-static = ["winio-ui-app-kit/objc-static"]

0 commit comments

Comments
 (0)