Reputation: 729
Under Windows 7, I use the following code to get the physical width in mm of screen. The 'hSize' is 482 which is much larger than the actual size which is about 310 (measured with ruler). Why is that?
HDC screen = GetDC(NULL);
int hSize=GetDeviceCaps(screen,HORZSIZE);
PS: I need DPI value to render maps.
Upvotes: 3
Views: 5155
Reputation: 39551
As the comments indicate GetDeviceCaps(HORSIZE/VERTSIZE)
is notoriously inaccurate. It's always been that way, and it will probably always be that way. There's nothing you can do about it, so you'll just have to pretend this API doesn't exist and move on. It won't help you find the real size of the monitor. You'd be better off just assuming a fixed default and letting the user adjust the dimensions manually if necessary.
Fortunately someone has already done there research and figured out a better way to find the physical size of a display on Windows. In a blog entry entitled Reading Monitor Physical Dimensions, or: Getting the EDID, the Right Way Ofek describes how you can get more accurate dimensions from the montior's EDID by using Windows' SetupAPI. The outline of the procedure is described as follows:
- Call
SetupDiGetClassDevsEx
to get anHDEVINFO
handle.- Use this
HDEVINFO
in a call toSetupDiEnumDeviceInfo
to populate anSP_DEVINFO_DATA
struct.- Use both
HDEVICE
andHDEVINFO
in a call toSetupDiOpenDevRegKey
, to finally get anHKEY
to the desired registry key – the one that holds the EDID block.
The linked blog entry contains sample code, and information about other alternative methods he tried.
Note that even EDID isn't always going to be accurate. While it's what the monitor itself says are its own dimensions, there's still plenty of opportunity for error. A vendor can easily make a mistake with the dimensions in the EDID and the monitor would still work perfectly, so there's little incentive to get these values right.
Upvotes: 10