C# 如何在支持每监视器DPI的应用程序中获得System.Drawing.Graphics上的正确DPI?

C# 如何在支持每监视器DPI的应用程序中获得System.Drawing.Graphics上的正确DPI?,c#,winforms,dpi,C#,Winforms,Dpi,我正在以每监视器v2 DPI感知模式运行.NET桌面应用程序。正确绘制UI的WinForms部分需要所有绘制者都知道当前的DPI值。高级油漆工可以从HWND获得它,这是一个有效的解决方案。但是,较低级别的画家只有GDI+System.Drawing.Graphics对象 我正在努力制作系统.绘图.图形告诉正确的DPI。现在我看到了它的系统级DPI,而不管它的HWND的当前DPI如何。它的DpiX/DpiY属性是只读的,因此它们必须受到间接影响 Graphics有两种基本的方法来为控件创建它,一种

我正在以每监视器v2 DPI感知模式运行.NET桌面应用程序。正确绘制UI的WinForms部分需要所有绘制者都知道当前的DPI值。高级油漆工可以从
HWND
获得它,这是一个有效的解决方案。但是,较低级别的画家只有GDI+
System.Drawing.Graphics
对象

我正在努力制作
系统.绘图.图形
告诉正确的DPI。现在我看到了它的系统级DPI,而不管它的
HWND
的当前DPI如何。它的
DpiX
/
DpiY
属性是只读的,因此它们必须受到间接影响

Graphics
有两种基本的方法来为控件创建它,一种是使用它的
HWND
,另一种是它上面的
HDC
(可能来自
::GetDC
::BeginPaint
甚至
WM_-PAINT
args)。无论哪种方式,它都只有系统DPI值,而不是每监视器感知值。制作一个
位图
,对其进行适当的配置,并首先在其中绘制,然后在控件上进行blit,这可能会起作用,但这既不太整洁,也不太理想


因此:我看到WinForms控件的
HWND
具有良好的每监视器感知DPI,我想在
图形
对象
DpiX
/
DpiY
属性上看到相同的良好值,有办法吗?

现在应该有办法了。要在两个监视器上显示表单,必须创建两个实例。要将图形/图像加载到两种形式中,您只需要此图形的一个实例。
图形独立于显示器,内部不需要它(只需要一组像素)。

现在应该有办法了。要在两个监视器上显示表单,必须创建两个实例。要将图形/图像加载到两种形式中,您只需要此图形的一个实例。
图形独立于您的显示器和内部显示器,不需要它(只需要一组像素)。

对不起,我看不出此文本与问题有何关联。对不起,我的答案!我首先完全误解了你的问题。我深入研究了v2 DPI感知的、有趣的东西。但是我发现只有一种方法可以获得正确的DPI值:新的
Control.DeviceDpi
属性。如果您反映此代码,您会发现一个使用
GetDeviceCaps
和DC进行不安全调用的DpiHelper类。如果您不能直接调用控件属性,可能会有所帮助。是的,我可以获取DPI,我无法使其进入
图形
DpiX
DpiY
属性,这样无论谁在绘制时从中读取,都不会使用错误的值。迟早会有人使用这些属性并使UI失真。在正常情况下(因为你周围都有相同的DPI),你不会注意到这一点,只有当你将桌面遥控到盒子中或连接另一个像素密度的显示器时才会注意到。如果你喜欢阅读PMv2,你可能想更深入地阅读
DPI\u HOSTING\u BEHAVIOR\u MIXED
。这就是它变得非常奇怪的地方。特别是可以将系统插入PMv2的部分,但如果您尝试其他方式,则UI会脱落。抱歉,我看不出这篇文章与问题有何关联。抱歉,我的回答!我首先完全误解了你的问题。我深入研究了v2 DPI感知的、有趣的东西。但是我发现只有一种方法可以获得正确的DPI值:新的
Control.DeviceDpi
属性。如果您反映此代码,您会发现一个使用
GetDeviceCaps
和DC进行不安全调用的DpiHelper类。如果您不能直接调用控件属性,可能会有所帮助。是的,我可以获取DPI,我无法使其进入
图形
DpiX
DpiY
属性,这样无论谁在绘制时从中读取,都不会使用错误的值。迟早会有人使用这些属性并使UI失真。在正常情况下(因为你周围都有相同的DPI),你不会注意到这一点,只有当你将桌面遥控到盒子中或连接另一个像素密度的显示器时才会注意到。如果你喜欢阅读PMv2,你可能想更深入地阅读
DPI\u HOSTING\u BEHAVIOR\u MIXED
。这就是它变得非常奇怪的地方。特别是那个可以将系统插入PMv2的部分,但如果您尝试另一种方式,则UI的各个部分都会脱落。其中提到了如何获取实际DPI比例因子的解决方案,但这个答案已经过时了(它为
GetDC(NULL)
获取DPI,这对于在多个监视器上运行的应用程序,尤其是在混合DPI托管行为模式下运行的应用程序来说是不正确的)。无论如何,我有办法获得某个
HWND
的DPI,但我想要一个
Graphics
对象用该DPI正确初始化,并告诉所有各方。如果某个油漆工只有
图形
而没有
HWND
,那么就没有获得DPI的好方法。而
图形上错误的DPI值将产生误导。请看下面的答案。其中提到了如何获取实际DPI比例因子的解决方案,但这个答案已经过时了(它为
GetDC(NULL)
获取DPI,这对于在多个监视器上运行的应用程序,尤其是在混合DPI托管行为模式下运行的应用程序来说是不正确的)。无论如何,我有办法获得某个
HWND
的DPI,但我想要一个
Graphics
对象用该DPI正确初始化,并告诉所有各方。如果某个油漆工只有
图形
而没有
HWND
,那么就没有获得DPI的好方法。而
图形
上错误的DPI值会产生误导。