diff options
Diffstat (limited to 'src/SFML/Window/Win32/WindowImplWin32.cpp')
-rwxr-xr-x | src/SFML/Window/Win32/WindowImplWin32.cpp | 223 |
1 files changed, 178 insertions, 45 deletions
diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp index e8e17fe..799834f 100755 --- a/src/SFML/Window/Win32/WindowImplWin32.cpp +++ b/src/SFML/Window/Win32/WindowImplWin32.cpp @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// // // SFML - Simple and Fast Multimedia Library -// Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org) +// Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org) // // This software is provided 'as-is', without any express or implied warranty. // In no event will the authors be held liable for any damages arising from the use of this software. @@ -31,12 +31,14 @@ #ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif +#ifdef WINVER + #undef WINVER +#endif #define _WIN32_WINDOWS 0x0501 #define _WIN32_WINNT 0x0501 #define WINVER 0x0501 #include <SFML/Window/Win32/WindowImplWin32.hpp> #include <SFML/Window/WindowStyle.hpp> -#include <GL/gl.h> #include <SFML/System/Err.hpp> #include <SFML/System/Utf.hpp> // dbt.h is lowercase here, as a cross-compile on linux with mingw-w64 @@ -45,6 +47,8 @@ #include <dbt.h> #include <vector> #include <cstring> +#include <iostream> +#include <string> // MinGW lacks the definition of some Win32 constants #ifndef XBUTTON1 @@ -84,14 +88,18 @@ namespace }; typedef HRESULT (WINAPI* SetProcessDpiAwarenessFuncType)(ProcessDpiAwareness); - SetProcessDpiAwarenessFuncType SetProcessDpiAwarenessFunc = reinterpret_cast<SetProcessDpiAwarenessFuncType>(GetProcAddress(shCoreDll, "SetProcessDpiAwareness")); + SetProcessDpiAwarenessFuncType SetProcessDpiAwarenessFunc = reinterpret_cast<SetProcessDpiAwarenessFuncType>(reinterpret_cast<void*>(GetProcAddress(shCoreDll, "SetProcessDpiAwareness"))); if (SetProcessDpiAwarenessFunc) { // We only check for E_INVALIDARG because we would get // E_ACCESSDENIED if the DPI was already set previously - // and S_OK means the call was successful - if (SetProcessDpiAwarenessFunc(ProcessSystemDpiAware) == E_INVALIDARG) + // and S_OK means the call was successful. + // We intentionally don't use Per Monitor V2 which can be + // enabled with SetProcessDpiAwarenessContext, because that + // would scale the title bar and thus change window size + // by default when moving the window between monitors. + if (SetProcessDpiAwarenessFunc(ProcessPerMonitorDpiAware) == E_INVALIDARG) { sf::err() << "Failed to set process DPI awareness" << std::endl; } @@ -112,7 +120,7 @@ namespace if (user32Dll) { typedef BOOL (WINAPI* SetProcessDPIAwareFuncType)(void); - SetProcessDPIAwareFuncType SetProcessDPIAwareFunc = reinterpret_cast<SetProcessDPIAwareFuncType>(GetProcAddress(user32Dll, "SetProcessDPIAware")); + SetProcessDPIAwareFuncType SetProcessDPIAwareFunc = reinterpret_cast<SetProcessDPIAwareFuncType>(reinterpret_cast<void*>(GetProcAddress(user32Dll, "SetProcessDPIAware"))); if (SetProcessDPIAwareFunc) { @@ -188,8 +196,8 @@ m_cursorGrabbed (m_fullscreen) HDC screenDC = GetDC(NULL); int left = (GetDeviceCaps(screenDC, HORZRES) - static_cast<int>(mode.width)) / 2; int top = (GetDeviceCaps(screenDC, VERTRES) - static_cast<int>(mode.height)) / 2; - int width = mode.width; - int height = mode.height; + int width = static_cast<int>(mode.width); + int height = static_cast<int>(mode.height); ReleaseDC(NULL, screenDC); // Choose the window style according to the Style parameter @@ -218,7 +226,7 @@ m_cursorGrabbed (m_fullscreen) m_handle = CreateWindowW(className, title.toWideString().c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this); // Register to receive device interface change notifications (used for joystick connection handling) - DEV_BROADCAST_DEVICEINTERFACE deviceInterface = {sizeof(DEV_BROADCAST_DEVICEINTERFACE), DBT_DEVTYP_DEVICEINTERFACE, 0, GUID_DEVINTERFACE_HID, 0}; + DEV_BROADCAST_DEVICEINTERFACE deviceInterface = {sizeof(DEV_BROADCAST_DEVICEINTERFACE), DBT_DEVTYP_DEVICEINTERFACE, 0, GUID_DEVINTERFACE_HID, {0}}; RegisterDeviceNotification(m_handle, &deviceInterface, DEVICE_NOTIFY_WINDOW_HANDLE); // If we're the first window handle, we only need to poll for joysticks when WM_DEVICECHANGE message is received @@ -331,7 +339,7 @@ Vector2u WindowImplWin32::getSize() const RECT rect; GetClientRect(m_handle, &rect); - return Vector2u(rect.right - rect.left, rect.bottom - rect.top); + return Vector2u(static_cast<unsigned int>(rect.right - rect.left), static_cast<unsigned int>(rect.bottom - rect.top)); } @@ -341,7 +349,7 @@ void WindowImplWin32::setSize(const Vector2u& size) // SetWindowPos wants the total size of the window (including title bar and borders), // so we have to compute it RECT rectangle = {0, 0, static_cast<long>(size.x), static_cast<long>(size.y)}; - AdjustWindowRect(&rectangle, GetWindowLong(m_handle, GWL_STYLE), false); + AdjustWindowRect(&rectangle, static_cast<DWORD>(GetWindowLongPtr(m_handle, GWL_STYLE)), false); int width = rectangle.right - rectangle.left; int height = rectangle.bottom - rectangle.top; @@ -374,13 +382,13 @@ void WindowImplWin32::setIcon(unsigned int width, unsigned int height, const Uin } // Create the icon from the pixel array - m_icon = CreateIcon(GetModuleHandleW(NULL), width, height, 1, 32, NULL, &iconPixels[0]); + m_icon = CreateIcon(GetModuleHandleW(NULL), static_cast<int>(width), static_cast<int>(height), 1, 32, NULL, &iconPixels[0]); // Set it as both big and small icon of the window if (m_icon) { - SendMessageW(m_handle, WM_SETICON, ICON_BIG, (LPARAM)m_icon); - SendMessageW(m_handle, WM_SETICON, ICON_SMALL, (LPARAM)m_icon); + SendMessageW(m_handle, WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(m_icon)); + SendMessageW(m_handle, WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(m_icon)); } else { @@ -399,14 +407,8 @@ void WindowImplWin32::setVisible(bool visible) //////////////////////////////////////////////////////////// void WindowImplWin32::setMouseCursorVisible(bool visible) { - // Don't call twice ShowCursor with the same parameter value; - // we don't want to increment/decrement the internal counter - // more than once. - if (visible != m_cursorVisible) - { - m_cursorVisible = visible; - ShowCursor(visible); - } + m_cursorVisible = visible; + SetCursor(m_cursorVisible ? m_lastCursor : NULL); } @@ -422,7 +424,7 @@ void WindowImplWin32::setMouseCursorGrabbed(bool grabbed) void WindowImplWin32::setMouseCursor(const CursorImpl& cursor) { m_lastCursor = cursor.m_cursor; - SetCursor(m_lastCursor); + SetCursor(m_cursorVisible ? m_lastCursor : NULL); } @@ -437,8 +439,9 @@ void WindowImplWin32::setKeyRepeatEnabled(bool enabled) void WindowImplWin32::requestFocus() { // Allow focus stealing only within the same process; compare PIDs of current and foreground window - DWORD thisPid = GetWindowThreadProcessId(m_handle, NULL); - DWORD foregroundPid = GetWindowThreadProcessId(GetForegroundWindow(), NULL); + DWORD thisPid, foregroundPid; + GetWindowThreadProcessId(m_handle, &thisPid); + GetWindowThreadProcessId(GetForegroundWindow(), &foregroundPid); if (thisPid == foregroundPid) { @@ -503,11 +506,11 @@ void WindowImplWin32::switchToFullscreen(const VideoMode& mode) } // Make the window flags compatible with fullscreen mode - SetWindowLongW(m_handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - SetWindowLongW(m_handle, GWL_EXSTYLE, WS_EX_APPWINDOW); + SetWindowLongPtr(m_handle, GWL_STYLE, static_cast<LONG_PTR>(WS_POPUP) | static_cast<LONG_PTR>(WS_CLIPCHILDREN) | static_cast<LONG_PTR>(WS_CLIPSIBLINGS)); + SetWindowLongPtr(m_handle, GWL_EXSTYLE, WS_EX_APPWINDOW); // Resize the window so that it fits the entire screen - SetWindowPos(m_handle, HWND_TOP, 0, 0, mode.width, mode.height, SWP_FRAMECHANGED); + SetWindowPos(m_handle, HWND_TOP, 0, 0, static_cast<int>(mode.width), static_cast<int>(mode.height), SWP_FRAMECHANGED); ShowWindow(m_handle, SW_SHOW); // Set "this" as the current fullscreen window @@ -564,6 +567,131 @@ void WindowImplWin32::grabCursor(bool grabbed) } } +//////////////////////////////////////////////////////////// +Keyboard::Scancode WindowImplWin32::toScancode(WPARAM wParam, LPARAM lParam) +{ + int code = (lParam & (0xFF << 16)) >> 16; + + // Retrieve the scancode from the VirtualKey for synthetic key messages + if (code == 0) + { + code = static_cast<int>(MapVirtualKey(static_cast<UINT>(wParam), MAPVK_VK_TO_VSC)); + } + + // Windows scancodes + // Reference: https://msdn.microsoft.com/en-us/library/aa299374(v=vs.60).aspx + switch (code) + { + case 1: return Keyboard::Scan::Escape; + case 2: return Keyboard::Scan::Num1; + case 3: return Keyboard::Scan::Num2; + case 4: return Keyboard::Scan::Num3; + case 5: return Keyboard::Scan::Num4; + case 6: return Keyboard::Scan::Num5; + case 7: return Keyboard::Scan::Num6; + case 8: return Keyboard::Scan::Num7; + case 9: return Keyboard::Scan::Num8; + case 10: return Keyboard::Scan::Num9; + case 11: return Keyboard::Scan::Num0; + case 12: return Keyboard::Scan::Hyphen; + case 13: return Keyboard::Scan::Equal; + case 14: return Keyboard::Scan::Backspace; + case 15: return Keyboard::Scan::Tab; + case 16: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::MediaPreviousTrack : Keyboard::Scan::Q; + case 17: return Keyboard::Scan::W; + case 18: return Keyboard::Scan::E; + case 19: return Keyboard::Scan::R; + case 20: return Keyboard::Scan::T; + case 21: return Keyboard::Scan::Y; + case 22: return Keyboard::Scan::U; + case 23: return Keyboard::Scan::I; + case 24: return Keyboard::Scan::O; + case 25: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::MediaNextTrack : Keyboard::Scan::P; + case 26: return Keyboard::Scan::LBracket; + case 27: return Keyboard::Scan::RBracket; + case 28: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::NumpadEnter : Keyboard::Scan::Enter; + case 29: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::RControl : Keyboard::Scan::LControl; + case 30: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Select : Keyboard::Scan::A; + case 31: return Keyboard::Scan::S; + case 32: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::VolumeMute : Keyboard::Scan::D; + case 33: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LaunchApplication1 : Keyboard::Scan::F; + case 34: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::MediaPlayPause : Keyboard::Scan::G; + case 35: return Keyboard::Scan::H; + case 36: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::MediaStop : Keyboard::Scan::J; + case 37: return Keyboard::Scan::K; + case 38: return Keyboard::Scan::L; + case 39: return Keyboard::Scan::Semicolon; + case 40: return Keyboard::Scan::Apostrophe; + case 41: return Keyboard::Scan::Grave; + case 42: return Keyboard::Scan::LShift; + case 43: return Keyboard::Scan::Backslash; + case 44: return Keyboard::Scan::Z; + case 45: return Keyboard::Scan::X; + case 46: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::VolumeDown : Keyboard::Scan::C; + case 47: return Keyboard::Scan::V; + case 48: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::VolumeUp : Keyboard::Scan::B; + case 49: return Keyboard::Scan::N; + case 50: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::HomePage : Keyboard::Scan::M; + case 51: return Keyboard::Scan::Comma; + case 52: return Keyboard::Scan::Period; + case 53: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::NumpadDivide : Keyboard::Scan::Slash; + case 54: return Keyboard::Scan::RShift; + case 55: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::PrintScreen : Keyboard::Scan::NumpadMultiply; + case 56: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::RAlt : Keyboard::Scan::LAlt; + case 57: return Keyboard::Scan::Space; + case 58: return Keyboard::Scan::CapsLock; + case 59: return Keyboard::Scan::F1; + case 60: return Keyboard::Scan::F2; + case 61: return Keyboard::Scan::F3; + case 62: return Keyboard::Scan::F4; + case 63: return Keyboard::Scan::F5; + case 64: return Keyboard::Scan::F6; + case 65: return Keyboard::Scan::F7; + case 66: return Keyboard::Scan::F8; + case 67: return Keyboard::Scan::F9; + case 68: return Keyboard::Scan::F10; + case 69: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::NumLock : Keyboard::Scan::Pause; + case 70: return Keyboard::Scan::ScrollLock; + case 71: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Home : Keyboard::Scan::Numpad7; + case 72: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Up : Keyboard::Scan::Numpad8; + case 73: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::PageUp : Keyboard::Scan::Numpad9; + case 74: return Keyboard::Scan::NumpadMinus; + case 75: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Left : Keyboard::Scan::Numpad4; + case 76: return Keyboard::Scan::Numpad5; + case 77: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Right : Keyboard::Scan::Numpad6; + case 78: return Keyboard::Scan::NumpadPlus; + case 79: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::End : Keyboard::Scan::Numpad1; + case 80: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Down : Keyboard::Scan::Numpad2; + case 81: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::PageDown : Keyboard::Scan::Numpad3; + case 82: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Insert : Keyboard::Scan::Numpad0; + case 83: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Delete : Keyboard::Scan::NumpadDecimal; + + case 86: return Keyboard::Scan::NonUsBackslash; + case 87: return Keyboard::Scan::F11; + case 88: return Keyboard::Scan::F12; + + case 91: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LSystem : Keyboard::Scan::Unknown; + case 92: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::RSystem : Keyboard::Scan::Unknown; + case 93: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Menu : Keyboard::Scan::Unknown; + + case 99: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Help : Keyboard::Scan::Unknown; + case 100: return Keyboard::Scan::F13; + case 101: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Search : Keyboard::Scan::F14; + case 102: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Favorites : Keyboard::Scan::F15; + case 103: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Refresh : Keyboard::Scan::F16; + case 104: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Stop : Keyboard::Scan::F17; + case 105: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Forward : Keyboard::Scan::F18; + case 106: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::Back : Keyboard::Scan::F19; + case 107: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LaunchApplication1 : Keyboard::Scan::F20; + case 108: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LaunchMail : Keyboard::Scan::F21; + case 109: return (HIWORD(lParam) & KF_EXTENDED) ? Keyboard::Scan::LaunchMediaSelect : Keyboard::Scan::F22; + case 110: return Keyboard::Scan::F23; + + case 118: return Keyboard::Scan::F24; + + default: return Keyboard::Scan::Unknown; + } +} //////////////////////////////////////////////////////////// void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam) @@ -586,8 +714,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam) case WM_SETCURSOR: { // The mouse has moved, if the cursor is in our window we must refresh the cursor - if (LOWORD(lParam) == HTCLIENT) - SetCursor(m_lastCursor); + if (LOWORD(lParam) == HTCLIENT) { + SetCursor(m_cursorVisible ? m_lastCursor : NULL); + } break; } @@ -732,12 +861,13 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam) if (m_keyRepeatEnabled || ((HIWORD(lParam) & KF_REPEAT) == 0)) { Event event; - event.type = Event::KeyPressed; - event.key.alt = HIWORD(GetKeyState(VK_MENU)) != 0; - event.key.control = HIWORD(GetKeyState(VK_CONTROL)) != 0; - event.key.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0; - event.key.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN)); - event.key.code = virtualKeyCodeToSF(wParam, lParam); + event.type = Event::KeyPressed; + event.key.alt = HIWORD(GetKeyState(VK_MENU)) != 0; + event.key.control = HIWORD(GetKeyState(VK_CONTROL)) != 0; + event.key.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0; + event.key.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN)); + event.key.code = virtualKeyCodeToSF(wParam, lParam); + event.key.scancode = toScancode(wParam, lParam); pushEvent(event); } break; @@ -748,12 +878,13 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam) case WM_SYSKEYUP: { Event event; - event.type = Event::KeyReleased; - event.key.alt = HIWORD(GetKeyState(VK_MENU)) != 0; - event.key.control = HIWORD(GetKeyState(VK_CONTROL)) != 0; - event.key.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0; - event.key.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN)); - event.key.code = virtualKeyCodeToSF(wParam, lParam); + event.type = Event::KeyReleased; + event.key.alt = HIWORD(GetKeyState(VK_MENU)) != 0; + event.key.control = HIWORD(GetKeyState(VK_CONTROL)) != 0; + event.key.shift = HIWORD(GetKeyState(VK_SHIFT)) != 0; + event.key.system = HIWORD(GetKeyState(VK_LWIN)) || HIWORD(GetKeyState(VK_RWIN)); + event.key.code = virtualKeyCodeToSF(wParam, lParam); + event.key.scancode = toScancode(wParam, lParam); pushEvent(event); break; } @@ -985,6 +1116,8 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam) pushEvent(event); break; } + + // Hardware configuration change event case WM_DEVICECHANGE: { // Some sort of device change has happened, update joystick connections @@ -1034,9 +1167,9 @@ Keyboard::Key WindowImplWin32::virtualKeyCodeToSF(WPARAM key, LPARAM flags) case VK_OEM_6: return Keyboard::RBracket; case VK_OEM_COMMA: return Keyboard::Comma; case VK_OEM_PERIOD: return Keyboard::Period; - case VK_OEM_7: return Keyboard::Quote; + case VK_OEM_7: return Keyboard::Apostrophe; case VK_OEM_5: return Keyboard::Backslash; - case VK_OEM_3: return Keyboard::Tilde; + case VK_OEM_3: return Keyboard::Grave; case VK_ESCAPE: return Keyboard::Escape; case VK_SPACE: return Keyboard::Space; case VK_RETURN: return Keyboard::Enter; @@ -1131,7 +1264,7 @@ LRESULT CALLBACK WindowImplWin32::globalOnEvent(HWND handle, UINT message, WPARA if (message == WM_CREATE) { // Get WindowImplWin32 instance (it was passed as the last argument of CreateWindow) - LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams; + LONG_PTR window = reinterpret_cast<LONG_PTR>(reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams); // Set as the "user data" parameter of the window SetWindowLongPtrW(handle, GWLP_USERDATA, window); |