diff --git a/example/windows/Runner.vcxproj b/example/windows/Runner.vcxproj
index 220e5414a..3830d4177 100644
--- a/example/windows/Runner.vcxproj
+++ b/example/windows/Runner.vcxproj
@@ -99,7 +99,7 @@
4100
- flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)
+ flutter_windows.dll.lib;%(AdditionalDependencies)
@@ -197,7 +197,7 @@
true
true
- flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)
+ flutter_windows.dll.lib;%(AdditionalDependencies)
diff --git a/example/windows/runner.exe.manifest b/example/windows/runner.exe.manifest
index 41208def9..c977c4a42 100644
--- a/example/windows/runner.exe.manifest
+++ b/example/windows/runner.exe.manifest
@@ -17,4 +17,4 @@
-
\ No newline at end of file
+
diff --git a/example/windows/win32_window.cc b/example/windows/win32_window.cc
index 429216236..4c0a33c8c 100644
--- a/example/windows/win32_window.cc
+++ b/example/windows/win32_window.cc
@@ -4,33 +4,41 @@
#include "win32_window.h"
+#include
+
#include "resource.h"
-#include "shellscalingapi.h"
namespace {
-// the Windows DPI system is based on this
+// The Windows DPI system is based on this
// constant for machines running at 100% scaling.
constexpr int kBaseDpi = 96;
constexpr const wchar_t kClassName[] = L"CLASSNAME";
+using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
+
// Scale helper to convert logical scaler values to physical using passed in
// scale factor
int Scale(int source, double scale_factor) {
return static_cast(source * scale_factor);
}
-// Returns the DPI for the monitor containing, or closest to, |point|.
-UINT GetDpiForMonitorAtPoint(const Win32Window::Point &point) {
- const POINT target_point = {static_cast(point.x),
- static_cast(point.y)};
- HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
- UINT dpi_x = 0, dpi_y = 0;
- GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y);
- return dpi_x;
-}
+// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
+// This API is only needed for PerMonitor V1 awareness mode.
+void EnableFullDpiSupportIfAvailable(HWND hwnd) {
+ HMODULE user32_module = LoadLibraryA("User32.dll");
+ if (!user32_module) {
+ return;
+ }
+ auto enable_non_client_dpi_scaling =
+ reinterpret_cast(
+ GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
+
+ enable_non_client_dpi_scaling(hwnd);
+ FreeLibrary(user32_module);
+}
} // namespace
Win32Window::Win32Window() {}
@@ -43,8 +51,11 @@ bool Win32Window::CreateAndShow(const std::wstring &title, const Point &origin,
WNDCLASS window_class = RegisterWindowClass();
- double scale_factor =
- static_cast(GetDpiForMonitorAtPoint(origin)) / kBaseDpi;
+ const POINT target_point = {static_cast(origin.x),
+ static_cast(origin.y)};
+ HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
+ UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
+ double scale_factor = dpi / kBaseDpi;
HWND window = CreateWindow(
window_class.lpszClassName, title.c_str(),
@@ -81,6 +92,7 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message,
reinterpret_cast(window_struct->lpCreateParams));
auto that = static_cast(window_struct->lpCreateParams);
+ EnableFullDpiSupportIfAvailable(window);
that->window_handle_ = window;
} else if (Win32Window *that = GetThisFromHandle(window)) {
return that->MessageHandler(window, message, wparam, lparam);
@@ -105,6 +117,16 @@ Win32Window::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam,
Destroy();
return 0;
+ case WM_DPICHANGED: {
+ auto newRectSize = reinterpret_cast(lparam);
+ LONG newWidth = newRectSize->right - newRectSize->left;
+ LONG newHeight = newRectSize->bottom - newRectSize->top;
+
+ SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
+ newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
+
+ return 0;
+ }
case WM_SIZE:
RECT rect;
GetClientRect(hwnd, &rect);
diff --git a/plugins/window_size/windows/plugin.vcxproj b/plugins/window_size/windows/plugin.vcxproj
index 8cc0adedc..fcc79f3ae 100644
--- a/plugins/window_size/windows/plugin.vcxproj
+++ b/plugins/window_size/windows/plugin.vcxproj
@@ -111,7 +111,7 @@
Windows
true
- flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)
+ flutter_windows.dll.lib;%(AdditionalDependencies)
@@ -199,7 +199,7 @@
true
true
true
- flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)
+ flutter_windows.dll.lib;%(AdditionalDependencies)
diff --git a/plugins/window_size/windows/window_size_plugin.cpp b/plugins/window_size/windows/window_size_plugin.cpp
index 40febb408..cac5b3ce8 100644
--- a/plugins/window_size/windows/window_size_plugin.cpp
+++ b/plugins/window_size/windows/window_size_plugin.cpp
@@ -13,12 +13,16 @@
// limitations under the License.
#include "window_size_plugin.h"
-#include
+// windows.h must be imported before VersionHelpers.h or it will break
+// compilation.
+#include
+
+#include
#include
#include
#include
#include
-#include
+#include
#include
#include
@@ -65,9 +69,8 @@ EncodableValue GetPlatformChannelRepresentationForMonitor(HMONITOR monitor) {
MONITORINFO info;
info.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(monitor, &info);
- UINT dpi_x, dpi_y;
- GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y);
- double scale_factor = dpi_x / kBaseDpi;
+ UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
+ double scale_factor = dpi / kBaseDpi;
return EncodableValue(EncodableMap{
{EncodableValue(kFrameKey),
GetPlatformChannelRepresentationForRect(info.rcMonitor)},
@@ -94,8 +97,7 @@ EncodableValue GetPlatformChannelRepresentationForWindow(HWND window) {
RECT frame;
GetWindowRect(window, &frame);
HMONITOR window_monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
- // TODO: Support fallback for systems older than Windows 10(1607).
- double scale_factor = GetDpiForWindow(window) / kBaseDpi;
+ double scale_factor = FlutterDesktopGetDpiForHWND(window) / kBaseDpi;
return EncodableValue(EncodableMap{
{EncodableValue(kFrameKey),
diff --git a/testbed/windows/Runner.vcxproj b/testbed/windows/Runner.vcxproj
index 220e5414a..3830d4177 100644
--- a/testbed/windows/Runner.vcxproj
+++ b/testbed/windows/Runner.vcxproj
@@ -99,7 +99,7 @@
4100
- flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)
+ flutter_windows.dll.lib;%(AdditionalDependencies)
@@ -197,7 +197,7 @@
true
true
- flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)
+ flutter_windows.dll.lib;%(AdditionalDependencies)
diff --git a/testbed/windows/runner.exe.manifest b/testbed/windows/runner.exe.manifest
index 41208def9..c977c4a42 100644
--- a/testbed/windows/runner.exe.manifest
+++ b/testbed/windows/runner.exe.manifest
@@ -17,4 +17,4 @@
-
\ No newline at end of file
+
diff --git a/testbed/windows/win32_window.cc b/testbed/windows/win32_window.cc
index 429216236..86b94705c 100644
--- a/testbed/windows/win32_window.cc
+++ b/testbed/windows/win32_window.cc
@@ -4,8 +4,9 @@
#include "win32_window.h"
+#include
+
#include "resource.h"
-#include "shellscalingapi.h"
namespace {
@@ -15,22 +16,29 @@ constexpr int kBaseDpi = 96;
constexpr const wchar_t kClassName[] = L"CLASSNAME";
+using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
+
// Scale helper to convert logical scaler values to physical using passed in
// scale factor
int Scale(int source, double scale_factor) {
return static_cast(source * scale_factor);
}
-// Returns the DPI for the monitor containing, or closest to, |point|.
-UINT GetDpiForMonitorAtPoint(const Win32Window::Point &point) {
- const POINT target_point = {static_cast(point.x),
- static_cast(point.y)};
- HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
- UINT dpi_x = 0, dpi_y = 0;
- GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y);
- return dpi_x;
-}
+// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
+// This API is only needed for PerMonitor V1 awareness mode.
+void EnableFullDpiSupportIfAvailable(HWND hwnd) {
+ HMODULE user32_module = LoadLibraryA("User32.dll");
+ if (!user32_module) {
+ return;
+ }
+ auto enable_non_client_dpi_scaling =
+ reinterpret_cast(
+ GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
+
+ enable_non_client_dpi_scaling(hwnd);
+ FreeLibrary(user32_module);
+}
} // namespace
Win32Window::Win32Window() {}
@@ -43,8 +51,11 @@ bool Win32Window::CreateAndShow(const std::wstring &title, const Point &origin,
WNDCLASS window_class = RegisterWindowClass();
- double scale_factor =
- static_cast(GetDpiForMonitorAtPoint(origin)) / kBaseDpi;
+ const POINT target_point = {static_cast(origin.x),
+ static_cast(origin.y)};
+ HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
+ UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
+ double scale_factor = dpi / kBaseDpi;
HWND window = CreateWindow(
window_class.lpszClassName, title.c_str(),
@@ -81,6 +92,7 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message,
reinterpret_cast(window_struct->lpCreateParams));
auto that = static_cast(window_struct->lpCreateParams);
+ EnableFullDpiSupportIfAvailable(window);
that->window_handle_ = window;
} else if (Win32Window *that = GetThisFromHandle(window)) {
return that->MessageHandler(window, message, wparam, lparam);
@@ -105,6 +117,16 @@ Win32Window::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam,
Destroy();
return 0;
+ case WM_DPICHANGED: {
+ auto newRectSize = reinterpret_cast(lparam);
+ LONG newWidth = newRectSize->right - newRectSize->left;
+ LONG newHeight = newRectSize->bottom - newRectSize->top;
+
+ SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
+ newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
+
+ return 0;
+ }
case WM_SIZE:
RECT rect;
GetClientRect(hwnd, &rect);