Windows 显示设置为 150% 时仍显示 96 DPI
在运行 Win7 的笔记本电脑上,当我将显示设置设置为 125% 时,DPI 按预期显示为 120(同时使用 Graphics.DpiX 和 GetDeviceCaps)。然而,当显示为 150% 时,DPI 为 96(?!),就像在 100% 时一样。有谁知道 a) 为什么会出现这种情况 b) 除了检查 DPI 之外还有其他方法来检测显示是否设置为 100% 以外的值吗?我正在编写一个应用程序,我想在显示设置为 >= 150% 时显示一条消息。
谢谢。
On my laptop running Win7, when I set the display setting to 125%, the DPI shows up as 120 (using both graphics.DpiX and GetDeviceCaps) as expected. However, with the display at 150%, the DPI is 96 (?!), just like it is at 100%. Does anyone know a) why this is the case and b) is there any other way other than checking the DPI to detect if the display is set to anything other than 100%? I'm writing an app that I want to display a message when the display is set to >= 150%.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我刚刚遇到了同样的问题,尽管 StackOverflow 上有很多与 DPI 相关的问题,但我没有在一处找到所有答案。
问题 a) 的答案比较简单:
从 Windows Vista 开始,Windows 支持两种与 DPI 相关的大小调整。如果您在显示设置上单击“设置自定义文本大小 (DPI)”,您可以看到默认情况下,125% 使用 Windows XP 兼容的调整大小,而 150% 则不使用。
问题 b) 是一个比较棘手的问题。如果您搜索 StackOverflow,通常您可以找到以下答案:
但是,无论实际 DPI 设置如何,它都将始终返回 96,除非...
- 您使用 Windows XP 或在 DPI 设置中签入了兼容模式。 问题:您无法对用户强制执行。
- DWM 已关闭(您使用基本或经典主题)。 问题:同上。
- 在使用之前调用 SetProcessDPIAware 函数获取设备上限。 问题:此函数应该在所有其他渲染之前调用一次。如果您现有不支持 DPI 的应用程序,则更改感知会破坏整个外观。一旦调用该函数,它就无法关闭。
- 您在之前和之后调用 SetProcessDpiAwareness使用 GetDeviceCaps。 问题:此功能至少需要 Windows 8.1
真正的工作解决方案
似乎 GetDeviceCaps 函数 在 MSDN 上未完整记录。至少我发现 pinvoke.net 提到了一些可以获得的进一步选项通过函数。最后我提出了以下解决方案:
以及所需的附加代码:
I've just struggled the same problem, and though there are a lot of DPI-related questions on StackOverflow, I did not find all the answers in one place.
The answer to question a) is the easier one:
Starting with Windows Vista, Windows supports two kinds of DPI-related resizing. If you click on "Set custom text size (DPI)" on Display settings, you can see that by default, 125% uses the Windows XP-compatible resizing, while 150% doesn't.
Question b) is a trickier one. If you search StackOverflow, usually you can find the following answer:
However, it will return always 96, regardless of actual DPI settings, unless...
- You use Windows XP or the compatibility mode is checked in at DPI settings. Problem: you cannot enforce it at the users.
- DWM is turned off (you use Basic or Classic themes). Problem: same as above.
- You call SetProcessDPIAware function before using GetDeviceCaps. Problem: This function should be called once, before all other rendering. If you have an existing DPI-unaware app, changing the awareness will ruin the whole appearance. It cannot be turned off once you called the function.
- You call SetProcessDpiAwareness before and after using GetDeviceCaps. Problem: This function requires at least Windows 8.1
The real working solution
It seems that the GetDeviceCaps function is not fully documented at MSDN. At least I discovered that pinvoke.net mentions a few further options that can be obtained by the function. At the end I came out with the following solution:
And the required additional code:
在 Windows Vista 和 Windows 7 上,DPI 高于 120(我认为)以及它认为不支持 DPI 的应用程序,它们会切换到 DPI 虚拟化模式。
这正是您所看到的 - 应用程序认为它以 96dpi 运行,而 Windows 则将其放大并渲染所有内容更大(且更模糊)。
有关更多详细信息:https://learn.microsoft.com/en-gb/ windows/win32/hidpi
(原始链接(现在重定向到上面):http://msdn.microsoft.com/en-us /library/dd464660(VS.85).aspx#dpi_virtualization)
本文介绍了如何在每个应用程序的基础上禁用它。
On Windows Vista and Windows 7, with DPIs above 120 (I think) and applications that it considers to be non-DPI aware, they switch into DPI Virtualization Mode.
This does exactly what you're seeing - the application thinks it's running in 96dpi while Windows blows it up and renders everything bigger (and blurrier).
For more details: https://learn.microsoft.com/en-gb/windows/win32/hidpi
(original link (now redirects to above): http://msdn.microsoft.com/en-us/library/dd464660(VS.85).aspx#dpi_virtualization)
The article explains how to disable it on a per-application basis.