以编程方式确定Windows DPI设置?

时间:2010-08-17 13:07:28

标签: c++ mfc windows-7 dpi highdpi

我们的一个非dpi感知MFC应用程序出了问题 如果将系统设置更改为高dpi(例如120或144 dpi),则任务栏上的应用程序图标会显示为搞定。不幸的是,我们必须为大型机注册我们自己的WNDCLASS,并且在WNDCLASS.hIcon成员中您必须设置一个图标。使用LoadIcon功能加载此图标。并且该函数尝试以标准大小加载图像(与GetSystemMetrics(SM_CXICON)返回相同),120dpi为40x40像素。这很不幸,因为我们没有提供这种尺寸的图标。但是有一个解决方法:从奇怪的是,dpi虚拟化似乎不适用于120 dpi,GetDeviceCaps(..., LOGPIXELSX)确实返回120 dpi并且GetSystemMetrics(SM_CXICON)返回40.所以我们可以捕获它并且只是加载不同大小的图标。但是对于144 dpi它不起作用,因为现在虚拟化似乎已经生效,我们得到96 dpi和32像素,这再次导致图标看起来非常难看。
我发现如果我只是将WNDCLASS.hIcon成员设置为NULL,则图标显示正常。但我想知道这是否可以,因为根据MSDN:

  

hIcon
处理班级图标。这个   成员必须是图标的句柄   资源。如果此成员为NULL,则   system提供默认图标。

即使我将该成员设置为NULL,我也能依靠显示总是向上的图标吗? 另一种方法是以正确的大小加载图标,但为此我必须知道系统实际上设置为144 dpi。在那里,我们处于初步问题。 有谁知道是否可以确定系统的DPI设置(来自dpi虚拟化应用程序)?请注意,我还想过做一些脏事,比如有一个dpi识别应用程序告诉我实际的dpi和类似的东西,但我想尽可能避免这样的事情。

致以最诚挚的问候,

humbagumba

更新
我发现将WNDCLASS.hIcon成员设置为NULL不是一个好主意,因为大型图标被替换为默认图标(即使它在任务栏上看起来很好......) - 我在第一次测试时没有注意到。

1 个答案:

答案 0 :(得分:5)

您必须向程序添加清单(或编辑现有清单)才能关闭DPI虚拟化。它应该是这样的:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
</assembly>

这不太可能导致几个新问题。关于这一点的所有内容都在MSDN Library article中得到了很好的解释。