Skip to content
This repository was archived by the owner on Dec 3, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example/windows/Runner.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>
Expand Down Expand Up @@ -197,7 +197,7 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>
Expand Down
2 changes: 1 addition & 1 deletion example/windows/runner.exe.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
</assembly>
</assembly>
48 changes: 35 additions & 13 deletions example/windows/win32_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,41 @@

#include "win32_window.h"

#include <flutter_windows.h>

#include "resource.h"
#include "shellscalingapi.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumably you also need to make a project change to stop linking directly to Shcore.lib?


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<int>(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<LONG>(point.x),
static_cast<LONG>(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<EnableNonClientDpiScaling *>(
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));

enable_non_client_dpi_scaling(hwnd);

FreeLibrary(user32_module);
}
} // namespace

Win32Window::Win32Window() {}
Expand All @@ -43,8 +51,11 @@ bool Win32Window::CreateAndShow(const std::wstring &title, const Point &origin,

WNDCLASS window_class = RegisterWindowClass();

double scale_factor =
static_cast<double>(GetDpiForMonitorAtPoint(origin)) / kBaseDpi;
const POINT target_point = {static_cast<LONG>(origin.x),
static_cast<LONG>(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(),
Expand Down Expand Up @@ -81,6 +92,7 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message,
reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams));

auto that = static_cast<Win32Window *>(window_struct->lpCreateParams);
EnableFullDpiSupportIfAvailable(window);
that->window_handle_ = window;
} else if (Win32Window *that = GetThisFromHandle(window)) {
return that->MessageHandler(window, message, wparam, lparam);
Expand All @@ -105,6 +117,16 @@ Win32Window::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam,
Destroy();
return 0;

case WM_DPICHANGED: {
auto newRectSize = reinterpret_cast<RECT *>(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);
Expand Down
4 changes: 2 additions & 2 deletions plugins/window_size/windows/plugin.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>
Expand Down Expand Up @@ -199,7 +199,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>
Expand Down
16 changes: 9 additions & 7 deletions plugins/window_size/windows/window_size_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
// limitations under the License.
#include "window_size_plugin.h"

#include <ShellScalingApi.h>
// windows.h must be imported before VersionHelpers.h or it will break
// compilation.
#include <windows.h>

#include <VersionHelpers.h>
#include <flutter/flutter_view.h>
#include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h>
#include <windows.h>
#include <flutter_windows.h>

#include <codecvt>
#include <memory>
Expand Down Expand Up @@ -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)},
Expand All @@ -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),
Expand Down
4 changes: 2 additions & 2 deletions testbed/windows/Runner.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
<DisableSpecificWarnings>4100</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalDependencies>flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>
Expand Down Expand Up @@ -197,7 +197,7 @@
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>flutter_windows.dll.lib;Shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>flutter_windows.dll.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>
Expand Down
2 changes: 1 addition & 1 deletion testbed/windows/runner.exe.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
</application>
</compatibility>
</assembly>
</assembly>
46 changes: 34 additions & 12 deletions testbed/windows/win32_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

#include "win32_window.h"

#include <flutter_windows.h>

#include "resource.h"
#include "shellscalingapi.h"

namespace {

Expand All @@ -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<int>(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<LONG>(point.x),
static_cast<LONG>(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<EnableNonClientDpiScaling *>(
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));

enable_non_client_dpi_scaling(hwnd);

FreeLibrary(user32_module);
}
} // namespace

Win32Window::Win32Window() {}
Expand All @@ -43,8 +51,11 @@ bool Win32Window::CreateAndShow(const std::wstring &title, const Point &origin,

WNDCLASS window_class = RegisterWindowClass();

double scale_factor =
static_cast<double>(GetDpiForMonitorAtPoint(origin)) / kBaseDpi;
const POINT target_point = {static_cast<LONG>(origin.x),
static_cast<LONG>(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(),
Expand Down Expand Up @@ -81,6 +92,7 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message,
reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams));

auto that = static_cast<Win32Window *>(window_struct->lpCreateParams);
EnableFullDpiSupportIfAvailable(window);
that->window_handle_ = window;
} else if (Win32Window *that = GetThisFromHandle(window)) {
return that->MessageHandler(window, message, wparam, lparam);
Expand All @@ -105,6 +117,16 @@ Win32Window::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam,
Destroy();
return 0;

case WM_DPICHANGED: {
auto newRectSize = reinterpret_cast<RECT *>(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);
Expand Down