这里有一个我在网址"https://ofekshilon.com/2011/11/13/reading-monitor-physical-dimensions-or-getting-the-edid-the-right-way/"上找到的方法。
作者说测量单位是毫米。
虽然不能给出精确的宽度和高度,但比HORSIZE和VERTSIZE更接近。我在两台不同的显示器上尝试了一下,得到了最大38厘米的差异(测量屏幕大小 - 计算屏幕大小)。
#include <SetupApi.h>
#pragma comment(lib, "setupapi.lib")
#define NAME_SIZE 128
const GUID GUID_CLASS_MONITOR = {0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18};
bool GetMonitorSizeFromEDID(const HKEY hDevRegKey, short& WidthMm, short& HeightMm)
{
DWORD dwType, AcutalValueNameLength = NAME_SIZE;
TCHAR valueName[NAME_SIZE];
BYTE EDIDdata[1024];
DWORD edidsize=sizeof(EDIDdata);
for (LONG i = 0, retValue = ERROR_SUCCESS; retValue != ERROR_NO_MORE_ITEMS; ++i)
{
retValue = RegEnumValueA ( hDevRegKey, i, &valueName[0],
&AcutalValueNameLength, NULL, &dwType,
EDIDdata,
&edidsize);
if (retValue != ERROR_SUCCESS || 0 != strcmp(valueName,"EDID"))
continue;
WidthMm = ((EDIDdata[68] & 0xF0) << 4) + EDIDdata[66];
HeightMm = ((EDIDdata[68] & 0x0F) << 8) + EDIDdata[67];
return true;
}
return false;
}
bool GetSizeForDevID(const char *TargetDevID, short& WidthMm, short& HeightMm)
{
HDEVINFO devInfo = SetupDiGetClassDevsExA(
&GUID_CLASS_MONITOR,
NULL,
NULL,
DIGCF_PRESENT,
NULL,
NULL,
NULL);
if (NULL == devInfo) return false;
bool bRes = false;
for (ULONG i=0; ERROR_NO_MORE_ITEMS != GetLastError(); ++i)
{
SP_DEVINFO_DATA devInfoData;
memset(&devInfoData,0,sizeof(devInfoData));
devInfoData.cbSize = sizeof(devInfoData);
if (SetupDiEnumDeviceInfo(devInfo,i,&devInfoData))
{
HKEY hDevRegKey = SetupDiOpenDevRegKey(devInfo,&devInfoData,DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
if(!hDevRegKey || (hDevRegKey == INVALID_HANDLE_VALUE)) continue;
bRes = GetMonitorSizeFromEDID(hDevRegKey, WidthMm, HeightMm);
RegCloseKey(hDevRegKey);
}
}
SetupDiDestroyDeviceInfoList(devInfo);
return bRes;
}
int main(int argc, CHAR* argv[])
{
short WidthMm, HeightMm;
DISPLAY_DEVICE dd;
dd.cb = sizeof(dd);
DWORD dev = 0;
int id = 1;
char DeviceID[1024];
bool bFoundDevice = false;
while (EnumDisplayDevices(0, dev, &dd, 0) && !bFoundDevice)
{
DISPLAY_DEVICE ddMon = {sizeof(ddMon)};
DWORD devMon = 0;
while (EnumDisplayDevices(dd.DeviceName, devMon, &ddMon, 0) && !bFoundDevice)
{
if (ddMon.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP &&
!(ddMon.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER))
{
sprintf(DeviceID,"%s", ddMon.DeviceID+8);
for(auto it=DeviceID; *it; ++it)
if(*it == '\\') { *it = 0; break; }
bFoundDevice = GetSizeForDevID(DeviceID, WidthMm, HeightMm);
}
devMon++;
ZeroMemory(&ddMon, sizeof(ddMon));
ddMon.cb = sizeof(ddMon);
}
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);
dev++;
}
return 0;
}