winforms - 每个显示器 DPI 感知的 Windows 系统镜像列表

标签 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 感知变体一样:

最佳答案

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

正如函数文档中提到的(以及@JonathanPotter的建议):

The IImageList pointer type, such as that returned in the ppv parameter, can be cast as an HIMAGELIST as needed; for example, for use in a list view.

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

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

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

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

关于winforms - 每个显示器 DPI 感知的 Windows 系统镜像列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43230907/

相关文章:

c# - C#图像处理非常慢

windows - 那么 Sleep() 和 this 是一样的吗?

winapi - 检查 Win32 TreeView 项会自动检查所有子项

windows - 在 user32.dll 中找不到 SetWindowsHookEx 程序

c# - DPI 意识 - 在一个版本中没有意识到,在另一个版本中有系统意识

c# - 从另一个正在运行的应用程序读取输出

c# - 正则表达式无法过滤 WinForms 中的 TextBox 字符

windows-xp - Windows XP 中的 DPI Aware 应用程序

c# - 如何获取每个表单的Text属性

c++ - 不同机器上的 Winapi 缩放