7 #include "flutter/fml/macros.h"
13 constexpr UINT kDefaultDpi = 96;
18 constexpr UINT kEffectiveDpiMonitorType = 0;
24 bool AssignProcAddress(HMODULE comBaseModule,
const char* name, T*& outProc) {
25 outProc =
reinterpret_cast<T*
>(GetProcAddress(comBaseModule, name));
26 return *outProc !=
nullptr;
41 UINT GetDpiForWindow(HWND);
48 using GetDpiForWindow_ = UINT __stdcall(HWND);
49 using GetDpiForMonitor_ = HRESULT __stdcall(HMONITOR hmonitor,
53 using EnableNonClientDpiScaling_ = BOOL __stdcall(HWND hwnd);
55 GetDpiForWindow_* get_dpi_for_window_ =
nullptr;
56 GetDpiForMonitor_* get_dpi_for_monitor_ =
nullptr;
57 EnableNonClientDpiScaling_* enable_non_client_dpi_scaling_ =
nullptr;
59 HMODULE user32_module_ =
nullptr;
60 HMODULE shlib_module_ =
nullptr;
61 bool dpi_for_window_supported_ =
false;
62 bool dpi_for_monitor_supported_ =
false;
64 FML_DISALLOW_COPY_AND_ASSIGN(DpiHelper);
67 DpiHelper::DpiHelper() {
68 if ((user32_module_ = LoadLibraryA(
"User32.dll")) !=
nullptr) {
69 dpi_for_window_supported_ = (AssignProcAddress(
70 user32_module_,
"GetDpiForWindow", get_dpi_for_window_));
72 if ((shlib_module_ = LoadLibraryA(
"Shcore.dll")) !=
nullptr) {
73 dpi_for_monitor_supported_ = AssignProcAddress(
74 shlib_module_,
"GetDpiForMonitor", get_dpi_for_monitor_);
78 DpiHelper::~DpiHelper() {
79 if (user32_module_ !=
nullptr) {
80 FreeLibrary(user32_module_);
82 if (shlib_module_ !=
nullptr) {
83 FreeLibrary(shlib_module_);
87 UINT DpiHelper::GetDpiForWindow(HWND hwnd) {
91 if (dpi_for_window_supported_ && hwnd !=
nullptr) {
92 return get_dpi_for_window_(hwnd);
95 if (dpi_for_monitor_supported_) {
96 HMONITOR monitor =
nullptr;
97 if (hwnd !=
nullptr) {
98 monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
102 HDC hdc = GetDC(hwnd);
103 UINT dpi = GetDeviceCaps(hdc, LOGPIXELSX);
104 ReleaseDC(hwnd, hdc);
109 if (dpi_for_monitor_supported_) {
110 if (monitor ==
nullptr) {
111 const POINT target_point = {0, 0};
112 monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTOPRIMARY);
114 UINT dpi_x = 0, dpi_y = 0;
116 get_dpi_for_monitor_(monitor, kEffectiveDpiMonitorType, &dpi_x, &dpi_y);
117 if (SUCCEEDED(result)) {
124 DpiHelper* GetHelper() {
125 static DpiHelper* dpi_helper =
new DpiHelper();
131 return GetHelper()->GetDpiForWindow(hwnd);
135 return GetHelper()->GetDpiForMonitor(monitor);