Windows 显示设置为 150% 时仍显示 96 DPI

标签 windows dpi

在我运行 Win7 的笔记本电脑上,当我将显示设置设置为 125% 时,DPI 显示为 120(同时使用 graphics.DpiX 和 GetDeviceCaps)。但是,在显示为 150% 时,DPI 为 96(?!),就像在 100% 时一样。有谁知道 a) 为什么会这样,b) 除了检查 DPI 以检测显示是否设置为 100% 以外的任何其他方式之外,还有其他方法吗?我正在编写一个应用程序,我想在显示设置为 >= 150% 时显示一条消息。

谢谢。

最佳答案

我刚刚遇到了同样的问题,尽管 StackOverflow 上有很多与 DPI 相关的问题,但我并没有在一个地方找到所有答案。

问题 a) 的答案比较简单: 从 Windows Vista 开始,Windows 支持两种与 DPI 相关的调整大小。如果您在显示设置上单击“设置自定义文本大小 (DPI)”,您会看到默认情况下,125% 使用与 Windows XP 兼容的调整大小,而 150% 则不使用。

Custom DPI Settings


问题 b) 比较棘手。如果您搜索 StackOverflow,通常您可以找到以下答案:

    using (Graphics screen = Graphics.FromHwnd(IntPtr.Zero))
    {
        IntPtr hdc = screen.GetHdc();
        int dpiX = GetDeviceCaps(hdc, DeviceCaps.LOGPIXELSX);
        screen.ReleaseHdc(hdc);
    }

但是,无论实际 DPI 设置如何,它都会始终返回 96,除非......
- 您使用 Windows XP 或在 DPI 设置中检查了兼容模式。 问题:您无法对用户强制执行。
- DWM 已关闭(您使用基本或经典主题)。 问题:同上。
- 你调用SetProcessDPIAware使用 GetDeviceCaps 之前的功能。 问题:这个函数应该在所有其他渲染之前被调用一次。如果你有一个现有的 DPI-unaware 应用程序,改变意识会破坏整个外观。函数调用后无法关闭。
- 你调用SetProcessDpiAwareness使用 GetDeviceCaps 之前和之后。 问题:此功能至少需要Windows 8.1

真正可行的解决方案

似乎GetDeviceCaps function MSDN 上没有完整记录。至少我发现pinvoke.net提到了该函数可以获得的一些其他选项。最后我提出了以下解决方案:

public static int GetSystemDpi()
{
    using (Graphics screen = Graphics.FromHwnd(IntPtr.Zero))
    {
        IntPtr hdc = screen.GetHdc();

        int virtualWidth = GetDeviceCaps(hdc, DeviceCaps.HORZRES);
        int physicalWidth = GetDeviceCaps(hdc, DeviceCaps.DESKTOPHORZRES);
        screen.ReleaseHdc(hdc);

        return (int)(96f * physicalWidth / virtualWidth);
    }
}

以及所需的附加代码:

private enum DeviceCaps
{
    /// <summary>
    /// Logical pixels inch in X
    /// </summary>
    LOGPIXELSX = 88,

    /// <summary>
    /// Horizontal width in pixels
    /// </summary>
    HORZRES = 8,

    /// <summary>
    /// Horizontal width of entire desktop in pixels
    /// </summary>
    DESKTOPHORZRES = 118
}

/// <summary>
/// Retrieves device-specific information for the specified device.
/// </summary>
/// <param name="hdc">A handle to the DC.</param>
/// <param name="nIndex">The item to be returned.</param>
[DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hdc, DeviceCaps nIndex);

关于Windows 显示设置为 150% 时仍显示 96 DPI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7003316/

相关文章:

windows - Visual Studio Code 空白终端,无法输入/键入任何内容 [Windows 10]

python-imaging-library - 图像的 DPI 信息到底存储在哪里(Exif 除外)?

windows - 没有 QApplication 或 QCoreApplication 的信号槽连接

python - 保存 Pillow 图像时如何正确设置 DPI?

c# - 如何将图像连同 DPI 信息一起保存到剪贴板?

android - 一个可绘制文件夹中的不同大小的图像(具有相同的名称)

javascript - 以实际尺寸显示图像

c++ - 如何将 CString 传递给格式字符串 %s?

c - 在 Windows 中使用 C 的 UART

windows - 如何使用 Chef 在 Windows 上安装 Xamarin