简体   繁体   English

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

[英]Determine windows DPI settings programmatically?

we've got a problem with one of our non dpi aware MFC applications. 我们的一个非dpi感知MFC应用程序出了问题。
If you change the system setting to high dpi (eg 120 or 144 dpi), the application icon on the taskbar looks screwed up. 如果将系统设置更改为高dpi(例如120或144 dpi),则任务栏上的应用程序图标会显示为搞定。 Unfortunately, we have to register our own WNDCLASS for the mainframe, and in the WNDCLASS.hIcon member you have to set an icon. 不幸的是,我们必须为大型机注册我们自己的WNDCLASS ,而在WNDCLASS.hIcon成员中,您必须设置一个图标。 This icon is loaded using the LoadIcon function. 使用LoadIcon函数加载此图标。 And that function tries to load the image in a standard size (the same as being returned by GetSystemMetrics(SM_CXICON) ), which for 120dpi is 40x40 pixels. 并且该函数尝试以标准大小加载图像(与GetSystemMetrics(SM_CXICON)返回的相同),120dpi为40x40像素。 That's unfortunate because we do not provide an icon in that size. 这很不幸,因为我们没有提供这种尺寸的图标。 But there's a workaround for this: Since strangely, the dpi virtualization seems to not be in effect for 120 dpi, GetDeviceCaps(..., LOGPIXELSX) does indeed return 120 dpi and GetSystemMetrics(SM_CXICON) returns 40. So we can catch that and just load the icon in a different size. 但是有一个解决方法:从奇怪的是,dpi虚拟化似乎没有生效120 dpi, GetDeviceCaps(..., LOGPIXELSX)确实返回120 dpi而GetSystemMetrics(SM_CXICON)返回40.所以我们可以捕获它只需加载不同大小的图标。 But for 144 dpi it doesn't work, because now the virtualization seems to be in effect, and we get 96 dpi and 32 pixels, which again cause the icon to look very ugly. 但是对于144 dpi它不起作用,因为现在虚拟化似乎生效,我们得到96 dpi和32像素,这再次导致图标看起来非常难看。
I found out that if I just set the WNDCLASS.hIcon member to NULL , the icon shows up fine. 我发现如果我只是将WNDCLASS.hIcon成员设置为NULL ,则图标显示正常。 But I wonder if that's ok because according to MSDN: 但是我想知道是否可以,因为根据MSDN:

hIcon 惠康
Handle to the class icon. 处理类图标。 This member must be a handle to an icon resource. 该成员必须是图标资源的句柄。 If this member is NULL, the system provides a default icon. 如果此成员为NULL,则系统提供默认图标。

So can I count on the icon showing always up even if I set that member to NULL? 即使我将该成员设置为NULL,我也能依靠显示总是向上的图标吗? The other way would be to also load the icon in the correct size but for that I would have to know that the system is actually set to 144 dpi. 另一种方法是以正确的大小加载图标,但为此我必须知道系统实际上设置为144 dpi。 And there we are at my initial question. 在那里,我们处于初步问题。 Does anyone know if it is possible to determine the system's DPI setting (from within a dpi virtualized application)? 有谁知道是否可以确定系统的DPI设置(来自dpi虚拟化应用程序)? Note that I've also thought about doing something dirty like having a dpi aware application tell me the actual dpi and stuff like that, but I wanna avoid such things if possible. 请注意,我还想过做一些脏事,比如有一个dpi识别应用程序告诉我实际的dpi和类似的东西,但我想避免这样的事情,如果可能的话。

Best regards, 最好的祝福,

humbagumba humbagumba

Update: 更新:
I found out that setting the WNDCLASS.hIcon member to NULL is not a good idea, because then the icon of the mainframe is replaced by a default icon (even though it looks fine on the taskbar...) - I didn't notice that during my first test. 我发现将WNDCLASS.hIcon成员设置为NULL并不是一个好主意,因为大型图标被替换为默认图标(即使它在任务栏上看起来很好......) - 我没注意到在我第一次测试期间。

You will have to add a manifest to your program (or edit the existing one) to turn DPI Virtualization off. 您必须向程序添加清单(或编辑现有清单)才能关闭DPI虚拟化。 It should look like this: 它应该如下所示:

<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>

That's not unlikely to cause several new problems. 这不太可能导致几个新问题。 Everything you'd want to know about this is covered very well in this MSDN Library article . MSDN Library文章中非常清楚了解您想要了解的所有内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM