We help IT Professionals succeed at work.

get dpi of screen using platform invoke

pdschuller
pdschuller asked
on
5,282 Views
Last Modified: 2013-12-03
I need to get the dots per inch that a Windows form uses on the client.  From what I have found out so far, I believe that I have to use GetWindowDC using P/Invoke.  I am programming in C# but I know VB.NET and could probably work w that too.  I have zero experience with C or C+ or C++

The related examples I have found start with stuff like the following, which I grasp, but cannot figure out how to use.

using System.Runtime.InteropServices

[DllImport("user32.dll")]
public static extern IntPtr GetDC(Int32 ptr);

Thanks
pdschuller
Comment
Watch Question

jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
You can get that using 'GetDeviceCaps()':

[DllImport("user32.dll")]
public static extern IntPtr GetDC(Int32 ptr);
public static extern Int32 GetDeviceCaps(IntPtr hdc, Int32 index);

The index values you need to provide are

#define LOGPIXELSX    88    /* Logical pixels/inch in X */
#define LOGPIXELSY    90    /* Logical pixels/inch in Y */

Author

Commented:
Wow.  I must be dense.  I almost get it but not quite. I have zero experience with C or C+.
 - GetDeviceCaps wants two parameters.  What do I supply?
 - How do I use LOGPIXCELXS and LOGPIXCELSY?
 - What do I do with GetDC?
 - is the Int23 that GetDeviceCaps returns the dpi?
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
>> - GetDeviceCaps wants two parameters.  What do I supply?

The 1st parameter is the device context, that one is available via 'GetDC()'

>> - How do I use LOGPIXCELXS and LOGPIXCELSY?

That's just the symbolic names from the SDK, you can just pass 88 or 90 as the index value. Dunno anything about C# and how to declare constantes there ;o)

>> - is the Int23 that GetDeviceCaps returns the dpi?

Short 'n sweet: Yes. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/devcons_88s3.asp ("GetDeviceCaps")


Oh, and there is http://www.codeproject.com/csharp/dotnetprinterbounds.asp ("Getting the printer's REAL margin bounds in .NET") which shows how to use 'GetDeviceCaps()' in C#

Author

Commented:
Sorry, but I dont have enough experience to piece it together to get to the C# from what you are giving me.  I need someone to answer the original question who can put the answer in C#:

I need to get the dots per inch that a Windows form uses on the client.  From what I have found out so far, I believe that I have to use GetDeviceCaps using P/Invoke.  I understand P/Invoke generally but have never used it.  I am programming in C# but I know VB.NET and could probably work w that too.  I have zero experience with C or C+ or C++
CERTIFIED EXPERT
Top Expert 2012
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
Got it:
(jkr, reply with "Hmmm interesting."  or something and I will put the points on that post. Your 88 and 90 thing was indispensible.)

        [DllImport("coredll.dll")]   // NOTE: the dll name here can be different on your device this is for SmartPhone
        public static extern Int32 GetDeviceCaps(IntPtr hdc, Int32 index);

        //GetCapture is utilized to access the HWND of the form
        [DllImport("coredll.dll")]
        public static extern IntPtr GetCapture();

        public Form1()
        {
            InitializeComponent();
            IntPtr hwnd = GetCapture();  // this returns the "handle" which is of type IntPtr in C#

            // second parameter in GetDeviceCaps is 88 for X value and 90 for Y value,
            // but both values return the same dpi.  square pixcels
            label2.Text = "dpi = " + GetDeviceCaps(hwnd, 90).ToString();
        }

Author

Commented:
I posted my solution after your post.  That article never tells you (a newbie like me) how to get the handle (hDC) to pass to

     public DeviceResolution(IntPtr hDC)

That is what I had to find elsewhere as

//GetCapture is utilized to access the HWND of the form
        [DllImport("coredll.dll")]
        public static extern IntPtr GetCapture();

        IntPtr hwnd = GetCapture();  // this returns the "handle" which is of type IntPtr in C#
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.