Link to home
Start Free TrialLog in
Avatar of pdschuller
pdschullerFlag for United States of America

asked on

get dpi of screen using platform invoke

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
Avatar of jkr
jkr
Flag of Germany image

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 */
Avatar of pdschuller

ASKER

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?
>> - 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#
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++
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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();
        }
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#