none
GetDeviceCaps(HORZSIZE) is incorrect in Windows 7 RRS feed

  • Question

  • In Windows 7, GetDeviceCaps(HORZSIZE) and GetDeviceCaps(VERTSIZE) are too large by more than 50%. This is much more accurate running with the same hardware in Windows XP. Is there a way to correct this? I beleive this is also the root cause of Windows 7 drawing issues I am having in MM_HIMETRIC mapping mode. Utilities that read the EDID from the registry will return some entries that seem accurate and others with the +50% error. Is there a way to update the EDID to fix this?

    Thursday, February 16, 2012 7:27 PM

Answers

  • If your problem is "I draw a 50 millimeter length line in MM_HIMETRIC, and when I measure it on my screen, its length is not 50 millimeters but 90 (or 30)", then I'm afraid there is no solution to this, and you will have to change your software requirements.

    Drawing measures are only accurate on printing devices, not on screen devices.

    Drawing softwares generaly have zoom feature that let you zoom your drawing to fit to the screen (max drawing size = screen pixel size), or display 100% (1 pixel you draw in MM_TEXT is 1 pixel on screen). 100% zoom display is NOT 1 inch you draw is 1 inch on your screen.

    The only thing you can measure on screen are pixels. You may decide that 1 inch is 96 pixels, or 125, or whatever. It's up to you. Use a realistic value as much as you can. Don't expect GDI to tell you this, because it can't.

    You should not care if 96pixels is not really 1 inch on your screen. If you use another screen, or another resolution, it will be yet another size.

    • Proposed as answer by Pierre Morel-Fourrier Wednesday, February 29, 2012 5:00 AM
    • Marked as answer by Rob Pan Thursday, March 1, 2012 9:20 AM
    Wednesday, February 22, 2012 12:54 AM
  • As an FYI, Windows does "enlarge" the logical units (but not HORZSIZE or VERTSIZE from what we are seeing) to account for the fact that you read a monitor from some distance larger than the distance between you and a piece of paper (explained by Petzold in his legendary book "Programming Windows", if I'm not mistaken).  So in general, a logical inch or centimeter should always appear larger on screen than a physical inch or centimeter.  This is expected and by design.

    Jose R. MCP

    • Proposed as answer by Pierre Morel-Fourrier Wednesday, February 29, 2012 5:00 AM
    • Marked as answer by Rob Pan Thursday, March 1, 2012 9:20 AM
    Wednesday, February 22, 2012 1:04 AM

All replies

  • My Windows 7 64-bit box returns accurate values, I think (593 x 370 millimeters).  This value will be affected by the DPI setting for the user.  Have you tested with different DPI settings?

    Jose R. MCP

    Friday, February 17, 2012 7:34 PM
  • I get 564mm and 318mm for HORZSIZE and VERTSIZE respectively, in 96, 120, and 144 DPI. The actual size is closer to 340mm x 190mm. This appears to be a problem on every Windows 7 PC I have tried, 32 and 64 bit. I wonder what is different on your system.
    Monday, February 20, 2012 9:12 PM
  • GetDeviceCaps(HORZSIZE) cannot be used to get your monitor size. This value is not accurate for a screen DC. GDI doesn't know if a 17" or 21" screen is plugged in, if they both display the same resolution.

    GetDeviceCaps(HORZSIZE) can be used with a printer DC. Then it gives you the real size of the page. But don't use it with a Screen DC.

    This is how Windows behaves for decades, even in Windows XP. I believe your drawing problems are not linked to this problem.

    Monday, February 20, 2012 11:39 PM
  • Ah, ok.  Yes.  Don't think those values are actual values.  Those are LOGICAL measures.  Actual monitor measures are not available.  It is strange, though, that the values remain constant for different DPI's.

    Jose R. MCP

    Tuesday, February 21, 2012 12:02 AM
  • > It is strange, though, that the values remain constant for different DPI's
    One more reason not to use it? :)
     
    If you change DPI, your monitor size and resolution doesn't change =>
    it CAN'T work correctly.
     
    Tuesday, February 21, 2012 12:08 AM
  • Sorry, that doesn't add up for me.  If there's a monitor property that describes how many dots compose an inch, and there is a fixed resolution size in dots (pixels), varying the number of dots per logical inch necessarily has to alter the total logical width and height.  Does this mean I have a misconception somewhere?

    Jose R. MCP

    Tuesday, February 21, 2012 12:19 AM
  • Yes that doesn't add up. That's why GetDeviceCaps(HORZSIZE) doesn't
    work correctly for the screen. But we are living with this for a very
    long time. GDI is very old (25 years).
     
    Tuesday, February 21, 2012 3:47 AM
  • This issue is not only about the GetDeviceCaps(HORZSIZE/VERTSIZE)... GetDeviceCaps(HORZSIZE/VERTSIZE) was much more accurate in Windows XP (at least on my machines) but returns dimensions 60% larger on Windows 7, 32 and 64 bit OS, using the same hardware.

    I actually don't need to use GetDeviceCaps() but I have C++ source code that uses MM_HIMETRIC mapping mode for drawing reports with graphs to the screen and printer. The MM_HIMETRIC drawing is also affected by this 60% inaccuracy. I am in the process of working around this issue by using a different mapping mode but if someone could help me understand why this all changed in Windows 7, I may be able to avoid changing a significant amount of code.

    Thanks for all of the feedback!

    Tuesday, February 21, 2012 1:22 PM
  • If your problem is "I draw a 50 millimeter length line in MM_HIMETRIC, and when I measure it on my screen, its length is not 50 millimeters but 90 (or 30)", then I'm afraid there is no solution to this, and you will have to change your software requirements.

    Drawing measures are only accurate on printing devices, not on screen devices.

    Drawing softwares generaly have zoom feature that let you zoom your drawing to fit to the screen (max drawing size = screen pixel size), or display 100% (1 pixel you draw in MM_TEXT is 1 pixel on screen). 100% zoom display is NOT 1 inch you draw is 1 inch on your screen.

    The only thing you can measure on screen are pixels. You may decide that 1 inch is 96 pixels, or 125, or whatever. It's up to you. Use a realistic value as much as you can. Don't expect GDI to tell you this, because it can't.

    You should not care if 96pixels is not really 1 inch on your screen. If you use another screen, or another resolution, it will be yet another size.

    • Proposed as answer by Pierre Morel-Fourrier Wednesday, February 29, 2012 5:00 AM
    • Marked as answer by Rob Pan Thursday, March 1, 2012 9:20 AM
    Wednesday, February 22, 2012 12:54 AM
  • As an FYI, Windows does "enlarge" the logical units (but not HORZSIZE or VERTSIZE from what we are seeing) to account for the fact that you read a monitor from some distance larger than the distance between you and a piece of paper (explained by Petzold in his legendary book "Programming Windows", if I'm not mistaken).  So in general, a logical inch or centimeter should always appear larger on screen than a physical inch or centimeter.  This is expected and by design.

    Jose R. MCP

    • Proposed as answer by Pierre Morel-Fourrier Wednesday, February 29, 2012 5:00 AM
    • Marked as answer by Rob Pan Thursday, March 1, 2012 9:20 AM
    Wednesday, February 22, 2012 1:04 AM
  • I am a second programmer, working on the same project as the oringal poster...

    The issue that we have is that GetDeviceCaps is returning a completely bogus number.  We know that drawing a perfect 1 inch (as verified by a ruler) rectangle on the screen is not as straight forward as it appears... but that is not our goal or our problem.

    GetDeviceCaps(HORZSIZE) = 564mm (using a ruler I get 344mm)

    GetDeviceCaps(VERTSIZE) = 318mm (using a ruler I get 193mm)

    These numbers aren't even close.  Is there something that can be done to get good numbers from GetDeviceCaps?

    We have tried reading the EDID (http://thetweaker.wordpress.com/2011/11/13/reading-monitor-physical-dimensions-or-getting-the-edid-the-right-way/) from the registry and get closer numbers (34cm and 19cm) but this is in centimeters instead of millimeters and is therefore not quite as accurate.  It is a "close enough" solution, but it isn't perfect.

    Any ideas?

    Wednesday, February 22, 2012 3:38 PM
  • I have no solution as you seem to want a physical measure and I don't think GDI has ever meant to satisfy that requirement.  Like I said above, a logical inch should always be greater than a physical inch because Windows should compensate for the distance between the human eye and the monitor, which is larger than the one between the human eye and a piece of paper.  This should be reflected in in LOENGLISH, HIENGLISH, LOMETRIC and HIMETRIC as explained by Charles Petzold in his wonderful book.

    Jose R. MCP

    Wednesday, February 22, 2012 3:44 PM
  • Let me make sure that I'm understanding correctly...

    When I was looking at this with WindowsXP I was getting good values for GetDeviceCaps(HORZSIZE) and (VERTSIZE), but basically everyone thinks that I was just getting lucky here?  ...Even though I have been running my software and getting the same output on machines for multiple hardware configurations, for close to 10 years.  Now that I've transitioned into Windows 7 and I'm getting bogus information, the answer is that I should not trust the numbers because they've never been good and no one is suprised that my numbers were wrong.  Maybe the MSDN information for GetDeviceCaps should be changed to say that HORZSIZE and VERTSIZE report physical dimensions that "may or may not" relate to your monitor?

    Wednesday, February 22, 2012 8:16 PM
  • > Let me make sure that I'm understanding correctly...
    Yes you do.
    By the way, the values returned by GetDeviceCaps are returned by the
    *device driver*, not by Windows itself. Device drivers are written by
    hardware manufacturers.
     
    Thursday, February 23, 2012 1:13 AM
  • We have used this himetric mode for more then 12 years. Since Windows NT 4.0 on most monitors this gave pretty accurate results. Windows XP also did a great job. I currently have a laptop running windows 7, which gives almost 50% of the request size.. Even in Windows XP not all monitors gave correct EDID data.

    But I find it very strange that some people here have a strong believe this was pure luck..... For 12 years on hundreds of PC's.

    So if the same hardware gives back bogus results.. Then this is definately a bug in Windows 7. I dont think the documentation states this mode can not be used while displaying on a monitor. And it also didnt state they dropped the working feature in Windows 7.

    I think it is broken. And I would like to see a fix.

    Tuesday, March 27, 2012 7:50 PM
  • I would then say that your only option is paid support from Microsoft.  http://support.microsoft.com.

    Jose R. MCP

    Tuesday, March 27, 2012 9:15 PM
  • The post you link to now contains code to retrieve the monitor size *in milimeters*.
    Monday, January 21, 2013 4:27 PM
  • So is it really impossible to set the physical size of and object in a graphical user interface to be constant independent of the monitor used????
    Wednesday, November 27, 2013 1:53 PM