C++ 我需要制作多大尺寸的ImageList图标&;为我的应用加载(考虑更高的DPI)?

C++ 我需要制作多大尺寸的ImageList图标&;为我的应用加载(考虑更高的DPI)?,c++,windows,winapi,gdi,dpi,C++,Windows,Winapi,Gdi,Dpi,我有一个用样式创建的控件(或Win32中的) 我打算在其项目中显示图标,例如: 但问题是我需要制作和加载多大的图标 让我解释一下。从旧的Win32示例中,我可以看到每个人都使用15x15像素的图标创建图像列表。但问题是,在任何具有更高分辨率的现代PC上,它看起来都是可怕的像素化。因此,我正在寻找一种动态方法来确定CListCtrl的图像列表的适当大小 也是问题的第一部分,我最初应该制作多大的图标 编辑 PS:自从DPI扩展出现以来,您是如何发现的?我目前正在使用以下方法: //No error

我有一个用样式创建的控件(或Win32中的)

我打算在其项目中显示图标,例如:

但问题是我需要制作和加载多大的图标

让我解释一下。从旧的Win32示例中,我可以看到每个人都使用15x15像素的图标创建图像列表。但问题是,在任何具有更高分辨率的现代PC上,它看起来都是可怕的像素化。因此,我正在寻找一种动态方法来确定CListCtrl的图像列表的适当大小

也是问题的第一部分,我最初应该制作多大的图标

编辑 PS:自从DPI扩展出现以来,您是如何发现的?我目前正在使用以下方法:

//No error handling for brevity
HDC hDC = ::GetDC(hAppsMainWindowHandle);
int nCx = ::GetDeviceCaps(hDC, LOGPIXELSX);
int nCy = ::GetDeviceCaps(hDC, LOGPIXELSY);
::ReleaseDC(hAppsMainWindowHandle, hDC);

//I technically get horizontal & vertical scaling --
//can those be different?
double scalingCx = (double)nCx / 96.0;  //1.0 = 100%
double scalingCy = (double)nCy / 96.0;
字体缩放是否有所不同?

列表视图根据其模式使用“小”或“大”图像列表。在报告模式下,它使用“小”图像列表。您可以使用
SM_CXSMICON
SM_CYSMICON
度量来获取“小”图像的尺寸(对于“大”图像,使用
SM_CXSMICON
SM_cycon

请注意,如果您的应用程序不支持DPI,则返回的值将是虚拟的/缩放的,因此要获得准确的值,请确保它通过或DPI清单支持DPI

更新:我刚刚遇到了这个函数,在编写支持DPI的应用程序时可能会对您有用:


制作更大的图像并让API将其缩小到更小的大小。

报告样式列表视图需要小图标,即具有
SM\u CXSMICON
by
SM\u CYSMICON
度量的图标。假设您的应用程序具有高DPI感知能力,那么这些指标的实际值取决于用户选择的字体缩放或DPI设置。因此,在前面,您无法知道应该使用什么大小的图标。您必须在运行时查询系统指标,并使用适当大小的图标

现在,可执行文件中包含的图标大小取决于您希望支持的DPI设置。回到XP时代,您可以合理地预期会遇到100%和125%的字体缩放。现在,高密度显示面板很常见,你真的需要支持更大的比例。至少150%和200%,很可能是175%

我能找到的最接近指导原则的是这篇MSDN文章:

这篇文章是围绕Vista的时间框架撰写的,已经展示了它的时代。我认为你必须以这些文章为指导,适应当今的硬件环境

您还会发现,人们在上面列出的整数和我链接到的文章中,以字体缩放值运行他们的机器。我的一位同事的支持率是120%。有趣的是,这突出了我们代码中的各种bug,所以让某人来跟踪你的程序总是很有用的


当您在运行时构建映像列表时,请根据系统指标调整它们的大小。并尽量避免缩放图标。例如,如果系统指标显示18px图标,而您只有16px和20px图标,则创建一个新的18px图标。用透明像素填充图像,并将16px图标插入这张18px图像的中间。把它做成图标。这种方法将避免别名问题

不是真的
GetSystemMetrics(SM_CYSMICON)
对于默认的100%DPI,返回
16
,明显超过1像素。如果我加载并显示16像素高的图像列表,顶部的像素会被切断,或者图标会被挤压。显示的正确尺寸为15x15。但是我找不到它的任何系统度量值。15x15不是小图标的正确大小,16x16是。我在Win32列表视图中使用16x16(我不使用MFC),它们工作正常,不会挤压。我甚至使用20x20(或24x24,我现在忘记了),这会导致列表项的高度增加,而且它们也工作得很好。因此,这可能是CListCtrl的问题,而不是底层列表视图的问题。
LoadIconWithScaleDown
非常简洁。当然了。确实需要选择合适的图标大小。但仍然会导致不可避免的缩放瑕疵。好吧,你可能有道理。我认为15px是上下文菜单的图标高度。(我也必须缩放它们。)在Win32 API中,15x15不是标准的图像大小。标准尺寸为16x16、24x24、32x32和48x48.100%字体缩放,96dpi,小图标为16px,大图标为32px。任何地方都没有15px图标。谢谢。问题正如您所指出的,您不知道用户将以何种比例运行UI。如果我愿意,我可以在Windows8.1中指定115%。(有趣的是,即使是Windows资源管理器也不总是正确地处理它。)因此,人们无法用一组“漂亮”的Photoshop缩放图标来预测这些设置。不幸的是,即使在今天的操作系统中,微软仍然“得不到”并且没有像样的API来进行向下扩展<代码>LoadIconWithScaleDown正如您上面指出的,仍然非常糟糕,仍然会导致“看起来很滑稽”的工件(甚至在我的8.1版Windows资源管理器中)。我解释了如何处理这个问题。在运行时查找图标大小。找到最大的图标资源,你有比这个小。根据大小正确的较小资源创建一个新图标,并在边缘周围有一个透明边框。我的最后一段。当你这样做的时候,你就有了一个应用程序,它可以在任何一种非标准的缩放下工作。没有合适的方式来缩小规模。这是一项不可能完成的任务。这就是为什么你需要提供很多版本的图标。我的应用附带16、20、24、32和48px版本的工具栏图标。我使用所描述的技术来显示我能显示的最大的一个,适合小图标大小。它工作得很好。这真的是你唯一的选择。有一种方法可以缩小规模。只是微软没有API。Photoshop和其他软件可以很巧妙地做到这一点。无论如何,我更新了我原来的pos