Winforms: 为什么Graphics.DpiX/DpiY总是返回96

本文介绍了Windows中DPI设置的工作原理及其对应用程序的影响。详细解释了为何修改DPI后,通过System.Drawing.Graphics获取的DPI值仍为默认值96的原因,并提供了如何正确获取实际DPI值的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、问题描述

Windows中缺省的DPI值为96。在Vista中,我们把DPI设为150%,也就是144。可如果此时我们去获取属性System.Drawing.Graphics.DpiX或者System.Drawing.Graphics.DpiY的值,我们发现得到的仍然是96,而不是144

二、原因分析

修改WindowsDPI值,所有窗口的字体会变大,因此窗口的布局(Layout)也有可能不同。Windows程序员可以根据WindowsDPI设置去定义窗口的布局,但我们发现很多程序员在根据DPI定义窗口布局的时候遇到了很多问题。所以Windows的解决办法就是不建议程序员根据DPI设置调整窗口布局,Windows会根据系统设置自动按比例放大窗口的所有元素(包括文字和控件)。这样虽然降低了程序员的灵活性和自主性,但至少保证了窗口布局在所有DPI设置时都是正确的。

于是从Vista开始,Windows添加了一个叫SetProcessDPIAwareAPI。缺省的情况下,该函数不被调用,因此我们的进程不知道DPI已经修改,那我们得到的DPI也总是其缺省值96了。

三、建议

如前所述,我们不建议程序员试图去获取DPI设置值,并根据该值去调整窗口布局。如果确实需要得到系统的DPI的设置值,我们必须调用API SetProcessDPIAware。下面是一个例子:

public class Utility

{

private const int LOGPIXELSX = 88;

private const int LOGPIXELSY = 90;

public static int DpiX

{

get

{

if (Environment.OSVersion.Version.Major >= 6)

SetProcessDPIAware();

IntPtr hDC = GetDC(new HandleRef(null, IntPtr.Zero));

return GetDeviceCaps(hDC, LOGPIXELSX);

}

}

public static int DpiY

{

get

{

if (Environment.OSVersion.Version.Major >= 6)

SetProcessDPIAware();

IntPtr hDC = GetDC(new HandleRef(null, IntPtr.Zero));

return GetDeviceCaps(hDC, LOGPIXELSY);

}

}

[DllImport("user32.dll")]

private extern static bool SetProcessDPIAware();

[DllImport("user32.dll")]

private extern static IntPtr GetDC(HandleRef hWnd);

[DllImport("gdi32.dll")]

private extern static int GetDeviceCaps(IntPtr hdc, int nIndex);

}

上述代码先得到显示器的DC,然后得到该DCX方向和Y方向的DPI值。另外值得注意的是,由于API SetProcessDPIAwareVista才被引入,所以在调用该API之前,我们需要判断Windows的版本号。Vista的主版本号是6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值