【问题标题】:Per monitor DPI aware Windows system image list每个显示器 DPI 感知 Windows 系统图像列表
【发布时间】:2017-08-31 01:13:54
【问题描述】:

如何检索给定 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 小图标:

所以我希望 SHGetFileInfo(或类似)有一个 DPI 感知变体,就像其他函数的 DPI 感知变体一样:

【问题讨论】:

  • 啊,我有代码指示SHGetImageList 返回巨型 256x256 图标,如果这是您需要的。再看一遍我怀疑我最初是从here
  • @MickyD 因为那不是“正确”的解决方案。图标设计师将在巨型图标和小图标中添加更多细节,例如16px 他们省略了这个细节并创建了定制的变体。
  • HIMAGELIST hImageList = reinterpret_cast<HIMAGELIST>(IImageList); fwiw.
  • 只有 4 种尺寸,您只需根据 DPI 和适当的比例选择最接近的一种。

标签: winforms winapi dpi-aware


【解决方案1】:

作为一个快速的解决方案,我最终使用了SHGetImageList正如@MickyD 所建议的

如函数文档中所述(以及@JonathanPotter 的建议)

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

因此我使用SHGetImageList 来收集所有可用的系统映像列表大小,方法是调用0..SHIL_LAST

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    相关资源
    最近更新 更多