Skip to content

Commit 1f60bfc

Browse files
authored
Fix missing shcore.dll error on Windows 7 (flutter#30699)
1 parent 8498779 commit 1f60bfc

File tree

2 files changed

+67
-4
lines changed

2 files changed

+67
-4
lines changed

third_party/accessibility/ax/BUILD.gn

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ source_set("ax") {
9999
]
100100
libs = [
101101
"oleacc.lib",
102-
"shcore.lib",
103102
"uiautomationcore.lib",
104103
]
105104
}

third_party/accessibility/base/win/display.cc

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,75 @@
77
namespace base {
88
namespace win {
99

10+
namespace {
11+
12+
template <typename T>
13+
bool AssignProcAddress(HMODULE comBaseModule, const char* name, T*& outProc) {
14+
outProc = reinterpret_cast<T*>(GetProcAddress(comBaseModule, name));
15+
return *outProc != nullptr;
16+
}
17+
18+
// Helper class for supporting display scale factor lookup across Windows
19+
// versions, with fallbacks where these lookups are unavailable.
20+
class ScaleHelperWin32 {
21+
public:
22+
ScaleHelperWin32();
23+
~ScaleHelperWin32();
24+
25+
/// Returns the scale factor for the specified monitor. Sets |scale| to
26+
/// SCALE_100_PERCENT if the API is not available.
27+
HRESULT GetScaleFactorForMonitor(HMONITOR hmonitor,
28+
DEVICE_SCALE_FACTOR* scale) const;
29+
30+
private:
31+
using GetScaleFactorForMonitor_ =
32+
HRESULT __stdcall(HMONITOR hmonitor, DEVICE_SCALE_FACTOR* scale);
33+
34+
GetScaleFactorForMonitor_* get_scale_factor_for_monitor_ = nullptr;
35+
36+
HMODULE shlib_module_ = nullptr;
37+
bool scale_factor_for_monitor_supported_ = false;
38+
};
39+
40+
ScaleHelperWin32::ScaleHelperWin32() {
41+
if ((shlib_module_ = LoadLibraryA("Shcore.dll")) != nullptr) {
42+
scale_factor_for_monitor_supported_ =
43+
AssignProcAddress(shlib_module_, "GetScaleFactorForMonitor",
44+
get_scale_factor_for_monitor_);
45+
}
46+
}
47+
48+
ScaleHelperWin32::~ScaleHelperWin32() {
49+
if (shlib_module_ != nullptr) {
50+
FreeLibrary(shlib_module_);
51+
}
52+
}
53+
54+
HRESULT ScaleHelperWin32::GetScaleFactorForMonitor(
55+
HMONITOR hmonitor,
56+
DEVICE_SCALE_FACTOR* scale) const {
57+
if (hmonitor == nullptr || scale == nullptr) {
58+
return E_INVALIDARG;
59+
}
60+
if (!scale_factor_for_monitor_supported_) {
61+
*scale = SCALE_100_PERCENT;
62+
return S_OK;
63+
}
64+
return get_scale_factor_for_monitor_(hmonitor, scale);
65+
}
66+
67+
ScaleHelperWin32* GetHelper() {
68+
static ScaleHelperWin32* helper = new ScaleHelperWin32();
69+
return helper;
70+
}
71+
72+
} // namespace
73+
1074
float GetScaleFactorForHWND(HWND hwnd) {
1175
HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
12-
DEVICE_SCALE_FACTOR scale_factor = DEVICE_SCALE_FACTOR_INVALID;
13-
if (SUCCEEDED(GetScaleFactorForMonitor(monitor, &scale_factor))) {
14-
return ScaleFactorToFloat(scale_factor);
76+
DEVICE_SCALE_FACTOR scale = DEVICE_SCALE_FACTOR_INVALID;
77+
if (SUCCEEDED(GetHelper()->GetScaleFactorForMonitor(monitor, &scale))) {
78+
return ScaleFactorToFloat(scale);
1579
}
1680
return 1.0f;
1781
}

0 commit comments

Comments
 (0)