diff --git a/src/Nazara/Platform/Win32/WindowImpl.cpp b/src/Nazara/Platform/Win32/WindowImpl.cpp index 6ee3365ac..a8f8a91aa 100644 --- a/src/Nazara/Platform/Win32/WindowImpl.cpp +++ b/src/Nazara/Platform/Win32/WindowImpl.cpp @@ -5,6 +5,7 @@ // Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation #include +#include #include #include #include @@ -61,7 +62,7 @@ namespace Nz bool async = (style & WindowStyle_Threaded) != 0; bool fullscreen = (style & WindowStyle_Fullscreen) != 0; DWORD win32Style, win32StyleEx; - unsigned int x, y; + int x, y; unsigned int width = mode.width; unsigned int height = mode.height; if (fullscreen) @@ -117,8 +118,14 @@ namespace Nz width = rect.right-rect.left; height = rect.bottom-rect.top; - x = (GetSystemMetrics(SM_CXSCREEN) - width)/2; - y = (GetSystemMetrics(SM_CYSCREEN) - height)/2; + + // Grab desktop rect in order to center our window on the main display + // TODO: Handle multiple displays + RECT desktopRect; + GetClientRect(GetDesktopWindow(), &desktopRect); + + x = (desktopRect.right / 2) - (width / 2); + y = (desktopRect.bottom / 2) - (height / 2); } m_callback = 0; @@ -939,6 +946,9 @@ namespace Nz bool WindowImpl::Initialize() { + if (!SetProcessDpiAware()) + NazaraWarning("failed to make process DPI-aware"); + // Nous devons faire un type Unicode pour que la fenêtre le soit également // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx WNDCLASSW windowClass; @@ -961,6 +971,50 @@ namespace Nz UnregisterClassW(className, GetModuleHandle(nullptr)); } + bool WindowImpl::SetProcessDpiAware() + { + // MSDN : https://docs.microsoft.com/en-us/windows/win32/hidpi/setting-the-default-dpi-awareness-for-a-process + // This will work only for windows Vista & above + + HINSTANCE shcoreLib = LoadLibraryW(L"SHCore.dll"); + if (shcoreLib) + { + CallOnExit closeLibOnExit([&] { FreeLibrary(shcoreLib); }); + + /// shellscalingapi.h + enum PROCESS_DPI_AWARENESS + { + PROCESS_DPI_UNAWARE, + PROCESS_SYSTEM_DPI_AWARE, + PROCESS_PER_MONITOR_DPI_AWARE + }; + + using SetProcessDpiAwarenessFunc = HRESULT (WINAPI*)(PROCESS_DPI_AWARENESS); + auto SetProcessDpiAwareness = reinterpret_cast(GetProcAddress(shcoreLib, "SetProcessDpiAwareness")); + + if (SetProcessDpiAwareness) + { + HRESULT result = SetProcessDpiAwareness(PROCESS_SYSTEM_DPI_AWARE); + + if (result == S_OK || result == E_ACCESSDENIED) //< E_ACCESSDENIED means it has already been set, probably by the .exe manifest + return true; + } + } + + // If SetProcessDpiAwareness doesn't exist, we call old user32 function + HMODULE user32 = GetModuleHandleW(L"user32.dll"); + if (!user32) + return false; //< Shouldn't happen as user32 is linked + + using SetProcessDPIAwareFunc = BOOL (WINAPI*)(); + auto SetProcessDPIAware = reinterpret_cast(GetProcAddress(user32, "SetProcessDPIAware")); + + if (!SetProcessDPIAware || !SetProcessDPIAware()) + return false; + + return true; + } + Keyboard::Key WindowImpl::ConvertVirtualKey(WPARAM key, LPARAM flags) { switch (key) diff --git a/src/Nazara/Platform/Win32/WindowImpl.hpp b/src/Nazara/Platform/Win32/WindowImpl.hpp index e05a86fdf..668108032 100644 --- a/src/Nazara/Platform/Win32/WindowImpl.hpp +++ b/src/Nazara/Platform/Win32/WindowImpl.hpp @@ -84,6 +84,8 @@ namespace Nz bool HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam); void PrepareWindow(bool fullscreen); + static bool SetProcessDpiAware(); + static Keyboard::Key ConvertVirtualKey(WPARAM key, LPARAM flags); static LRESULT CALLBACK MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam); static UInt32 RetrieveStyle(HWND window);