每个监视器DPI感知Windows系统映像列表

时间:2017-04-05 12:15:11

标签: winforms winapi dpi-aware

如何检索给定DPI的系统图像列表?

当应用程序具有系统DPI感知功能时,SHGetFileInfo和类似函数会返回正确缩放的系统映像列表的句柄。 C ++示例:

handle =
  SHGetFileInfo(L"", 0, &fileInfo, sizeof(fileInfo),
                SHGFI_SYSICONINDEX | (large ? SHGFI_LARGEICON : SHGFI_SMALLICON));

但是对于每个监视器的DPI感知,这还不够,因为应用程序可以在不使用系统DPI的监视器上运行(或者应用程序可以有多个窗口,每个窗口在不同的监视器上,具有不同的DPI)。

例如,在168 DPI(175%变焦)显示器上,使用标准96系统DPI,您可以获得小的未缩放16x16图标:

unscaled system icons

所以我希望,SHGetFileInfo(或类似的)有一个DPI感知变体,其他功能的DPI识别变体的方式如下:

1 个答案:

答案 0 :(得分:3)

作为一种快速解决方案,我最终使用了@ {MickyD 建议的SHGetImageList

如功能文档中所述(以及@JonathanPotter建议)

  

IImageList指针类型(例如ppv参数中返回的指针类型)可根据需要强制转换为HIMAGELIST;例如,用于列表视图。

因此,我使用SHGetImageList通过调用0..SHIL_LAST来收集所有可用的系统图像列表大小。

对于每个返回的图像列表,我使用ImageList_GetIconSize查询其图标大小并将其全部缓存。

然后,当特定DPI需要图像列表时,我选择最接近的可用尺寸。

一个明显的缺点是,在具有高系统DPI但具有一个低DPI监视器的多监视器系统上,无法为低DPI监视器检索合理大小的小图标。