From 601aee89a0e54590de41e8098b72e8ca4d09a484 Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 23 Jun 2026 10:40:43 +0200 Subject: [PATCH 1/2] Use the proper HInstance value --- src/platform/win/gl.rs | 22 ++++++++-------------- src/platform/win/mod.rs | 11 ++++++++--- src/platform/win/window_state.rs | 6 ++++-- src/wrappers/win32/h_instance.rs | 25 ++++++++++++------------- src/wrappers/win32/window.rs | 2 +- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/platform/win/gl.rs b/src/platform/win/gl.rs index 12092274..1dea04b6 100644 --- a/src/platform/win/gl.rs +++ b/src/platform/win/gl.rs @@ -4,7 +4,7 @@ use std::rc::Rc; use windows_sys::{ core::s, Win32::{ - Foundation::{FreeLibrary, HINSTANCE, HMODULE, HWND}, + Foundation::{FreeLibrary, HMODULE, HWND}, Graphics::{ Gdi::{GetDC, ReleaseDC, HDC}, OpenGL::{ @@ -14,10 +14,7 @@ use windows_sys::{ PFD_TYPE_RGBA, PIXELFORMATDESCRIPTOR, }, }, - System::{ - LibraryLoader::{GetProcAddress, LoadLibraryA}, - SystemServices::IMAGE_DOS_HEADER, - }, + System::LibraryLoader::{GetProcAddress, LoadLibraryA}, UI::WindowsAndMessaging::{ CreateWindowExW, DefWindowProcW, DestroyWindow, RegisterClassW, UnregisterClassW, CS_OWNDC, CW_USEDEFAULT, WNDCLASSW, @@ -26,6 +23,7 @@ use windows_sys::{ }; use crate::gl::*; +use crate::wrappers::win32::h_instance::HInstance; use crate::wrappers::win32::uuid::Uuid; use crate::wrappers::win32::window::HWnd; // See https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_create_context.txt @@ -82,10 +80,6 @@ pub struct GlContextInner { gl_library: HMODULE, } -extern "C" { - static __ImageBase: IMAGE_DOS_HEADER; -} - impl GlContextInner { pub unsafe fn create(window: HWnd, config: GlConfig) -> Result { // Create temporary window and context to load function pointers @@ -94,12 +88,12 @@ impl GlContextInner { let mut class_name: Vec = OsStr::new(&class_name_str).encode_wide().collect(); class_name.push(0); - let hinstance = &__ImageBase as *const IMAGE_DOS_HEADER as HINSTANCE; + let hinstance = HInstance::get_from_dll(); let wnd_class = WNDCLASSW { style: CS_OWNDC, lpfnWndProc: Some(DefWindowProcW), - hInstance: hinstance, + hInstance: hinstance.as_raw(), lpszClassName: class_name.as_ptr(), ..std::mem::zeroed() }; @@ -120,7 +114,7 @@ impl GlContextInner { CW_USEDEFAULT, std::ptr::null_mut(), std::ptr::null_mut(), - hinstance, + hinstance.as_raw(), std::ptr::null_mut(), ); @@ -148,7 +142,7 @@ impl GlContextInner { let hglrc_tmp = wglCreateContext(hdc_tmp); if hglrc_tmp.is_null() { ReleaseDC(hwnd_tmp, hdc_tmp); - UnregisterClassW(class as *const _, hinstance); + UnregisterClassW(class as *const _, hinstance.as_raw()); DestroyWindow(hwnd_tmp); return Err(GlError::CreationFailed(())); } @@ -173,7 +167,7 @@ impl GlContextInner { wglMakeCurrent(hdc_tmp, std::ptr::null_mut()); wglDeleteContext(hglrc_tmp); ReleaseDC(hwnd_tmp, hdc_tmp); - UnregisterClassW(class as *const _, hinstance); + UnregisterClassW(class as *const _, hinstance.as_raw()); DestroyWindow(hwnd_tmp); // Create actual context diff --git a/src/platform/win/mod.rs b/src/platform/win/mod.rs index 61889721..3d75c41c 100644 --- a/src/platform/win/mod.rs +++ b/src/platform/win/mod.rs @@ -4,6 +4,7 @@ mod keyboard; mod window; mod window_state; +use crate::wrappers::win32::h_instance::HInstance; use raw_window_handle::{DisplayHandle, Win32WindowHandle}; use std::fmt::Debug; use std::num::NonZeroIsize; @@ -22,8 +23,9 @@ pub struct PlatformHandle { impl PlatformHandle { pub fn window_handle(&self) -> Option> { - let handle = Win32WindowHandle::new(self.hwnd); - // TODO: add HINSTANCE + let mut handle = Win32WindowHandle::new(self.hwnd); + handle.hinstance = Some(HInstance::get_from_dll().addr()); + Some(unsafe { raw_window_handle::WindowHandle::borrow_raw(handle.into()) }) } @@ -34,6 +36,9 @@ impl PlatformHandle { impl Debug for PlatformHandle { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("PlatformHandle (Win32)").field("hwnd", &self.hwnd.get()).finish() + f.debug_struct("PlatformHandle (Win32)") + .field("hwnd", &self.hwnd.get()) + .field("hinstance", &HInstance::get_from_dll().addr().get()) + .finish() } } diff --git a/src/platform/win/window_state.rs b/src/platform/win/window_state.rs index 11b735da..7e7e9706 100644 --- a/src/platform/win/window_state.rs +++ b/src/platform/win/window_state.rs @@ -1,6 +1,7 @@ use crate::platform::win::keyboard::KeyboardState; use crate::platform::PlatformHandle; use crate::wrappers::win32::cursor::SystemCursor; +use crate::wrappers::win32::h_instance::HInstance; use crate::wrappers::win32::window::HWnd; use crate::wrappers::win32::{Dpi, ExtendedUser32}; use crate::{Event, EventStatus, MouseCursor, WindowHandler, WindowScalePolicy, WindowSize}; @@ -132,8 +133,9 @@ impl WindowState { pub fn window_handle(&self) -> Option> { let Some(hwnd) = NonZeroIsize::new(self.hwnd as _) else { unreachable!() }; - let handle = Win32WindowHandle::new(hwnd); - // TODO: add HINSTANCE + let mut handle = Win32WindowHandle::new(hwnd); + handle.hinstance = Some(HInstance::get_from_dll().addr()); + Some(unsafe { raw_window_handle::WindowHandle::borrow_raw(handle.into()) }) } diff --git a/src/wrappers/win32/h_instance.rs b/src/wrappers/win32/h_instance.rs index b9e5359f..15c7388c 100644 --- a/src/wrappers/win32/h_instance.rs +++ b/src/wrappers/win32/h_instance.rs @@ -1,8 +1,8 @@ use std::ffi::c_void; -use std::ptr::{null_mut, NonNull}; -use windows_core::Error; +use std::num::NonZeroIsize; +use std::ptr::NonNull; use windows_sys::Win32::Foundation::HINSTANCE; -use windows_sys::Win32::System::LibraryLoader::GetModuleHandleW; +use windows_sys::Win32::System::SystemServices::IMAGE_DOS_HEADER; #[derive(Copy, Clone, PartialEq)] pub struct HInstance(NonNull); @@ -16,21 +16,20 @@ unsafe impl Send for HInstance {} unsafe impl Sync for HInstance {} impl HInstance { - pub fn get() -> Self { - let result = unsafe { GetModuleHandleW(null_mut()) }; + pub fn get_from_dll() -> Self { + extern "C" { + static __ImageBase: IMAGE_DOS_HEADER; + } - let Some(result) = NonNull::new(result) else { - panic!( - "Failed to get HInstance pointer: GetModuleHandleW failed: {}", - Error::from_thread() - ) - }; - - Self(result) + unsafe { Self(NonNull::from(&__ImageBase).cast()) } } #[inline] pub fn as_raw(&self) -> HINSTANCE { self.0.as_ptr() } + + pub fn addr(&self) -> NonZeroIsize { + self.0.addr().cast_signed() + } } diff --git a/src/wrappers/win32/window.rs b/src/wrappers/win32/window.rs index a8f4d39b..94bd72a8 100644 --- a/src/wrappers/win32/window.rs +++ b/src/wrappers/win32/window.rs @@ -54,7 +54,7 @@ pub fn create_window( title: &HSTRING, style: WindowStyle, nc_size: PhysicalSize, parent: HWND, _dpi_ctx: &DpiAwarenessContext, initializer: impl FnOnce(HWnd) -> W + 'static, ) -> Result { - let instance = HInstance::get(); + let instance = HInstance::get_from_dll(); let window_class = RegisteredClass::register_new(instance, Some(wnd_proc::))?; let data = WindowData::new(initializer, window_class.clone()); From 6a461ef6545fc20a2e76fb9b99d0ce02e283473b Mon Sep 17 00:00:00 2001 From: Adrien Prokopowicz <6529475+prokopyl@users.noreply.github.com> Date: Tue, 23 Jun 2026 10:52:57 +0200 Subject: [PATCH 2/2] Fix for MSRV --- src/wrappers/win32/h_instance.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wrappers/win32/h_instance.rs b/src/wrappers/win32/h_instance.rs index 15c7388c..f9ab3e94 100644 --- a/src/wrappers/win32/h_instance.rs +++ b/src/wrappers/win32/h_instance.rs @@ -30,6 +30,9 @@ impl HInstance { } pub fn addr(&self) -> NonZeroIsize { - self.0.addr().cast_signed() + match NonZeroIsize::new(self.0.as_ptr() as isize) { + Some(addr) => addr, + None => unreachable!(), + } } }