Make Windows implementation DPI-Aware (+ fix issue with window position) (#322)

* WindowImpl : Fix windows centering on desktop

* WindowImpl : Make nazara DPI aware

* Refactor dpi stuff

* Minor aesthetic stuff

* More minor stuff

Co-authored-by: HardCPP <hardcpp@gmail.com>
This commit is contained in:
Jérôme Leclercq 2020-05-18 17:04:52 +02:00 committed by GitHub
parent db0b2ba27b
commit 8d8f44f4b9
2 changed files with 59 additions and 3 deletions

View File

@ -5,6 +5,7 @@
// Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation
#include <Nazara/Platform/Win32/WindowImpl.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/ConditionVariable.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Mutex.hpp>
@ -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<SetProcessDpiAwarenessFunc>(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<SetProcessDPIAwareFunc>(GetProcAddress(user32, "SetProcessDPIAware"));
if (!SetProcessDPIAware || !SetProcessDPIAware())
return false;
return true;
}
Keyboard::Key WindowImpl::ConvertVirtualKey(WPARAM key, LPARAM flags)
{
switch (key)

View File

@ -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);