How do I retrieve system image list for given DPI?
When an application is system DPI-aware, the SHGetFileInfo
and similar functions return a handle to a correctly scaled system image list. C++ example:
handle =
SHGetFileInfo(L"", 0, &fileInfo, sizeof(fileInfo),
SHGFI_SYSICONINDEX | (large ? SHGFI_LARGEICON : SHGFI_SMALLICON));
But with per-monitor DPI awareness, that's not enough, as the application can run on a monitor that does not use system DPI (or the application can have multiple windows, each on different monitor, with different DPI).
For example, on 168 DPI (175% zoom) monitor, with standard 96 system DPI, you get small unscaled 16x16 icons:
So I'm hoping, that there's a DPI-aware variant to the SHGetFileInfo
(or similar), the way there are DPI aware variants of other functions like:
GetSystemMetricsForDpi
for GetSystemMetrics
;SystemParametersInfoForDpi
for SystemParametersInfo
;OpenThemeDataForDpi
for OpenThemeData
.Right-click the application, select Properties, select the Compatibility tab, and then select the Disable display scaling on high DPI settings check box.
To make your application dpi-aware, you must cancel automatic dpi scaling, and then adjust user interface elements to scale appropriately to the system dpi.
GDI DPI Scaling enables applications that are not DPI aware to become per monitor DPI aware. This policy setting lets you specify legacy applications that have GDI DPI Scaling turned on. If you enable this policy setting, GDI DPI Scaling is turned on for all legacy applications in the list.
As a quick solution, I ended up using SHGetImageList
, as suggested by @MickyD.
As mentioned in the function documentation (and as suggested by @JonathanPotter):
The
IImageList
pointer type, such as that returned in theppv
parameter, can be cast as anHIMAGELIST
as needed; for example, for use in a list view.
Hence I use the SHGetImageList
to collect all available system image lists sizes by calling it for 0..SHIL_LAST
.
For each returned image list, I query its icon size using ImageList_GetIconSize
and cache them all.
Then, when an image list is needed for a particular DPI, I pick the closest size available.
An obvious drawback is that on multi monitor systems with high system DPI, but with one low DPI monitor, one cannot retrieve reasonable size of small icons for the low DPI monitor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With