diff --git a/Cargo.toml b/Cargo.toml index bb0da1eb23..0671c4bae1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,14 @@ categories = ["gui"] [package.metadata.docs.rs] features = ["serde", "web-sys"] default-target = "x86_64-unknown-linux-gnu" -targets = ["i686-pc-windows-msvc", "x86_64-pc-windows-msvc", "i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-apple-darwin", "wasm32-unknown-unknown"] +targets = [ + "i686-pc-windows-msvc", + "x86_64-pc-windows-msvc", + "i686-unknown-linux-gnu", + "x86_64-unknown-linux-gnu", + "x86_64-apple-darwin", + "wasm32-unknown-unknown", +] [features] default = ["x11", "wayland"] @@ -59,34 +66,10 @@ features = ["display_link"] [target.'cfg(target_os = "windows")'.dependencies] parking_lot = "0.11" - -[target.'cfg(target_os = "windows")'.dependencies.winapi] -version = "0.3.6" -features = [ - "combaseapi", - "commctrl", - "dwmapi", - "errhandlingapi", - "imm", - "hidusage", - "libloaderapi", - "objbase", - "ole2", - "processthreadsapi", - "shellapi", - "shellscalingapi", - "shobjidl_core", - "unknwnbase", - "winbase", - "windowsx", - "winerror", - "wingdi", - "winnt", - "winuser", -] +winapi = { path = "winapi" } [target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies] -wayland-client = { version = "0.28", features = [ "dlopen"] , optional = true } +wayland-client = { version = "0.28", features = ["dlopen"], optional = true } sctk = { package = "smithay-client-toolkit", version = "0.12.3", optional = true } mio = { version = "0.7", features = ["os-ext"], optional = true } mio-misc = { version = "1.0", optional = true } @@ -118,7 +101,7 @@ features = [ 'Node', 'PointerEvent', 'Window', - 'WheelEvent' + 'WheelEvent', ] [target.'cfg(target_arch = "wasm32")'.dependencies.wasm-bindgen] diff --git a/src/platform/windows.rs b/src/platform/windows.rs index 83a33c6373..efe354e919 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -3,9 +3,9 @@ use std::os::raw::c_void; use std::path::Path; -use libc; -use winapi::shared::minwindef::WORD; -use winapi::shared::windef::{HMENU, HWND}; +use winapi::Windows::Win32::UI::{ + KeyboardAndMouseInput::EnableWindow, MenusAndResources::HMENU, WindowsAndMessaging::HWND, +}; use crate::{ dpi::PhysicalSize, @@ -72,11 +72,11 @@ impl EventLoopExtWindows for EventLoop { /// Additional methods on `Window` that are specific to Windows. pub trait WindowExtWindows { /// Returns the HINSTANCE of the window - fn hinstance(&self) -> *mut libc::c_void; + fn hinstance(&self) -> *mut c_void; /// Returns the native handle that is used by this window. /// /// The pointer will become invalid when the native window was destroyed. - fn hwnd(&self) -> *mut libc::c_void; + fn hwnd(&self) -> *mut c_void; /// Enables or disables mouse and keyboard input to the specified window. /// @@ -102,19 +102,19 @@ pub trait WindowExtWindows { impl WindowExtWindows for Window { #[inline] - fn hinstance(&self) -> *mut libc::c_void { - self.window.hinstance() as *mut _ + fn hinstance(&self) -> *mut c_void { + self.window.hinstance().0 as *mut _ } #[inline] - fn hwnd(&self) -> *mut libc::c_void { - self.window.hwnd() as *mut _ + fn hwnd(&self) -> *mut c_void { + self.window.hwnd().0 as *mut _ } #[inline] fn set_enable(&self, enabled: bool) { unsafe { - winapi::um::winuser::EnableWindow(self.hwnd() as _, enabled as _); + EnableWindow(HWND(self.hwnd() as isize), enabled); } } @@ -239,7 +239,7 @@ impl MonitorHandleExtWindows for MonitorHandle { #[inline] fn hmonitor(&self) -> *mut c_void { - self.inner.hmonitor() as *mut _ + self.inner.hmonitor().0 as *mut _ } } @@ -277,7 +277,7 @@ pub trait IconExtWindows: Sized { /// /// In cases where the specified size does not exist in the file, Windows may perform scaling /// to get an icon of the desired size. - fn from_resource(ordinal: WORD, size: Option>) -> Result; + fn from_resource(ordinal: u32, size: Option>) -> Result; } impl IconExtWindows for Icon { @@ -289,7 +289,7 @@ impl IconExtWindows for Icon { Ok(Icon { inner: win_icon }) } - fn from_resource(ordinal: WORD, size: Option>) -> Result { + fn from_resource(ordinal: u32, size: Option>) -> Result { let win_icon = WinIcon::from_resource(ordinal, size)?; Ok(Icon { inner: win_icon }) } diff --git a/src/platform_impl/windows/dark_mode.rs b/src/platform_impl/windows/dark_mode.rs index 6aabbf8b86..ff7e95ef1f 100644 --- a/src/platform_impl/windows/dark_mode.rs +++ b/src/platform_impl/windows/dark_mode.rs @@ -1,73 +1,49 @@ +use std::os::windows::ffi::OsStrExt; /// This is a simple implementation of support for Windows Dark Mode, /// which is inspired by the solution in https://github.com/ysc3839/win32-darkmode -use std::ffi::OsStr; -use std::os::windows::ffi::OsStrExt; - -use winapi::{ - shared::{ - basetsd::SIZE_T, - minwindef::{BOOL, DWORD, FALSE, UINT, ULONG, WORD}, - ntdef::{LPSTR, NTSTATUS, NT_SUCCESS, PVOID, WCHAR}, - windef::HWND, - winerror::S_OK, +use std::{ffi::OsStr, iter::once}; + +use winapi::Windows::Win32::{ + System::{ + SystemServices::{ + GetProcAddress, LoadLibraryA, BOOL, PSTR, PWSTR, VER_EQUAL, VER_GREATER_EQUAL, + }, + WindowsProgramming::{ + VerSetConditionMask, VerifyVersionInfoW, OSVERSIONINFOEXW, VER_BUILDNUMBER, + VER_MAJORVERSION, VER_MINORVERSION, + }, + }, + UI::{ + Accessibility::{HCF_HIGHCONTRASTON, HIGHCONTRASTA}, + Controls::SetWindowTheme, + WindowsAndMessaging::{ + SystemParametersInfoA, HWND, SPI_GETHIGHCONTRAST, SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS, + }, }, - um::{libloaderapi, uxtheme, winuser}, }; use crate::window::Theme; lazy_static! { - static ref WIN10_BUILD_VERSION: Option = { - // FIXME: RtlGetVersion is a documented windows API, - // should be part of winapi! - - #[allow(non_snake_case)] - #[repr(C)] - struct OSVERSIONINFOW { - dwOSVersionInfoSize: ULONG, - dwMajorVersion: ULONG, - dwMinorVersion: ULONG, - dwBuildNumber: ULONG, - dwPlatformId: ULONG, - szCSDVersion: [WCHAR; 128], - } - - type RtlGetVersion = unsafe extern "system" fn (*mut OSVERSIONINFOW) -> NTSTATUS; - let handle = get_function!("ntdll.dll", RtlGetVersion); - - if let Some(rtl_get_version) = handle { - unsafe { - let mut vi = OSVERSIONINFOW { - dwOSVersionInfoSize: 0, - dwMajorVersion: 0, - dwMinorVersion: 0, - dwBuildNumber: 0, - dwPlatformId: 0, - szCSDVersion: [0; 128], - }; - - let status = (rtl_get_version)(&mut vi as _); - - if NT_SUCCESS(status) && vi.dwMajorVersion == 10 && vi.dwMinorVersion == 0 { - Some(vi.dwBuildNumber) - } else { - None - } - } - } else { - None - } - }; - static ref DARK_MODE_SUPPORTED: bool = { - // We won't try to do anything for windows versions < 17763 - // (Windows 10 October 2018 update) - match *WIN10_BUILD_VERSION { - Some(v) => v >= 17763, - None => false - } + let mut condition_mask = 0; + condition_mask = VerSetConditionMask(condition_mask, VER_MAJORVERSION, VER_EQUAL as u8); + condition_mask = VerSetConditionMask(condition_mask, VER_MINORVERSION, VER_EQUAL as u8); + condition_mask = + VerSetConditionMask(condition_mask, VER_BUILDNUMBER, VER_GREATER_EQUAL as u8); + + VerifyVersionInfoW( + &mut OSVERSIONINFOEXW { + dwMajorVersion: 10, + dwMinorVersion: 0, + dwBuildNumber: 17763, + ..Default::default() + }, + VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER, + condition_mask, + ) + .as_bool() }; - static ref DARK_THEME_NAME: Vec = widestring("DarkMode_Explorer"); static ref LIGHT_THEME_NAME: Vec = widestring(""); } @@ -87,13 +63,13 @@ pub fn try_theme(hwnd: HWND, preferred_theme: Option) -> Theme { Theme::Light }; let theme_name = match theme { - Theme::Dark => DARK_THEME_NAME.as_ptr(), - Theme::Light => LIGHT_THEME_NAME.as_ptr(), + Theme::Dark => DARK_THEME_NAME.as_mut_ptr(), + Theme::Light => LIGHT_THEME_NAME.as_mut_ptr(), }; - let status = unsafe { uxtheme::SetWindowTheme(hwnd, theme_name as _, std::ptr::null()) }; + let status = unsafe { SetWindowTheme(hwnd, PWSTR(theme_name), None) }; - if status == S_OK && set_dark_mode_for_window(hwnd, is_dark_mode) { + if status.is_ok() && set_dark_mode_for_window(hwnd, is_dark_mode) { return theme; } } @@ -116,8 +92,8 @@ fn set_dark_mode_for_window(hwnd: HWND, is_dark_mode: bool) -> bool { #[repr(C)] struct WINDOWCOMPOSITIONATTRIBDATA { Attrib: WINDOWCOMPOSITIONATTRIB, - pvData: PVOID, - cbData: SIZE_T, + pvData: *mut std::os::raw::c_void, + cbData: usize, } lazy_static! { @@ -128,7 +104,7 @@ fn set_dark_mode_for_window(hwnd: HWND, is_dark_mode: bool) -> bool { if let Some(set_window_composition_attribute) = *SET_WINDOW_COMPOSITION_ATTRIBUTE { unsafe { // SetWindowCompositionAttribute needs a bigbool (i32), not bool. - let mut is_dark_mode_bigbool = is_dark_mode as BOOL; + let mut is_dark_mode_bigbool: BOOL = is_dark_mode.into(); let mut data = WINDOWCOMPOSITIONATTRIBDATA { Attrib: WCA_USEDARKMODECOLORS, @@ -136,9 +112,7 @@ fn set_dark_mode_for_window(hwnd: HWND, is_dark_mode: bool) -> bool { cbData: std::mem::size_of_val(&is_dark_mode_bigbool) as _, }; - let status = set_window_composition_attribute(hwnd, &mut data as *mut _); - - status != FALSE + set_window_composition_attribute(hwnd, &mut data as *mut _).as_bool() } } else { false @@ -153,26 +127,20 @@ fn should_apps_use_dark_mode() -> bool { type ShouldAppsUseDarkMode = unsafe extern "system" fn() -> bool; lazy_static! { static ref SHOULD_APPS_USE_DARK_MODE: Option = { - unsafe { - const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: WORD = 132; - - let module = libloaderapi::LoadLibraryA("uxtheme.dll\0".as_ptr() as _); + const UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL: u32 = 132; - if module.is_null() { - return None; - } + let module = unsafe { LoadLibraryA(PSTR("uxtheme.dll".as_mut_ptr())) }; + if module.is_null() { + return None; + } - let handle = libloaderapi::GetProcAddress( + unsafe { + GetProcAddress( module, - winuser::MAKEINTRESOURCEA(UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL), - ); - - if handle.is_null() { - None - } else { - Some(std::mem::transmute(handle)) - } + PSTR(UXTHEME_SHOULDAPPSUSEDARKMODE_ORDINAL as *mut u8), + ) } + .map(|func| std::mem::transmute(func)) }; } @@ -181,41 +149,21 @@ fn should_apps_use_dark_mode() -> bool { .unwrap_or(false) } -// FIXME: This definition was missing from winapi. Can remove from -// here and use winapi once the following PR is released: -// https://github.com/retep998/winapi-rs/pull/815 -#[repr(C)] -#[allow(non_snake_case)] -struct HIGHCONTRASTA { - cbSize: UINT, - dwFlags: DWORD, - lpszDefaultScheme: LPSTR, -} - -const HCF_HIGHCONTRASTON: DWORD = 1; - fn is_high_contrast() -> bool { - let mut hc = HIGHCONTRASTA { - cbSize: 0, - dwFlags: 0, - lpszDefaultScheme: std::ptr::null_mut(), - }; + let mut hc: HIGHCONTRASTA = unsafe { std::mem::zeroed() }; let ok = unsafe { - winuser::SystemParametersInfoA( - winuser::SPI_GETHIGHCONTRAST, + SystemParametersInfoA( + SPI_GETHIGHCONTRAST, std::mem::size_of_val(&hc) as _, &mut hc as *mut _ as _, - 0, + SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS(0), ) }; - ok != FALSE && (HCF_HIGHCONTRASTON & hc.dwFlags) == 1 + !ok.as_bool() && (HCF_HIGHCONTRASTON & hc.dwFlags) == HCF_HIGHCONTRASTON } fn widestring(src: &'static str) -> Vec { - OsStr::new(src) - .encode_wide() - .chain(Some(0).into_iter()) - .collect() + OsStr::new(src).encode_wide().chain(once(0)).collect() } diff --git a/src/platform_impl/windows/dpi.rs b/src/platform_impl/windows/dpi.rs index f7ec439135..f697df5411 100644 --- a/src/platform_impl/windows/dpi.rs +++ b/src/platform_impl/windows/dpi.rs @@ -6,20 +6,21 @@ use crate::platform_impl::platform::util::{ ENABLE_NON_CLIENT_DPI_SCALING, GET_DPI_FOR_MONITOR, GET_DPI_FOR_WINDOW, SET_PROCESS_DPI_AWARE, SET_PROCESS_DPI_AWARENESS, SET_PROCESS_DPI_AWARENESS_CONTEXT, }; -use winapi::{ - shared::{ - minwindef::FALSE, - windef::{DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE, HMONITOR, HWND}, - winerror::S_OK, - }, - um::{ - shellscalingapi::{MDT_EFFECTIVE_DPI, PROCESS_PER_MONITOR_DPI_AWARE}, - wingdi::{GetDeviceCaps, LOGPIXELSX}, - winuser::{self, MONITOR_DEFAULTTONEAREST}, +use winapi::Windows::Win32::{ + Graphics::Gdi::{ + GetDC, GetDeviceCaps, MonitorFromWindow, GET_DEVICE_CAPS_INDEX, HMONITOR, LOGPIXELSX, + MONITOR_DEFAULTTONEAREST, }, + System::SystemServices::DPI_AWARENESS_CONTEXT, + UI::HiDpi::{MDT_EFFECTIVE_DPI, PROCESS_PER_MONITOR_DPI_AWARE}, + UI::WindowsAndMessaging::{IsProcessDPIAware, HWND}, }; -const DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2: DPI_AWARENESS_CONTEXT = -4isize as _; +// These should be removed once https://github.com/microsoft/win32metadata/issues/425 lands in windows-rs +const DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2: DPI_AWARENESS_CONTEXT = + DPI_AWARENESS_CONTEXT(-4isize); +const DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE: DPI_AWARENESS_CONTEXT = + DPI_AWARENESS_CONTEXT(-3isize); pub fn become_dpi_aware() { static ENABLE_DPI_AWARENESS: Once = Once::new(); @@ -27,8 +28,8 @@ pub fn become_dpi_aware() { unsafe { if let Some(SetProcessDpiAwarenessContext) = *SET_PROCESS_DPI_AWARENESS_CONTEXT { // We are on Windows 10 Anniversary Update (1607) or later. - if SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) - == FALSE + if !SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) + .as_bool() { // V2 only works with Windows 10 Creators Update (1703). Try using the older // V1 if we can't set V2. @@ -59,7 +60,7 @@ pub fn get_monitor_dpi(hmonitor: HMONITOR) -> Option { // We are on Windows 8.1 or later. let mut dpi_x = 0; let mut dpi_y = 0; - if GetDpiForMonitor(hmonitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut dpi_y) == S_OK { + if GetDpiForMonitor(hmonitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut dpi_y).is_ok() { // MSDN says that "the values of *dpiX and *dpiY are identical. You only need to // record one of the values to determine the DPI and respond appropriately". // https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx @@ -76,7 +77,7 @@ pub fn dpi_to_scale_factor(dpi: u32) -> f64 { } pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 { - let hdc = winuser::GetDC(hwnd); + let hdc = GetDC(hwnd); if hdc.is_null() { panic!("[winit] `GetDC` returned null!"); } @@ -88,24 +89,24 @@ pub unsafe fn hwnd_dpi(hwnd: HWND) -> u32 { } } else if let Some(GetDpiForMonitor) = *GET_DPI_FOR_MONITOR { // We are on Windows 8.1 or later. - let monitor = winuser::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + let monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); if monitor.is_null() { return BASE_DPI; } let mut dpi_x = 0; let mut dpi_y = 0; - if GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut dpi_y) == S_OK { + if GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &mut dpi_x, &mut dpi_y).is_ok() { dpi_x as u32 } else { BASE_DPI } } else { // We are on Vista or later. - if winuser::IsProcessDPIAware() != FALSE { + if IsProcessDPIAware().as_bool() { // If the process is DPI aware, then scaling must be handled by the application using // this DPI value. - GetDeviceCaps(hdc, LOGPIXELSX) as u32 + GetDeviceCaps(hdc, GET_DEVICE_CAPS_INDEX(LOGPIXELSX)) as u32 } else { // If the process is DPI unaware, then scaling is performed by the OS; we thus return // 96 (scale factor 1.0) to prevent the window from being re-scaled by both the diff --git a/src/platform_impl/windows/drop_handler.rs b/src/platform_impl/windows/drop_handler.rs index f6c7a044d4..466f69212d 100644 --- a/src/platform_impl/windows/drop_handler.rs +++ b/src/platform_impl/windows/drop_handler.rs @@ -1,3 +1,5 @@ +// TODO: This file can be transitioned to windows-rs once https://github.com/microsoft/windows-rs/issues/81 lands + use std::{ ffi::OsString, os::windows::ffi::OsStringExt, @@ -6,21 +8,7 @@ use std::{ sync::atomic::{AtomicUsize, Ordering}, }; -use winapi::{ - ctypes::c_void, - shared::{ - guiddef::REFIID, - minwindef::{DWORD, UINT, ULONG}, - windef::{HWND, POINTL}, - winerror::S_OK, - }, - um::{ - objidl::IDataObject, - oleidl::{IDropTarget, IDropTargetVtbl, DROPEFFECT_COPY, DROPEFFECT_NONE}, - shellapi, unknwnbase, - winnt::HRESULT, - }, -}; +use winapi::Windows::Win32::{System::Com::IDropTarget, UI::WindowsAndMessaging::HWND}; use crate::platform_impl::platform::WindowId; diff --git a/src/platform_impl/windows/event.rs b/src/platform_impl/windows/event.rs index 161cf6b2de..7cd90781d8 100644 --- a/src/platform_impl/windows/event.rs +++ b/src/platform_impl/windows/event.rs @@ -1,37 +1,56 @@ use std::{ char, os::raw::c_int, - ptr, - sync::atomic::{AtomicBool, AtomicPtr, Ordering}, + sync::atomic::{AtomicBool, AtomicIsize, Ordering}, }; -use crate::event::{ModifiersState, ScanCode, VirtualKeyCode}; - -use winapi::{ - shared::minwindef::{HKL, HKL__, LPARAM, UINT, WPARAM}, - um::winuser, +use winapi::Windows::Win32::{ + System::SystemServices::PWSTR, + UI::KeyboardAndMouseInput::{ + GetKeyState, GetKeyboardLayout, GetKeyboardState, MapVirtualKeyA, ToUnicodeEx, + }, + UI::WindowsAndMessaging::{ + MAPVK_VK_TO_CHAR, VK_ADD, VK_APPS, VK_BACK, VK_BROWSER_BACK, VK_BROWSER_FAVORITES, + VK_BROWSER_FORWARD, VK_BROWSER_HOME, VK_BROWSER_REFRESH, VK_BROWSER_SEARCH, + VK_BROWSER_STOP, VK_CAPITAL, VK_CONTROL, VK_CONVERT, VK_DECIMAL, VK_DELETE, VK_DIVIDE, + VK_DOWN, VK_END, VK_ESCAPE, VK_F1, VK_F10, VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, + VK_F17, VK_F18, VK_F19, VK_F2, VK_F20, VK_F21, VK_F22, VK_F23, VK_F24, VK_F3, VK_F4, VK_F5, + VK_F6, VK_F7, VK_F8, VK_F9, VK_HOME, VK_INSERT, VK_KANA, VK_KANJI, VK_LAUNCH_MAIL, + VK_LAUNCH_MEDIA_SELECT, VK_LCONTROL, VK_LEFT, VK_LMENU, VK_LSHIFT, VK_LWIN, + VK_MEDIA_NEXT_TRACK, VK_MEDIA_PLAY_PAUSE, VK_MEDIA_PREV_TRACK, VK_MEDIA_STOP, VK_MENU, + VK_MULTIPLY, VK_NEXT, VK_NONCONVERT, VK_NUMLOCK, VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, + VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, + VK_OEM_1, VK_OEM_102, VK_OEM_2, VK_OEM_3, VK_OEM_4, VK_OEM_5, VK_OEM_6, VK_OEM_7, + VK_OEM_COMMA, VK_OEM_MINUS, VK_OEM_PERIOD, VK_OEM_PLUS, VK_PAUSE, VK_PRIOR, VK_RCONTROL, + VK_RETURN, VK_RIGHT, VK_RMENU, VK_RSHIFT, VK_RWIN, VK_SCROLL, VK_SHIFT, VK_SLEEP, + VK_SNAPSHOT, VK_SPACE, VK_SUBTRACT, VK_TAB, VK_UP, VK_VOLUME_DOWN, VK_VOLUME_MUTE, + VK_VOLUME_UP, + }, + UI::{TextServices::HKL, WindowsAndMessaging::MAPVK_VSC_TO_VK_EX}, }; -fn key_pressed(vkey: c_int) -> bool { - unsafe { (winuser::GetKeyState(vkey) & (1 << 15)) == (1 << 15) } +use crate::event::{ModifiersState, ScanCode, VirtualKeyCode}; + +fn key_pressed(vkey: u32) -> bool { + unsafe { (GetKeyState(vkey as i32) & (1 << 15)) == (1 << 15) } } pub fn get_key_mods() -> ModifiersState { - let filter_out_altgr = layout_uses_altgr() && key_pressed(winuser::VK_RMENU); + let filter_out_altgr = layout_uses_altgr() && key_pressed(VK_RMENU); let mut mods = ModifiersState::empty(); - mods.set(ModifiersState::SHIFT, key_pressed(winuser::VK_SHIFT)); + mods.set(ModifiersState::SHIFT, key_pressed(VK_SHIFT)); mods.set( ModifiersState::CTRL, - key_pressed(winuser::VK_CONTROL) && !filter_out_altgr, + key_pressed(VK_CONTROL) && !filter_out_altgr, ); mods.set( ModifiersState::ALT, - key_pressed(winuser::VK_MENU) && !filter_out_altgr, + key_pressed(VK_MENU) && !filter_out_altgr, ); mods.set( ModifiersState::LOGO, - key_pressed(winuser::VK_LWIN) || key_pressed(winuser::VK_RWIN), + key_pressed(VK_LWIN) || key_pressed(VK_RWIN), ); mods } @@ -87,7 +106,7 @@ impl From for ModifiersState { pub fn get_pressed_keys() -> impl Iterator { let mut keyboard_state = vec![0u8; 256]; - unsafe { winuser::GetKeyboardState(keyboard_state.as_mut_ptr()) }; + unsafe { GetKeyboardState(keyboard_state.as_mut_ptr()) }; keyboard_state .into_iter() .enumerate() @@ -97,11 +116,11 @@ pub fn get_pressed_keys() -> impl Iterator { unsafe fn get_char(keyboard_state: &[u8; 256], v_key: u32, hkl: HKL) -> Option { let mut unicode_bytes = [0u16; 5]; - let len = winuser::ToUnicodeEx( + let len = ToUnicodeEx( v_key, 0, keyboard_state.as_ptr(), - unicode_bytes.as_mut_ptr(), + PWSTR(unicode_bytes.as_mut_ptr()), unicode_bytes.len() as _, 0, hkl, @@ -126,21 +145,21 @@ unsafe fn get_char(keyboard_state: &[u8; 256], v_key: u32, hkl: HKL) -> Option bool { unsafe { - static ACTIVE_LAYOUT: AtomicPtr = AtomicPtr::new(ptr::null_mut()); + static ACTIVE_LAYOUT: AtomicIsize = AtomicIsize::new(0); static USES_ALTGR: AtomicBool = AtomicBool::new(false); - let hkl = winuser::GetKeyboardLayout(0); - let old_hkl = ACTIVE_LAYOUT.swap(hkl, Ordering::SeqCst); + let hkl = GetKeyboardLayout(0); + let old_hkl = ACTIVE_LAYOUT.swap(hkl.0, Ordering::SeqCst); - if hkl == old_hkl { + if hkl == HKL(old_hkl) { return USES_ALTGR.load(Ordering::SeqCst); } let mut keyboard_state_altgr = [0u8; 256]; // AltGr is an alias for Ctrl+Alt for... some reason. Whatever it is, those are the keypresses // we have to emulate to do an AltGr test. - keyboard_state_altgr[winuser::VK_MENU as usize] = 0x80; - keyboard_state_altgr[winuser::VK_CONTROL as usize] = 0x80; + keyboard_state_altgr[VK_MENU as usize] = 0x80; + keyboard_state_altgr[VK_CONTROL as usize] = 0x80; let keyboard_state_empty = [0u8; 256]; @@ -160,55 +179,55 @@ fn layout_uses_altgr() -> bool { } } -pub fn vkey_to_winit_vkey(vkey: c_int) -> Option { +pub fn vkey_to_winit_vkey(vkey: u32) -> Option { // VK_* codes are documented here https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx match vkey { - //winuser::VK_LBUTTON => Some(VirtualKeyCode::Lbutton), - //winuser::VK_RBUTTON => Some(VirtualKeyCode::Rbutton), - //winuser::VK_CANCEL => Some(VirtualKeyCode::Cancel), - //winuser::VK_MBUTTON => Some(VirtualKeyCode::Mbutton), - //winuser::VK_XBUTTON1 => Some(VirtualKeyCode::Xbutton1), - //winuser::VK_XBUTTON2 => Some(VirtualKeyCode::Xbutton2), - winuser::VK_BACK => Some(VirtualKeyCode::Back), - winuser::VK_TAB => Some(VirtualKeyCode::Tab), - //winuser::VK_CLEAR => Some(VirtualKeyCode::Clear), - winuser::VK_RETURN => Some(VirtualKeyCode::Return), - winuser::VK_LSHIFT => Some(VirtualKeyCode::LShift), - winuser::VK_RSHIFT => Some(VirtualKeyCode::RShift), - winuser::VK_LCONTROL => Some(VirtualKeyCode::LControl), - winuser::VK_RCONTROL => Some(VirtualKeyCode::RControl), - winuser::VK_LMENU => Some(VirtualKeyCode::LAlt), - winuser::VK_RMENU => Some(VirtualKeyCode::RAlt), - winuser::VK_PAUSE => Some(VirtualKeyCode::Pause), - winuser::VK_CAPITAL => Some(VirtualKeyCode::Capital), - winuser::VK_KANA => Some(VirtualKeyCode::Kana), - //winuser::VK_HANGUEL => Some(VirtualKeyCode::Hanguel), - //winuser::VK_HANGUL => Some(VirtualKeyCode::Hangul), - //winuser::VK_JUNJA => Some(VirtualKeyCode::Junja), - //winuser::VK_FINAL => Some(VirtualKeyCode::Final), - //winuser::VK_HANJA => Some(VirtualKeyCode::Hanja), - winuser::VK_KANJI => Some(VirtualKeyCode::Kanji), - winuser::VK_ESCAPE => Some(VirtualKeyCode::Escape), - winuser::VK_CONVERT => Some(VirtualKeyCode::Convert), - winuser::VK_NONCONVERT => Some(VirtualKeyCode::NoConvert), - //winuser::VK_ACCEPT => Some(VirtualKeyCode::Accept), - //winuser::VK_MODECHANGE => Some(VirtualKeyCode::Modechange), - winuser::VK_SPACE => Some(VirtualKeyCode::Space), - winuser::VK_PRIOR => Some(VirtualKeyCode::PageUp), - winuser::VK_NEXT => Some(VirtualKeyCode::PageDown), - winuser::VK_END => Some(VirtualKeyCode::End), - winuser::VK_HOME => Some(VirtualKeyCode::Home), - winuser::VK_LEFT => Some(VirtualKeyCode::Left), - winuser::VK_UP => Some(VirtualKeyCode::Up), - winuser::VK_RIGHT => Some(VirtualKeyCode::Right), - winuser::VK_DOWN => Some(VirtualKeyCode::Down), - //winuser::VK_SELECT => Some(VirtualKeyCode::Select), - //winuser::VK_PRINT => Some(VirtualKeyCode::Print), - //winuser::VK_EXECUTE => Some(VirtualKeyCode::Execute), - winuser::VK_SNAPSHOT => Some(VirtualKeyCode::Snapshot), - winuser::VK_INSERT => Some(VirtualKeyCode::Insert), - winuser::VK_DELETE => Some(VirtualKeyCode::Delete), - //winuser::VK_HELP => Some(VirtualKeyCode::Help), + // VK_LBUTTON => Some(VirtualKeyCode::Lbutton), + // VK_RBUTTON => Some(VirtualKeyCode::Rbutton), + // VK_CANCEL => Some(VirtualKeyCode::Cancel), + // VK_MBUTTON => Some(VirtualKeyCode::Mbutton), + // VK_XBUTTON1 => Some(VirtualKeyCode::Xbutton1), + // VK_XBUTTON2 => Some(VirtualKeyCode::Xbutton2), + VK_BACK => Some(VirtualKeyCode::Back), + VK_TAB => Some(VirtualKeyCode::Tab), + // VK_CLEAR => Some(VirtualKeyCode::Clear), + VK_RETURN => Some(VirtualKeyCode::Return), + VK_LSHIFT => Some(VirtualKeyCode::LShift), + VK_RSHIFT => Some(VirtualKeyCode::RShift), + VK_LCONTROL => Some(VirtualKeyCode::LControl), + VK_RCONTROL => Some(VirtualKeyCode::RControl), + VK_LMENU => Some(VirtualKeyCode::LAlt), + VK_RMENU => Some(VirtualKeyCode::RAlt), + VK_PAUSE => Some(VirtualKeyCode::Pause), + VK_CAPITAL => Some(VirtualKeyCode::Capital), + VK_KANA => Some(VirtualKeyCode::Kana), + // VK_HANGUEL => Some(VirtualKeyCode::Hanguel), + // VK_HANGUL => Some(VirtualKeyCode::Hangul), + // VK_JUNJA => Some(VirtualKeyCode::Junja), + // VK_FINAL => Some(VirtualKeyCode::Final), + // VK_HANJA => Some(VirtualKeyCode::Hanja), + VK_KANJI => Some(VirtualKeyCode::Kanji), + VK_ESCAPE => Some(VirtualKeyCode::Escape), + VK_CONVERT => Some(VirtualKeyCode::Convert), + VK_NONCONVERT => Some(VirtualKeyCode::NoConvert), + // VK_ACCEPT => Some(VirtualKeyCode::Accept), + // VK_MODECHANGE => Some(VirtualKeyCode::Modechange), + VK_SPACE => Some(VirtualKeyCode::Space), + VK_PRIOR => Some(VirtualKeyCode::PageUp), + VK_NEXT => Some(VirtualKeyCode::PageDown), + VK_END => Some(VirtualKeyCode::End), + VK_HOME => Some(VirtualKeyCode::Home), + VK_LEFT => Some(VirtualKeyCode::Left), + VK_UP => Some(VirtualKeyCode::Up), + VK_RIGHT => Some(VirtualKeyCode::Right), + VK_DOWN => Some(VirtualKeyCode::Down), + // VK_SELECT => Some(VirtualKeyCode::Select), + // VK_PRINT => Some(VirtualKeyCode::Print), + // VK_EXECUTE => Some(VirtualKeyCode::Execute), + VK_SNAPSHOT => Some(VirtualKeyCode::Snapshot), + VK_INSERT => Some(VirtualKeyCode::Insert), + VK_DELETE => Some(VirtualKeyCode::Delete), + // VK_HELP => Some(VirtualKeyCode::Help), 0x30 => Some(VirtualKeyCode::Key0), 0x31 => Some(VirtualKeyCode::Key1), 0x32 => Some(VirtualKeyCode::Key2), @@ -245,121 +264,115 @@ pub fn vkey_to_winit_vkey(vkey: c_int) -> Option { 0x58 => Some(VirtualKeyCode::X), 0x59 => Some(VirtualKeyCode::Y), 0x5A => Some(VirtualKeyCode::Z), - winuser::VK_LWIN => Some(VirtualKeyCode::LWin), - winuser::VK_RWIN => Some(VirtualKeyCode::RWin), - winuser::VK_APPS => Some(VirtualKeyCode::Apps), - winuser::VK_SLEEP => Some(VirtualKeyCode::Sleep), - winuser::VK_NUMPAD0 => Some(VirtualKeyCode::Numpad0), - winuser::VK_NUMPAD1 => Some(VirtualKeyCode::Numpad1), - winuser::VK_NUMPAD2 => Some(VirtualKeyCode::Numpad2), - winuser::VK_NUMPAD3 => Some(VirtualKeyCode::Numpad3), - winuser::VK_NUMPAD4 => Some(VirtualKeyCode::Numpad4), - winuser::VK_NUMPAD5 => Some(VirtualKeyCode::Numpad5), - winuser::VK_NUMPAD6 => Some(VirtualKeyCode::Numpad6), - winuser::VK_NUMPAD7 => Some(VirtualKeyCode::Numpad7), - winuser::VK_NUMPAD8 => Some(VirtualKeyCode::Numpad8), - winuser::VK_NUMPAD9 => Some(VirtualKeyCode::Numpad9), - winuser::VK_MULTIPLY => Some(VirtualKeyCode::NumpadMultiply), - winuser::VK_ADD => Some(VirtualKeyCode::NumpadAdd), - //winuser::VK_SEPARATOR => Some(VirtualKeyCode::Separator), - winuser::VK_SUBTRACT => Some(VirtualKeyCode::NumpadSubtract), - winuser::VK_DECIMAL => Some(VirtualKeyCode::NumpadDecimal), - winuser::VK_DIVIDE => Some(VirtualKeyCode::NumpadDivide), - winuser::VK_F1 => Some(VirtualKeyCode::F1), - winuser::VK_F2 => Some(VirtualKeyCode::F2), - winuser::VK_F3 => Some(VirtualKeyCode::F3), - winuser::VK_F4 => Some(VirtualKeyCode::F4), - winuser::VK_F5 => Some(VirtualKeyCode::F5), - winuser::VK_F6 => Some(VirtualKeyCode::F6), - winuser::VK_F7 => Some(VirtualKeyCode::F7), - winuser::VK_F8 => Some(VirtualKeyCode::F8), - winuser::VK_F9 => Some(VirtualKeyCode::F9), - winuser::VK_F10 => Some(VirtualKeyCode::F10), - winuser::VK_F11 => Some(VirtualKeyCode::F11), - winuser::VK_F12 => Some(VirtualKeyCode::F12), - winuser::VK_F13 => Some(VirtualKeyCode::F13), - winuser::VK_F14 => Some(VirtualKeyCode::F14), - winuser::VK_F15 => Some(VirtualKeyCode::F15), - winuser::VK_F16 => Some(VirtualKeyCode::F16), - winuser::VK_F17 => Some(VirtualKeyCode::F17), - winuser::VK_F18 => Some(VirtualKeyCode::F18), - winuser::VK_F19 => Some(VirtualKeyCode::F19), - winuser::VK_F20 => Some(VirtualKeyCode::F20), - winuser::VK_F21 => Some(VirtualKeyCode::F21), - winuser::VK_F22 => Some(VirtualKeyCode::F22), - winuser::VK_F23 => Some(VirtualKeyCode::F23), - winuser::VK_F24 => Some(VirtualKeyCode::F24), - winuser::VK_NUMLOCK => Some(VirtualKeyCode::Numlock), - winuser::VK_SCROLL => Some(VirtualKeyCode::Scroll), - winuser::VK_BROWSER_BACK => Some(VirtualKeyCode::NavigateBackward), - winuser::VK_BROWSER_FORWARD => Some(VirtualKeyCode::NavigateForward), - winuser::VK_BROWSER_REFRESH => Some(VirtualKeyCode::WebRefresh), - winuser::VK_BROWSER_STOP => Some(VirtualKeyCode::WebStop), - winuser::VK_BROWSER_SEARCH => Some(VirtualKeyCode::WebSearch), - winuser::VK_BROWSER_FAVORITES => Some(VirtualKeyCode::WebFavorites), - winuser::VK_BROWSER_HOME => Some(VirtualKeyCode::WebHome), - winuser::VK_VOLUME_MUTE => Some(VirtualKeyCode::Mute), - winuser::VK_VOLUME_DOWN => Some(VirtualKeyCode::VolumeDown), - winuser::VK_VOLUME_UP => Some(VirtualKeyCode::VolumeUp), - winuser::VK_MEDIA_NEXT_TRACK => Some(VirtualKeyCode::NextTrack), - winuser::VK_MEDIA_PREV_TRACK => Some(VirtualKeyCode::PrevTrack), - winuser::VK_MEDIA_STOP => Some(VirtualKeyCode::MediaStop), - winuser::VK_MEDIA_PLAY_PAUSE => Some(VirtualKeyCode::PlayPause), - winuser::VK_LAUNCH_MAIL => Some(VirtualKeyCode::Mail), - winuser::VK_LAUNCH_MEDIA_SELECT => Some(VirtualKeyCode::MediaSelect), - /*winuser::VK_LAUNCH_APP1 => Some(VirtualKeyCode::Launch_app1), - winuser::VK_LAUNCH_APP2 => Some(VirtualKeyCode::Launch_app2),*/ - winuser::VK_OEM_PLUS => Some(VirtualKeyCode::Equals), - winuser::VK_OEM_COMMA => Some(VirtualKeyCode::Comma), - winuser::VK_OEM_MINUS => Some(VirtualKeyCode::Minus), - winuser::VK_OEM_PERIOD => Some(VirtualKeyCode::Period), - winuser::VK_OEM_1 => map_text_keys(vkey), - winuser::VK_OEM_2 => map_text_keys(vkey), - winuser::VK_OEM_3 => map_text_keys(vkey), - winuser::VK_OEM_4 => map_text_keys(vkey), - winuser::VK_OEM_5 => map_text_keys(vkey), - winuser::VK_OEM_6 => map_text_keys(vkey), - winuser::VK_OEM_7 => map_text_keys(vkey), - /* winuser::VK_OEM_8 => Some(VirtualKeyCode::Oem_8), */ - winuser::VK_OEM_102 => Some(VirtualKeyCode::OEM102), - /*winuser::VK_PROCESSKEY => Some(VirtualKeyCode::Processkey), - winuser::VK_PACKET => Some(VirtualKeyCode::Packet), - winuser::VK_ATTN => Some(VirtualKeyCode::Attn), - winuser::VK_CRSEL => Some(VirtualKeyCode::Crsel), - winuser::VK_EXSEL => Some(VirtualKeyCode::Exsel), - winuser::VK_EREOF => Some(VirtualKeyCode::Ereof), - winuser::VK_PLAY => Some(VirtualKeyCode::Play), - winuser::VK_ZOOM => Some(VirtualKeyCode::Zoom), - winuser::VK_NONAME => Some(VirtualKeyCode::Noname), - winuser::VK_PA1 => Some(VirtualKeyCode::Pa1), - winuser::VK_OEM_CLEAR => Some(VirtualKeyCode::Oem_clear),*/ + VK_LWIN => Some(VirtualKeyCode::LWin), + VK_RWIN => Some(VirtualKeyCode::RWin), + VK_APPS => Some(VirtualKeyCode::Apps), + VK_SLEEP => Some(VirtualKeyCode::Sleep), + VK_NUMPAD0 => Some(VirtualKeyCode::Numpad0), + VK_NUMPAD1 => Some(VirtualKeyCode::Numpad1), + VK_NUMPAD2 => Some(VirtualKeyCode::Numpad2), + VK_NUMPAD3 => Some(VirtualKeyCode::Numpad3), + VK_NUMPAD4 => Some(VirtualKeyCode::Numpad4), + VK_NUMPAD5 => Some(VirtualKeyCode::Numpad5), + VK_NUMPAD6 => Some(VirtualKeyCode::Numpad6), + VK_NUMPAD7 => Some(VirtualKeyCode::Numpad7), + VK_NUMPAD8 => Some(VirtualKeyCode::Numpad8), + VK_NUMPAD9 => Some(VirtualKeyCode::Numpad9), + VK_MULTIPLY => Some(VirtualKeyCode::NumpadMultiply), + VK_ADD => Some(VirtualKeyCode::NumpadAdd), + // VK_SEPARATOR => Some(VirtualKeyCode::Separator), + VK_SUBTRACT => Some(VirtualKeyCode::NumpadSubtract), + VK_DECIMAL => Some(VirtualKeyCode::NumpadDecimal), + VK_DIVIDE => Some(VirtualKeyCode::NumpadDivide), + VK_F1 => Some(VirtualKeyCode::F1), + VK_F2 => Some(VirtualKeyCode::F2), + VK_F3 => Some(VirtualKeyCode::F3), + VK_F4 => Some(VirtualKeyCode::F4), + VK_F5 => Some(VirtualKeyCode::F5), + VK_F6 => Some(VirtualKeyCode::F6), + VK_F7 => Some(VirtualKeyCode::F7), + VK_F8 => Some(VirtualKeyCode::F8), + VK_F9 => Some(VirtualKeyCode::F9), + VK_F10 => Some(VirtualKeyCode::F10), + VK_F11 => Some(VirtualKeyCode::F11), + VK_F12 => Some(VirtualKeyCode::F12), + VK_F13 => Some(VirtualKeyCode::F13), + VK_F14 => Some(VirtualKeyCode::F14), + VK_F15 => Some(VirtualKeyCode::F15), + VK_F16 => Some(VirtualKeyCode::F16), + VK_F17 => Some(VirtualKeyCode::F17), + VK_F18 => Some(VirtualKeyCode::F18), + VK_F19 => Some(VirtualKeyCode::F19), + VK_F20 => Some(VirtualKeyCode::F20), + VK_F21 => Some(VirtualKeyCode::F21), + VK_F22 => Some(VirtualKeyCode::F22), + VK_F23 => Some(VirtualKeyCode::F23), + VK_F24 => Some(VirtualKeyCode::F24), + VK_NUMLOCK => Some(VirtualKeyCode::Numlock), + VK_SCROLL => Some(VirtualKeyCode::Scroll), + VK_BROWSER_BACK => Some(VirtualKeyCode::NavigateBackward), + VK_BROWSER_FORWARD => Some(VirtualKeyCode::NavigateForward), + VK_BROWSER_REFRESH => Some(VirtualKeyCode::WebRefresh), + VK_BROWSER_STOP => Some(VirtualKeyCode::WebStop), + VK_BROWSER_SEARCH => Some(VirtualKeyCode::WebSearch), + VK_BROWSER_FAVORITES => Some(VirtualKeyCode::WebFavorites), + VK_BROWSER_HOME => Some(VirtualKeyCode::WebHome), + VK_VOLUME_MUTE => Some(VirtualKeyCode::Mute), + VK_VOLUME_DOWN => Some(VirtualKeyCode::VolumeDown), + VK_VOLUME_UP => Some(VirtualKeyCode::VolumeUp), + VK_MEDIA_NEXT_TRACK => Some(VirtualKeyCode::NextTrack), + VK_MEDIA_PREV_TRACK => Some(VirtualKeyCode::PrevTrack), + VK_MEDIA_STOP => Some(VirtualKeyCode::MediaStop), + VK_MEDIA_PLAY_PAUSE => Some(VirtualKeyCode::PlayPause), + VK_LAUNCH_MAIL => Some(VirtualKeyCode::Mail), + VK_LAUNCH_MEDIA_SELECT => Some(VirtualKeyCode::MediaSelect), + // VK_LAUNCH_APP1 => Some(VirtualKeyCode::Launch_app1), + // VK_LAUNCH_APP2 => Some(VirtualKeyCode::Launch_app2), + VK_OEM_PLUS => Some(VirtualKeyCode::Equals), + VK_OEM_COMMA => Some(VirtualKeyCode::Comma), + VK_OEM_MINUS => Some(VirtualKeyCode::Minus), + VK_OEM_PERIOD => Some(VirtualKeyCode::Period), + VK_OEM_1 => map_text_keys(vkey), + VK_OEM_2 => map_text_keys(vkey), + VK_OEM_3 => map_text_keys(vkey), + VK_OEM_4 => map_text_keys(vkey), + VK_OEM_5 => map_text_keys(vkey), + VK_OEM_6 => map_text_keys(vkey), + VK_OEM_7 => map_text_keys(vkey), + // VK_OEM_8 => Some(VirtualKeyCode::Oem_8), + VK_OEM_102 => Some(VirtualKeyCode::OEM102), + // VK_PROCESSKEY => Some(VirtualKeyCode::Processkey), + // VK_PACKET => Some(VirtualKeyCode::Packet), + // VK_ATTN => Some(VirtualKeyCode::Attn), + // VK_CRSEL => Some(VirtualKeyCode::Crsel), + // VK_EXSEL => Some(VirtualKeyCode::Exsel), + // VK_EREOF => Some(VirtualKeyCode::Ereof), + // VK_PLAY => Some(VirtualKeyCode::Play), + // VK_ZOOM => Some(VirtualKeyCode::Zoom), + // VK_NONAME => Some(VirtualKeyCode::Noname), + // VK_PA1 => Some(VirtualKeyCode::Pa1), + // VK_OEM_CLEAR => Some(VirtualKeyCode::Oem_clear), _ => None, } } -pub fn handle_extended_keys( - vkey: c_int, - mut scancode: UINT, - extended: bool, -) -> Option<(c_int, UINT)> { +pub fn handle_extended_keys(vkey: u32, mut scancode: u32, extended: bool) -> Option<(u32, u32)> { // Welcome to hell https://blog.molecular-matters.com/2011/09/05/properly-handling-keyboard-input/ scancode = if extended { 0xE000 } else { 0x0000 } | scancode; let vkey = match vkey { - winuser::VK_SHIFT => unsafe { - winuser::MapVirtualKeyA(scancode, winuser::MAPVK_VSC_TO_VK_EX) as _ - }, - winuser::VK_CONTROL => { + VK_SHIFT => unsafe { MapVirtualKeyA(scancode, MAPVK_VSC_TO_VK_EX) }, + VK_CONTROL => { if extended { - winuser::VK_RCONTROL + VK_RCONTROL } else { - winuser::VK_LCONTROL + VK_LCONTROL } } - winuser::VK_MENU => { + VK_MENU => { if extended { - winuser::VK_RMENU + VK_RMENU } else { - winuser::VK_LMENU + VK_LMENU } } _ => { @@ -367,20 +380,20 @@ pub fn handle_extended_keys( // When VK_PAUSE is pressed it emits a LeftControl + NumLock scancode event sequence, but reports VK_PAUSE // as the virtual key on both events, or VK_PAUSE on the first event or 0xFF when using raw input. // Don't emit anything for the LeftControl event in the pair... - 0xE01D if vkey == winuser::VK_PAUSE => return None, + 0xE01D if vkey == VK_PAUSE => return None, // ...and emit the Pause event for the second event in the pair. - 0x45 if vkey == winuser::VK_PAUSE || vkey == 0xFF as _ => { + 0x45 if vkey == VK_PAUSE || vkey == 0xFF as _ => { scancode = 0xE059; - winuser::VK_PAUSE + VK_PAUSE } // VK_PAUSE has an incorrect vkey value when used with modifiers. VK_PAUSE also reports a different // scancode when used with modifiers than when used without 0xE046 => { scancode = 0xE059; - winuser::VK_PAUSE + VK_PAUSE } // VK_SCROLL has an incorrect vkey value when used with modifiers. - 0x46 => winuser::VK_SCROLL, + 0x46 => VK_SCROLL, _ => vkey, } } @@ -388,22 +401,17 @@ pub fn handle_extended_keys( Some((vkey, scancode)) } -pub fn process_key_params( - wparam: WPARAM, - lparam: LPARAM, -) -> Option<(ScanCode, Option)> { - let scancode = ((lparam >> 16) & 0xff) as UINT; +pub fn process_key_params(wparam: u32, lparam: u32) -> Option<(ScanCode, Option)> { + let scancode = (lparam >> 16) & 0xff; let extended = (lparam & 0x01000000) != 0; - handle_extended_keys(wparam as _, scancode, extended) + handle_extended_keys(wparam, scancode, extended) .map(|(vkey, scancode)| (scancode, vkey_to_winit_vkey(vkey))) } // This is needed as windows doesn't properly distinguish // some virtual key codes for different keyboard layouts -fn map_text_keys(win_virtual_key: i32) -> Option { - let char_key = - unsafe { winuser::MapVirtualKeyA(win_virtual_key as u32, winuser::MAPVK_VK_TO_CHAR) } - & 0x7FFF; +fn map_text_keys(win_virtual_key: u32) -> Option { + let char_key = unsafe { MapVirtualKeyA(win_virtual_key as u32, MAPVK_VK_TO_CHAR) } & 0x7FFF; match char::from_u32(char_key) { Some(';') => Some(VirtualKeyCode::Semicolon), Some('/') => Some(VirtualKeyCode::Slash), diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 795d840dd9..1322b10639 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -16,18 +16,54 @@ use std::{ thread, time::{Duration, Instant}, }; -use winapi::shared::basetsd::{DWORD_PTR, UINT_PTR}; -use winapi::{ - shared::{ - minwindef::{BOOL, DWORD, HIWORD, INT, LOWORD, LPARAM, LRESULT, UINT, WORD, WPARAM}, - windef::{HWND, POINT, RECT}, - windowsx, winerror, +use winapi::Windows::Win32::{ + Devices::HumanInterfaceDevice::MOUSE_MOVE_RELATIVE, + Graphics::Gdi::{ + ClientToScreen, GetMonitorInfoW, GetUpdateRect, MonitorFromRect, MonitorFromWindow, + RedrawWindow, ScreenToClient, ValidateRect, HBRUSH, MONITORINFO, MONITOR_DEFAULTTONULL, + MONITOR_FROM_FLAGS, RDW_INTERNALPAINT, }, - um::{ - commctrl, libloaderapi, ole2, processthreadsapi, winbase, - winnt::{HANDLE, LONG, LPCSTR, SHORT}, - winuser, + System::{ + Com::RevokeDragDrop, + SystemServices::{ + GetModuleHandleW, MsgWaitForMultipleObjectsEx, BOOL, HANDLE, LRESULT, + MWMO_INPUTAVAILABLE, PSTR, PWSTR, + }, + Threading::{GetCurrentThreadId, WAIT_TIMEOUT}, + WindowsProgramming::INFINITE, + }, + UI::{ + Controls::HOVER_DEFAULT, + DisplayDevices::{POINT, RECT}, + KeyboardAndMouseInput::{ + MapVirtualKeyA, ReleaseCapture, SetCapture, TrackMouseEvent, HRAWINPUT, + RIM_TYPEKEYBOARD, RIM_TYPEMOUSE, TME_LEAVE, TRACKMOUSEEVENT, + }, + MenusAndResources::{HCURSOR, HICON}, + PointerInput::{ + POINTER_FLAG_DOWN, POINTER_FLAG_UP, POINTER_FLAG_UPDATE, POINTER_INFO, + POINTER_PEN_INFO, POINTER_TOUCH_INFO, + }, + Shell::{DefSubclassProc, RemoveWindowSubclass, SetWindowSubclass}, + TouchInput::{ + CloseTouchInputHandle, GetTouchInputInfo, HTOUCHINPUT, TOUCHEVENTF_DOWN, + TOUCHEVENTF_MOVE, TOUCHEVENTF_UP, TOUCHINPUT, + }, + WindowsAndMessaging::{ + CreateWindowExW, DefWindowProcW, DestroyWindow, DispatchMessageW, GetClientRect, + GetCursorPos, GetMessageW, GetWindowLongW, LoadCursorW, PeekMessageW, PostMessageW, + PostThreadMessageW, RegisterClassExW, RegisterWindowMessageA, SetCursor, + SetWindowLongPtrW, SetWindowPos, TranslateMessage, GIDC_ARRIVAL, GIDC_REMOVAL, + GWL_EXSTYLE, GWL_STYLE, HTCAPTION, HTCLIENT, HWND, LPARAM, MAPVK_VK_TO_VSC, MINMAXINFO, + PEEK_MESSAGE_REMOVE_TYPE, PM_QS_PAINT, PM_REMOVE, QS_ALLEVENTS, RI_KEY_E0, RI_KEY_E1, + RI_MOUSE_WHEEL, SC_MINIMIZE, SC_RESTORE, SC_SCREENSAVE, SIZE_MAXIMIZED, SWP_NOACTIVATE, + SWP_NOMOVE, SWP_NOZORDER, VK_F4, WHEEL_DELTA, WINDOWPOS, WINDOW_STYLE, WM_CLOSE, + WM_DESTROY, WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE, WM_INPUT_DEVICE_CHANGE, WM_NCCREATE, + WM_NCDESTROY, WM_NCLBUTTONDOWN, WM_PAINT, WM_WINDOWPOSCHANGING, WNDCLASSEXW, + WNDCLASS_STYLES, WPARAM, WS_EX_LAYERED, WS_EX_NOACTIVATE, WS_EX_TRANSPARENT, WS_POPUP, + WS_VISIBLE, + }, }, }; @@ -51,13 +87,13 @@ use crate::{ use runner::{EventLoopRunner, EventLoopRunnerShared}; type GetPointerFrameInfoHistory = unsafe extern "system" fn( - pointerId: UINT, - entriesCount: *mut UINT, - pointerCount: *mut UINT, - pointerInfo: *mut winuser::POINTER_INFO, + pointerId: u32, + entriesCount: *mut u32, + pointerCount: *mut u32, + pointerInfo: *mut POINTER_INFO, ) -> BOOL; -type SkipPointerFrameMessages = unsafe extern "system" fn(pointerId: UINT) -> BOOL; +type SkipPointerFrameMessages = unsafe extern "system" fn(pointerId: u32) -> BOOL; type GetPointerDeviceRects = unsafe extern "system" fn( device: HANDLE, pointerDeviceRect: *mut RECT, @@ -65,10 +101,10 @@ type GetPointerDeviceRects = unsafe extern "system" fn( ) -> BOOL; type GetPointerTouchInfo = - unsafe extern "system" fn(pointerId: UINT, touchInfo: *mut winuser::POINTER_TOUCH_INFO) -> BOOL; + unsafe extern "system" fn(pointerId: u32, touchInfo: *mut POINTER_TOUCH_INFO) -> BOOL; type GetPointerPenInfo = - unsafe extern "system" fn(pointId: UINT, penInfo: *mut winuser::POINTER_PEN_INFO) -> BOOL; + unsafe extern "system" fn(pointId: u32, penInfo: *mut POINTER_PEN_INFO) -> BOOL; lazy_static! { static ref GET_POINTER_FRAME_INFO_HISTORY: Option = @@ -114,14 +150,14 @@ pub struct EventLoop { } pub struct EventLoopWindowTarget { - thread_id: DWORD, + thread_id: u32, thread_msg_target: HWND, pub(crate) runner_shared: EventLoopRunnerShared, } macro_rules! main_thread_check { ($fn_name:literal) => {{ - let thread_id = unsafe { processthreadsapi::GetCurrentThreadId() }; + let thread_id = unsafe { GetCurrentThreadId() }; if thread_id != main_thread_id() { panic!(concat!( "Initializing the event loop outside of the main thread is a significant \ @@ -153,12 +189,11 @@ impl EventLoop { } pub fn new_dpi_unaware_any_thread() -> EventLoop { - let thread_id = unsafe { processthreadsapi::GetCurrentThreadId() }; + let thread_id = unsafe { GetCurrentThreadId() }; let thread_msg_target = create_event_target_window(); - let send_thread_msg_target = thread_msg_target as usize; - thread::spawn(move || wait_thread(thread_id, send_thread_msg_target as HWND)); + thread::spawn(move || wait_thread(thread_id, thread_msg_target)); let wait_thread_id = get_wait_thread_id(); let runner_shared = Rc::new(EventLoopRunner::new(thread_msg_target, wait_thread_id)); @@ -214,11 +249,11 @@ impl EventLoop { runner.poll(); 'main: loop { - if 0 == winuser::GetMessageW(&mut msg, ptr::null_mut(), 0, 0) { + if !GetMessageW(&mut msg, None, 0, 0).as_bool() { break 'main; } - winuser::TranslateMessage(&mut msg); - winuser::DispatchMessageW(&mut msg); + TranslateMessage(&mut msg); + DispatchMessageW(&mut msg); if let Err(payload) = runner.take_panic_error() { runner.reset_runner(); @@ -265,14 +300,14 @@ impl EventLoopWindowTarget { } } -fn main_thread_id() -> DWORD { - static mut MAIN_THREAD_ID: DWORD = 0; +fn main_thread_id() -> u32 { + static mut MAIN_THREAD_ID: u32 = 0; #[used] #[allow(non_upper_case_globals)] #[link_section = ".CRT$XCU"] static INIT_MAIN_THREAD_ID: unsafe fn() = { unsafe fn initer() { - MAIN_THREAD_ID = processthreadsapi::GetCurrentThreadId(); + MAIN_THREAD_ID = GetCurrentThreadId(); } initer }; @@ -280,34 +315,35 @@ fn main_thread_id() -> DWORD { unsafe { MAIN_THREAD_ID } } -fn get_wait_thread_id() -> DWORD { - unsafe { - let mut msg = mem::zeroed(); - let result = winuser::GetMessageW( +fn get_wait_thread_id() -> u32 { + let mut msg = unsafe { mem::zeroed() }; + let result = unsafe { + GetMessageW( &mut msg, - -1 as _, + HWND(-1), *SEND_WAIT_THREAD_ID_MSG_ID, *SEND_WAIT_THREAD_ID_MSG_ID, - ); - assert_eq!( - msg.message, *SEND_WAIT_THREAD_ID_MSG_ID, - "this shouldn't be possible. please open an issue with Winit. error code: {}", - result - ); - msg.lParam as DWORD - } + ) + }; + assert_eq!( + msg.message, + *SEND_WAIT_THREAD_ID_MSG_ID, + "this shouldn't be possible. please open an issue with Winit. error code: {}", + result.as_bool() + ); + msg.lParam.0 as u32 } -fn wait_thread(parent_thread_id: DWORD, msg_window_id: HWND) { +fn wait_thread(parent_thread_id: u32, msg_window_id: HWND) { unsafe { - let mut msg: winuser::MSG; + let mut msg; - let cur_thread_id = processthreadsapi::GetCurrentThreadId(); - winuser::PostThreadMessageW( + let cur_thread_id = GetCurrentThreadId(); + PostThreadMessageW( parent_thread_id, *SEND_WAIT_THREAD_ID_MSG_ID, - 0, - cur_thread_id as LPARAM, + None, + LPARAM(cur_thread_id as isize), ); let mut wait_until_opt = None; @@ -318,21 +354,19 @@ fn wait_thread(parent_thread_id: DWORD, msg_window_id: HWND) { msg = mem::zeroed(); if wait_until_opt.is_some() { - if 0 != winuser::PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, winuser::PM_REMOVE) { - winuser::TranslateMessage(&mut msg); - winuser::DispatchMessageW(&mut msg); + if PeekMessageW(&mut msg, None, 0, 0, PM_REMOVE).as_bool() { + TranslateMessage(&mut msg); + DispatchMessageW(&mut msg); } + } else if !GetMessageW(&mut msg, None, 0, 0).as_bool() { + break 'main; } else { - if 0 == winuser::GetMessageW(&mut msg, ptr::null_mut(), 0, 0) { - break 'main; - } else { - winuser::TranslateMessage(&mut msg); - winuser::DispatchMessageW(&mut msg); - } + TranslateMessage(&mut msg); + DispatchMessageW(&mut msg); } if msg.message == *WAIT_UNTIL_MSG_ID { - wait_until_opt = Some(*WaitUntilInstantBox::from_raw(msg.lParam as *mut _)); + wait_until_opt = Some(*WaitUntilInstantBox::from_raw(msg.lParam.0 as *mut _)); } else if msg.message == *CANCEL_WAIT_UNTIL_MSG_ID { wait_until_opt = None; } @@ -343,19 +377,19 @@ fn wait_thread(parent_thread_id: DWORD, msg_window_id: HWND) { // MsgWaitForMultipleObjects tends to overshoot just a little bit. We subtract // 1 millisecond from the requested time and spinlock for the remainder to // compensate for that. - let resume_reason = winuser::MsgWaitForMultipleObjectsEx( + let resume_reason = MsgWaitForMultipleObjectsEx( 0, ptr::null(), dur2timeout(wait_until - now).saturating_sub(1), - winuser::QS_ALLEVENTS, - winuser::MWMO_INPUTAVAILABLE, + QS_ALLEVENTS, + MWMO_INPUTAVAILABLE, ); - if resume_reason == winerror::WAIT_TIMEOUT { - winuser::PostMessageW(msg_window_id, *PROCESS_NEW_EVENTS_MSG_ID, 0, 0); + if resume_reason == WAIT_TIMEOUT.0 { + PostMessageW(msg_window_id, *PROCESS_NEW_EVENTS_MSG_ID, None, None); wait_until_opt = None; } } else { - winuser::PostMessageW(msg_window_id, *PROCESS_NEW_EVENTS_MSG_ID, 0, 0); + PostMessageW(msg_window_id, *PROCESS_NEW_EVENTS_MSG_ID, None, None); wait_until_opt = None; } } @@ -364,7 +398,7 @@ fn wait_thread(parent_thread_id: DWORD, msg_window_id: HWND) { } // Implementation taken from https://github.com/rust-lang/rust/blob/db5476571d9b27c862b95c1e64764b0ac8980e23/src/libstd/sys/windows/mod.rs -fn dur2timeout(dur: Duration) -> DWORD { +fn dur2timeout(dur: Duration) -> u32 { // Note that a duration is a (u64, u32) (seconds, nanoseconds) pair, and the // timeouts in windows APIs are typically u32 milliseconds. To translate, we // have two pieces to take care of: @@ -383,25 +417,25 @@ fn dur2timeout(dur: Duration) -> DWORD { }) }) .map(|ms| { - if ms > DWORD::max_value() as u64 { - winbase::INFINITE + if ms > u32::max_value() as u64 { + INFINITE } else { - ms as DWORD + ms as u32 } }) - .unwrap_or(winbase::INFINITE) + .unwrap_or(INFINITE) } impl Drop for EventLoop { fn drop(&mut self) { unsafe { - winuser::DestroyWindow(self.window_target.p.thread_msg_target); + DestroyWindow(self.window_target.p.thread_msg_target); } } } pub(crate) struct EventLoopThreadExecutor { - thread_id: DWORD, + thread_id: u32, target_window: HWND, } @@ -411,7 +445,7 @@ unsafe impl Sync for EventLoopThreadExecutor {} impl EventLoopThreadExecutor { /// Check to see if we're in the parent event loop's thread. pub(super) fn in_event_loop_thread(&self) -> bool { - let cur_thread_id = unsafe { processthreadsapi::GetCurrentThreadId() }; + let cur_thread_id = unsafe { GetCurrentThreadId() }; self.thread_id == cur_thread_id } @@ -442,13 +476,12 @@ impl EventLoopThreadExecutor { let raw = Box::into_raw(boxed2); - let res = winuser::PostMessageW( - self.target_window, - *EXEC_MSG_ID, - raw as *mut () as usize as WPARAM, - 0, + let res = + PostMessageW(self.target_window, *EXEC_MSG_ID, WPARAM(raw as usize), None); + assert!( + res.as_bool(), + "PostMessage failed ; is the messages queue full?" ); - assert!(res != 0, "PostMessage failed ; is the messages queue full?"); } } } @@ -474,7 +507,7 @@ impl Clone for EventLoopProxy { impl EventLoopProxy { pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> { unsafe { - if winuser::PostMessageW(self.target_window, *USER_EVENT_MSG_ID, 0, 0) != 0 { + if PostMessageW(self.target_window, *USER_EVENT_MSG_ID, None, None).as_bool() { self.event_send.send(event).ok(); Ok(()) } else { @@ -491,7 +524,7 @@ lazy_static! { // WPARAM and LPARAM are unused. static ref USER_EVENT_MSG_ID: u32 = { unsafe { - winuser::RegisterWindowMessageA("Winit::WakeupMsg\0".as_ptr() as LPCSTR) + RegisterWindowMessageA(PSTR("Winit::WakeupMsg".as_mut_ptr())) } }; // Message sent when we want to execute a closure in the thread. @@ -499,43 +532,43 @@ lazy_static! { // and LPARAM is unused. static ref EXEC_MSG_ID: u32 = { unsafe { - winuser::RegisterWindowMessageA("Winit::ExecMsg\0".as_ptr() as *const i8) + RegisterWindowMessageA(PSTR("Winit::ExecMsg".as_mut_ptr())) } }; static ref PROCESS_NEW_EVENTS_MSG_ID: u32 = { unsafe { - winuser::RegisterWindowMessageA("Winit::ProcessNewEvents\0".as_ptr() as *const i8) + RegisterWindowMessageA(PSTR("Winit::ProcessNewEvents".as_mut_ptr())) } }; /// lparam is the wait thread's message id. static ref SEND_WAIT_THREAD_ID_MSG_ID: u32 = { unsafe { - winuser::RegisterWindowMessageA("Winit::SendWaitThreadId\0".as_ptr() as *const i8) + RegisterWindowMessageA(PSTR("Winit::SendWaitThreadId".as_mut_ptr())) } }; /// lparam points to a `Box` signifying the time `PROCESS_NEW_EVENTS_MSG_ID` should /// be sent. static ref WAIT_UNTIL_MSG_ID: u32 = { unsafe { - winuser::RegisterWindowMessageA("Winit::WaitUntil\0".as_ptr() as *const i8) + RegisterWindowMessageA(PSTR("Winit::WaitUntil".as_mut_ptr())) } }; static ref CANCEL_WAIT_UNTIL_MSG_ID: u32 = { unsafe { - winuser::RegisterWindowMessageA("Winit::CancelWaitUntil\0".as_ptr() as *const i8) + RegisterWindowMessageA(PSTR("Winit::CancelWaitUntil".as_mut_ptr())) } }; // Message sent by a `Window` when it wants to be destroyed by the main thread. // WPARAM and LPARAM are unused. pub static ref DESTROY_MSG_ID: u32 = { unsafe { - winuser::RegisterWindowMessageA("Winit::DestroyMsg\0".as_ptr() as LPCSTR) + RegisterWindowMessageA(PSTR("Winit::DestroyMsg".as_mut_ptr())) } }; // WPARAM is a bool specifying the `WindowFlags::MARKER_RETAIN_STATE_ON_SIZE` flag. See the // documentation in the `window_state` module for more information. pub static ref SET_RETAIN_STATE_ON_SIZE_MSG_ID: u32 = unsafe { - winuser::RegisterWindowMessageA("Winit::SetRetainMaximized\0".as_ptr() as LPCSTR) + RegisterWindowMessageA(PSTR("Winit::SetRetainMaximized".as_mut_ptr())) }; static ref THREAD_EVENT_TARGET_WINDOW_CLASS: Vec = unsafe { use std::ffi::OsStr; @@ -546,22 +579,22 @@ lazy_static! { .chain(Some(0).into_iter()) .collect(); - let class = winuser::WNDCLASSEXW { - cbSize: mem::size_of::() as UINT, - style: 0, - lpfnWndProc: Some(winuser::DefWindowProcW), + let class = WNDCLASSEXW { + cbSize: mem::size_of::() as u32, + style: WNDCLASS_STYLES(0), + lpfnWndProc: Some(util::DefWindowProcW), cbClsExtra: 0, cbWndExtra: 0, - hInstance: libloaderapi::GetModuleHandleW(ptr::null()), - hIcon: ptr::null_mut(), - hCursor: ptr::null_mut(), // must be null in order for cursor state to work properly - hbrBackground: ptr::null_mut(), - lpszMenuName: ptr::null(), - lpszClassName: class_name.as_ptr(), - hIconSm: ptr::null_mut(), + hInstance: GetModuleHandleW(None), + hIcon: HICON::NULL, + hCursor: HCURSOR::NULL, // must be null in order for cursor state to work properly + hbrBackground: HBRUSH::NULL, + lpszMenuName: PWSTR::NULL, + lpszClassName: PWSTR(class_name.as_mut_ptr()), + hIconSm: HICON::NULL, }; - winuser::RegisterClassExW(&class); + RegisterClassExW(&class); class_name }; @@ -569,27 +602,27 @@ lazy_static! { fn create_event_target_window() -> HWND { unsafe { - let window = winuser::CreateWindowExW( - winuser::WS_EX_NOACTIVATE | winuser::WS_EX_TRANSPARENT | winuser::WS_EX_LAYERED, - THREAD_EVENT_TARGET_WINDOW_CLASS.as_ptr(), - ptr::null_mut(), + let window = CreateWindowExW( + WS_EX_NOACTIVATE | WS_EX_TRANSPARENT | WS_EX_LAYERED, + PWSTR(THREAD_EVENT_TARGET_WINDOW_CLASS.as_mut_ptr()), + None, + WINDOW_STYLE(0), 0, 0, 0, 0, - 0, - ptr::null_mut(), - ptr::null_mut(), - libloaderapi::GetModuleHandleW(ptr::null()), + None, + None, + GetModuleHandleW(None), ptr::null_mut(), ); - winuser::SetWindowLongPtrW( + SetWindowLongPtrW( window, - winuser::GWL_STYLE, + GWL_STYLE, // The window technically has to be visible to receive WM_PAINT messages (which are used // for delivering events during resizes), but it isn't displayed to the user because of // the LAYERED style. - (winuser::WS_VISIBLE | winuser::WS_POPUP) as _, + (WS_VISIBLE | WS_POPUP).0 as isize, ); window } @@ -607,13 +640,13 @@ fn subclass_event_target_window( user_event_receiver: rx, }; let input_ptr = Box::into_raw(Box::new(subclass_input)); - let subclass_result = commctrl::SetWindowSubclass( + let subclass_result = SetWindowSubclass( window, Some(thread_event_target_callback::), THREAD_EVENT_TARGET_SUBCLASS_ID, - input_ptr as DWORD_PTR, + input_ptr as usize, ); - assert_eq!(subclass_result, 1); + assert!(subclass_result.as_bool()); tx } @@ -621,20 +654,20 @@ fn subclass_event_target_window( fn remove_event_target_window_subclass(window: HWND) { let removal_result = unsafe { - commctrl::RemoveWindowSubclass( + RemoveWindowSubclass( window, Some(thread_event_target_callback::), THREAD_EVENT_TARGET_SUBCLASS_ID, ) }; - assert_eq!(removal_result, 1); + assert!(removal_result.as_bool()); } /// Capture mouse input, allowing `window` to receive mouse events when the cursor is outside of /// the window. unsafe fn capture_mouse(window: HWND, window_state: &mut WindowState) { window_state.mouse.capture_count += 1; - winuser::SetCapture(window); + SetCapture(window); } /// Release mouse input, stopping windows on this thread from receiving mouse input when the cursor @@ -644,35 +677,35 @@ unsafe fn release_mouse(mut window_state: parking_lot::MutexGuard<'_, WindowStat if window_state.mouse.capture_count == 0 { // ReleaseCapture() causes a WM_CAPTURECHANGED where we lock the window_state. drop(window_state); - winuser::ReleaseCapture(); + ReleaseCapture(); } } -const WINDOW_SUBCLASS_ID: UINT_PTR = 0; -const THREAD_EVENT_TARGET_SUBCLASS_ID: UINT_PTR = 1; +const WINDOW_SUBCLASS_ID: usize = 0; +const THREAD_EVENT_TARGET_SUBCLASS_ID: usize = 1; pub(crate) fn subclass_window(window: HWND, subclass_input: SubclassInput) { subclass_input.event_loop_runner.register_window(window); let input_ptr = Box::into_raw(Box::new(subclass_input)); let subclass_result = unsafe { - commctrl::SetWindowSubclass( + SetWindowSubclass( window, Some(public_window_callback::), WINDOW_SUBCLASS_ID, - input_ptr as DWORD_PTR, + input_ptr as usize, ) }; - assert_eq!(subclass_result, 1); + assert!(subclass_result.as_bool()); } fn remove_window_subclass(window: HWND) { let removal_result = unsafe { - commctrl::RemoveWindowSubclass( + RemoveWindowSubclass( window, Some(public_window_callback::), WINDOW_SUBCLASS_ID, ) }; - assert_eq!(removal_result, 1); + assert!(removal_result.as_bool()); } fn normalize_pointer_pressure(pressure: u32) -> Option { @@ -707,18 +740,20 @@ unsafe fn flush_paint_messages( return; } - if 0 == winuser::PeekMessageW( + if !PeekMessageW( &mut msg, redraw_window, - winuser::WM_PAINT, - winuser::WM_PAINT, - winuser::PM_REMOVE | winuser::PM_QS_PAINT, - ) { + WM_PAINT, + WM_PAINT, + PM_REMOVE | PM_QS_PAINT, + ) + .as_bool() + { return; } - winuser::TranslateMessage(&mut msg); - winuser::DispatchMessageW(&mut msg); + TranslateMessage(&mut msg); + DispatchMessageW(&mut msg); }); true } else { @@ -729,15 +764,20 @@ unsafe fn flush_paint_messages( unsafe fn process_control_flow(runner: &EventLoopRunner) { match runner.control_flow() { ControlFlow::Poll => { - winuser::PostMessageW(runner.thread_msg_target(), *PROCESS_NEW_EVENTS_MSG_ID, 0, 0); + PostMessageW( + runner.thread_msg_target(), + *PROCESS_NEW_EVENTS_MSG_ID, + None, + None, + ); } ControlFlow::Wait => (), ControlFlow::WaitUntil(until) => { - winuser::PostThreadMessageW( + PostThreadMessageW( runner.wait_thread_id(), *WAIT_UNTIL_MSG_ID, - 0, - Box::into_raw(WaitUntilInstantBox::new(until)) as LPARAM, + None, + LPARAM(Box::into_raw(WaitUntilInstantBox::new(until)) as isize), ); } ControlFlow::Exit => (), @@ -758,7 +798,7 @@ fn update_modifiers(window: HWND, subclass_input: &SubclassInput) { unsafe { subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: ModifiersChanged(modifiers), }); } @@ -774,11 +814,11 @@ fn update_modifiers(window: HWND, subclass_input: &SubclassInput) { // FIXME: detect WM_DWMCOMPOSITIONCHANGED and call DwmEnableBlurBehindWindow if necessary unsafe extern "system" fn public_window_callback( window: HWND, - msg: UINT, + msg: u32, wparam: WPARAM, lparam: LPARAM, - uidsubclass: UINT_PTR, - subclass_input_ptr: DWORD_PTR, + uidsubclass: usize, + subclass_input_ptr: usize, ) -> LRESULT { let subclass_input_ptr = subclass_input_ptr as *mut SubclassInput; let (result, subclass_removed, recurse_depth) = { @@ -806,121 +846,122 @@ unsafe extern "system" fn public_window_callback( unsafe fn public_window_callback_inner( window: HWND, - msg: UINT, + msg: u32, wparam: WPARAM, lparam: LPARAM, - _: UINT_PTR, + _: usize, subclass_input: &SubclassInput, ) -> LRESULT { - winuser::RedrawWindow( + RedrawWindow( subclass_input.event_loop_runner.thread_msg_target(), ptr::null(), - ptr::null_mut(), - winuser::RDW_INTERNALPAINT, + None, + RDW_INTERNALPAINT, ); // I decided to bind the closure to `callback` and pass it to catch_unwind rather than passing // the closure to catch_unwind directly so that the match body indendation wouldn't change and // the git blame and history would be preserved. let callback = || match msg { - winuser::WM_ENTERSIZEMOVE => { + WM_ENTERSIZEMOVE => { subclass_input .window_state .lock() .set_window_flags_in_place(|f| f.insert(WindowFlags::MARKER_IN_SIZE_MOVE)); - 0 + LRESULT::NULL } - winuser::WM_EXITSIZEMOVE => { + WM_EXITSIZEMOVE => { subclass_input .window_state .lock() .set_window_flags_in_place(|f| f.remove(WindowFlags::MARKER_IN_SIZE_MOVE)); - 0 + LRESULT::NULL } - winuser::WM_NCCREATE => { + WM_NCCREATE => { enable_non_client_dpi_scaling(window); - commctrl::DefSubclassProc(window, msg, wparam, lparam) + DefSubclassProc(window, msg, wparam, lparam) } - winuser::WM_NCLBUTTONDOWN => { - if wparam == winuser::HTCAPTION as _ { - winuser::PostMessageW(window, winuser::WM_MOUSEMOVE, 0, lparam); + WM_NCLBUTTONDOWN => { + if wparam.0 == HTCAPTION as usize { + PostMessageW( + window, + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_MOUSEMOVE, + None, + lparam, + ); } - commctrl::DefSubclassProc(window, msg, wparam, lparam) + DefSubclassProc(window, msg, wparam, lparam) } - winuser::WM_CLOSE => { + WM_CLOSE => { use crate::event::WindowEvent::CloseRequested; subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: CloseRequested, }); - 0 + LRESULT::NULL } - winuser::WM_DESTROY => { + WM_DESTROY => { use crate::event::WindowEvent::Destroyed; - ole2::RevokeDragDrop(window); + RevokeDragDrop(window); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: Destroyed, }); subclass_input.event_loop_runner.remove_window(window); - 0 + LRESULT::NULL } - winuser::WM_NCDESTROY => { + WM_NCDESTROY => { remove_window_subclass::(window); subclass_input.subclass_removed.set(true); - 0 + LRESULT::NULL } - winuser::WM_PAINT => { + WM_PAINT => { if subclass_input.event_loop_runner.should_buffer() { // this branch can happen in response to `UpdateWindow`, if win32 decides to // redraw the window outside the normal flow of the event loop. - winuser::RedrawWindow( - window, - ptr::null(), - ptr::null_mut(), - winuser::RDW_INTERNALPAINT, - ); + RedrawWindow(window, ptr::null(), None, RDW_INTERNALPAINT); } else { let managing_redraw = flush_paint_messages(Some(window), &subclass_input.event_loop_runner); - subclass_input.send_event(Event::RedrawRequested(RootWindowId(WindowId(window)))); + subclass_input.send_event(Event::RedrawRequested(RootWindowId(WindowId(window.0)))); if managing_redraw { subclass_input.event_loop_runner.redraw_events_cleared(); process_control_flow(&subclass_input.event_loop_runner); } } - commctrl::DefSubclassProc(window, msg, wparam, lparam) + DefSubclassProc(window, msg, wparam, lparam) } - winuser::WM_WINDOWPOSCHANGING => { + WM_WINDOWPOSCHANGING => { let mut window_state = subclass_input.window_state.lock(); if let Some(ref mut fullscreen) = window_state.fullscreen { - let window_pos = &mut *(lparam as *mut winuser::WINDOWPOS); - let new_rect = RECT { + let window_pos = &*(lparam.0 as *const WINDOWPOS); + let mut new_rect = RECT { left: window_pos.x, top: window_pos.y, right: window_pos.x + window_pos.cx, bottom: window_pos.y + window_pos.cy, }; - let new_monitor = - winuser::MonitorFromRect(&new_rect, winuser::MONITOR_DEFAULTTONULL); + let new_monitor = MonitorFromRect(&mut new_rect, MONITOR_DEFAULTTONULL); match fullscreen { Fullscreen::Borderless(ref mut fullscreen_monitor) => { - if new_monitor != ptr::null_mut() + if !new_monitor.is_null() && fullscreen_monitor .as_ref() .map(|monitor| new_monitor != monitor.inner.hmonitor()) .unwrap_or(true) { if let Ok(new_monitor_info) = monitor::get_monitor_info(new_monitor) { - let new_monitor_rect = new_monitor_info.rcMonitor; + let new_monitor_rect = new_monitor_info + .__AnonymousBase_winuser_L13558_C43 + .rcMonitor; window_pos.x = new_monitor_rect.left; window_pos.y = new_monitor_rect.top; window_pos.cx = new_monitor_rect.right - new_monitor_rect.left; @@ -934,7 +975,9 @@ unsafe fn public_window_callback_inner( Fullscreen::Exclusive(ref video_mode) => { let old_monitor = video_mode.video_mode.monitor.hmonitor(); if let Ok(old_monitor_info) = monitor::get_monitor_info(old_monitor) { - let old_monitor_rect = old_monitor_info.rcMonitor; + let old_monitor_rect = old_monitor_info + .__AnonymousBase_winuser_L13558_C43 + .rcMonitor; window_pos.x = old_monitor_rect.left; window_pos.y = old_monitor_rect.top; window_pos.cx = old_monitor_rect.right - old_monitor_rect.left; @@ -944,36 +987,35 @@ unsafe fn public_window_callback_inner( } } - 0 + LRESULT::NULL } // WM_MOVE supplies client area positions, so we send Moved here instead. - winuser::WM_WINDOWPOSCHANGED => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_WINDOWPOSCHANGED => { use crate::event::WindowEvent::Moved; - let windowpos = lparam as *const winuser::WINDOWPOS; - if (*windowpos).flags & winuser::SWP_NOMOVE != winuser::SWP_NOMOVE { + let windowpos = &*(lparam.0 as *const WINDOWPOS); + if windowpos.flags & SWP_NOMOVE != SWP_NOMOVE { let physical_position = - PhysicalPosition::new((*windowpos).x as i32, (*windowpos).y as i32); + PhysicalPosition::new(windowpos.x as i32, windowpos.y as i32); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: Moved(physical_position), }); } // This is necessary for us to still get sent WM_SIZE. - commctrl::DefSubclassProc(window, msg, wparam, lparam) + DefSubclassProc(window, msg, wparam, lparam) } - winuser::WM_SIZE => { - use crate::event::WindowEvent::Resized; - let w = LOWORD(lparam as DWORD) as u32; - let h = HIWORD(lparam as DWORD) as u32; + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SIZE => { + let w = lparam.0 as u32; // LOWORD missing + let h = (lparam.0 >> 16) as u32; // HIWORD missing let physical_size = PhysicalSize::new(w, h); let event = Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), - event: Resized(physical_size), + window_id: RootWindowId(WindowId(window.0)), + event: WindowEvent::Resized(physical_size), }; { @@ -983,31 +1025,32 @@ unsafe fn public_window_callback_inner( .window_flags() .contains(WindowFlags::MARKER_RETAIN_STATE_ON_SIZE) { - let maximized = wparam == winuser::SIZE_MAXIMIZED; + let maximized = wparam.0 == SIZE_MAXIMIZED as usize; w.set_window_flags_in_place(|f| f.set(WindowFlags::MAXIMIZED, maximized)); } } subclass_input.send_event(event); - 0 + LRESULT::NULL } - winuser::WM_CHAR | winuser::WM_SYSCHAR => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_CHAR + | winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SYSCHAR => { use crate::event::WindowEvent::ReceivedCharacter; use std::char; - let is_high_surrogate = 0xD800 <= wparam && wparam <= 0xDBFF; - let is_low_surrogate = 0xDC00 <= wparam && wparam <= 0xDFFF; + let is_high_surrogate = 0xD800 <= wparam.0 && wparam.0 <= 0xDBFF; + let is_low_surrogate = 0xDC00 <= wparam.0 && wparam.0 <= 0xDFFF; if is_high_surrogate { - subclass_input.window_state.lock().high_surrogate = Some(wparam as u16); + subclass_input.window_state.lock().high_surrogate = Some(wparam.0 as u16); } else if is_low_surrogate { let high_surrogate = subclass_input.window_state.lock().high_surrogate.take(); if let Some(high_surrogate) = high_surrogate { - let pair = [high_surrogate, wparam as u16]; + let pair = [high_surrogate, wparam.0 as u16]; if let Some(Ok(chr)) = char::decode_utf16(pair.iter().copied()).next() { subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: ReceivedCharacter(chr), }); } @@ -1015,39 +1058,39 @@ unsafe fn public_window_callback_inner( } else { subclass_input.window_state.lock().high_surrogate = None; - if let Some(chr) = char::from_u32(wparam as u32) { + if let Some(chr) = char::from_u32(wparam.0 as u32) { subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: ReceivedCharacter(chr), }); } } - 0 + LRESULT::NULL } // this is necessary for us to maintain minimize/restore state - winuser::WM_SYSCOMMAND => { - if wparam == winuser::SC_RESTORE { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SYSCOMMAND => { + if wparam.0 == SC_RESTORE as usize { let mut w = subclass_input.window_state.lock(); w.set_window_flags_in_place(|f| f.set(WindowFlags::MINIMIZED, false)); } - if wparam == winuser::SC_MINIMIZE { + if wparam.0 == SC_MINIMIZE as usize { let mut w = subclass_input.window_state.lock(); w.set_window_flags_in_place(|f| f.set(WindowFlags::MINIMIZED, true)); } // Send `WindowEvent::Minimized` here if we decide to implement one - if wparam == winuser::SC_SCREENSAVE { + if wparam.0 == SC_SCREENSAVE as usize { let window_state = subclass_input.window_state.lock(); if window_state.fullscreen.is_some() { - return 0; + return LRESULT::NULL; } } - winuser::DefWindowProcW(window, msg, wparam, lparam) + DefWindowProcW(window, msg, wparam, lparam) } - winuser::WM_MOUSEMOVE => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_MOUSEMOVE => { use crate::event::WindowEvent::{CursorEntered, CursorMoved}; let mouse_was_outside_window = { let mut w = subclass_input.window_state.lock(); @@ -1061,23 +1104,23 @@ unsafe fn public_window_callback_inner( if mouse_was_outside_window { subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: CursorEntered { device_id: DEVICE_ID, }, }); // Calling TrackMouseEvent in order to receive mouse leave events. - winuser::TrackMouseEvent(&mut winuser::TRACKMOUSEEVENT { - cbSize: mem::size_of::() as DWORD, - dwFlags: winuser::TME_LEAVE, + TrackMouseEvent(&mut TRACKMOUSEEVENT { + cbSize: mem::size_of::() as u32, + dwFlags: TME_LEAVE, hwndTrack: window, - dwHoverTime: winuser::HOVER_DEFAULT, + dwHoverTime: HOVER_DEFAULT, }); } - let x = windowsx::GET_X_LPARAM(lparam) as f64; - let y = windowsx::GET_Y_LPARAM(lparam) as f64; + let x = lparam.0 as u32 as f64; // GET_X_LPARAM missing + let y = (lparam.0 >> 16) as u32 as f64; // GET_Y_LPARAM missing let position = PhysicalPosition::new(x, y); let cursor_moved; { @@ -1092,7 +1135,7 @@ unsafe fn public_window_callback_inner( update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: CursorMoved { device_id: DEVICE_ID, position, @@ -1101,10 +1144,10 @@ unsafe fn public_window_callback_inner( }); } - 0 + LRESULT::NULL } - winuser::WM_MOUSELEAVE => { + winapi::Windows::Win32::UI::Controls::WM_MOUSELEAVE => { use crate::event::WindowEvent::CursorLeft; { let mut w = subclass_input.window_state.lock(); @@ -1114,26 +1157,26 @@ unsafe fn public_window_callback_inner( } subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: CursorLeft { device_id: DEVICE_ID, }, }); - 0 + LRESULT::NULL } - winuser::WM_MOUSEWHEEL => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_MOUSEWHEEL => { use crate::event::MouseScrollDelta::LineDelta; - let value = (wparam >> 16) as i16; + let value = (wparam.0 >> 16) as i16; let value = value as i32; - let value = value as f32 / winuser::WHEEL_DELTA as f32; + let value = value as f32 / WHEEL_DELTA as f32; update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::MouseWheel { device_id: DEVICE_ID, delta: LineDelta(0.0, value), @@ -1142,20 +1185,20 @@ unsafe fn public_window_callback_inner( }, }); - 0 + LRESULT::NULL } - winuser::WM_MOUSEHWHEEL => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_MOUSEHWHEEL => { use crate::event::MouseScrollDelta::LineDelta; - let value = (wparam >> 16) as i16; + let value = (wparam.0 >> 16) as i16; let value = value as i32; - let value = value as f32 / winuser::WHEEL_DELTA as f32; + let value = value as f32 / WHEEL_DELTA as f32; update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::MouseWheel { device_id: DEVICE_ID, delta: LineDelta(value, 0.0), @@ -1164,20 +1207,24 @@ unsafe fn public_window_callback_inner( }, }); - 0 + LRESULT::NULL } - winuser::WM_KEYDOWN | winuser::WM_SYSKEYDOWN => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_KEYDOWN + | winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SYSKEYDOWN => { use crate::event::{ElementState::Pressed, VirtualKeyCode}; - if msg == winuser::WM_SYSKEYDOWN && wparam as i32 == winuser::VK_F4 { - commctrl::DefSubclassProc(window, msg, wparam, lparam) + if msg == winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SYSKEYDOWN + && wparam.0 as u32 == VK_F4 + { + DefSubclassProc(window, msg, wparam, lparam) } else { - if let Some((scancode, vkey)) = process_key_params(wparam, lparam) { + if let Some((scancode, vkey)) = process_key_params(wparam.0 as u32, lparam.0 as u32) + { update_modifiers(window, subclass_input); #[allow(deprecated)] subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::KeyboardInput { device_id: DEVICE_ID, input: KeyboardInput { @@ -1193,23 +1240,24 @@ unsafe fn public_window_callback_inner( // consistent with the other platforms we'll emit a delete character here. if vkey == Some(VirtualKeyCode::Delete) { subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::ReceivedCharacter('\u{7F}'), }); } } - 0 + LRESULT::NULL } } - winuser::WM_KEYUP | winuser::WM_SYSKEYUP => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_KEYUP + | winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SYSKEYUP => { use crate::event::ElementState::Released; - if let Some((scancode, vkey)) = process_key_params(wparam, lparam) { + if let Some((scancode, vkey)) = process_key_params(wparam.0 as u32, lparam.0 as u32) { update_modifiers(window, subclass_input); #[allow(deprecated)] subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::KeyboardInput { device_id: DEVICE_ID, input: KeyboardInput { @@ -1222,10 +1270,10 @@ unsafe fn public_window_callback_inner( }, }); } - 0 + LRESULT::NULL } - winuser::WM_LBUTTONDOWN => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_LBUTTONDOWN => { use crate::event::{ElementState::Pressed, MouseButton::Left, WindowEvent::MouseInput}; capture_mouse(window, &mut *subclass_input.window_state.lock()); @@ -1233,7 +1281,7 @@ unsafe fn public_window_callback_inner( update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: MouseInput { device_id: DEVICE_ID, state: Pressed, @@ -1241,10 +1289,10 @@ unsafe fn public_window_callback_inner( modifiers: event::get_key_mods(), }, }); - 0 + LRESULT::NULL } - winuser::WM_LBUTTONUP => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_LBUTTONUP => { use crate::event::{ ElementState::Released, MouseButton::Left, WindowEvent::MouseInput, }; @@ -1254,7 +1302,7 @@ unsafe fn public_window_callback_inner( update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: MouseInput { device_id: DEVICE_ID, state: Released, @@ -1262,10 +1310,10 @@ unsafe fn public_window_callback_inner( modifiers: event::get_key_mods(), }, }); - 0 + LRESULT::NULL } - winuser::WM_RBUTTONDOWN => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_RBUTTONDOWN => { use crate::event::{ ElementState::Pressed, MouseButton::Right, WindowEvent::MouseInput, }; @@ -1275,7 +1323,7 @@ unsafe fn public_window_callback_inner( update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: MouseInput { device_id: DEVICE_ID, state: Pressed, @@ -1283,10 +1331,10 @@ unsafe fn public_window_callback_inner( modifiers: event::get_key_mods(), }, }); - 0 + LRESULT::NULL } - winuser::WM_RBUTTONUP => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_RBUTTONUP => { use crate::event::{ ElementState::Released, MouseButton::Right, WindowEvent::MouseInput, }; @@ -1296,7 +1344,7 @@ unsafe fn public_window_callback_inner( update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: MouseInput { device_id: DEVICE_ID, state: Released, @@ -1304,10 +1352,10 @@ unsafe fn public_window_callback_inner( modifiers: event::get_key_mods(), }, }); - 0 + LRESULT::NULL } - winuser::WM_MBUTTONDOWN => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_MBUTTONDOWN => { use crate::event::{ ElementState::Pressed, MouseButton::Middle, WindowEvent::MouseInput, }; @@ -1317,7 +1365,7 @@ unsafe fn public_window_callback_inner( update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: MouseInput { device_id: DEVICE_ID, state: Pressed, @@ -1325,10 +1373,10 @@ unsafe fn public_window_callback_inner( modifiers: event::get_key_mods(), }, }); - 0 + LRESULT::NULL } - winuser::WM_MBUTTONUP => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_MBUTTONUP => { use crate::event::{ ElementState::Released, MouseButton::Middle, WindowEvent::MouseInput, }; @@ -1338,7 +1386,7 @@ unsafe fn public_window_callback_inner( update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: MouseInput { device_id: DEVICE_ID, state: Released, @@ -1346,21 +1394,21 @@ unsafe fn public_window_callback_inner( modifiers: event::get_key_mods(), }, }); - 0 + LRESULT::NULL } - winuser::WM_XBUTTONDOWN => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_XBUTTONDOWN => { use crate::event::{ ElementState::Pressed, MouseButton::Other, WindowEvent::MouseInput, }; - let xbutton = winuser::GET_XBUTTON_WPARAM(wparam); + let xbutton = (wparam.0 >> 16) as u16; // GET_XBUTTON_WPARAM missing capture_mouse(window, &mut *subclass_input.window_state.lock()); update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: MouseInput { device_id: DEVICE_ID, state: Pressed, @@ -1368,21 +1416,21 @@ unsafe fn public_window_callback_inner( modifiers: event::get_key_mods(), }, }); - 0 + LRESULT::NULL } - winuser::WM_XBUTTONUP => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_XBUTTONUP => { use crate::event::{ ElementState::Released, MouseButton::Other, WindowEvent::MouseInput, }; - let xbutton = winuser::GET_XBUTTON_WPARAM(wparam); + let xbutton = (wparam.0 >> 16) as u16; // GET_XBUTTON_WPARAM missing release_mouse(subclass_input.window_state.lock()); update_modifiers(window, subclass_input); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: MouseInput { device_id: DEVICE_ID, state: Released, @@ -1390,31 +1438,32 @@ unsafe fn public_window_callback_inner( modifiers: event::get_key_mods(), }, }); - 0 + LRESULT::NULL } - winuser::WM_CAPTURECHANGED => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_CAPTURECHANGED => { // lparam here is a handle to the window which is gaining mouse capture. // If it is the same as our window, then we're essentially retaining the capture. This // can happen if `SetCapture` is called on our window when it already has the mouse // capture. - if lparam != window as isize { + if lparam.0 != window.0 { subclass_input.window_state.lock().mouse.capture_count = 0; } - 0 + LRESULT::NULL } - winuser::WM_TOUCH => { - let pcount = LOWORD(wparam as DWORD) as usize; - let mut inputs = Vec::with_capacity(pcount); - inputs.set_len(pcount); - let htouch = lparam as winuser::HTOUCHINPUT; - if winuser::GetTouchInputInfo( + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_TOUCH => { + let pcount = wparam.0 as u32; // LOWORD missing + let mut inputs = Vec::with_capacity(pcount as usize); + inputs.set_len(pcount as usize); + let htouch = HTOUCHINPUT(lparam.0); + if GetTouchInputInfo( htouch, - pcount as UINT, + pcount, inputs.as_mut_ptr(), - mem::size_of::() as INT, - ) > 0 + mem::size_of::() as i32, + ) + .as_bool() { for input in &inputs { let mut location = POINT { @@ -1422,7 +1471,7 @@ unsafe fn public_window_callback_inner( y: input.y / 100, }; - if winuser::ScreenToClient(window, &mut location as *mut _) == 0 { + if !ScreenToClient(window, &mut location as *mut _).as_bool() { continue; } @@ -1430,13 +1479,13 @@ unsafe fn public_window_callback_inner( let y = location.y as f64 + (input.y % 100) as f64 / 100f64; let location = PhysicalPosition::new(x, y); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::Touch(Touch { - phase: if input.dwFlags & winuser::TOUCHEVENTF_DOWN != 0 { + phase: if (input.dwFlags & TOUCHEVENTF_DOWN).0 != 0 { TouchPhase::Started - } else if input.dwFlags & winuser::TOUCHEVENTF_UP != 0 { + } else if (input.dwFlags & TOUCHEVENTF_UP).0 != 0 { TouchPhase::Ended - } else if input.dwFlags & winuser::TOUCHEVENTF_MOVE != 0 { + } else if (input.dwFlags & TOUCHEVENTF_MOVE).0 != 0 { TouchPhase::Moved } else { continue; @@ -1449,11 +1498,13 @@ unsafe fn public_window_callback_inner( }); } } - winuser::CloseTouchInputHandle(htouch); - 0 + CloseTouchInputHandle(htouch); + LRESULT::NULL } - winuser::WM_POINTERDOWN | winuser::WM_POINTERUPDATE | winuser::WM_POINTERUP => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_POINTERDOWN + | winapi::Windows::Win32::UI::WindowsAndMessaging::WM_POINTERUPDATE + | winapi::Windows::Win32::UI::WindowsAndMessaging::WM_POINTERUP => { if let ( Some(GetPointerFrameInfoHistory), Some(SkipPointerFrameMessages), @@ -1463,30 +1514,32 @@ unsafe fn public_window_callback_inner( *SKIP_POINTER_FRAME_MESSAGES, *GET_POINTER_DEVICE_RECTS, ) { - let pointer_id = LOWORD(wparam as DWORD) as UINT; - let mut entries_count = 0 as UINT; - let mut pointers_count = 0 as UINT; - if GetPointerFrameInfoHistory( + let pointer_id = wparam.0 as u32; // LOWORD missing + let mut entries_count = 0; + let mut pointers_count = 0; + if !GetPointerFrameInfoHistory( pointer_id, - &mut entries_count as *mut _, - &mut pointers_count as *mut _, + &mut entries_count, + &mut pointers_count, std::ptr::null_mut(), - ) == 0 + ) + .as_bool() { - return 0; + return LRESULT::NULL; } let pointer_info_count = (entries_count * pointers_count) as usize; let mut pointer_infos = Vec::with_capacity(pointer_info_count); pointer_infos.set_len(pointer_info_count); - if GetPointerFrameInfoHistory( + if !GetPointerFrameInfoHistory( pointer_id, - &mut entries_count as *mut _, - &mut pointers_count as *mut _, + &mut entries_count, + &mut pointers_count, pointer_infos.as_mut_ptr(), - ) == 0 + ) + .as_bool() { - return 0; + return LRESULT::NULL; } // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getpointerframeinfohistory @@ -1496,11 +1549,12 @@ unsafe fn public_window_callback_inner( let mut device_rect = mem::MaybeUninit::uninit(); let mut display_rect = mem::MaybeUninit::uninit(); - if (GetPointerDeviceRects( + if !GetPointerDeviceRects( pointer_info.sourceDevice, device_rect.as_mut_ptr(), display_rect.as_mut_ptr(), - )) == 0 + ) + .as_bool() { continue; } @@ -1528,36 +1582,35 @@ unsafe fn public_window_callback_inner( y: y.floor() as i32, }; - if winuser::ScreenToClient(window, &mut location as *mut _) == 0 { + if !ScreenToClient(window, &mut location as *mut _).as_bool() { continue; } let force = match pointer_info.pointerType { - winuser::PT_TOUCH => { + winapi::Windows::Win32::UI::WindowsAndMessaging::PT_TOUCH => { let mut touch_info = mem::MaybeUninit::uninit(); GET_POINTER_TOUCH_INFO.and_then(|GetPointerTouchInfo| { - match GetPointerTouchInfo( + if GetPointerTouchInfo( pointer_info.pointerId, touch_info.as_mut_ptr(), - ) { - 0 => None, - _ => normalize_pointer_pressure( - touch_info.assume_init().pressure, - ), + ) + .as_bool() + { + normalize_pointer_pressure(touch_info.assume_init().pressure) + } else { + None } }) } - winuser::PT_PEN => { + winapi::Windows::Win32::UI::WindowsAndMessaging::PT_PEN => { let mut pen_info = mem::MaybeUninit::uninit(); GET_POINTER_PEN_INFO.and_then(|GetPointerPenInfo| { - match GetPointerPenInfo( - pointer_info.pointerId, - pen_info.as_mut_ptr(), - ) { - 0 => None, - _ => { - normalize_pointer_pressure(pen_info.assume_init().pressure) - } + if GetPointerPenInfo(pointer_info.pointerId, pen_info.as_mut_ptr()) + .as_bool() + { + normalize_pointer_pressure(pen_info.assume_init().pressure) + } else { + None } }) } @@ -1568,14 +1621,13 @@ unsafe fn public_window_callback_inner( let y = location.y as f64 + y.fract(); let location = PhysicalPosition::new(x, y); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::Touch(Touch { - phase: if pointer_info.pointerFlags & winuser::POINTER_FLAG_DOWN != 0 { + phase: if (pointer_info.pointerFlags & POINTER_FLAG_DOWN).0 != 0 { TouchPhase::Started - } else if pointer_info.pointerFlags & winuser::POINTER_FLAG_UP != 0 { + } else if (pointer_info.pointerFlags & POINTER_FLAG_UP).0 != 0 { TouchPhase::Ended - } else if pointer_info.pointerFlags & winuser::POINTER_FLAG_UPDATE != 0 - { + } else if (pointer_info.pointerFlags & POINTER_FLAG_UPDATE).0 != 0 { TouchPhase::Moved } else { continue; @@ -1590,21 +1642,20 @@ unsafe fn public_window_callback_inner( SkipPointerFrameMessages(pointer_id); } - 0 + LRESULT::NULL } - winuser::WM_SETFOCUS => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SETFOCUS => { use crate::event::{ElementState::Released, WindowEvent::Focused}; for windows_keycode in event::get_pressed_keys() { - let scancode = - winuser::MapVirtualKeyA(windows_keycode as _, winuser::MAPVK_VK_TO_VSC); - let virtual_keycode = event::vkey_to_winit_vkey(windows_keycode); + let scancode = MapVirtualKeyA(windows_keycode as _, MAPVK_VK_TO_VSC); + let virtual_keycode = event::vkey_to_winit_vkey(windows_keycode as u32); update_modifiers(window, subclass_input); #[allow(deprecated)] subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::KeyboardInput { device_id: DEVICE_ID, input: KeyboardInput { @@ -1619,27 +1670,26 @@ unsafe fn public_window_callback_inner( } subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: Focused(true), }); - 0 + LRESULT::NULL } - winuser::WM_KILLFOCUS => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_KILLFOCUS => { use crate::event::{ ElementState::Released, ModifiersState, WindowEvent::{Focused, ModifiersChanged}, }; for windows_keycode in event::get_pressed_keys() { - let scancode = - winuser::MapVirtualKeyA(windows_keycode as _, winuser::MAPVK_VK_TO_VSC); - let virtual_keycode = event::vkey_to_winit_vkey(windows_keycode); + let scancode = MapVirtualKeyA(windows_keycode as _, MAPVK_VK_TO_VSC); + let virtual_keycode = event::vkey_to_winit_vkey(windows_keycode as u32); #[allow(deprecated)] subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: WindowEvent::KeyboardInput { device_id: DEVICE_ID, input: KeyboardInput { @@ -1655,48 +1705,44 @@ unsafe fn public_window_callback_inner( subclass_input.window_state.lock().modifiers_state = ModifiersState::empty(); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: ModifiersChanged(ModifiersState::empty()), }); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: Focused(false), }); - 0 + LRESULT::NULL } - winuser::WM_SETCURSOR => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SETCURSOR => { let set_cursor_to = { let window_state = subclass_input.window_state.lock(); // The return value for the preceding `WM_NCHITTEST` message is conveniently // provided through the low-order word of lParam. We use that here since // `WM_MOUSEMOVE` seems to come after `WM_SETCURSOR` for a given cursor movement. - let in_client_area = LOWORD(lparam as DWORD) == winuser::HTCLIENT as WORD; - if in_client_area { - Some(window_state.mouse.cursor) - } else { - None - } + let in_client_area = lparam.0 as u32 == HTCLIENT; // LOWORD missing + in_client_area.then(|| window_state.mouse.cursor) }; match set_cursor_to { Some(cursor) => { - let cursor = winuser::LoadCursorW(ptr::null_mut(), cursor.to_windows_cursor()); - winuser::SetCursor(cursor); - 0 + let cursor = LoadCursorW(None, cursor.to_windows_cursor()); + SetCursor(cursor); + LRESULT::NULL } - None => winuser::DefWindowProcW(window, msg, wparam, lparam), + None => DefWindowProcW(window, msg, wparam, lparam), } } - winuser::WM_DROPFILES => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_DROPFILES => { // See `FileDropHandler` for implementation. - 0 + LRESULT::NULL } - winuser::WM_GETMINMAXINFO => { - let mmi = lparam as *mut winuser::MINMAXINFO; + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_GETMINMAXINFO => { + let mmi = lparam.0 as *mut MINMAXINFO; let window_state = subclass_input.window_state.lock(); @@ -1719,19 +1765,19 @@ unsafe fn public_window_callback_inner( } } - 0 + LRESULT::NULL } // Only sent on Windows 8.1 or newer. On Windows 7 and older user has to log out to change // DPI, therefore all applications are closed while DPI is changing. - winuser::WM_DPICHANGED => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_DPICHANGED => { use crate::event::WindowEvent::ScaleFactorChanged; // This message actually provides two DPI values - x and y. However MSDN says that // "you only need to use either the X-axis or the Y-axis value when scaling your // application since they are the same". // https://msdn.microsoft.com/en-us/library/windows/desktop/dn312083(v=vs.85).aspx - let new_dpi_x = u32::from(LOWORD(wparam as DWORD)); + let new_dpi_x = u32::from(wparam.0 as u32); // LOWORD missing let new_scale_factor = dpi_to_scale_factor(new_dpi_x); let old_scale_factor: f64; @@ -1741,18 +1787,18 @@ unsafe fn public_window_callback_inner( window_state.scale_factor = new_scale_factor; if new_scale_factor == old_scale_factor { - return 0; + return LRESULT::NULL; } window_state.fullscreen.is_none() && !window_state.window_flags().contains(WindowFlags::MAXIMIZED) }; - let style = winuser::GetWindowLongW(window, winuser::GWL_STYLE) as _; - let style_ex = winuser::GetWindowLongW(window, winuser::GWL_EXSTYLE) as _; + let style = GetWindowLongW(window, GWL_STYLE) as _; + let style_ex = GetWindowLongW(window, GWL_EXSTYLE) as _; // New size as suggested by Windows. - let suggested_rect = *(lparam as *const RECT); + let suggested_rect = *(lparam.0 as *const RECT); // The window rect provided is the window's outer size, not it's inner size. However, // win32 doesn't provide an `UnadjustWindowRectEx` function to get the client rect from @@ -1774,9 +1820,9 @@ unsafe fn public_window_callback_inner( let old_physical_inner_rect = { let mut old_physical_inner_rect = mem::zeroed(); - winuser::GetClientRect(window, &mut old_physical_inner_rect); + GetClientRect(window, &mut old_physical_inner_rect); let mut origin = mem::zeroed(); - winuser::ClientToScreen(window, &mut origin); + ClientToScreen(window, &mut origin); old_physical_inner_rect.left += origin.x; old_physical_inner_rect.right += origin.x; @@ -1802,7 +1848,7 @@ unsafe fn public_window_callback_inner( }; let _ = subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: ScaleFactorChanged { scale_factor: new_scale_factor, new_inner_size: &mut new_physical_inner_size, @@ -1834,8 +1880,8 @@ unsafe fn public_window_callback_inner( let mut conservative_rect = RECT { left: suggested_ul.0, top: suggested_ul.1, - right: suggested_ul.0 + new_physical_inner_size.width as LONG, - bottom: suggested_ul.1 + new_physical_inner_size.height as LONG, + right: suggested_ul.0 + new_physical_inner_size.width as i32, + bottom: suggested_ul.1 + new_physical_inner_size.height as i32, }; conservative_rect = util::adjust_window_rect_with_styles( @@ -1852,7 +1898,7 @@ unsafe fn public_window_callback_inner( let bias = { let cursor_pos = { let mut pos = mem::zeroed(); - winuser::GetCursorPos(&mut pos); + GetCursorPos(&mut pos); pos }; let suggested_cursor_horizontal_ratio = (cursor_pos.x - suggested_rect.left) @@ -1862,7 +1908,7 @@ unsafe fn public_window_callback_inner( (cursor_pos.x - (suggested_cursor_horizontal_ratio * (conservative_rect.right - conservative_rect.left) as f64) - as LONG) + as i32) - conservative_rect.left }; conservative_rect.left += bias; @@ -1871,17 +1917,18 @@ unsafe fn public_window_callback_inner( // Check to see if the new window rect is on the monitor with the new DPI factor. // If it isn't, offset the window so that it is. - let new_dpi_monitor = winuser::MonitorFromWindow(window, 0); - let conservative_rect_monitor = winuser::MonitorFromRect(&conservative_rect, 0); + let new_dpi_monitor = MonitorFromWindow(window, MONITOR_FROM_FLAGS(0)); + let conservative_rect_monitor = + MonitorFromRect(&mut conservative_rect, MONITOR_FROM_FLAGS(0)); new_outer_rect = if conservative_rect_monitor == new_dpi_monitor { conservative_rect } else { let get_monitor_rect = |monitor| { - let mut monitor_info = winuser::MONITORINFO { - cbSize: mem::size_of::() as _, + let mut monitor_info = MONITORINFO { + cbSize: mem::size_of::() as u32, ..mem::zeroed() }; - winuser::GetMonitorInfoW(monitor, &mut monitor_info); + GetMonitorInfoW(monitor, &mut monitor_info); monitor_info.rcMonitor }; let wrong_monitor = conservative_rect_monitor; @@ -1917,7 +1964,9 @@ unsafe fn public_window_callback_inner( conservative_rect.top += delta_nudge_to_dpi_monitor.1; conservative_rect.bottom += delta_nudge_to_dpi_monitor.1; - if winuser::MonitorFromRect(&conservative_rect, 0) == new_dpi_monitor { + if MonitorFromRect(&mut conservative_rect, MONITOR_FROM_FLAGS(0)) + == new_dpi_monitor + { break; } } @@ -1926,20 +1975,20 @@ unsafe fn public_window_callback_inner( }; } - winuser::SetWindowPos( + SetWindowPos( window, - ptr::null_mut(), + None, new_outer_rect.left, new_outer_rect.top, new_outer_rect.right - new_outer_rect.left, new_outer_rect.bottom - new_outer_rect.top, - winuser::SWP_NOZORDER | winuser::SWP_NOACTIVATE, + SWP_NOZORDER | SWP_NOACTIVATE, ); - 0 + LRESULT::NULL } - winuser::WM_SETTINGCHANGE => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_WININICHANGE => { use crate::event::WindowEvent::ThemeChanged; let preferred_theme = subclass_input.window_state.lock().preferred_theme; @@ -1952,27 +2001,27 @@ unsafe fn public_window_callback_inner( window_state.current_theme = new_theme; mem::drop(window_state); subclass_input.send_event(Event::WindowEvent { - window_id: RootWindowId(WindowId(window)), + window_id: RootWindowId(WindowId(window.0)), event: ThemeChanged(new_theme), }); } } - commctrl::DefSubclassProc(window, msg, wparam, lparam) + DefSubclassProc(window, msg, wparam, lparam) } _ => { if msg == *DESTROY_MSG_ID { - winuser::DestroyWindow(window); - 0 + DestroyWindow(window); + LRESULT::NULL } else if msg == *SET_RETAIN_STATE_ON_SIZE_MSG_ID { let mut window_state = subclass_input.window_state.lock(); window_state.set_window_flags_in_place(|f| { - f.set(WindowFlags::MARKER_RETAIN_STATE_ON_SIZE, wparam != 0) + f.set(WindowFlags::MARKER_RETAIN_STATE_ON_SIZE, !wparam.is_null()) }); - 0 + LRESULT::NULL } else { - commctrl::DefSubclassProc(window, msg, wparam, lparam) + DefSubclassProc(window, msg, wparam, lparam) } } }; @@ -1980,26 +2029,21 @@ unsafe fn public_window_callback_inner( subclass_input .event_loop_runner .catch_unwind(callback) - .unwrap_or(-1) + .unwrap_or(LRESULT(-1)) } unsafe extern "system" fn thread_event_target_callback( window: HWND, - msg: UINT, + msg: u32, wparam: WPARAM, lparam: LPARAM, - _: UINT_PTR, - subclass_input_ptr: DWORD_PTR, + _: usize, + subclass_input_ptr: usize, ) -> LRESULT { let subclass_input = Box::from_raw(subclass_input_ptr as *mut ThreadMsgTargetSubclassInput); - if msg != winuser::WM_PAINT { - winuser::RedrawWindow( - window, - ptr::null(), - ptr::null_mut(), - winuser::RDW_INTERNALPAINT, - ); + if msg != WM_PAINT { + RedrawWindow(window, ptr::null(), None, RDW_INTERNALPAINT); } let mut subclass_removed = false; @@ -2008,15 +2052,15 @@ unsafe extern "system" fn thread_event_target_callback( // the closure to catch_unwind directly so that the match body indendation wouldn't change and // the git blame and history would be preserved. let callback = || match msg { - winuser::WM_NCDESTROY => { + WM_NCDESTROY => { remove_event_target_window_subclass::(window); subclass_removed = true; - 0 + LRESULT::NULL } // Because WM_PAINT comes after all other messages, we use it during modal loops to detect // when the event queue has been emptied. See `process_event` for more details. - winuser::WM_PAINT => { - winuser::ValidateRect(window, ptr::null()); + WM_PAINT => { + ValidateRect(window, ptr::null()); // If the WM_PAINT handler in `public_window_callback` has already flushed the redraw // events, `handling_events` will return false and we won't emit a second // `RedrawEventsCleared` event. @@ -2024,12 +2068,7 @@ unsafe extern "system" fn thread_event_target_callback( if subclass_input.event_loop_runner.should_buffer() { // This branch can be triggered when a nested win32 event loop is triggered // inside of the `event_handler` callback. - winuser::RedrawWindow( - window, - ptr::null(), - ptr::null_mut(), - winuser::RDW_INTERNALPAINT, - ); + RedrawWindow(window, ptr::null(), None, RDW_INTERNALPAINT); } else { // This WM_PAINT handler will never be re-entrant because `flush_paint_messages` // doesn't call WM_PAINT for the thread event target (i.e. this window). @@ -2043,38 +2082,38 @@ unsafe extern "system" fn thread_event_target_callback( } // Default WM_PAINT behaviour. This makes sure modals and popups are shown immediatly when opening them. - commctrl::DefSubclassProc(window, msg, wparam, lparam) + DefSubclassProc(window, msg, wparam, lparam) } - winuser::WM_INPUT_DEVICE_CHANGE => { - let event = match wparam as _ { - winuser::GIDC_ARRIVAL => DeviceEvent::Added, - winuser::GIDC_REMOVAL => DeviceEvent::Removed, + WM_INPUT_DEVICE_CHANGE => { + let event = match wparam.0 as u32 { + GIDC_ARRIVAL => DeviceEvent::Added, + GIDC_REMOVAL => DeviceEvent::Removed, _ => unreachable!(), }; subclass_input.send_event(Event::DeviceEvent { - device_id: wrap_device_id(lparam as _), + device_id: wrap_device_id(lparam.0), event, }); - 0 + LRESULT::NULL } - winuser::WM_INPUT => { + winapi::Windows::Win32::UI::WindowsAndMessaging::WM_INPUT => { use crate::event::{ DeviceEvent::{Button, Key, Motion, MouseMotion, MouseWheel}, ElementState::{Pressed, Released}, MouseScrollDelta::LineDelta, }; - if let Some(data) = raw_input::get_raw_input_data(lparam as _) { - let device_id = wrap_device_id(data.header.hDevice as _); + if let Some(data) = raw_input::get_raw_input_data(HRAWINPUT(lparam.0)) { + let device_id = wrap_device_id(data.header.hDevice.0); - if data.header.dwType == winuser::RIM_TYPEMOUSE { - let mouse = data.data.mouse(); + if data.header.dwType == RIM_TYPEMOUSE.0 { + let mouse = data.data.mouse; - if util::has_flag(mouse.usFlags, winuser::MOUSE_MOVE_RELATIVE) { + if util::has_flag(mouse.usFlags, MOUSE_MOVE_RELATIVE as u16) { let x = mouse.lLastX as f64; let y = mouse.lLastY as f64; @@ -2100,9 +2139,12 @@ unsafe extern "system" fn thread_event_target_callback( } } - if util::has_flag(mouse.usButtonFlags, winuser::RI_MOUSE_WHEEL) { + if util::has_flag( + mouse.Anonymous.Anonymous.usButtonFlags, + RI_MOUSE_WHEEL as u16, + ) { let delta = - mouse.usButtonData as SHORT as f32 / winuser::WHEEL_DELTA as f32; + mouse.Anonymous.Anonymous.usButtonData as f32 / WHEEL_DELTA as f32; subclass_input.send_event(Event::DeviceEvent { device_id, event: MouseWheel { @@ -2111,7 +2153,9 @@ unsafe extern "system" fn thread_event_target_callback( }); } - let button_state = raw_input::get_raw_mouse_button_state(mouse.usButtonFlags); + let button_state = raw_input::get_raw_mouse_button_state( + mouse.Anonymous.Anonymous.usButtonFlags as u32, + ); // Left, middle, and right, respectively. for (index, state) in button_state.iter().enumerate() { if let Some(state) = *state { @@ -2125,20 +2169,24 @@ unsafe extern "system" fn thread_event_target_callback( }); } } - } else if data.header.dwType == winuser::RIM_TYPEKEYBOARD { - let keyboard = data.data.keyboard(); - - let pressed = keyboard.Message == winuser::WM_KEYDOWN - || keyboard.Message == winuser::WM_SYSKEYDOWN; - let released = keyboard.Message == winuser::WM_KEYUP - || keyboard.Message == winuser::WM_SYSKEYUP; + } else if data.header.dwType == RIM_TYPEKEYBOARD.0 { + let keyboard = data.data.keyboard; + + let pressed = keyboard.Message + == winapi::Windows::Win32::UI::WindowsAndMessaging::WM_KEYDOWN + || keyboard.Message + == winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SYSKEYDOWN; + let released = keyboard.Message + == winapi::Windows::Win32::UI::WindowsAndMessaging::WM_KEYUP + || keyboard.Message + == winapi::Windows::Win32::UI::WindowsAndMessaging::WM_SYSKEYUP; if pressed || released { let state = if pressed { Pressed } else { Released }; let scancode = keyboard.MakeCode as _; - let extended = util::has_flag(keyboard.Flags, winuser::RI_KEY_E0 as _) - | util::has_flag(keyboard.Flags, winuser::RI_KEY_E1 as _); + let extended = util::has_flag(keyboard.Flags, RI_KEY_E0 as u16) + | util::has_flag(keyboard.Flags, RI_KEY_E1 as u16); if let Some((vkey, scancode)) = handle_extended_keys(keyboard.VKey as _, scancode, extended) @@ -2160,26 +2208,26 @@ unsafe extern "system" fn thread_event_target_callback( } } - commctrl::DefSubclassProc(window, msg, wparam, lparam) + DefSubclassProc(window, msg, wparam, lparam) } _ if msg == *USER_EVENT_MSG_ID => { if let Ok(event) = subclass_input.user_event_receiver.recv() { subclass_input.send_event(Event::UserEvent(event)); } - 0 + LRESULT::NULL } _ if msg == *EXEC_MSG_ID => { - let mut function: ThreadExecFn = Box::from_raw(wparam as usize as *mut _); + let mut function: ThreadExecFn = Box::from_raw(wparam.0 as *mut _); function(); - 0 + LRESULT::NULL } _ if msg == *PROCESS_NEW_EVENTS_MSG_ID => { - winuser::PostThreadMessageW( + PostThreadMessageW( subclass_input.event_loop_runner.wait_thread_id(), *CANCEL_WAIT_UNTIL_MSG_ID, - 0, - 0, + None, + None, ); // if the control_flow is WaitUntil, make sure the given moment has actually passed @@ -2189,22 +2237,17 @@ unsafe extern "system" fn thread_event_target_callback( { let mut msg = mem::zeroed(); while Instant::now() < wait_until { - if 0 != winuser::PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, 0) { + if PeekMessageW(&mut msg, None, 0, 0, PEEK_MESSAGE_REMOVE_TYPE(0)).as_bool() { // This works around a "feature" in PeekMessageW. If the message PeekMessageW // gets is a WM_PAINT message that had RDW_INTERNALPAINT set (i.e. doesn't // have an update region), PeekMessageW will remove that window from the // redraw queue even though we told it not to remove messages from the // queue. We fix it by re-dispatching an internal paint message to that // window. - if msg.message == winuser::WM_PAINT { + if msg.message == WM_PAINT { let mut rect = mem::zeroed(); - if 0 == winuser::GetUpdateRect(msg.hwnd, &mut rect, 0) { - winuser::RedrawWindow( - msg.hwnd, - ptr::null(), - ptr::null_mut(), - winuser::RDW_INTERNALPAINT, - ); + if !GetUpdateRect(msg.hwnd, &mut rect, false).as_bool() { + RedrawWindow(msg.hwnd, ptr::null(), None, RDW_INTERNALPAINT); } } @@ -2213,15 +2256,15 @@ unsafe extern "system" fn thread_event_target_callback( } } subclass_input.event_loop_runner.poll(); - 0 + LRESULT::NULL } - _ => commctrl::DefSubclassProc(window, msg, wparam, lparam), + _ => DefSubclassProc(window, msg, wparam, lparam), }; let result = subclass_input .event_loop_runner .catch_unwind(callback) - .unwrap_or(-1); + .unwrap_or(LRESULT(-1)); if subclass_removed { mem::drop(subclass_input); } else { diff --git a/src/platform_impl/windows/event_loop/runner.rs b/src/platform_impl/windows/event_loop/runner.rs index 4f90966c43..692d43700c 100644 --- a/src/platform_impl/windows/event_loop/runner.rs +++ b/src/platform_impl/windows/event_loop/runner.rs @@ -7,9 +7,9 @@ use std::{ time::Instant, }; -use winapi::{ - shared::{minwindef::DWORD, windef::HWND}, - um::winuser, +use winapi::Windows::Win32::{ + Graphics::Gdi::{RedrawWindow, RDW_INTERNALPAINT}, + UI::WindowsAndMessaging::HWND, }; use crate::{ @@ -24,7 +24,7 @@ pub(crate) type EventLoopRunnerShared = Rc>; pub(crate) struct EventLoopRunner { // The event loop's win32 handles thread_msg_target: HWND, - wait_thread_id: DWORD, + wait_thread_id: u32, control_flow: Cell, runner_state: Cell, @@ -33,7 +33,7 @@ pub(crate) struct EventLoopRunner { event_handler: Cell, &mut ControlFlow)>>>, event_buffer: RefCell>>, - owned_windows: Cell>, + owned_windows: Cell>, panic_error: Cell>, } @@ -63,7 +63,7 @@ enum BufferedEvent { } impl EventLoopRunner { - pub(crate) fn new(thread_msg_target: HWND, wait_thread_id: DWORD) -> EventLoopRunner { + pub(crate) fn new(thread_msg_target: HWND, wait_thread_id: u32) -> EventLoopRunner { EventLoopRunner { thread_msg_target, wait_thread_id, @@ -113,7 +113,7 @@ impl EventLoopRunner { self.thread_msg_target } - pub fn wait_thread_id(&self) -> DWORD { + pub fn wait_thread_id(&self) -> u32 { self.wait_thread_id } @@ -174,20 +174,20 @@ impl EventLoopRunner { } pub fn register_window(&self, window: HWND) { let mut owned_windows = self.owned_windows.take(); - owned_windows.insert(window); + owned_windows.insert(window.0); self.owned_windows.set(owned_windows); } pub fn remove_window(&self, window: HWND) { let mut owned_windows = self.owned_windows.take(); - owned_windows.remove(&window); + owned_windows.remove(&window.0); self.owned_windows.set(owned_windows); } pub fn owned_windows(&self, mut f: impl FnMut(HWND)) { let mut owned_windows = self.owned_windows.take(); for hwnd in &owned_windows { - f(*hwnd); + f(HWND(*hwnd)); } let new_owned_windows = self.owned_windows.take(); owned_windows.extend(&new_owned_windows); @@ -208,18 +208,16 @@ impl EventLoopRunner { self.move_state_to(RunnerState::HandlingRedrawEvents); } self.call_event_handler(event); + } else if self.should_buffer() { + // If the runner is already borrowed, we're in the middle of an event loop invocation. Add + // the event to a buffer to be processed later. + self.event_buffer + .borrow_mut() + .push_back(BufferedEvent::from_event(event)) } else { - if self.should_buffer() { - // If the runner is already borrowed, we're in the middle of an event loop invocation. Add - // the event to a buffer to be processed later. - self.event_buffer - .borrow_mut() - .push_back(BufferedEvent::from_event(event)) - } else { - self.move_state_to(RunnerState::HandlingMainEvents); - self.call_event_handler(event); - self.dispatch_buffered_events(); - } + self.move_state_to(RunnerState::HandlingMainEvents); + self.call_event_handler(event); + self.dispatch_buffered_events(); } } @@ -392,12 +390,7 @@ impl EventLoopRunner { }; self.call_event_handler(Event::NewEvents(start_cause)); self.dispatch_buffered_events(); - winuser::RedrawWindow( - self.thread_msg_target, - ptr::null(), - ptr::null_mut(), - winuser::RDW_INTERNALPAINT, - ); + RedrawWindow(self.thread_msg_target, ptr::null(), None, RDW_INTERNALPAINT); } unsafe fn call_redraw_events_cleared(&self) { @@ -433,7 +426,7 @@ impl BufferedEvent { }, }); util::set_inner_size_physical( - (window_id.0).0, + HWND((window_id.0).0), new_inner_size.width as _, new_inner_size.height as _, ); diff --git a/src/platform_impl/windows/icon.rs b/src/platform_impl/windows/icon.rs index 1308c7467e..8553b18bf4 100644 --- a/src/platform_impl/windows/icon.rs +++ b/src/platform_impl/windows/icon.rs @@ -1,13 +1,16 @@ -use std::{fmt, io, iter::once, mem, os::windows::ffi::OsStrExt, path::Path, ptr, sync::Arc}; +use std::{fmt, io, iter::once, mem, os::windows::ffi::OsStrExt, path::Path, sync::Arc}; -use winapi::{ - ctypes::{c_int, wchar_t}, - shared::{ - minwindef::{BYTE, LPARAM, WORD, WPARAM}, - windef::{HICON, HWND}, +use winapi::Windows::Win32::{ + System::SystemServices::{GetModuleHandleW, HANDLE, PWSTR}, + UI::WindowsAndMessaging::{ + CreateIcon, DestroyIcon, LoadImageW, SendMessageW, HWND, ICON_BIG, ICON_SMALL, LPARAM, + WM_SETICON, WPARAM, + }, + UI::{ + Controls::{LR_DEFAULTSIZE, LR_LOADFROMFILE}, + MenusAndResources::HICON, + WindowsAndMessaging::IMAGE_ICON, }, - um::libloaderapi, - um::winuser, }; use crate::dpi::PhysicalSize; @@ -32,18 +35,18 @@ impl RgbaIcon { } assert_eq!(and_mask.len(), pixel_count); let handle = unsafe { - winuser::CreateIcon( - ptr::null_mut(), - self.width as c_int, - self.height as c_int, + CreateIcon( + None, + self.width as i32, + self.height as i32, 1, - (PIXEL_SIZE * 8) as BYTE, - and_mask.as_ptr() as *const BYTE, - rgba.as_ptr() as *const BYTE, - ) as HICON + (PIXEL_SIZE * 8) as u8, + and_mask.as_ptr(), + rgba.as_ptr(), + ) }; if !handle.is_null() { - Ok(WinIcon::from_handle(handle)) + Ok(WinIcon::from_icon(handle)) } else { Err(BadIcon::OsError(io::Error::last_os_error())) } @@ -52,13 +55,13 @@ impl RgbaIcon { #[derive(Debug)] pub enum IconType { - Small = winuser::ICON_SMALL as isize, - Big = winuser::ICON_BIG as isize, + Small = ICON_SMALL as isize, + Big = ICON_BIG as isize, } #[derive(Debug)] struct RaiiIcon { - handle: HICON, + handle: HANDLE, } #[derive(Clone)] @@ -69,7 +72,7 @@ pub struct WinIcon { unsafe impl Send for WinIcon {} impl WinIcon { - pub fn as_raw_handle(&self) -> HICON { + pub fn as_raw_handle(&self) -> HANDLE { self.inner.handle } @@ -88,14 +91,14 @@ impl WinIcon { let (width, height) = size.map(Into::into).unwrap_or((0, 0)); let handle = unsafe { - winuser::LoadImageW( - ptr::null_mut(), - wide_path.as_ptr() as *const wchar_t, - winuser::IMAGE_ICON, - width as c_int, - height as c_int, - winuser::LR_DEFAULTSIZE | winuser::LR_LOADFROMFILE, - ) as HICON + LoadImageW( + None, + PWSTR(wide_path.as_mut_ptr()), + IMAGE_ICON, + width, + height, + LR_DEFAULTSIZE | LR_LOADFROMFILE, + ) }; if !handle.is_null() { Ok(WinIcon::from_handle(handle)) @@ -105,20 +108,20 @@ impl WinIcon { } pub fn from_resource( - resource_id: WORD, + resource_id: u32, size: Option>, ) -> Result { // width / height of 0 along with LR_DEFAULTSIZE tells windows to load the default icon size let (width, height) = size.map(Into::into).unwrap_or((0, 0)); let handle = unsafe { - winuser::LoadImageW( - libloaderapi::GetModuleHandleW(ptr::null_mut()), - winuser::MAKEINTRESOURCEW(resource_id), - winuser::IMAGE_ICON, - width as c_int, - height as c_int, - winuser::LR_DEFAULTSIZE, - ) as HICON + LoadImageW( + GetModuleHandleW(None), + PWSTR(resource_id as *mut u16), + IMAGE_ICON, + width, + height, + LR_DEFAULTSIZE, + ) }; if !handle.is_null() { Ok(WinIcon::from_handle(handle)) @@ -134,16 +137,24 @@ impl WinIcon { pub fn set_for_window(&self, hwnd: HWND, icon_type: IconType) { unsafe { - winuser::SendMessageW( + SendMessageW( hwnd, - winuser::WM_SETICON, - icon_type as WPARAM, - self.as_raw_handle() as LPARAM, + WM_SETICON, + WPARAM(icon_type as usize), + LPARAM(self.as_raw_handle().0), ); } } - fn from_handle(handle: HICON) -> Self { + fn from_icon(handle: HICON) -> Self { + Self { + inner: Arc::new(RaiiIcon { + handle: HANDLE(handle.0), + }), + } + } + + fn from_handle(handle: HANDLE) -> Self { Self { inner: Arc::new(RaiiIcon { handle }), } @@ -152,7 +163,7 @@ impl WinIcon { impl Drop for RaiiIcon { fn drop(&mut self) { - unsafe { winuser::DestroyIcon(self.handle) }; + unsafe { DestroyIcon(HICON(self.handle.0)) }; } } @@ -164,6 +175,6 @@ impl fmt::Debug for WinIcon { pub fn unset_for_window(hwnd: HWND, icon_type: IconType) { unsafe { - winuser::SendMessageW(hwnd, winuser::WM_SETICON, icon_type as WPARAM, 0 as LPARAM); + SendMessageW(hwnd, WM_SETICON, WPARAM(icon_type as usize), LPARAM(0)); } } diff --git a/src/platform_impl/windows/mod.rs b/src/platform_impl/windows/mod.rs index 07629e6dfb..cd648dbf53 100644 --- a/src/platform_impl/windows/mod.rs +++ b/src/platform_impl/windows/mod.rs @@ -1,6 +1,9 @@ #![cfg(target_os = "windows")] -use winapi::{self, shared::windef::HMENU, shared::windef::HWND}; +use winapi::Windows::Win32::{ + System::SystemServices::HANDLE, + UI::{MenusAndResources::HMENU, WindowsAndMessaging::HWND}, +}; pub use self::{ event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget}, @@ -50,12 +53,12 @@ unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {} // Cursor name in UTF-16. Used to set cursor in `WM_SETCURSOR`. #[derive(Debug, Clone, Copy)] -pub struct Cursor(pub *const winapi::ctypes::wchar_t); +pub struct Cursor(pub *const u16); unsafe impl Send for Cursor {} unsafe impl Sync for Cursor {} #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct DeviceId(u32); +pub struct DeviceId(isize); impl DeviceId { pub unsafe fn dummy() -> Self { @@ -66,7 +69,7 @@ impl DeviceId { impl DeviceId { pub fn persistent_identifier(&self) -> Option { if self.0 != 0 { - raw_input::get_raw_input_device_name(self.0 as _) + raw_input::get_raw_input_device_name(HANDLE(self.0)) } else { None } @@ -76,22 +79,18 @@ impl DeviceId { // Constant device ID, to be removed when this backend is updated to report real device IDs. const DEVICE_ID: RootDeviceId = RootDeviceId(DeviceId(0)); -fn wrap_device_id(id: u32) -> RootDeviceId { +fn wrap_device_id(id: isize) -> RootDeviceId { RootDeviceId(DeviceId(id)) } pub type OsError = std::io::Error; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct WindowId(HWND); -unsafe impl Send for WindowId {} -unsafe impl Sync for WindowId {} +pub struct WindowId(isize); impl WindowId { pub unsafe fn dummy() -> Self { - use std::ptr::null_mut; - - WindowId(null_mut()) + WindowId(0) } } diff --git a/src/platform_impl/windows/monitor.rs b/src/platform_impl/windows/monitor.rs index ff88d102db..3e4e54cc22 100644 --- a/src/platform_impl/windows/monitor.rs +++ b/src/platform_impl/windows/monitor.rs @@ -1,17 +1,25 @@ -use winapi::{ - shared::{ - minwindef::{BOOL, DWORD, LPARAM, TRUE, WORD}, - windef::{HDC, HMONITOR, HWND, LPRECT, POINT}, +use winapi::Windows::Win32::{ + Graphics::Gdi::{ + EnumDisplayMonitors, EnumDisplaySettingsExW, GetMonitorInfoW, MonitorFromPoint, + MonitorFromWindow, DM_BITSPERPEL, DM_DISPLAYFREQUENCY, DM_PELSHEIGHT, DM_PELSWIDTH, + ENUM_DISPLAY_SETTINGS_MODE, HDC, HMONITOR, MONITORINFO, MONITORINFOEXW, + MONITOR_DEFAULTTONEAREST, MONITOR_DEFAULTTOPRIMARY, + }, + System::SystemServices::{BOOL, PWSTR}, + UI::{ + DisplayDevices::{DEVMODEW, POINT, RECT}, + WindowsAndMessaging::{HWND, LPARAM}, }, - um::{wingdi, winuser}, }; use std::{ collections::{BTreeSet, VecDeque}, - io, mem, ptr, + ffi::OsString, + io, mem, + os::windows::prelude::OsStringExt, + ptr, }; -use super::util; use crate::{ dpi::{PhysicalPosition, PhysicalSize}, monitor::{MonitorHandle as RootMonitorHandle, VideoMode as RootVideoMode}, @@ -27,7 +35,7 @@ pub struct VideoMode { pub(crate) bit_depth: u16, pub(crate) refresh_rate: u16, pub(crate) monitor: MonitorHandle, - pub(crate) native_video_mode: wingdi::DEVMODEW, + pub(crate) native_video_mode: DEVMODEW, } impl PartialEq for VideoMode { @@ -82,34 +90,27 @@ impl VideoMode { } #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] -pub struct MonitorHandle(HMONITOR); - -// Send is not implemented for HMONITOR, we have to wrap it and implement it manually. -// For more info see: -// https://github.com/retep998/winapi-rs/issues/360 -// https://github.com/retep998/winapi-rs/issues/396 - -unsafe impl Send for MonitorHandle {} +pub struct MonitorHandle(isize); unsafe extern "system" fn monitor_enum_proc( hmonitor: HMONITOR, _hdc: HDC, - _place: LPRECT, + _place: *mut RECT, data: LPARAM, ) -> BOOL { - let monitors = data as *mut VecDeque; + let monitors = data.0 as *mut VecDeque; (*monitors).push_back(MonitorHandle::new(hmonitor)); - TRUE // continue enumeration + true.into() // continue enumeration } pub fn available_monitors() -> VecDeque { let mut monitors: VecDeque = VecDeque::new(); unsafe { - winuser::EnumDisplayMonitors( - ptr::null_mut(), + EnumDisplayMonitors( + None, ptr::null_mut(), Some(monitor_enum_proc), - &mut monitors as *mut _ as LPARAM, + LPARAM(&mut monitors as *mut _ as isize), ); } monitors @@ -117,12 +118,12 @@ pub fn available_monitors() -> VecDeque { pub fn primary_monitor() -> MonitorHandle { const ORIGIN: POINT = POINT { x: 0, y: 0 }; - let hmonitor = unsafe { winuser::MonitorFromPoint(ORIGIN, winuser::MONITOR_DEFAULTTOPRIMARY) }; + let hmonitor = unsafe { MonitorFromPoint(ORIGIN, MONITOR_DEFAULTTOPRIMARY) }; MonitorHandle::new(hmonitor) } pub fn current_monitor(hwnd: HWND) -> MonitorHandle { - let hmonitor = unsafe { winuser::MonitorFromWindow(hwnd, winuser::MONITOR_DEFAULTTONEAREST) }; + let hmonitor = unsafe { MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST) }; MonitorHandle::new(hmonitor) } @@ -137,31 +138,34 @@ impl Window { } } -pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result { - let mut monitor_info: winuser::MONITORINFOEXW = unsafe { mem::zeroed() }; - monitor_info.cbSize = mem::size_of::() as DWORD; +pub(crate) fn get_monitor_info(hmonitor: HMONITOR) -> Result { + let mut monitor_info: MONITORINFOEXW = unsafe { mem::zeroed() }; + monitor_info.__AnonymousBase_winuser_L13558_C43.cbSize = + mem::size_of::() as u32; let status = unsafe { - winuser::GetMonitorInfoW( + GetMonitorInfoW( hmonitor, - &mut monitor_info as *mut winuser::MONITORINFOEXW as *mut winuser::MONITORINFO, + &mut monitor_info as *mut MONITORINFOEXW as *mut MONITORINFO, ) }; - if status == 0 { - Err(io::Error::last_os_error()) - } else { + if status.as_bool() { Ok(monitor_info) + } else { + Err(io::Error::last_os_error()) } } impl MonitorHandle { pub(crate) fn new(hmonitor: HMONITOR) -> Self { - MonitorHandle(hmonitor) + MonitorHandle(hmonitor.0) } #[inline] pub fn name(&self) -> Option { - let monitor_info = get_monitor_info(self.0).unwrap(); - Some(util::wchar_ptr_to_string(monitor_info.szDevice.as_ptr())) + let monitor_info = get_monitor_info(self.hmonitor()).unwrap(); + unsafe { OsString::from_wide(&monitor_info.szDevice) } + .into_string() + .ok() } #[inline] @@ -171,30 +175,50 @@ impl MonitorHandle { #[inline] pub fn hmonitor(&self) -> HMONITOR { - self.0 + HMONITOR(self.0) } #[inline] pub fn size(&self) -> PhysicalSize { - let monitor_info = get_monitor_info(self.0).unwrap(); + let monitor_info = get_monitor_info(self.hmonitor()).unwrap(); PhysicalSize { - width: (monitor_info.rcMonitor.right - monitor_info.rcMonitor.left) as u32, - height: (monitor_info.rcMonitor.bottom - monitor_info.rcMonitor.top) as u32, + width: (monitor_info + .__AnonymousBase_winuser_L13558_C43 + .rcMonitor + .right + - monitor_info + .__AnonymousBase_winuser_L13558_C43 + .rcMonitor + .left) as u32, + height: (monitor_info + .__AnonymousBase_winuser_L13558_C43 + .rcMonitor + .bottom + - monitor_info + .__AnonymousBase_winuser_L13558_C43 + .rcMonitor + .top) as u32, } } #[inline] pub fn position(&self) -> PhysicalPosition { - let monitor_info = get_monitor_info(self.0).unwrap(); + let monitor_info = get_monitor_info(self.hmonitor()).unwrap(); PhysicalPosition { - x: monitor_info.rcMonitor.left, - y: monitor_info.rcMonitor.top, + x: monitor_info + .__AnonymousBase_winuser_L13558_C43 + .rcMonitor + .left, + y: monitor_info + .__AnonymousBase_winuser_L13558_C43 + .rcMonitor + .top, } } #[inline] pub fn scale_factor(&self) -> f64 { - dpi_to_scale_factor(get_monitor_dpi(self.0).unwrap_or(96)) + dpi_to_scale_factor(get_monitor_dpi(self.hmonitor()).unwrap_or(96)) } #[inline] @@ -207,19 +231,24 @@ impl MonitorHandle { loop { unsafe { - let monitor_info = get_monitor_info(self.0).unwrap(); - let device_name = monitor_info.szDevice.as_ptr(); - let mut mode: wingdi::DEVMODEW = mem::zeroed(); - mode.dmSize = mem::size_of_val(&mode) as WORD; - if winuser::EnumDisplaySettingsExW(device_name, i, &mut mode, 0) == 0 { + let mut monitor_info = get_monitor_info(self.hmonitor()).unwrap(); + let device_name = monitor_info.szDevice.as_mut_ptr(); + let mut mode: DEVMODEW = mem::zeroed(); + mode.dmSize = mem::size_of_val(&mode) as u16; + if !EnumDisplaySettingsExW( + PWSTR(device_name), + ENUM_DISPLAY_SETTINGS_MODE(i), + &mut mode, + 0, + ) + .as_bool() + { break; } i += 1; - const REQUIRED_FIELDS: DWORD = wingdi::DM_BITSPERPEL - | wingdi::DM_PELSWIDTH - | wingdi::DM_PELSHEIGHT - | wingdi::DM_DISPLAYFREQUENCY; + const REQUIRED_FIELDS: u32 = + (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY) as u32; assert!(mode.dmFields & REQUIRED_FIELDS == REQUIRED_FIELDS); modes.insert(RootVideoMode { diff --git a/src/platform_impl/windows/raw_input.rs b/src/platform_impl/windows/raw_input.rs index 73b136a82f..953a699af4 100644 --- a/src/platform_impl/windows/raw_input.rs +++ b/src/platform_impl/windows/raw_input.rs @@ -1,22 +1,23 @@ use std::{ + ffi::OsString, mem::{self, size_of}, + os::windows::prelude::OsStringExt, ptr, }; -use winapi::{ - ctypes::wchar_t, - shared::{ - hidusage::{HID_USAGE_GENERIC_KEYBOARD, HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC}, - minwindef::{TRUE, UINT, USHORT}, - windef::HWND, - }, - um::{ - winnt::HANDLE, - winuser::{ - self, HRAWINPUT, RAWINPUT, RAWINPUTDEVICE, RAWINPUTDEVICELIST, RAWINPUTHEADER, - RIDEV_DEVNOTIFY, RIDEV_INPUTSINK, RIDI_DEVICEINFO, RIDI_DEVICENAME, RID_DEVICE_INFO, - RID_DEVICE_INFO_HID, RID_DEVICE_INFO_KEYBOARD, RID_DEVICE_INFO_MOUSE, RID_INPUT, - RIM_TYPEHID, RIM_TYPEKEYBOARD, RIM_TYPEMOUSE, +use winapi::Windows::Win32::{ + System::SystemServices::HANDLE, + UI::{ + KeyboardAndMouseInput::{ + GetRawInputData, GetRawInputDeviceInfoW, GetRawInputDeviceList, + RegisterRawInputDevices, HRAWINPUT, RAWINPUT, RAWINPUTDEVICE, RAWINPUTDEVICELIST, + RAWINPUTHEADER, RIDEV_DEVNOTIFY, RIDEV_INPUTSINK, RIDI_DEVICEINFO, RIDI_DEVICENAME, + RID_DEVICE_INFO, RID_DEVICE_INFO_HID, RID_DEVICE_INFO_KEYBOARD, RID_DEVICE_INFO_MOUSE, + RID_INPUT, RIM_TYPEHID, RIM_TYPEKEYBOARD, RIM_TYPEMOUSE, + }, + WindowsAndMessaging::{ + HWND, RI_MOUSE_LEFT_BUTTON_DOWN, RI_MOUSE_LEFT_BUTTON_UP, RI_MOUSE_MIDDLE_BUTTON_DOWN, + RI_MOUSE_MIDDLE_BUTTON_UP, RI_MOUSE_RIGHT_BUTTON_DOWN, RI_MOUSE_RIGHT_BUTTON_UP, }, }, }; @@ -25,23 +26,21 @@ use crate::{event::ElementState, platform_impl::platform::util}; #[allow(dead_code)] pub fn get_raw_input_device_list() -> Option> { - let list_size = size_of::() as UINT; + let list_size = size_of::() as u32; let mut num_devices = 0; - let status = - unsafe { winuser::GetRawInputDeviceList(ptr::null_mut(), &mut num_devices, list_size) }; + let status = unsafe { GetRawInputDeviceList(ptr::null_mut(), &mut num_devices, list_size) }; - if status == UINT::max_value() { + if status == u32::MAX { return None; } let mut buffer = Vec::with_capacity(num_devices as _); - let num_stored = unsafe { - winuser::GetRawInputDeviceList(buffer.as_ptr() as _, &mut num_devices, list_size) - }; + let num_stored = + unsafe { GetRawInputDeviceList(buffer.as_ptr() as _, &mut num_devices, list_size) }; - if num_stored == UINT::max_value() { + if num_stored == u32::MAX { return None; } @@ -63,9 +62,9 @@ impl From for RawDeviceInfo { fn from(info: RID_DEVICE_INFO) -> Self { unsafe { match info.dwType { - RIM_TYPEMOUSE => RawDeviceInfo::Mouse(*info.u.mouse()), - RIM_TYPEKEYBOARD => RawDeviceInfo::Keyboard(*info.u.keyboard()), - RIM_TYPEHID => RawDeviceInfo::Hid(*info.u.hid()), + RIM_TYPEMOUSE => RawDeviceInfo::Mouse(info.Anonymous.mouse), + RIM_TYPEKEYBOARD => RawDeviceInfo::Keyboard(info.Anonymous.keyboard), + RIM_TYPEHID => RawDeviceInfo::Hid(info.Anonymous.hid), _ => unreachable!(), } } @@ -75,13 +74,13 @@ impl From for RawDeviceInfo { #[allow(dead_code)] pub fn get_raw_input_device_info(handle: HANDLE) -> Option { let mut info: RID_DEVICE_INFO = unsafe { mem::zeroed() }; - let info_size = size_of::() as UINT; + let info_size = size_of::() as u32; info.cbSize = info_size; let mut minimum_size = 0; let status = unsafe { - winuser::GetRawInputDeviceInfoW( + GetRawInputDeviceInfoW( handle, RIDI_DEVICEINFO, &mut info as *mut _ as _, @@ -89,7 +88,7 @@ pub fn get_raw_input_device_info(handle: HANDLE) -> Option { ) }; - if status == UINT::max_value() || status == 0 { + if status == u32::max_value() || status == 0 { return None; } @@ -101,17 +100,17 @@ pub fn get_raw_input_device_info(handle: HANDLE) -> Option { pub fn get_raw_input_device_name(handle: HANDLE) -> Option { let mut minimum_size = 0; let status = unsafe { - winuser::GetRawInputDeviceInfoW(handle, RIDI_DEVICENAME, ptr::null_mut(), &mut minimum_size) + GetRawInputDeviceInfoW(handle, RIDI_DEVICENAME, ptr::null_mut(), &mut minimum_size) }; if status != 0 { return None; } - let mut name: Vec = Vec::with_capacity(minimum_size as _); + let mut name = Vec::::with_capacity(minimum_size as _); let status = unsafe { - winuser::GetRawInputDeviceInfoW( + GetRawInputDeviceInfoW( handle, RIDI_DEVICENAME, name.as_ptr() as _, @@ -119,7 +118,7 @@ pub fn get_raw_input_device_name(handle: HANDLE) -> Option { ) }; - if status == UINT::max_value() || status == 0 { + if status == u32::max_value() || status == 0 { return None; } @@ -127,17 +126,16 @@ pub fn get_raw_input_device_name(handle: HANDLE) -> Option { unsafe { name.set_len(minimum_size as _) }; - Some(util::wchar_to_string(&name)) + Some(unsafe { OsString::from_wide(&name) }.into_string().unwrap()) } pub fn register_raw_input_devices(devices: &[RAWINPUTDEVICE]) -> bool { - let device_size = size_of::() as UINT; + let device_size = size_of::() as u32; - let success = unsafe { - winuser::RegisterRawInputDevices(devices.as_ptr() as _, devices.len() as _, device_size) - }; + let success = + unsafe { RegisterRawInputDevices(devices.as_mut_ptr(), devices.len() as _, device_size) }; - success == TRUE + success.into() } pub fn register_all_mice_and_keyboards_for_raw_input(window_handle: HWND) -> bool { @@ -145,16 +143,18 @@ pub fn register_all_mice_and_keyboards_for_raw_input(window_handle: HWND) -> boo // RIDEV_INPUTSINK: receive events even if we're not in the foreground let flags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK; + // HID_USAGE values are missing: https://github.com/microsoft/win32metadata/issues/428 + let devices: [RAWINPUTDEVICE; 2] = [ RAWINPUTDEVICE { - usUsagePage: HID_USAGE_PAGE_GENERIC, - usUsage: HID_USAGE_GENERIC_MOUSE, + usUsagePage: 0x01, //HID_USAGE_PAGE_GENERIC + usUsage: 0x02, //HID_USAGE_GENERIC_MOUSE dwFlags: flags, hwndTarget: window_handle, }, RAWINPUTDEVICE { - usUsagePage: HID_USAGE_PAGE_GENERIC, - usUsage: HID_USAGE_GENERIC_KEYBOARD, + usUsagePage: 0x01, //HID_USAGE_PAGE_GENERIC + usUsage: 0x06, //HID_USAGE_GENERIC_KEYBOARD dwFlags: flags, hwndTarget: window_handle, }, @@ -165,11 +165,11 @@ pub fn register_all_mice_and_keyboards_for_raw_input(window_handle: HWND) -> boo pub fn get_raw_input_data(handle: HRAWINPUT) -> Option { let mut data: RAWINPUT = unsafe { mem::zeroed() }; - let mut data_size = size_of::() as UINT; - let header_size = size_of::() as UINT; + let mut data_size = size_of::() as u32; + let header_size = size_of::() as u32; let status = unsafe { - winuser::GetRawInputData( + GetRawInputData( handle, RID_INPUT, &mut data as *mut _ as _, @@ -178,7 +178,7 @@ pub fn get_raw_input_data(handle: HRAWINPUT) -> Option { ) }; - if status == UINT::max_value() || status == 0 { + if status == u32::max_value() || status == 0 { return None; } @@ -186,9 +186,9 @@ pub fn get_raw_input_data(handle: HRAWINPUT) -> Option { } fn button_flags_to_element_state( - button_flags: USHORT, - down_flag: USHORT, - up_flag: USHORT, + button_flags: u32, + down_flag: u32, + up_flag: u32, ) -> Option { // We assume the same button won't be simultaneously pressed and released. if util::has_flag(button_flags, down_flag) { @@ -200,22 +200,22 @@ fn button_flags_to_element_state( } } -pub fn get_raw_mouse_button_state(button_flags: USHORT) -> [Option; 3] { +pub fn get_raw_mouse_button_state(button_flags: u32) -> [Option; 3] { [ button_flags_to_element_state( button_flags, - winuser::RI_MOUSE_LEFT_BUTTON_DOWN, - winuser::RI_MOUSE_LEFT_BUTTON_UP, + RI_MOUSE_LEFT_BUTTON_DOWN, + RI_MOUSE_LEFT_BUTTON_UP, ), button_flags_to_element_state( button_flags, - winuser::RI_MOUSE_MIDDLE_BUTTON_DOWN, - winuser::RI_MOUSE_MIDDLE_BUTTON_UP, + RI_MOUSE_MIDDLE_BUTTON_DOWN, + RI_MOUSE_MIDDLE_BUTTON_UP, ), button_flags_to_element_state( button_flags, - winuser::RI_MOUSE_RIGHT_BUTTON_DOWN, - winuser::RI_MOUSE_RIGHT_BUTTON_UP, + RI_MOUSE_RIGHT_BUTTON_DOWN, + RI_MOUSE_RIGHT_BUTTON_UP, ), ] } diff --git a/src/platform_impl/windows/util.rs b/src/platform_impl/windows/util.rs index 5faaae3e68..9bc5de6b62 100644 --- a/src/platform_impl/windows/util.rs +++ b/src/platform_impl/windows/util.rs @@ -1,27 +1,43 @@ use std::{ io, mem, ops::BitAnd, - os::raw::c_void, - ptr, slice, + ptr, sync::atomic::{AtomicBool, Ordering}, }; -use crate::{dpi::PhysicalSize, window::CursorIcon}; use winapi::{ - ctypes::wchar_t, - shared::{ - minwindef::{BOOL, DWORD, UINT}, - windef::{DPI_AWARENESS_CONTEXT, HMONITOR, HWND, LPRECT, RECT}, - }, - um::{ - libloaderapi::{GetProcAddress, LoadLibraryA}, - shellscalingapi::{MONITOR_DPI_TYPE, PROCESS_DPI_AWARENESS}, - winbase::lstrlenW, - winnt::{HRESULT, LONG, LPCSTR}, - winuser, + windows::HRESULT, + Windows::Win32::{ + Graphics::Gdi::{ClientToScreen, InvalidateRgn, HMONITOR}, + System::SystemServices::{ + GetProcAddress, LoadLibraryA, BOOL, DPI_AWARENESS_CONTEXT, LRESULT, PSTR, PWSTR, + }, + UI::{ + DisplayDevices::RECT, + HiDpi::{ + AdjustWindowRectExForDpi, GetDpiForWindow, MONITOR_DPI_TYPE, PROCESS_DPI_AWARENESS, + }, + KeyboardAndMouseInput::GetActiveWindow, + WindowsAndMessaging::{ + ClipCursor, GetClientRect, GetClipCursor, GetMenu, GetSystemMetrics, + GetWindowLongPtrW, GetWindowLongW, GetWindowRect, SetWindowPos, ShowCursor, + GWL_EXSTYLE, GWL_STYLE, HWND, IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, + IDC_HELP, IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, + IDC_SIZEWE, IDC_WAIT, LPARAM, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, + SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN, SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE, + SWP_NOMOVE, SWP_NOREPOSITION, SWP_NOZORDER, WPARAM, + }, + }, }, }; +use crate::{dpi::PhysicalSize, window::CursorIcon}; + +#[link(name = "USER32")] +extern "system" { + pub fn DefWindowProcW(hwnd: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT; +} + pub fn has_flag(bitset: T, flag: T) -> bool where T: Copy + PartialEq + BitAnd, @@ -29,19 +45,9 @@ where bitset & flag == flag } -pub fn wchar_to_string(wchar: &[wchar_t]) -> String { - String::from_utf16_lossy(wchar).to_string() -} - -pub fn wchar_ptr_to_string(wchar: *const wchar_t) -> String { - let len = unsafe { lstrlenW(wchar) } as usize; - let wchar_slice = unsafe { slice::from_raw_parts(wchar, len) }; - wchar_to_string(wchar_slice) -} - pub unsafe fn status_map BOOL>(mut fun: F) -> Option { let mut data: T = mem::zeroed(); - if fun(&mut data) != 0 { + if !fun(&mut data).as_bool() { Some(data) } else { None @@ -49,7 +55,7 @@ pub unsafe fn status_map BOOL>(mut fun: F) -> Option { } fn win_to_err BOOL>(f: F) -> Result<(), io::Error> { - if f() != 0 { + if !f().as_bool() { Ok(()) } else { Err(io::Error::last_os_error()) @@ -57,7 +63,7 @@ fn win_to_err BOOL>(f: F) -> Result<(), io::Error> { } pub fn get_window_rect(hwnd: HWND) -> Option { - unsafe { status_map(|rect| winuser::GetWindowRect(hwnd, rect)) } + unsafe { status_map(|rect| GetWindowRect(hwnd, rect)) } } pub fn get_client_rect(hwnd: HWND) -> Result { @@ -65,8 +71,8 @@ pub fn get_client_rect(hwnd: HWND) -> Result { let mut rect = mem::zeroed(); let mut top_left = mem::zeroed(); - win_to_err(|| winuser::ClientToScreen(hwnd, &mut top_left))?; - win_to_err(|| winuser::GetClientRect(hwnd, &mut rect))?; + win_to_err(|| ClientToScreen(hwnd, &mut top_left))?; + win_to_err(|| GetClientRect(hwnd, &mut rect))?; rect.left += top_left.x; rect.top += top_left.y; rect.right += top_left.x; @@ -80,9 +86,9 @@ pub fn adjust_size(hwnd: HWND, size: PhysicalSize) -> PhysicalSize { let (width, height): (u32, u32) = size.into(); let rect = RECT { left: 0, - right: width as LONG, + right: width as i32, top: 0, - bottom: height as LONG, + bottom: height as i32, }; let rect = adjust_window_rect(hwnd, rect).unwrap_or(rect); PhysicalSize::new((rect.right - rect.left) as _, (rect.bottom - rect.top) as _) @@ -95,58 +101,57 @@ pub(crate) fn set_inner_size_physical(window: HWND, x: u32, y: u32) { RECT { top: 0, left: 0, - bottom: y as LONG, - right: x as LONG, + bottom: y as i32, + right: x as i32, }, ) .expect("adjust_window_rect failed"); let outer_x = (rect.right - rect.left).abs() as _; let outer_y = (rect.top - rect.bottom).abs() as _; - winuser::SetWindowPos( + SetWindowPos( window, - ptr::null_mut(), + None, 0, 0, outer_x, outer_y, - winuser::SWP_ASYNCWINDOWPOS - | winuser::SWP_NOZORDER - | winuser::SWP_NOREPOSITION - | winuser::SWP_NOMOVE - | winuser::SWP_NOACTIVATE, + SWP_ASYNCWINDOWPOS | SWP_NOZORDER | SWP_NOREPOSITION | SWP_NOMOVE | SWP_NOACTIVATE, ); - winuser::InvalidateRgn(window, ptr::null_mut(), 0); + InvalidateRgn(window, None, false); } } pub fn adjust_window_rect(hwnd: HWND, rect: RECT) -> Option { unsafe { - let style = winuser::GetWindowLongW(hwnd, winuser::GWL_STYLE); - let style_ex = winuser::GetWindowLongW(hwnd, winuser::GWL_EXSTYLE); - adjust_window_rect_with_styles(hwnd, style as _, style_ex as _, rect) + let style = GetWindowLongPtrW(hwnd, GWL_STYLE); + let style_ex = GetWindowLongW(hwnd, GWL_EXSTYLE); + adjust_window_rect_with_styles(hwnd, style as u32, style_ex as _, rect) } } pub fn adjust_window_rect_with_styles( hwnd: HWND, - style: DWORD, - style_ex: DWORD, + style: u32, + style_ex: u32, rect: RECT, ) -> Option { unsafe { status_map(|r| { *r = rect; - let b_menu = !winuser::GetMenu(hwnd).is_null() as BOOL; - if let (Some(get_dpi_for_window), Some(adjust_window_rect_ex_for_dpi)) = - (*GET_DPI_FOR_WINDOW, *ADJUST_WINDOW_RECT_EX_FOR_DPI) - { - let dpi = get_dpi_for_window(hwnd); - adjust_window_rect_ex_for_dpi(r, style as _, b_menu, style_ex as _, dpi) - } else { - winuser::AdjustWindowRectEx(r, style as _, b_menu, style_ex as _) - } + let b_menu = !GetMenu(hwnd).is_null(); + + // if let (Some(get_dpi_for_window), Some(adjust_window_rect_ex_for_dpi)) = + // (*GET_DPI_FOR_WINDOW, *ADJUST_WINDOW_RECT_EX_FOR_DPI) + // { + + let dpi = GetDpiForWindow(hwnd); + AdjustWindowRectExForDpi(r, style, b_menu, style_ex, dpi) + + // } else { + // winuser::AdjustWindowRectEx(r, style as _, b_menu, style_ex as _) + // } }) } } @@ -155,14 +160,14 @@ pub fn set_cursor_hidden(hidden: bool) { static HIDDEN: AtomicBool = AtomicBool::new(false); let changed = HIDDEN.swap(hidden, Ordering::SeqCst) ^ hidden; if changed { - unsafe { winuser::ShowCursor(!hidden as BOOL) }; + unsafe { ShowCursor(!hidden) }; } } pub fn get_cursor_clip() -> Result { unsafe { let mut rect: RECT = mem::zeroed(); - win_to_err(|| winuser::GetClipCursor(&mut rect)).map(|_| rect) + win_to_err(|| GetClipCursor(&mut rect)).map(|_| rect) } } @@ -175,78 +180,69 @@ pub fn set_cursor_clip(rect: Option) -> Result<(), io::Error> { .as_ref() .map(|r| r as *const RECT) .unwrap_or(ptr::null()); - win_to_err(|| winuser::ClipCursor(rect_ptr)) + win_to_err(|| ClipCursor(rect_ptr)) } } pub fn get_desktop_rect() -> RECT { unsafe { - let left = winuser::GetSystemMetrics(winuser::SM_XVIRTUALSCREEN); - let top = winuser::GetSystemMetrics(winuser::SM_YVIRTUALSCREEN); + let left = GetSystemMetrics(SM_XVIRTUALSCREEN); + let top = GetSystemMetrics(SM_YVIRTUALSCREEN); RECT { left, top, - right: left + winuser::GetSystemMetrics(winuser::SM_CXVIRTUALSCREEN), - bottom: top + winuser::GetSystemMetrics(winuser::SM_CYVIRTUALSCREEN), + right: left + GetSystemMetrics(SM_CXVIRTUALSCREEN), + bottom: top + GetSystemMetrics(SM_CYVIRTUALSCREEN), } } } pub fn is_focused(window: HWND) -> bool { - window == unsafe { winuser::GetActiveWindow() } + window == unsafe { GetActiveWindow() } } impl CursorIcon { - pub(crate) fn to_windows_cursor(self) -> *const wchar_t { + pub(crate) fn to_windows_cursor(self) -> PWSTR { match self { - CursorIcon::Arrow | CursorIcon::Default => winuser::IDC_ARROW, - CursorIcon::Hand => winuser::IDC_HAND, - CursorIcon::Crosshair => winuser::IDC_CROSS, - CursorIcon::Text | CursorIcon::VerticalText => winuser::IDC_IBEAM, - CursorIcon::NotAllowed | CursorIcon::NoDrop => winuser::IDC_NO, + CursorIcon::Arrow | CursorIcon::Default => IDC_ARROW, + CursorIcon::Hand => IDC_HAND, + CursorIcon::Crosshair => IDC_CROSS, + CursorIcon::Text | CursorIcon::VerticalText => IDC_IBEAM, + CursorIcon::NotAllowed | CursorIcon::NoDrop => IDC_NO, CursorIcon::Grab | CursorIcon::Grabbing | CursorIcon::Move | CursorIcon::AllScroll => { - winuser::IDC_SIZEALL + IDC_SIZEALL } CursorIcon::EResize | CursorIcon::WResize | CursorIcon::EwResize - | CursorIcon::ColResize => winuser::IDC_SIZEWE, + | CursorIcon::ColResize => IDC_SIZEWE, CursorIcon::NResize | CursorIcon::SResize | CursorIcon::NsResize - | CursorIcon::RowResize => winuser::IDC_SIZENS, - CursorIcon::NeResize | CursorIcon::SwResize | CursorIcon::NeswResize => { - winuser::IDC_SIZENESW - } - CursorIcon::NwResize | CursorIcon::SeResize | CursorIcon::NwseResize => { - winuser::IDC_SIZENWSE - } - CursorIcon::Wait => winuser::IDC_WAIT, - CursorIcon::Progress => winuser::IDC_APPSTARTING, - CursorIcon::Help => winuser::IDC_HELP, - _ => winuser::IDC_ARROW, // use arrow for the missing cases. + | CursorIcon::RowResize => IDC_SIZENS, + CursorIcon::NeResize | CursorIcon::SwResize | CursorIcon::NeswResize => IDC_SIZENESW, + CursorIcon::NwResize | CursorIcon::SeResize | CursorIcon::NwseResize => IDC_SIZENWSE, + CursorIcon::Wait => IDC_WAIT, + CursorIcon::Progress => IDC_APPSTARTING, + CursorIcon::Help => IDC_HELP, + _ => IDC_ARROW, // use arrow for the missing cases. } } } // Helper function to dynamically load function pointer. // `library` and `function` must be zero-terminated. -pub(super) fn get_function_impl(library: &str, function: &str) -> Option<*const c_void> { - assert_eq!(library.chars().last(), Some('\0')); - assert_eq!(function.chars().last(), Some('\0')); - +pub(super) fn get_function_impl( + library: &str, + function: &str, +) -> Option<*const std::os::raw::c_void> { // Library names we will use are ASCII so we can use the A version to avoid string conversion. - let module = unsafe { LoadLibraryA(library.as_ptr() as LPCSTR) }; + let module = unsafe { LoadLibraryA(PSTR(library.as_mut_ptr())) }; if module.is_null() { return None; } - let function_ptr = unsafe { GetProcAddress(module, function.as_ptr() as LPCSTR) }; - if function_ptr.is_null() { - return None; - } - - Some(function_ptr as _) + unsafe { GetProcAddress(module, PSTR(function.as_mut_ptr())) }.map(|func| func as _) } macro_rules! get_function { @@ -264,20 +260,20 @@ pub type SetProcessDpiAwareness = unsafe extern "system" fn(value: PROCESS_DPI_AWARENESS) -> HRESULT; pub type SetProcessDpiAwarenessContext = unsafe extern "system" fn(value: DPI_AWARENESS_CONTEXT) -> BOOL; -pub type GetDpiForWindow = unsafe extern "system" fn(hwnd: HWND) -> UINT; +pub type GetDpiForWindow = unsafe extern "system" fn(hwnd: HWND) -> u32; pub type GetDpiForMonitor = unsafe extern "system" fn( hmonitor: HMONITOR, dpi_type: MONITOR_DPI_TYPE, - dpi_x: *mut UINT, - dpi_y: *mut UINT, + dpi_x: *mut u32, + dpi_y: *mut u32, ) -> HRESULT; pub type EnableNonClientDpiScaling = unsafe extern "system" fn(hwnd: HWND) -> BOOL; pub type AdjustWindowRectExForDpi = unsafe extern "system" fn( - rect: LPRECT, - dwStyle: DWORD, + rect: *mut RECT, + dwStyle: u32, bMenu: BOOL, - dwExStyle: DWORD, - dpi: UINT, + dwExStyle: u32, + dpi: u32, ) -> BOOL; lazy_static! { diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 2e5e8e5727..f2241e6b03 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -5,29 +5,57 @@ use raw_window_handle::{windows::WindowsHandle, RawWindowHandle}; use std::{ cell::Cell, ffi::OsStr, - io, mem, + io, + iter::once, + mem, os::windows::ffi::OsStrExt, ptr, sync::{mpsc::channel, Arc}, }; - -use winapi::{ - ctypes::c_int, - shared::{ - minwindef::{HINSTANCE, LPARAM, UINT, WPARAM}, - windef::{HWND, POINT, POINTS, RECT}, +use winapi::Windows::Win32::{ + Globalization::{ + ImmGetContext, ImmReleaseContext, ImmSetCompositionWindow, CFS_POINT, COMPOSITIONFORM, + }, + Graphics::{ + Dwm::{DwmEnableBlurBehindWindow, DWM_BB_BLURREGION, DWM_BB_ENABLE, DWM_BLURBEHIND}, + Gdi::{ + ChangeDisplaySettingsExW, ClientToScreen, CreateRectRgn, DeleteObject, InvalidateRgn, + RedrawWindow, CDS_FULLSCREEN, DISP_CHANGE_BADFLAGS, DISP_CHANGE_BADMODE, + DISP_CHANGE_BADPARAM, DISP_CHANGE_FAILED, DISP_CHANGE_SUCCESSFUL, HBRUSH, + RDW_INTERNALPAINT, + }, }, - um::{ - combaseapi, dwmapi, - imm::{CFS_POINT, COMPOSITIONFORM}, - libloaderapi, - objbase::COINIT_APARTMENTTHREADED, - ole2, - oleidl::LPDROPTARGET, - shobjidl_core::{CLSID_TaskbarList, ITaskbarList2}, - wingdi::{CreateRectRgn, DeleteObject}, - winnt::{LPCWSTR, SHORT}, - winuser, + System::{ + Com::{ + CoCreateInstance, CoInitializeEx, CoUninitialize, OleInitialize, RegisterDragDrop, + CLSCTX_ALL, COINIT_APARTMENTTHREADED, + }, + Diagnostics::Debug::{ + FlashWindowEx, FLASHWINFO, FLASHW_ALL, FLASHW_STOP, FLASHW_TIMERNOFG, FLASHW_TRAY, + }, + SystemServices::{ + GetModuleHandleW, HANDLE, HINSTANCE, LRESULT, OLE_E_WRONGCOMPOBJ, PWSTR, + RPC_E_CHANGED_MODE, + }, + }, + UI::{ + DisplayDevices::{POINT, POINTS, RECT}, + KeyboardAndMouseInput::{ + GetActiveWindow, MapVirtualKeyW, ReleaseCapture, SendInput, INPUT, INPUT_0, + INPUT_KEYBOARD, KEYBDINPUT, KEYEVENTF_EXTENDEDKEY, KEYEVENTF_KEYUP, + }, + MenusAndResources::{HCURSOR, HICON}, + Shell::{ITaskbarList2, TaskbarList}, + TouchInput::{RegisterTouchWindow, TWF_WANTPALM}, + WindowsAndMessaging::{ + CreateWindowExW, DefWindowProcW, GetClientRect, GetCursorPos, GetSystemMetrics, + GetWindowLongPtrW, GetWindowPlacement, LoadCursorW, PeekMessageW, PostMessageW, + RegisterClassExW, SetCursor, SetCursorPos, SetForegroundWindow, SetWindowPlacement, + SetWindowPos, SetWindowTextW, CS_HREDRAW, CS_OWNDC, CS_VREDRAW, CW_USEDEFAULT, + GWLP_HINSTANCE, HTCAPTION, HWND, LPARAM, MAPVK_VK_TO_VSC, NID_READY, PM_NOREMOVE, + SM_DIGITIZER, SM_IMMENABLED, SWP_ASYNCWINDOWPOS, SWP_NOACTIVATE, SWP_NOSIZE, + SWP_NOZORDER, VK_LMENU, VK_MENU, WM_NCLBUTTONDOWN, WNDCLASSEXW, WPARAM, + }, }, }; @@ -75,9 +103,7 @@ impl Window { let drag_and_drop = pl_attr.drag_and_drop; init(w_attr, pl_attr, event_loop).map(|win| { let file_drop_handler = if drag_and_drop { - use winapi::shared::winerror::{OLE_E_WRONGCOMPOBJ, RPC_E_CHANGED_MODE, S_OK}; - - let ole_init_result = ole2::OleInitialize(ptr::null_mut()); + let ole_init_result = OleInitialize(ptr::null_mut()); // It is ok if the initialize result is `S_FALSE` because it might happen that // multiple windows are created on the same thread. if ole_init_result == OLE_E_WRONGCOMPOBJ { @@ -99,13 +125,9 @@ impl Window { } }), ); - let handler_interface_ptr = - &mut (*file_drop_handler.data).interface as LPDROPTARGET; + let handler_interface_ptr = &mut (*file_drop_handler.data).interface; - assert_eq!( - ole2::RegisterDragDrop(win.window.0, handler_interface_ptr), - S_OK - ); + assert!(RegisterDragDrop(win.window.0, handler_interface_ptr).is_ok()); Some(file_drop_handler) } else { None @@ -128,10 +150,10 @@ impl Window { pub fn set_title(&self, text: &str) { let text = OsStr::new(text) .encode_wide() - .chain(Some(0).into_iter()) + .chain(once(0)) .collect::>(); unsafe { - winuser::SetWindowTextW(self.window.0, text.as_ptr() as LPCWSTR); + SetWindowTextW(self.window.0, PWSTR(text.as_mut_ptr())); } } @@ -149,12 +171,7 @@ impl Window { #[inline] pub fn request_redraw(&self) { unsafe { - winuser::RedrawWindow( - self.window.0, - ptr::null(), - ptr::null_mut(), - winuser::RDW_INTERNALPAINT, - ); + RedrawWindow(self.window.0, ptr::null(), None, RDW_INTERNALPAINT); } } @@ -168,7 +185,7 @@ impl Window { #[inline] pub fn inner_position(&self) -> Result, NotSupportedError> { let mut position: POINT = unsafe { mem::zeroed() }; - if unsafe { winuser::ClientToScreen(self.window.0, &mut position) } == 0 { + if !unsafe { ClientToScreen(self.window.0, &mut position) }.as_bool() { panic!("Unexpected ClientToScreen failure: please report this error to https://github.com/rust-windowing/winit") } Ok(PhysicalPosition::new(position.x as i32, position.y as i32)) @@ -187,26 +204,23 @@ impl Window { }); unsafe { - winuser::SetWindowPos( + SetWindowPos( self.window.0, - ptr::null_mut(), - x as c_int, - y as c_int, + None, + x, + y, 0, 0, - winuser::SWP_ASYNCWINDOWPOS - | winuser::SWP_NOZORDER - | winuser::SWP_NOSIZE - | winuser::SWP_NOACTIVATE, + SWP_ASYNCWINDOWPOS | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE, ); - winuser::InvalidateRgn(self.window.0, ptr::null_mut(), 0); + InvalidateRgn(self.window.0, None, false); } } #[inline] pub fn inner_size(&self) -> PhysicalSize { let mut rect: RECT = unsafe { mem::zeroed() }; - if unsafe { winuser::GetClientRect(self.window.0, &mut rect) } == 0 { + if !unsafe { GetClientRect(self.window.0, &mut rect) }.as_bool() { panic!("Unexpected GetClientRect failure: please report this error to https://github.com/rust-windowing/winit") } PhysicalSize::new( @@ -279,14 +293,14 @@ impl Window { #[inline] pub fn hinstance(&self) -> HINSTANCE { - unsafe { winuser::GetWindowLongPtrW(self.hwnd(), winuser::GWLP_HINSTANCE) as *mut _ } + HINSTANCE(unsafe { GetWindowLongPtrW(self.hwnd(), GWLP_HINSTANCE) }) } #[inline] pub fn raw_window_handle(&self) -> RawWindowHandle { let handle = WindowsHandle { - hwnd: self.window.0 as *mut _, - hinstance: self.hinstance() as *mut _, + hwnd: (self.window.0).0 as *mut _, + hinstance: self.hinstance().0 as *mut _, ..WindowsHandle::empty() }; RawWindowHandle::Windows(handle) @@ -296,8 +310,8 @@ impl Window { pub fn set_cursor_icon(&self, cursor: CursorIcon) { self.window_state.lock().mouse.cursor = cursor; self.thread_executor.execute_in_thread(move || unsafe { - let cursor = winuser::LoadCursorW(ptr::null_mut(), cursor.to_windows_cursor()); - winuser::SetCursor(cursor); + let cursor = LoadCursorW(None, cursor.to_windows_cursor()); + SetCursor(cursor); }); } @@ -347,10 +361,10 @@ impl Window { let mut point = POINT { x, y }; unsafe { - if winuser::ClientToScreen(self.window.0, &mut point) == 0 { + if !ClientToScreen(self.window.0, &mut point).as_bool() { return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); } - if winuser::SetCursorPos(point.x, point.y) == 0 { + if !SetCursorPos(point.x, point.y).as_bool() { return Err(ExternalError::Os(os_error!(io::Error::last_os_error()))); } } @@ -359,31 +373,31 @@ impl Window { #[inline] pub fn drag_window(&self) -> Result<(), ExternalError> { + let points = { + let mut pos = unsafe { mem::zeroed() }; + unsafe { GetCursorPos(&mut pos) }; + pos + }; + let points = POINTS { + x: points.x as i16, + y: points.y as i16, + }; + unsafe { ReleaseCapture() }; unsafe { - let points = { - let mut pos = mem::zeroed(); - winuser::GetCursorPos(&mut pos); - pos - }; - let points = POINTS { - x: points.x as SHORT, - y: points.y as SHORT, - }; - winuser::ReleaseCapture(); - winuser::PostMessageW( + PostMessageW( self.window.0, - winuser::WM_NCLBUTTONDOWN, - winuser::HTCAPTION as WPARAM, - &points as *const _ as LPARAM, - ); - } + WM_NCLBUTTONDOWN, + WPARAM(HTCAPTION as usize), + LPARAM(&points as *const POINTS as isize), + ) + }; Ok(()) } #[inline] pub fn id(&self) -> WindowId { - WindowId(self.window.0) + WindowId((self.window.0).0) } #[inline] @@ -450,47 +464,44 @@ impl Window { let mut display_name = OsStr::new(&monitor.inner.native_identifier()) .encode_wide() + .chain(once(0)) .collect::>(); - // `encode_wide` does not add a null-terminator but - // `ChangeDisplaySettingsExW` requires a null-terminated - // string, so add it - display_name.push(0); let mut native_video_mode = video_mode.video_mode.native_video_mode.clone(); let res = unsafe { - winuser::ChangeDisplaySettingsExW( - display_name.as_ptr(), + ChangeDisplaySettingsExW( + PWSTR(display_name.as_mut_ptr()), &mut native_video_mode, - std::ptr::null_mut(), - winuser::CDS_FULLSCREEN, + None, + CDS_FULLSCREEN, std::ptr::null_mut(), ) }; - debug_assert!(res != winuser::DISP_CHANGE_BADFLAGS); - debug_assert!(res != winuser::DISP_CHANGE_BADMODE); - debug_assert!(res != winuser::DISP_CHANGE_BADPARAM); - debug_assert!(res != winuser::DISP_CHANGE_FAILED); - assert_eq!(res, winuser::DISP_CHANGE_SUCCESSFUL); + debug_assert!(res != DISP_CHANGE_BADFLAGS); + debug_assert!(res != DISP_CHANGE_BADMODE); + debug_assert!(res != DISP_CHANGE_BADPARAM); + debug_assert!(res != DISP_CHANGE_FAILED); + assert_eq!(res, DISP_CHANGE_SUCCESSFUL); } (&Some(Fullscreen::Exclusive(_)), &None) | (&Some(Fullscreen::Exclusive(_)), &Some(Fullscreen::Borderless(_))) => { let res = unsafe { - winuser::ChangeDisplaySettingsExW( - std::ptr::null_mut(), + ChangeDisplaySettingsExW( + None, std::ptr::null_mut(), - std::ptr::null_mut(), - winuser::CDS_FULLSCREEN, + None, + CDS_FULLSCREEN, std::ptr::null_mut(), ) }; - debug_assert!(res != winuser::DISP_CHANGE_BADFLAGS); - debug_assert!(res != winuser::DISP_CHANGE_BADMODE); - debug_assert!(res != winuser::DISP_CHANGE_BADPARAM); - debug_assert!(res != winuser::DISP_CHANGE_FAILED); - assert_eq!(res, winuser::DISP_CHANGE_SUCCESSFUL); + debug_assert!(res != DISP_CHANGE_BADFLAGS); + debug_assert!(res != DISP_CHANGE_BADMODE); + debug_assert!(res != DISP_CHANGE_BADPARAM); + debug_assert!(res != DISP_CHANGE_FAILED); + assert_eq!(res, DISP_CHANGE_SUCCESSFUL); } _ => (), } @@ -505,7 +516,7 @@ impl Window { // fine, taking control back from the DWM and ensuring that the `SetWindowPos` call // below goes through. let mut msg = mem::zeroed(); - winuser::PeekMessageW(&mut msg, ptr::null_mut(), 0, 0, 0); + PeekMessageW(&mut msg, None, 0, 0, PM_NOREMOVE); } // Update window style @@ -526,7 +537,7 @@ impl Window { // Save window bounds before entering fullscreen let placement = unsafe { let mut placement = mem::zeroed(); - winuser::GetWindowPlacement(window.0, &mut placement); + GetWindowPlacement(window.0, &mut placement); placement }; @@ -544,16 +555,16 @@ impl Window { let size: (u32, u32) = monitor.size().into(); unsafe { - winuser::SetWindowPos( + SetWindowPos( window.0, - ptr::null_mut(), + None, position.0, position.1, size.0 as i32, size.1 as i32, - winuser::SWP_ASYNCWINDOWPOS | winuser::SWP_NOZORDER, + SWP_ASYNCWINDOWPOS | SWP_NOZORDER, ); - winuser::InvalidateRgn(window.0, ptr::null_mut(), 0); + InvalidateRgn(window.0, None, false); } } None => { @@ -561,8 +572,8 @@ impl Window { if let Some(SavedWindow { placement }) = window_state_lock.saved_window.take() { drop(window_state_lock); unsafe { - winuser::SetWindowPlacement(window.0, &placement); - winuser::InvalidateRgn(window.0, ptr::null_mut(), 0); + SetWindowPlacement(window.0, &placement); + InvalidateRgn(window.0, None, false); } } } @@ -630,17 +641,16 @@ impl Window { } pub(crate) fn set_ime_position_physical(&self, x: i32, y: i32) { - if unsafe { winuser::GetSystemMetrics(winuser::SM_IMMENABLED) } != 0 { + if unsafe { GetSystemMetrics(SM_IMMENABLED) } != 0 { let mut composition_form = COMPOSITIONFORM { dwStyle: CFS_POINT, ptCurrentPos: POINT { x, y }, rcArea: unsafe { mem::zeroed() }, }; - unsafe { - let himc = winapi::um::imm::ImmGetContext(self.window.0); - winapi::um::imm::ImmSetCompositionWindow(himc, &mut composition_form); - winapi::um::imm::ImmReleaseContext(self.window.0, himc); - } + + let himc = unsafe { ImmGetContext(self.window.0) }; + unsafe { ImmSetCompositionWindow(himc, &mut composition_form) }; + unsafe { ImmReleaseContext(self.window.0, himc) }; } } @@ -653,7 +663,7 @@ impl Window { #[inline] pub fn request_user_attention(&self, request_type: Option) { let window = self.window.clone(); - let active_window_handle = unsafe { winuser::GetActiveWindow() }; + let active_window_handle = unsafe { GetActiveWindow() }; if window.0 == active_window_handle { return; } @@ -661,23 +671,19 @@ impl Window { self.thread_executor.execute_in_thread(move || unsafe { let (flags, count) = request_type .map(|ty| match ty { - UserAttentionType::Critical => { - (winuser::FLASHW_ALL | winuser::FLASHW_TIMERNOFG, u32::MAX) - } - UserAttentionType::Informational => { - (winuser::FLASHW_TRAY | winuser::FLASHW_TIMERNOFG, 0) - } + UserAttentionType::Critical => (FLASHW_ALL | FLASHW_TIMERNOFG, u32::MAX), + UserAttentionType::Informational => (FLASHW_TRAY | FLASHW_TIMERNOFG, 0), }) - .unwrap_or((winuser::FLASHW_STOP, 0)); + .unwrap_or((FLASHW_STOP, 0)); - let mut flash_info = winuser::FLASHWINFO { - cbSize: mem::size_of::() as UINT, + let mut flash_info = FLASHWINFO { + cbSize: mem::size_of::() as u32, hwnd: window.0, dwFlags: flags, uCount: count, dwTimeout: 0, }; - winuser::FlashWindowEx(&mut flash_info); + FlashWindowEx(&mut flash_info); }); } @@ -693,7 +699,7 @@ impl Drop for Window { unsafe { // The window must be destroyed from the same thread that created it, so we send a // custom message to be handled by our callback to do the actual work. - winuser::PostMessageW(self.window.0, *DESTROY_MSG_ID, 0, 0); + PostMessageW(self.window.0, *DESTROY_MSG_ID, None, None); } } } @@ -755,18 +761,18 @@ unsafe fn init( // creating the real window this time, by using the functions in `extra_functions` let real_window = { let (style, ex_style) = window_flags.to_window_styles(); - let handle = winuser::CreateWindowExW( + let handle = CreateWindowExW( ex_style, - class_name.as_ptr(), - title.as_ptr() as LPCWSTR, + PWSTR(class_name.as_mut_ptr()), + PWSTR(title.as_mut_ptr()), style, - winuser::CW_USEDEFAULT, - winuser::CW_USEDEFAULT, - winuser::CW_USEDEFAULT, - winuser::CW_USEDEFAULT, - parent.unwrap_or(ptr::null_mut()), - pl_attribs.menu.unwrap_or(ptr::null_mut()), - libloaderapi::GetModuleHandleW(ptr::null()), + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + parent, + pl_attribs.menu, + GetModuleHandleW(None), ptr::null_mut(), ); @@ -779,9 +785,9 @@ unsafe fn init( // Register for touch events if applicable { - let digitizer = winuser::GetSystemMetrics(winuser::SM_DIGITIZER) as u32; - if digitizer & winuser::NID_READY != 0 { - winuser::RegisterTouchWindow(real_window.0, winuser::TWF_WANTPALM); + let digitizer = GetSystemMetrics(SM_DIGITIZER) as u32; + if digitizer & NID_READY != 0 { + RegisterTouchWindow(real_window.0, TWF_WANTPALM); } } @@ -793,15 +799,15 @@ unsafe fn init( // Empty region for the blur effect, so the window is fully transparent let region = CreateRectRgn(0, 0, -1, -1); - let bb = dwmapi::DWM_BLURBEHIND { - dwFlags: dwmapi::DWM_BB_ENABLE | dwmapi::DWM_BB_BLURREGION, - fEnable: 1, + let bb = DWM_BLURBEHIND { + dwFlags: DWM_BB_ENABLE | DWM_BB_BLURREGION, + fEnable: true.into(), hRgnBlur: region, - fTransitionOnMaximized: 0, + fTransitionOnMaximized: false.into(), }; - dwmapi::DwmEnableBlurBehindWindow(real_window.0, &bb); - DeleteObject(region as _); + DwmEnableBlurBehindWindow(real_window.0, &bb); + DeleteObject(region); } // If the system theme is dark, we need to set the window theme now @@ -863,52 +869,61 @@ unsafe fn register_window_class( let h_icon = taskbar_icon .as_ref() .map(|icon| icon.inner.as_raw_handle()) - .unwrap_or(ptr::null_mut()); + .unwrap_or(HANDLE::NULL); let h_icon_small = window_icon .as_ref() .map(|icon| icon.inner.as_raw_handle()) - .unwrap_or(ptr::null_mut()); + .unwrap_or(HANDLE::NULL); - let class = winuser::WNDCLASSEXW { - cbSize: mem::size_of::() as UINT, - style: winuser::CS_HREDRAW | winuser::CS_VREDRAW | winuser::CS_OWNDC, - lpfnWndProc: Some(winuser::DefWindowProcW), + let class = WNDCLASSEXW { + cbSize: mem::size_of::() as u32, + style: CS_HREDRAW | CS_VREDRAW | CS_OWNDC, + lpfnWndProc: Some(def_wnd_proc), cbClsExtra: 0, cbWndExtra: 0, - hInstance: libloaderapi::GetModuleHandleW(ptr::null()), - hIcon: h_icon, - hCursor: ptr::null_mut(), // must be null in order for cursor state to work properly - hbrBackground: ptr::null_mut(), - lpszMenuName: ptr::null(), - lpszClassName: class_name.as_ptr(), - hIconSm: h_icon_small, + hInstance: GetModuleHandleW(None), + hIcon: HICON(h_icon.0), + hCursor: HCURSOR::NULL, // must be null in order for cursor state to work properly + hbrBackground: HBRUSH::NULL, + lpszMenuName: PWSTR::NULL, + lpszClassName: PWSTR(class_name.as_mut_ptr()), + hIconSm: HICON(h_icon_small.0), }; // We ignore errors because registering the same window class twice would trigger // an error, and because errors here are detected during CreateWindowEx anyway. // Also since there is no weird element in the struct, there is no reason for this // call to fail. - winuser::RegisterClassExW(&class); + RegisterClassExW(&class); class_name } +unsafe extern "system" fn def_wnd_proc( + hwnd: HWND, + msg: u32, + wparam: WPARAM, + lparam: LPARAM, +) -> LRESULT { + DefWindowProcW(hwnd, msg, wparam, lparam) +} + struct ComInitialized(*mut ()); impl Drop for ComInitialized { fn drop(&mut self) { - unsafe { combaseapi::CoUninitialize() }; + unsafe { CoUninitialize() }; } } thread_local! { static COM_INITIALIZED: ComInitialized = { unsafe { - combaseapi::CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED); + CoInitializeEx(ptr::null_mut(), COINIT_APARTMENTTHREADED); ComInitialized(ptr::null_mut()) } }; - static TASKBAR_LIST: Cell<*mut ITaskbarList2> = Cell::new(ptr::null_mut()); + static TASKBAR_LIST: Cell> = Cell::new(None); } pub fn com_initialized() { @@ -927,28 +942,25 @@ unsafe fn taskbar_mark_fullscreen(handle: HWND, fullscreen: bool) { com_initialized(); TASKBAR_LIST.with(|task_bar_list_ptr| { - let mut task_bar_list = task_bar_list_ptr.get(); - - if task_bar_list == ptr::null_mut() { - use winapi::{shared::winerror::S_OK, Interface}; + let mut task_bar_list = match task_bar_list_ptr.into_inner() { + Some(task_bar_list) => task_bar_list, + None => { + let task_bar_list: ITaskbarList2 = + match CoCreateInstance(&TaskbarList, None, CLSCTX_ALL) { + Ok(task_bar_list) => task_bar_list, + Err(_) => return, // In some old windows, the taskbar object could not be created, we just ignore it + }; + task_bar_list_ptr.set(Some(task_bar_list)); - let hr = combaseapi::CoCreateInstance( - &CLSID_TaskbarList, - ptr::null_mut(), - combaseapi::CLSCTX_ALL, - &ITaskbarList2::uuidof(), - &mut task_bar_list as *mut _ as *mut _, - ); + if task_bar_list.HrInit().is_err() { + return; + } - if hr != S_OK || (*task_bar_list).HrInit() != S_OK { - // In some old windows, the taskbar object could not be created, we just ignore it - return; + task_bar_list } - task_bar_list_ptr.set(task_bar_list) - } + }; - task_bar_list = task_bar_list_ptr.get(); - (*task_bar_list).MarkFullscreenWindow(handle, if fullscreen { 1 } else { 0 }); + task_bar_list.MarkFullscreenWindow(handle, fullscreen); }) } @@ -957,25 +969,39 @@ unsafe fn force_window_active(handle: HWND) { // This is a little hack which can "steal" the foreground window permission // We only call this function in the window creation, so it should be fine. // See : https://stackoverflow.com/questions/10740346/setforegroundwindow-only-working-while-visual-studio-is-open - let alt_sc = winuser::MapVirtualKeyW(winuser::VK_MENU as _, winuser::MAPVK_VK_TO_VSC); - - let mut inputs: [winuser::INPUT; 2] = mem::zeroed(); - inputs[0].type_ = winuser::INPUT_KEYBOARD; - inputs[0].u.ki_mut().wVk = winuser::VK_LMENU as _; - inputs[0].u.ki_mut().wScan = alt_sc as _; - inputs[0].u.ki_mut().dwFlags = winuser::KEYEVENTF_EXTENDEDKEY; - - inputs[1].type_ = winuser::INPUT_KEYBOARD; - inputs[1].u.ki_mut().wVk = winuser::VK_LMENU as _; - inputs[1].u.ki_mut().wScan = alt_sc as _; - inputs[1].u.ki_mut().dwFlags = winuser::KEYEVENTF_EXTENDEDKEY | winuser::KEYEVENTF_KEYUP; + let alt_sc = MapVirtualKeyW(VK_MENU, MAPVK_VK_TO_VSC); + + let mut inputs = [ + INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: VK_LMENU as u16, + wScan: alt_sc as u16, + dwFlags: KEYEVENTF_EXTENDEDKEY, + ..Default::default() + }, + }, + }, + INPUT { + r#type: INPUT_KEYBOARD, + Anonymous: INPUT_0 { + ki: KEYBDINPUT { + wVk: VK_LMENU as u16, + wScan: alt_sc as u16, + dwFlags: KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, + ..Default::default() + }, + }, + }, + ]; // Simulate a key press and release - winuser::SendInput( - inputs.len() as _, + SendInput( + inputs.len() as u32, inputs.as_mut_ptr(), - mem::size_of::() as _, + mem::size_of::() as i32, ); - winuser::SetForegroundWindow(handle); + SetForegroundWindow(handle); } diff --git a/src/platform_impl/windows/window_state.rs b/src/platform_impl/windows/window_state.rs index 9e41bd7925..5441b8facf 100644 --- a/src/platform_impl/windows/window_state.rs +++ b/src/platform_impl/windows/window_state.rs @@ -6,13 +6,22 @@ use crate::{ window::{CursorIcon, Fullscreen, Theme, WindowAttributes}, }; use parking_lot::MutexGuard; -use std::{io, ptr}; -use winapi::{ - shared::{ - minwindef::DWORD, - windef::{HWND, RECT}, +use std::io; +use winapi::Windows::Win32::{ + Graphics::Gdi::InvalidateRgn, + UI::{ + DisplayDevices::RECT, + WindowsAndMessaging::{ + SendMessageW, SetWindowLongW, SetWindowPos, ShowWindow, GWL_EXSTYLE, GWL_STYLE, HWND, + HWND_NOTOPMOST, HWND_TOPMOST, LPARAM, SWP_ASYNCWINDOWPOS, SWP_FRAMECHANGED, + SWP_NOACTIVATE, SWP_NOMOVE, SWP_NOSIZE, SWP_NOZORDER, SW_HIDE, SW_MAXIMIZE, + SW_MINIMIZE, SW_RESTORE, SW_SHOW, WINDOWPLACEMENT, WINDOW_EX_STYLE, WINDOW_STYLE, + WPARAM, WS_BORDER, WS_CAPTION, WS_CHILD, WS_CLIPCHILDREN, WS_CLIPSIBLINGS, + WS_EX_ACCEPTFILES, WS_EX_APPWINDOW, WS_EX_NOREDIRECTIONBITMAP, WS_EX_TOPMOST, + WS_EX_WINDOWEDGE, WS_MAXIMIZE, WS_MAXIMIZEBOX, WS_MINIMIZE, WS_MINIMIZEBOX, + WS_OVERLAPPEDWINDOW, WS_POPUP, WS_SIZEBOX, WS_SYSMENU, WS_VISIBLE, + }, }, - um::winuser, }; /// Contains information about states and the window that the callback is going to use. @@ -39,7 +48,7 @@ pub struct WindowState { #[derive(Clone)] pub struct SavedWindow { - pub placement: winuser::WINDOWPLACEMENT, + pub placement: WINDOWPLACEMENT, } #[derive(Clone)] @@ -187,10 +196,8 @@ impl WindowFlags { self } - pub fn to_window_styles(self) -> (DWORD, DWORD) { - use winapi::um::winuser::*; - - let (mut style, mut style_ex) = (0, 0); + pub fn to_window_styles(self) -> (WINDOW_STYLE, WINDOW_EX_STYLE) { + let (mut style, mut style_ex) = (WINDOW_STYLE::default(), WINDOW_EX_STYLE::default()); if self.contains(WindowFlags::RESIZABLE) { style |= WS_SIZEBOX | WS_MAXIMIZEBOX; @@ -230,7 +237,7 @@ impl WindowFlags { if self.intersects( WindowFlags::MARKER_EXCLUSIVE_FULLSCREEN | WindowFlags::MARKER_BORDERLESS_FULLSCREEN, ) { - style &= !WS_OVERLAPPEDWINDOW; + style.0 &= !WS_OVERLAPPEDWINDOW.0; } (style, style_ex) @@ -248,43 +255,43 @@ impl WindowFlags { if diff.contains(WindowFlags::VISIBLE) { unsafe { - winuser::ShowWindow( + ShowWindow( window, - match new.contains(WindowFlags::VISIBLE) { - true => winuser::SW_SHOW, - false => winuser::SW_HIDE, + if new.contains(WindowFlags::VISIBLE) { + SW_SHOW + } else { + SW_HIDE }, ); } } if diff.contains(WindowFlags::ALWAYS_ON_TOP) { unsafe { - winuser::SetWindowPos( + SetWindowPos( window, - match new.contains(WindowFlags::ALWAYS_ON_TOP) { - true => winuser::HWND_TOPMOST, - false => winuser::HWND_NOTOPMOST, + if new.contains(WindowFlags::ALWAYS_ON_TOP) { + HWND_TOPMOST + } else { + HWND_NOTOPMOST }, 0, 0, 0, 0, - winuser::SWP_ASYNCWINDOWPOS - | winuser::SWP_NOMOVE - | winuser::SWP_NOSIZE - | winuser::SWP_NOACTIVATE, + SWP_ASYNCWINDOWPOS | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE, ); - winuser::InvalidateRgn(window, ptr::null_mut(), 0); + InvalidateRgn(window, None, false); } } if diff.contains(WindowFlags::MAXIMIZED) || new.contains(WindowFlags::MAXIMIZED) { unsafe { - winuser::ShowWindow( + ShowWindow( window, - match new.contains(WindowFlags::MAXIMIZED) { - true => winuser::SW_MAXIMIZE, - false => winuser::SW_RESTORE, + if new.contains(WindowFlags::MAXIMIZED) { + SW_MAXIMIZE + } else { + SW_RESTORE }, ); } @@ -293,11 +300,12 @@ impl WindowFlags { // Minimize operations should execute after maximize for proper window animations if diff.contains(WindowFlags::MINIMIZED) { unsafe { - winuser::ShowWindow( + ShowWindow( window, - match new.contains(WindowFlags::MINIMIZED) { - true => winuser::SW_MINIMIZE, - false => winuser::SW_RESTORE, + if new.contains(WindowFlags::MINIMIZED) { + SW_MINIMIZE + } else { + SW_RESTORE }, ); } @@ -307,18 +315,20 @@ impl WindowFlags { let (style, style_ex) = new.to_window_styles(); unsafe { - winuser::SendMessageW(window, *event_loop::SET_RETAIN_STATE_ON_SIZE_MSG_ID, 1, 0); + SendMessageW( + window, + *event_loop::SET_RETAIN_STATE_ON_SIZE_MSG_ID, + WPARAM(1), + LPARAM(0), + ); // This condition is necessary to avoid having an unrestorable window if !new.contains(WindowFlags::MINIMIZED) { - winuser::SetWindowLongW(window, winuser::GWL_STYLE, style as _); - winuser::SetWindowLongW(window, winuser::GWL_EXSTYLE, style_ex as _); + SetWindowLongW(window, GWL_STYLE, style.0 as i32); + SetWindowLongW(window, GWL_EXSTYLE, style_ex.0 as i32); } - let mut flags = winuser::SWP_NOZORDER - | winuser::SWP_NOMOVE - | winuser::SWP_NOSIZE - | winuser::SWP_FRAMECHANGED; + let mut flags = SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED; // We generally don't want style changes here to affect window // focus, but for fullscreen windows they must be activated @@ -326,12 +336,17 @@ impl WindowFlags { if !new.contains(WindowFlags::MARKER_EXCLUSIVE_FULLSCREEN) && !new.contains(WindowFlags::MARKER_BORDERLESS_FULLSCREEN) { - flags |= winuser::SWP_NOACTIVATE; + flags |= SWP_NOACTIVATE; } // Refresh the window frame - winuser::SetWindowPos(window, ptr::null_mut(), 0, 0, 0, 0, flags); - winuser::SendMessageW(window, *event_loop::SET_RETAIN_STATE_ON_SIZE_MSG_ID, 0, 0); + SetWindowPos(window, None, 0, 0, 0, 0, flags); + SendMessageW( + window, + *event_loop::SET_RETAIN_STATE_ON_SIZE_MSG_ID, + WPARAM(0), + LPARAM(0), + ); } } } diff --git a/winapi/Cargo.toml b/winapi/Cargo.toml new file mode 100644 index 0000000000..a29e92906f --- /dev/null +++ b/winapi/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "winapi" +version = "0.1.0" +authors = ["Clemens Wasser "] +edition = "2018" + +[dependencies] +windows = "0.10" + +[build-dependencies] +windows = "0.10" \ No newline at end of file diff --git a/winapi/build.rs b/winapi/build.rs new file mode 100644 index 0000000000..690c18db66 --- /dev/null +++ b/winapi/build.rs @@ -0,0 +1,121 @@ +fn main() { + windows::build!( + Windows::Win32::Devices::HumanInterfaceDevice::MOUSE_MOVE_RELATIVE, + Windows::Win32::Globalization::{ + ImmGetContext, ImmReleaseContext, ImmSetCompositionWindow, CFS_POINT, + }, + Windows::Win32::Graphics::Dwm::{ + DwmEnableBlurBehindWindow, DWM_BB_BLURREGION, DWM_BB_ENABLE, DWM_BLURBEHIND, + }, + Windows::Win32::Graphics::Gdi::{ + ChangeDisplaySettingsExW, ClientToScreen, CreateRectRgn, DeleteObject, EnumDisplayMonitors, + EnumDisplaySettingsExW, GetDC, GetDeviceCaps, GetMonitorInfoW, GetUpdateRect, + InvalidateRgn, MonitorFromPoint, MonitorFromRect, MonitorFromWindow, RedrawWindow, + ScreenToClient, ValidateRect, CDS_FULLSCREEN, CDS_TYPE, DISP_CHANGE, DISP_CHANGE_BADFLAGS, + DISP_CHANGE_BADMODE, DISP_CHANGE_BADPARAM, DISP_CHANGE_FAILED, DISP_CHANGE_SUCCESSFUL, + DM_BITSPERPEL, DM_DISPLAYFREQUENCY, DM_PELSHEIGHT, DM_PELSWIDTH, LOGPIXELSX, + MONITORINFOEXW, MONITOR_DEFAULTTONEAREST, MONITOR_DEFAULTTONULL, MONITOR_DEFAULTTOPRIMARY, + RDW_INTERNALPAINT, REDRAW_WINDOW_FLAGS, + }, + Windows::Win32::System::Com::{ + CoCreateInstance, CoInitializeEx, CoUninitialize, OleInitialize, RegisterDragDrop, + RevokeDragDrop, CLSCTX_ALL, COINIT_APARTMENTTHREADED, + }, + Windows::Win32::System::Diagnostics::Debug::{ + FlashWindowEx, FLASHWINFO, FLASHW_ALL, FLASHW_STOP, FLASHW_TIMERNOFG, FLASHW_TRAY, + }, + Windows::Win32::System::SystemServices::{ + GetModuleHandleW, GetProcAddress, LoadLibraryA, MsgWaitForMultipleObjectsEx, + DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT, HINSTANCE, MWMO_INPUTAVAILABLE, + OLE_E_WRONGCOMPOBJ, PSTR, PWSTR, RPC_E_CHANGED_MODE, VER_EQUAL, VER_GREATER_EQUAL, + }, + Windows::Win32::System::Threading::{GetCurrentThreadId, WAIT_TIMEOUT}, + Windows::Win32::System::WindowsProgramming::{ + VerSetConditionMask, VerifyVersionInfoW, INFINITE, VER_BUILDNUMBER, VER_MAJORVERSION, + VER_MINORVERSION, + }, + Windows::Win32::UI::Accessibility::{HCF_HIGHCONTRASTON, HIGHCONTRASTA}, + Windows::Win32::UI::Controls::{ + SetWindowTheme, HOVER_DEFAULT, LR_DEFAULTSIZE, LR_LOADFROMFILE, WM_MOUSELEAVE, + }, + Windows::Win32::UI::DisplayDevices::POINTS, + Windows::Win32::UI::HiDpi::{ + AdjustWindowRectExForDpi, GetDpiForWindow, MDT_EFFECTIVE_DPI, MONITOR_DPI_TYPE, + PROCESS_DPI_AWARENESS, PROCESS_PER_MONITOR_DPI_AWARE, + }, + Windows::Win32::UI::KeyboardAndMouseInput::{ + EnableWindow, GetActiveWindow, GetKeyState, GetKeyboardLayout, GetKeyboardState, + GetRawInputData, GetRawInputDeviceInfoW, GetRawInputDeviceList, MapVirtualKeyA, + MapVirtualKeyW, RegisterRawInputDevices, ReleaseCapture, ReleaseCapture, SendInput, + SetCapture, ToUnicodeEx, TrackMouseEvent, INPUT_KEYBOARD, INPUT_TYPE, KEYBD_EVENT_FLAGS, + KEYEVENTF_EXTENDEDKEY, KEYEVENTF_KEYUP, RAWINPUT, RAWINPUTDEVICELIST, RIDEV_DEVNOTIFY, + RIDEV_INPUTSINK, RIDI_DEVICEINFO, RIDI_DEVICENAME, RID_DEVICE_INFO, RID_DEVICE_INFO_HID, + RID_DEVICE_INFO_KEYBOARD, RID_DEVICE_INFO_MOUSE, RID_INPUT, RIM_TYPEHID, RIM_TYPEKEYBOARD, + RIM_TYPEKEYBOARD, RIM_TYPEMOUSE, TME_LEAVE, + }, + Windows::Win32::UI::MenusAndResources::HMENU, + Windows::Win32::UI::PointerInput::{ + POINTER_FLAG_DOWN, POINTER_FLAG_UP, POINTER_FLAG_UPDATE, POINTER_INFO, POINTER_PEN_INFO, + POINTER_TOUCH_INFO, + }, + Windows::Win32::UI::Shell::{ + DefSubclassProc, ITaskbarList2, RemoveWindowSubclass, SetWindowSubclass, TaskbarList, + }, + Windows::Win32::UI::TouchInput::{ + CloseTouchInputHandle, GetTouchInputInfo, RegisterTouchWindow, HTOUCHINPUT, + TOUCHEVENTF_DOWN, TOUCHEVENTF_MOVE, TOUCHEVENTF_UP, TWF_WANTPALM, + }, + Windows::Win32::UI::WindowsAndMessaging::{ + AdjustWindowRectEx, ClipCursor, CreateIcon, CreateWindowExW, DefWindowProcW, DestroyIcon, + DestroyWindow, DispatchMessageW, GetClientRect, GetClipCursor, GetCursorPos, GetMenu, + GetMessageW, GetSystemMetrics, GetWindowLongPtrW, GetWindowLongW, GetWindowPlacement, + GetWindowRect, IsProcessDPIAware, LoadCursorW, LoadImageW, PeekMessageW, PostMessageW, + PostThreadMessageW, RegisterClassExW, RegisterWindowMessageA, SendMessageW, SetCursor, + SetCursorPos, SetForegroundWindow, SetWindowLongPtrW, SetWindowLongW, SetWindowPlacement, + SetWindowPos, SetWindowTextW, ShowCursor, ShowWindow, SystemParametersInfoA, + TranslateMessage, CS_HREDRAW, CS_OWNDC, CS_VREDRAW, CW_USEDEFAULT, GIDC_ARRIVAL, + GIDC_REMOVAL, GWLP_HINSTANCE, GWL_EXSTYLE, GWL_STYLE, HTCAPTION, HTCLIENT, HWND_NOTOPMOST, + HWND_TOPMOST, ICON_BIG, ICON_SMALL, IDC_APPSTARTING, IDC_ARROW, IDC_CROSS, IDC_HAND, + IDC_HELP, IDC_IBEAM, IDC_NO, IDC_SIZEALL, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE, + IDC_SIZEWE, IDC_WAIT, IMAGE_ICON, MAPVK_VK_TO_CHAR, MAPVK_VK_TO_VSC, MAPVK_VSC_TO_VK_EX, + MINMAXINFO, NID_READY, PM_NOREMOVE, PM_QS_PAINT, PM_REMOVE, PT_PEN, PT_TOUCH, QS_ALLEVENTS, + RI_KEY_E0, RI_KEY_E1, RI_MOUSE_LEFT_BUTTON_DOWN, RI_MOUSE_LEFT_BUTTON_UP, + RI_MOUSE_MIDDLE_BUTTON_DOWN, RI_MOUSE_MIDDLE_BUTTON_UP, RI_MOUSE_RIGHT_BUTTON_DOWN, + RI_MOUSE_RIGHT_BUTTON_UP, RI_MOUSE_WHEEL, SC_MINIMIZE, SC_RESTORE, SC_SCREENSAVE, + SET_WINDOW_POS_FLAGS, SIZE_MAXIMIZED, SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_DIGITIZER, + SM_IMMENABLED, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN, SPI_GETHIGHCONTRAST, + SWP_ASYNCWINDOWPOS, SWP_ASYNCWINDOWPOS, SWP_FRAMECHANGED, SWP_NOACTIVATE, SWP_NOACTIVATE, + SWP_NOMOVE, SWP_NOREPOSITION, SWP_NOSIZE, SWP_NOSIZE, SWP_NOZORDER, SW_HIDE, SW_MAXIMIZE, + SW_MINIMIZE, SW_RESTORE, SW_SHOW, SYSTEM_METRICS_INDEX, VK_ADD, VK_APPS, VK_BACK, + VK_BROWSER_BACK, VK_BROWSER_FAVORITES, VK_BROWSER_FORWARD, VK_BROWSER_HOME, + VK_BROWSER_REFRESH, VK_BROWSER_SEARCH, VK_BROWSER_STOP, VK_CAPITAL, VK_CONTROL, VK_CONVERT, + VK_DECIMAL, VK_DELETE, VK_DIVIDE, VK_DOWN, VK_END, VK_ESCAPE, VK_F1, VK_F10, VK_F11, + VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18, VK_F19, VK_F2, VK_F20, VK_F21, + VK_F22, VK_F23, VK_F24, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_HOME, + VK_INSERT, VK_KANA, VK_KANJI, VK_LAUNCH_MAIL, VK_LAUNCH_MEDIA_SELECT, VK_LCONTROL, VK_LEFT, + VK_LMENU, VK_LMENU, VK_LSHIFT, VK_LWIN, VK_LWIN, VK_MEDIA_NEXT_TRACK, VK_MEDIA_PLAY_PAUSE, + VK_MEDIA_PREV_TRACK, VK_MEDIA_STOP, VK_MENU, VK_MENU, VK_MULTIPLY, VK_NEXT, VK_NONCONVERT, + VK_NUMLOCK, VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD5, + VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, VK_OEM_1, VK_OEM_102, VK_OEM_2, VK_OEM_3, + VK_OEM_4, VK_OEM_5, VK_OEM_6, VK_OEM_7, VK_OEM_COMMA, VK_OEM_MINUS, VK_OEM_PERIOD, + VK_OEM_PLUS, VK_PAUSE, VK_PRIOR, VK_RCONTROL, VK_RETURN, VK_RIGHT, VK_RMENU, VK_RSHIFT, + VK_RWIN, VK_RWIN, VK_SCROLL, VK_SHIFT, VK_SLEEP, VK_SNAPSHOT, VK_SPACE, VK_SUBTRACT, + VK_TAB, VK_UP, VK_VOLUME_DOWN, VK_VOLUME_MUTE, VK_VOLUME_UP, WHEEL_DELTA, WINDOWPOS, + WINDOW_EX_STYLE, WINDOW_LONG_PTR_INDEX, WINDOW_STYLE, WM_CAPTURECHANGED, WM_CHAR, WM_CLOSE, + WM_DESTROY, WM_DPICHANGED, WM_DROPFILES, WM_ENTERSIZEMOVE, WM_EXITSIZEMOVE, + WM_GETMINMAXINFO, WM_INPUT, WM_INPUT_DEVICE_CHANGE, WM_KEYDOWN, WM_KEYDOWN, WM_KEYUP, + WM_KEYUP, WM_KILLFOCUS, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP, + WM_MOUSEHWHEEL, WM_MOUSEMOVE, WM_MOUSEMOVE, WM_MOUSEWHEEL, WM_NCCREATE, WM_NCDESTROY, + WM_NCDESTROY, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN, WM_PAINT, WM_PAINT, WM_PAINT, WM_PAINT, + WM_PAINT, WM_POINTERDOWN, WM_POINTERUP, WM_POINTERUPDATE, WM_RBUTTONDOWN, WM_RBUTTONUP, + WM_SETCURSOR, WM_SETFOCUS, WM_SETICON, WM_SIZE, WM_SYSCHAR, WM_SYSCOMMAND, WM_SYSKEYDOWN, + WM_SYSKEYDOWN, WM_SYSKEYDOWN, WM_SYSKEYUP, WM_SYSKEYUP, WM_TOUCH, WM_WINDOWPOSCHANGED, + WM_WINDOWPOSCHANGING, WM_WININICHANGE, WM_XBUTTONDOWN, WM_XBUTTONUP, WNDCLASSEXW, + WNDCLASS_STYLES, WS_BORDER, WS_CAPTION, WS_CHILD, WS_CLIPCHILDREN, WS_CLIPSIBLINGS, + WS_EX_ACCEPTFILES, WS_EX_APPWINDOW, WS_EX_LAYERED, WS_EX_NOACTIVATE, + WS_EX_NOREDIRECTIONBITMAP, WS_EX_TOPMOST, WS_EX_TRANSPARENT, WS_EX_WINDOWEDGE, WS_MAXIMIZE, + WS_MAXIMIZEBOX, WS_MINIMIZE, WS_MINIMIZEBOX, WS_OVERLAPPEDWINDOW, WS_POPUP, WS_POPUP, + WS_SIZEBOX, WS_SYSMENU, WS_VISIBLE, + }, + ); +} diff --git a/winapi/src/lib.rs b/winapi/src/lib.rs new file mode 100644 index 0000000000..70e971d91c --- /dev/null +++ b/winapi/src/lib.rs @@ -0,0 +1,3 @@ +pub use windows; + +windows::include_bindings!(); \ No newline at end of file