diff --git a/third_party/accessibility/ax/BUILD.gn b/third_party/accessibility/ax/BUILD.gn index ef38c51dee33e..3c234b72344a7 100644 --- a/third_party/accessibility/ax/BUILD.gn +++ b/third_party/accessibility/ax/BUILD.gn @@ -99,7 +99,6 @@ source_set("ax") { ] libs = [ "oleacc.lib", - "shcore.lib", "uiautomationcore.lib", ] } diff --git a/third_party/accessibility/base/win/display.cc b/third_party/accessibility/base/win/display.cc index 64024e125e642..85c927dbec8c5 100644 --- a/third_party/accessibility/base/win/display.cc +++ b/third_party/accessibility/base/win/display.cc @@ -7,11 +7,75 @@ namespace base { namespace win { +namespace { + +template +bool AssignProcAddress(HMODULE comBaseModule, const char* name, T*& outProc) { + outProc = reinterpret_cast(GetProcAddress(comBaseModule, name)); + return *outProc != nullptr; +} + +// Helper class for supporting display scale factor lookup across Windows +// versions, with fallbacks where these lookups are unavailable. +class ScaleHelperWin32 { + public: + ScaleHelperWin32(); + ~ScaleHelperWin32(); + + /// Returns the scale factor for the specified monitor. Sets |scale| to + /// SCALE_100_PERCENT if the API is not available. + HRESULT GetScaleFactorForMonitor(HMONITOR hmonitor, + DEVICE_SCALE_FACTOR* scale) const; + + private: + using GetScaleFactorForMonitor_ = + HRESULT __stdcall(HMONITOR hmonitor, DEVICE_SCALE_FACTOR* scale); + + GetScaleFactorForMonitor_* get_scale_factor_for_monitor_ = nullptr; + + HMODULE shlib_module_ = nullptr; + bool scale_factor_for_monitor_supported_ = false; +}; + +ScaleHelperWin32::ScaleHelperWin32() { + if ((shlib_module_ = LoadLibraryA("Shcore.dll")) != nullptr) { + scale_factor_for_monitor_supported_ = + AssignProcAddress(shlib_module_, "GetScaleFactorForMonitor", + get_scale_factor_for_monitor_); + } +} + +ScaleHelperWin32::~ScaleHelperWin32() { + if (shlib_module_ != nullptr) { + FreeLibrary(shlib_module_); + } +} + +HRESULT ScaleHelperWin32::GetScaleFactorForMonitor( + HMONITOR hmonitor, + DEVICE_SCALE_FACTOR* scale) const { + if (hmonitor == nullptr || scale == nullptr) { + return E_INVALIDARG; + } + if (!scale_factor_for_monitor_supported_) { + *scale = SCALE_100_PERCENT; + return S_OK; + } + return get_scale_factor_for_monitor_(hmonitor, scale); +} + +ScaleHelperWin32* GetHelper() { + static ScaleHelperWin32* helper = new ScaleHelperWin32(); + return helper; +} + +} // namespace + float GetScaleFactorForHWND(HWND hwnd) { HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); - DEVICE_SCALE_FACTOR scale_factor = DEVICE_SCALE_FACTOR_INVALID; - if (SUCCEEDED(GetScaleFactorForMonitor(monitor, &scale_factor))) { - return ScaleFactorToFloat(scale_factor); + DEVICE_SCALE_FACTOR scale = DEVICE_SCALE_FACTOR_INVALID; + if (SUCCEEDED(GetHelper()->GetScaleFactorForMonitor(monitor, &scale))) { + return ScaleFactorToFloat(scale); } return 1.0f; }