I need to find out if the user's screen is set to normal 96 dpi (small size), large 120 dpi fonts, or something else. How do I do that in VB.NET (preferred) or C#?
-
A native way (written in Delphi but only using the native Windows API): `var dc: HDC; res: integer; begin dc := GetDC(0); if dc <> 0 then try res := GetDeviceCaps(dc, LOGPIXELSX); finally ReleaseDC(0, dc) end;` – Andreas Rejbrand May 21 '11 at 15:46
-
As Andreas suggests, you can also call the Windows API functions `GetDC` and `GetDeviceCaps` in order to get this information, but you'll have to use P/Invoke to get at them from a .NET application, and there's little benefit in doing so since the `Graphics` class has already wrapped this up so nicely in managed code. – Cody Gray - on strike May 21 '11 at 15:53
-
1But anyway, **thanks for [paying your taxes](http://blogs.msdn.com/b/oldnewthing/archive/2004/07/14/182971.aspx)**!! – Cody Gray - on strike May 21 '11 at 15:54
2 Answers
The best way is just to let the form resize itself automatically, based on the user's current DPI settings. To make it do that, just set the AutoScaleMode
property to AutoScaleMode.Dpi
and enable the AutoSize
property. You can do this either from the Properties Window in the designer or though code:
Public Sub New()
InitializeComponent()
Me.AutoScaleMode = AutoScaleMode.Dpi
Me.AutoSize = True
End Sub
Or, if you need to know this information while drawing (such as in the Paint
event handler method), you can extract the information from the DpiX
and DpiY
properties of the Graphics
class instance.
Private Sub myControl_Paint(ByVal sender As Object, ByVal e As PaintEventArgs)
Dim dpiX As Single = e.Graphics.DpiX
Dim dpiY As Single = e.Graphics.DpiY
' Do your drawing here
' ...
End Sub
Finally, if you need to determine the DPI level on-the-fly, you will have to create a temporary instance of the Graphics
class for your form, and check the DpiX
and DpiY
properties, as shown above. The CreateGraphics
method of the form class makes this very easy to do; just ensure that you wrap the creation of this object in a Using
statement to avoid memory leaks. Sample code:
Dim dpiX As Single
Dim dpiY As Single
Using g As Graphics = myForm.CreateGraphics()
dpiX = g.DpiX
dpiY = g.DpiY
End Using

- 239,200
- 50
- 490
- 574
-
Hi, and thanks! But does the dpi relates to the screen size (X / Y) or the font size (X only available) ? In other words, can I be certain that dpiX = dpiY in all cases? Otherwise, the new font would look stretched, wouldn't it? – Didier Levy May 22 '11 at 12:15
-
@Didier: Yes, normally dpiX will be equivalent to dpiY. If not, it would look stretched. It would depend on the resolution and the user's chosen DPI settings. The default small settings have dpiX = 96 and dpiY = 96. The default large settings have dpiX = 120 and dpiY = 120. You might check out [this MSDN page](http://msdn.microsoft.com/en-us/library/dd464646.aspx) on high-DPI applications. The linked [how-to page](http://msdn.microsoft.com/en-us/library/dd464660.aspx) is excellent. – Cody Gray - on strike May 22 '11 at 13:16