From b9a131bae8b0858d111984a13410b8b5312656d3 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 1 Oct 2019 15:38:30 -0700 Subject: [PATCH 01/10] Support system dpi awareness for older versions of Windows --- shell/platform/windows/win32_dpi_helper.cc | 28 ++++++++++++++++++++-- shell/platform/windows/win32_dpi_helper.h | 15 ++++++++++++ shell/platform/windows/win32_window.cc | 25 ++++++++++++------- shell/platform/windows/win32_window.h | 2 +- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.cc b/shell/platform/windows/win32_dpi_helper.cc index c31044ce2c767..1b23430ca9ec2 100644 --- a/shell/platform/windows/win32_dpi_helper.cc +++ b/shell/platform/windows/win32_dpi_helper.cc @@ -1,5 +1,7 @@ #include "flutter/shell/platform/windows/win32_dpi_helper.h" +#include + namespace flutter { namespace { @@ -18,7 +20,6 @@ Win32DpiHelper::Win32DpiHelper() { if (user32_module_ == nullptr) { return; } - if (!AssignProcAddress(user32_module_, "EnableNonClientDpiScaling", enable_non_client_dpi_scaling_)) { return; @@ -33,7 +34,6 @@ Win32DpiHelper::Win32DpiHelper() { set_process_dpi_awareness_context_)) { return; } - permonitorv2_supported_ = true; } @@ -43,6 +43,22 @@ Win32DpiHelper::~Win32DpiHelper() { } } +// SetAwareness +// Check the available api. Start with v2, then fall back. +void Win32DpiHelper::SetDpiAwerenessAllVersions() { + if (permonitorv2_supported_) { + SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + } else { + std::cerr << "Per Monitor V2 DPI awareness is not supported on this " + "version of Windows. Setting System DPI awareness\n"; + AssignProcAddress(user32_module_, "GetDpiForSystem", get_dpi_for_system_); + AssignProcAddress(user32_module_, "SetProcessDpiAware", + set_process_dpi_aware_); + + SetProcessDPIAware(); + } +} + bool Win32DpiHelper::IsPerMonitorV2Available() { return permonitorv2_supported_; } @@ -61,6 +77,10 @@ UINT Win32DpiHelper::GetDpiForWindow(HWND hwnd) { return get_dpi_for_window_(hwnd); } +UINT Win32DpiHelper::GetDpiForSystem() { + return get_dpi_for_system_(); +} + BOOL Win32DpiHelper::SetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT context) { if (!permonitorv2_supported_) { @@ -69,4 +89,8 @@ BOOL Win32DpiHelper::SetProcessDpiAwarenessContext( return set_process_dpi_awareness_context_(context); } +BOOL Win32DpiHelper::SetProcessDpiAware() { + return set_process_dpi_aware_(); +} + } // namespace flutter diff --git a/shell/platform/windows/win32_dpi_helper.h b/shell/platform/windows/win32_dpi_helper.h index ddf51184bf956..8ba635cee0859 100644 --- a/shell/platform/windows/win32_dpi_helper.h +++ b/shell/platform/windows/win32_dpi_helper.h @@ -28,17 +28,32 @@ class Win32DpiHelper { // Wrapper for OS functionality to return the DPI for |HWND| UINT GetDpiForWindow(HWND); + // Wrapper for OS functionality to return the DPI for the System. Only used if + // Per Monitor V2 is not supported by the current Windows version. + UINT GetDpiForSystem(); + // Sets the current process to a specified DPI awareness context. BOOL SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT); + // Sets the current process to System-level DPI awareness. + BOOL SetProcessDpiAware(); + + // Sets the DPI awareness for the application. For versions >= Windows 1703, + // use Per Monitor V2. For any older versions, use System. + void SetDpiAwerenessAllVersions(); + private: using EnableNonClientDpiScaling_ = BOOL __stdcall(HWND); using GetDpiForWindow_ = UINT __stdcall(HWND); using SetProcessDpiAwarenessContext_ = BOOL __stdcall(DPI_AWARENESS_CONTEXT); + using SetProcessDpiAware_ = BOOL __stdcall(); + using GetDpiForSystem_ = UINT __stdcall(); EnableNonClientDpiScaling_* enable_non_client_dpi_scaling_ = nullptr; GetDpiForWindow_* get_dpi_for_window_ = nullptr; SetProcessDpiAwarenessContext_* set_process_dpi_awareness_context_ = nullptr; + SetProcessDpiAware_* set_process_dpi_aware_ = nullptr; + GetDpiForSystem_* get_dpi_for_system_ = nullptr; HMODULE user32_module_ = nullptr; bool permonitorv2_supported_ = false; diff --git a/shell/platform/windows/win32_window.cc b/shell/platform/windows/win32_window.cc index 43690efec2753..3462bd5067b09 100644 --- a/shell/platform/windows/win32_window.cc +++ b/shell/platform/windows/win32_window.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/shell/platform/windows/win32_window.h" +#include namespace flutter { @@ -26,7 +27,11 @@ void Win32Window::InitializeChild(const char* title, Destroy(); std::wstring converted_title = NarrowToWide(title); - WNDCLASS window_class = ResgisterWindowClass(converted_title); + // Set DPI awareness for all Windows versions. This call has to be made before + // the HWND is created. + dpi_helper_->SetDpiAwerenessAllVersions(); + + WNDCLASS window_class = RegisterWindowClass(converted_title); auto* result = CreateWindowEx( 0, window_class.lpszClassName, converted_title.c_str(), @@ -54,7 +59,7 @@ std::wstring Win32Window::NarrowToWide(const char* source) { return wideTitle; } -WNDCLASS Win32Window::ResgisterWindowClass(std::wstring& title) { +WNDCLASS Win32Window::RegisterWindowClass(std::wstring& title) { window_class_name_ = title; WNDCLASS window_class{}; @@ -83,13 +88,17 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, auto that = static_cast(cs->lpCreateParams); - // Since the application is running in Per-monitor V2 mode, turn on - // automatic titlebar scaling - BOOL result = that->dpi_helper_->EnableNonClientDpiScaling(window); - if (result != TRUE) { - OutputDebugString(L"Failed to enable non-client area autoscaling"); + if (that->dpi_helper_->IsPerMonitorV2Available()) { + // Since the application is running in Per-monitor V2 mode, turn on + // automatic titlebar scaling + BOOL result = that->dpi_helper_->EnableNonClientDpiScaling(window); + if (result != TRUE) { + OutputDebugString(L"Failed to enable non-client area autoscaling"); + } + that->current_dpi_ = that->dpi_helper_->GetDpiForWindow(window); + } else { + that->current_dpi_ = that->dpi_helper_->GetDpiForSystem(); } - that->current_dpi_ = that->dpi_helper_->GetDpiForWindow(window); that->window_handle_ = window; } else if (Win32Window* that = GetThisFromHandle(window)) { return that->MessageHandler(window, message, wparam, lparam); diff --git a/shell/platform/windows/win32_window.h b/shell/platform/windows/win32_window.h index e670a52519308..63a00c355dea6 100644 --- a/shell/platform/windows/win32_window.h +++ b/shell/platform/windows/win32_window.h @@ -57,7 +57,7 @@ class Win32Window { // Registers a window class with default style attributes, cursor and // icon. - WNDCLASS ResgisterWindowClass(std::wstring& title); + WNDCLASS RegisterWindowClass(std::wstring& title); // OS callback called by message pump. Handles the WM_NCCREATE message which // is passed when the non-client area is being created and enables automatic From f04b0b9848a8927b302ef3591bf4e4f863c0a4c5 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 1 Oct 2019 18:42:24 -0700 Subject: [PATCH 02/10] Fix documentation --- shell/platform/windows/win32_dpi_helper.cc | 2 -- shell/platform/windows/win32_window.cc | 1 - 2 files changed, 3 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.cc b/shell/platform/windows/win32_dpi_helper.cc index 1b23430ca9ec2..eaa6be5765e01 100644 --- a/shell/platform/windows/win32_dpi_helper.cc +++ b/shell/platform/windows/win32_dpi_helper.cc @@ -43,8 +43,6 @@ Win32DpiHelper::~Win32DpiHelper() { } } -// SetAwareness -// Check the available api. Start with v2, then fall back. void Win32DpiHelper::SetDpiAwerenessAllVersions() { if (permonitorv2_supported_) { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); diff --git a/shell/platform/windows/win32_window.cc b/shell/platform/windows/win32_window.cc index 3462bd5067b09..1cda8cba0fb6b 100644 --- a/shell/platform/windows/win32_window.cc +++ b/shell/platform/windows/win32_window.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "flutter/shell/platform/windows/win32_window.h" -#include namespace flutter { From 4f5eae92cc7a5e582f96d116db5587837b950e41 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Tue, 1 Oct 2019 18:46:26 -0700 Subject: [PATCH 03/10] Fix documentation --- shell/platform/windows/win32_dpi_helper.h | 3 +++ shell/platform/windows/win32_window.cc | 12 ++---------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.h b/shell/platform/windows/win32_dpi_helper.h index 8ba635cee0859..196affab9f2e2 100644 --- a/shell/platform/windows/win32_dpi_helper.h +++ b/shell/platform/windows/win32_dpi_helper.h @@ -40,6 +40,9 @@ class Win32DpiHelper { // Sets the DPI awareness for the application. For versions >= Windows 1703, // use Per Monitor V2. For any older versions, use System. + // + // This call is overriden if DPI awareness is stated in the application + // manifest. void SetDpiAwerenessAllVersions(); private: diff --git a/shell/platform/windows/win32_window.cc b/shell/platform/windows/win32_window.cc index 1cda8cba0fb6b..702827da2915b 100644 --- a/shell/platform/windows/win32_window.cc +++ b/shell/platform/windows/win32_window.cc @@ -6,16 +6,8 @@ namespace flutter { -Win32Window::Win32Window() { - // Assume Windows 10 1703 or greater for DPI handling. When running on a - // older release of Windows where this context doesn't exist, DPI calls will - // fail and Flutter rendering will be impacted until this is fixed. - // To handle downlevel correctly, dpi_helper must use the most recent DPI - // context available should be used: Windows 1703: Per-Monitor V2, 8.1: - // Per-Monitor V1, Windows 7: System See - // https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows - // for more information. -} +Win32Window::Win32Window() {} + Win32Window::~Win32Window() { Destroy(); } From 040295d23c46aa727087da3833364cf6409445db Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Wed, 2 Oct 2019 09:46:16 -0700 Subject: [PATCH 04/10] Address comments --- shell/platform/windows/win32_dpi_helper.cc | 34 +++++----------------- shell/platform/windows/win32_dpi_helper.h | 11 +++---- shell/platform/windows/win32_window.cc | 11 +++---- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.cc b/shell/platform/windows/win32_dpi_helper.cc index eaa6be5765e01..5843def87e43f 100644 --- a/shell/platform/windows/win32_dpi_helper.cc +++ b/shell/platform/windows/win32_dpi_helper.cc @@ -1,7 +1,5 @@ #include "flutter/shell/platform/windows/win32_dpi_helper.h" -#include - namespace flutter { namespace { @@ -43,17 +41,17 @@ Win32DpiHelper::~Win32DpiHelper() { } } -void Win32DpiHelper::SetDpiAwerenessAllVersions() { +BOOL Win32DpiHelper::SetDpiAwareness() { if (permonitorv2_supported_) { - SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + return set_process_dpi_awareness_context_( + DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + } else { - std::cerr << "Per Monitor V2 DPI awareness is not supported on this " - "version of Windows. Setting System DPI awareness\n"; AssignProcAddress(user32_module_, "GetDpiForSystem", get_dpi_for_system_); AssignProcAddress(user32_module_, "SetProcessDpiAware", set_process_dpi_aware_); - SetProcessDPIAware(); + return set_process_dpi_aware_(); } } @@ -68,27 +66,11 @@ BOOL Win32DpiHelper::EnableNonClientDpiScaling(HWND hwnd) { return enable_non_client_dpi_scaling_(hwnd); } -UINT Win32DpiHelper::GetDpiForWindow(HWND hwnd) { - if (!permonitorv2_supported_) { - return false; +UINT Win32DpiHelper::GetDpi(HWND hwnd) { + if (permonitorv2_supported_) { + return get_dpi_for_window_(hwnd); } - return get_dpi_for_window_(hwnd); -} - -UINT Win32DpiHelper::GetDpiForSystem() { return get_dpi_for_system_(); } -BOOL Win32DpiHelper::SetProcessDpiAwarenessContext( - DPI_AWARENESS_CONTEXT context) { - if (!permonitorv2_supported_) { - return false; - } - return set_process_dpi_awareness_context_(context); -} - -BOOL Win32DpiHelper::SetProcessDpiAware() { - return set_process_dpi_aware_(); -} - } // namespace flutter diff --git a/shell/platform/windows/win32_dpi_helper.h b/shell/platform/windows/win32_dpi_helper.h index 196affab9f2e2..3d55f72f6c9f2 100644 --- a/shell/platform/windows/win32_dpi_helper.h +++ b/shell/platform/windows/win32_dpi_helper.h @@ -25,12 +25,9 @@ class Win32DpiHelper { // Wrapper for OS functionality to turn on automatic window non-client scaling BOOL EnableNonClientDpiScaling(HWND); - // Wrapper for OS functionality to return the DPI for |HWND| - UINT GetDpiForWindow(HWND); - - // Wrapper for OS functionality to return the DPI for the System. Only used if - // Per Monitor V2 is not supported by the current Windows version. - UINT GetDpiForSystem(); + // Wrapper for OS functionality to return the DPI for |HWND| if Per Monitor V2 + // awareness has been set. Otherwise, returns the DPI for the System. + UINT GetDpi(HWND); // Sets the current process to a specified DPI awareness context. BOOL SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT); @@ -43,7 +40,7 @@ class Win32DpiHelper { // // This call is overriden if DPI awareness is stated in the application // manifest. - void SetDpiAwerenessAllVersions(); + BOOL SetDpiAwareness(); private: using EnableNonClientDpiScaling_ = BOOL __stdcall(HWND); diff --git a/shell/platform/windows/win32_window.cc b/shell/platform/windows/win32_window.cc index 702827da2915b..2b1c2bdc12141 100644 --- a/shell/platform/windows/win32_window.cc +++ b/shell/platform/windows/win32_window.cc @@ -20,7 +20,9 @@ void Win32Window::InitializeChild(const char* title, // Set DPI awareness for all Windows versions. This call has to be made before // the HWND is created. - dpi_helper_->SetDpiAwerenessAllVersions(); + if (!dpi_helper_->SetDpiAwareness()) { + OutputDebugString(L"Failed to set DPI awareness"); + } WNDCLASS window_class = RegisterWindowClass(converted_title); @@ -86,10 +88,9 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, if (result != TRUE) { OutputDebugString(L"Failed to enable non-client area autoscaling"); } - that->current_dpi_ = that->dpi_helper_->GetDpiForWindow(window); - } else { - that->current_dpi_ = that->dpi_helper_->GetDpiForSystem(); } + that->current_dpi_ = that->dpi_helper_->GetDpi(window); + that->window_handle_ = window; } else if (Win32Window* that = GetThisFromHandle(window)) { return that->MessageHandler(window, message, wparam, lparam); @@ -282,7 +283,7 @@ Win32Window::HandleDpiChange(HWND hwnd, // The DPI is only passed for DPI change messages on top level windows, // hence call function to get DPI if needed. if (uDpi == 0) { - uDpi = dpi_helper_->GetDpiForWindow(hwnd); + uDpi = dpi_helper_->GetDpi(hwnd); } current_dpi_ = uDpi; window->OnDpiScale(uDpi); From c6f3aae469a2909b9d5b1c2a3ea565d0a028c788 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Wed, 2 Oct 2019 09:46:57 -0700 Subject: [PATCH 05/10] Remove unused call --- shell/platform/windows/win32_dpi_helper.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.h b/shell/platform/windows/win32_dpi_helper.h index 3d55f72f6c9f2..6f06d8024d79e 100644 --- a/shell/platform/windows/win32_dpi_helper.h +++ b/shell/platform/windows/win32_dpi_helper.h @@ -29,9 +29,6 @@ class Win32DpiHelper { // awareness has been set. Otherwise, returns the DPI for the System. UINT GetDpi(HWND); - // Sets the current process to a specified DPI awareness context. - BOOL SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT); - // Sets the current process to System-level DPI awareness. BOOL SetProcessDpiAware(); From b2f68e370c4543cd98ff1ab6330bab709d663965 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Wed, 2 Oct 2019 09:51:04 -0700 Subject: [PATCH 06/10] Another one --- shell/platform/windows/win32_dpi_helper.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.h b/shell/platform/windows/win32_dpi_helper.h index 6f06d8024d79e..013f215e540ae 100644 --- a/shell/platform/windows/win32_dpi_helper.h +++ b/shell/platform/windows/win32_dpi_helper.h @@ -29,9 +29,6 @@ class Win32DpiHelper { // awareness has been set. Otherwise, returns the DPI for the System. UINT GetDpi(HWND); - // Sets the current process to System-level DPI awareness. - BOOL SetProcessDpiAware(); - // Sets the DPI awareness for the application. For versions >= Windows 1703, // use Per Monitor V2. For any older versions, use System. // From a9eb31cd0111218dd8800fe6752d133356c2186f Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Thu, 23 Jan 2020 14:58:50 -0800 Subject: [PATCH 07/10] Changed to get --- shell/platform/windows/win32_dpi_helper.cc | 66 ++++++++++------------ shell/platform/windows/win32_dpi_helper.h | 38 +++++-------- shell/platform/windows/win32_window.cc | 17 +----- 3 files changed, 43 insertions(+), 78 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.cc b/shell/platform/windows/win32_dpi_helper.cc index 5843def87e43f..f9d9c37487fc0 100644 --- a/shell/platform/windows/win32_dpi_helper.cc +++ b/shell/platform/windows/win32_dpi_helper.cc @@ -13,64 +13,56 @@ bool AssignProcAddress(HMODULE comBaseModule, const char* name, T*& outProc) { } // namespace Win32DpiHelper::Win32DpiHelper() { - // TODO ensure that this helper works correctly on downlevel builds. user32_module_ = LoadLibraryA("User32.dll"); if (user32_module_ == nullptr) { return; } - if (!AssignProcAddress(user32_module_, "EnableNonClientDpiScaling", - enable_non_client_dpi_scaling_)) { + shlib_module_ = LoadLibraryA("Shcore.dll"); + if (shlib_module_ == nullptr) { return; } - if (!AssignProcAddress(user32_module_, "GetDpiForWindow", - get_dpi_for_window_)) { - return; + if (AssignProcAddress(user32_module_, "GetDpiForWindow", + get_dpi_for_window_)) { + dpi_for_window_supported_ = true; } - if (!AssignProcAddress(user32_module_, "SetProcessDpiAwarenessContext", - set_process_dpi_awareness_context_)) { - return; + if (AssignProcAddress(shlib_module_, "GetDpiForMonitor", + get_dpi_for_monitor_) && + AssignProcAddress(user32_module_, "MonitorFromWindow", + monitor_from_window_)) { + dpi_for_monitor_supported_ = true; } - permonitorv2_supported_ = true; } Win32DpiHelper::~Win32DpiHelper() { if (user32_module_ != nullptr) { FreeLibrary(user32_module_); } -} - -BOOL Win32DpiHelper::SetDpiAwareness() { - if (permonitorv2_supported_) { - return set_process_dpi_awareness_context_( - DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - - } else { - AssignProcAddress(user32_module_, "GetDpiForSystem", get_dpi_for_system_); - AssignProcAddress(user32_module_, "SetProcessDpiAware", - set_process_dpi_aware_); - - return set_process_dpi_aware_(); - } -} - -bool Win32DpiHelper::IsPerMonitorV2Available() { - return permonitorv2_supported_; -} - -BOOL Win32DpiHelper::EnableNonClientDpiScaling(HWND hwnd) { - if (!permonitorv2_supported_) { - return false; + if (shlib_module_ != nullptr) { + FreeLibrary(shlib_module_); } - return enable_non_client_dpi_scaling_(hwnd); } UINT Win32DpiHelper::GetDpi(HWND hwnd) { - if (permonitorv2_supported_) { + // GetDpiForWindow returns the DPI for any awareness mode. If not available, fallback to a + // per monitor, system, or default DPI. + if (dpi_for_window_supported_) { return get_dpi_for_window_(hwnd); + } else if (dpi_for_monitor_supported_) { + HMONITOR monitor = monitor_from_window_(hwnd, MONITOR_DEFAULTTONEAREST); + UINT dpi_x = 0, dpi_y = 0; + HRESULT result = + get_dpi_for_monitor_(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); + if (result == S_OK) { + return dpi_x; + } + } else { + HDC hdc = GetDC(hwnd); + UINT dpi = GetDeviceCaps(hdc, LOGPIXELSX); + ReleaseDC(hwnd, hdc); + return dpi; } - return get_dpi_for_system_(); + return default_dpi_; } - } // namespace flutter diff --git a/shell/platform/windows/win32_dpi_helper.h b/shell/platform/windows/win32_dpi_helper.h index 013f215e540ae..7e67d8c1a47ba 100644 --- a/shell/platform/windows/win32_dpi_helper.h +++ b/shell/platform/windows/win32_dpi_helper.h @@ -18,39 +18,27 @@ class Win32DpiHelper { ~Win32DpiHelper(); - // Check if Windows Per Monitor V2 DPI scaling functionality is available on - // current system. - bool IsPerMonitorV2Available(); - - // Wrapper for OS functionality to turn on automatic window non-client scaling - BOOL EnableNonClientDpiScaling(HWND); - - // Wrapper for OS functionality to return the DPI for |HWND| if Per Monitor V2 - // awareness has been set. Otherwise, returns the DPI for the System. + // Returns the current DPI. Supports all DPI awareness modes, and is backward + // compatible down to Windows Vista. UINT GetDpi(HWND); - // Sets the DPI awareness for the application. For versions >= Windows 1703, - // use Per Monitor V2. For any older versions, use System. - // - // This call is overriden if DPI awareness is stated in the application - // manifest. - BOOL SetDpiAwareness(); - private: - using EnableNonClientDpiScaling_ = BOOL __stdcall(HWND); using GetDpiForWindow_ = UINT __stdcall(HWND); - using SetProcessDpiAwarenessContext_ = BOOL __stdcall(DPI_AWARENESS_CONTEXT); - using SetProcessDpiAware_ = BOOL __stdcall(); - using GetDpiForSystem_ = UINT __stdcall(); + using GetDpiForMonitor_ = HRESULT __stdcall(HMONITOR hmonitor, + MONITOR_DPI_TYPE dpiType, + UINT* dpiX, + UINT* dpiY); + using MonitorFromWindow_ = HMONITOR __stdcall(HWND hwnd, DWORD dwFlags); - EnableNonClientDpiScaling_* enable_non_client_dpi_scaling_ = nullptr; GetDpiForWindow_* get_dpi_for_window_ = nullptr; - SetProcessDpiAwarenessContext_* set_process_dpi_awareness_context_ = nullptr; - SetProcessDpiAware_* set_process_dpi_aware_ = nullptr; - GetDpiForSystem_* get_dpi_for_system_ = nullptr; + GetDpiForMonitor_* get_dpi_for_monitor_ = nullptr; + MonitorFromWindow_* monitor_from_window_ = nullptr; HMODULE user32_module_ = nullptr; - bool permonitorv2_supported_ = false; + HMODULE shlib_module_ = nullptr; + bool dpi_for_window_supported_ = false; + bool dpi_for_monitor_supported_ = false; + UINT default_dpi_ = 96; }; } // namespace flutter diff --git a/shell/platform/windows/win32_window.cc b/shell/platform/windows/win32_window.cc index 2b1c2bdc12141..3a63b1eb6ae52 100644 --- a/shell/platform/windows/win32_window.cc +++ b/shell/platform/windows/win32_window.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/shell/platform/windows/win32_window.h" +#include namespace flutter { @@ -18,12 +19,6 @@ void Win32Window::InitializeChild(const char* title, Destroy(); std::wstring converted_title = NarrowToWide(title); - // Set DPI awareness for all Windows versions. This call has to be made before - // the HWND is created. - if (!dpi_helper_->SetDpiAwareness()) { - OutputDebugString(L"Failed to set DPI awareness"); - } - WNDCLASS window_class = RegisterWindowClass(converted_title); auto* result = CreateWindowEx( @@ -80,17 +75,7 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, reinterpret_cast(cs->lpCreateParams)); auto that = static_cast(cs->lpCreateParams); - - if (that->dpi_helper_->IsPerMonitorV2Available()) { - // Since the application is running in Per-monitor V2 mode, turn on - // automatic titlebar scaling - BOOL result = that->dpi_helper_->EnableNonClientDpiScaling(window); - if (result != TRUE) { - OutputDebugString(L"Failed to enable non-client area autoscaling"); - } - } that->current_dpi_ = that->dpi_helper_->GetDpi(window); - that->window_handle_ = window; } else if (Win32Window* that = GetThisFromHandle(window)) { return that->MessageHandler(window, message, wparam, lparam); From 408d22d7846679e613ebb14b27e28ba14bb35d67 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Thu, 23 Jan 2020 15:09:10 -0800 Subject: [PATCH 08/10] Format --- shell/platform/windows/win32_dpi_helper.cc | 4 ++-- shell/platform/windows/win32_window.cc | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.cc b/shell/platform/windows/win32_dpi_helper.cc index f9d9c37487fc0..dd74d249be86a 100644 --- a/shell/platform/windows/win32_dpi_helper.cc +++ b/shell/platform/windows/win32_dpi_helper.cc @@ -45,8 +45,8 @@ Win32DpiHelper::~Win32DpiHelper() { } UINT Win32DpiHelper::GetDpi(HWND hwnd) { - // GetDpiForWindow returns the DPI for any awareness mode. If not available, fallback to a - // per monitor, system, or default DPI. + // GetDpiForWindow returns the DPI for any awareness mode. If not available, + // fallback to a per monitor, system, or default DPI. if (dpi_for_window_supported_) { return get_dpi_for_window_(hwnd); } else if (dpi_for_monitor_supported_) { diff --git a/shell/platform/windows/win32_window.cc b/shell/platform/windows/win32_window.cc index 3a63b1eb6ae52..e499bfbd129f8 100644 --- a/shell/platform/windows/win32_window.cc +++ b/shell/platform/windows/win32_window.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "flutter/shell/platform/windows/win32_window.h" -#include namespace flutter { From 61bc8105dfeeef3c159428b1ac25f2a42b2cd9dd Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Thu, 23 Jan 2020 15:11:18 -0800 Subject: [PATCH 09/10] Documentation --- shell/platform/windows/win32_dpi_helper.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.h b/shell/platform/windows/win32_dpi_helper.h index 7e67d8c1a47ba..2bbf69aa0ad4a 100644 --- a/shell/platform/windows/win32_dpi_helper.h +++ b/shell/platform/windows/win32_dpi_helper.h @@ -10,16 +10,16 @@ namespace flutter { -// A helper class for abstracting various Windows DPI related functions across -// Windows OS versions. +/// A helper class for abstracting various Windows DPI related functions across +/// Windows OS versions. class Win32DpiHelper { public: Win32DpiHelper(); ~Win32DpiHelper(); - // Returns the current DPI. Supports all DPI awareness modes, and is backward - // compatible down to Windows Vista. + /// Returns the current DPI. Supports all DPI awareness modes, and is backward + /// compatible down to Windows Vista. UINT GetDpi(HWND); private: From 1bb1a02c840bd31f5b4c2c8fea6d7b9289e98fc3 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Thu, 23 Jan 2020 16:43:15 -0800 Subject: [PATCH 10/10] Address review --- shell/platform/windows/win32_dpi_helper.cc | 31 ++++++++++++---------- shell/platform/windows/win32_dpi_helper.h | 1 - 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/shell/platform/windows/win32_dpi_helper.cc b/shell/platform/windows/win32_dpi_helper.cc index dd74d249be86a..40a79e72c31d9 100644 --- a/shell/platform/windows/win32_dpi_helper.cc +++ b/shell/platform/windows/win32_dpi_helper.cc @@ -4,6 +4,8 @@ namespace flutter { namespace { +constexpr UINT kDefaultDpi = 96; + template bool AssignProcAddress(HMODULE comBaseModule, const char* name, T*& outProc) { outProc = reinterpret_cast(GetProcAddress(comBaseModule, name)); @@ -17,14 +19,16 @@ Win32DpiHelper::Win32DpiHelper() { if (user32_module_ == nullptr) { return; } - shlib_module_ = LoadLibraryA("Shcore.dll"); - if (shlib_module_ == nullptr) { - return; - } if (AssignProcAddress(user32_module_, "GetDpiForWindow", get_dpi_for_window_)) { dpi_for_window_supported_ = true; + return; + } + + shlib_module_ = LoadLibraryA("Shcore.dll"); + if (shlib_module_ == nullptr) { + return; } if (AssignProcAddress(shlib_module_, "GetDpiForMonitor", @@ -49,20 +53,19 @@ UINT Win32DpiHelper::GetDpi(HWND hwnd) { // fallback to a per monitor, system, or default DPI. if (dpi_for_window_supported_) { return get_dpi_for_window_(hwnd); - } else if (dpi_for_monitor_supported_) { + } + + if (dpi_for_monitor_supported_) { HMONITOR monitor = monitor_from_window_(hwnd, MONITOR_DEFAULTTONEAREST); UINT dpi_x = 0, dpi_y = 0; HRESULT result = get_dpi_for_monitor_(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y); - if (result == S_OK) { - return dpi_x; - } - } else { - HDC hdc = GetDC(hwnd); - UINT dpi = GetDeviceCaps(hdc, LOGPIXELSX); - ReleaseDC(hwnd, hdc); - return dpi; + return SUCCEEDED(result) ? dpi_x : kDefaultDpi; } - return default_dpi_; + + HDC hdc = GetDC(hwnd); + UINT dpi = GetDeviceCaps(hdc, LOGPIXELSX); + ReleaseDC(hwnd, hdc); + return dpi; } } // namespace flutter diff --git a/shell/platform/windows/win32_dpi_helper.h b/shell/platform/windows/win32_dpi_helper.h index 2bbf69aa0ad4a..6ded84836713f 100644 --- a/shell/platform/windows/win32_dpi_helper.h +++ b/shell/platform/windows/win32_dpi_helper.h @@ -38,7 +38,6 @@ class Win32DpiHelper { HMODULE shlib_module_ = nullptr; bool dpi_for_window_supported_ = false; bool dpi_for_monitor_supported_ = false; - UINT default_dpi_ = 96; }; } // namespace flutter