As a developer/C/C++
모니터 Enumerate
산에™
2012. 7. 18. 11:50
#include <atlstr.h> |
002 |
#include <SetupApi.h> |
003 |
#pragma comment(lib, "setupapi.lib") |
004 |
|
005 |
#define NAME_SIZE 128 |
006 |
|
007 |
const GUID GUID_CLASS_MONITOR = {0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}; |
008 |
|
009 |
// Assumes hDevRegKey is valid |
010 |
bool GetMonitorSizeFromEDID( const HKEY hDevRegKey, short & WidthMm, short & HeightMm) |
011 |
{ |
012 |
DWORD dwType, AcutalValueNameLength = NAME_SIZE; |
013 |
TCHAR valueName[NAME_SIZE]; |
014 |
|
015 |
BYTE EDIDdata[1024]; |
016 |
DWORD edidsize= sizeof (EDIDdata); |
017 |
|
018 |
for ( LONG i = 0, retValue = ERROR_SUCCESS; retValue != ERROR_NO_MORE_ITEMS; ++i) |
019 |
{ |
020 |
retValue = RegEnumValue ( hDevRegKey, i, &valueName[0], |
021 |
&AcutalValueNameLength, NULL, &dwType, |
022 |
EDIDdata, // buffer |
023 |
&edidsize); // buffer size |
024 |
|
025 |
if (retValue != ERROR_SUCCESS || 0 != _tcscmp(valueName,_T( "EDID" ))) |
026 |
continue ; |
027 |
|
028 |
WidthMm = ((EDIDdata[68] & 0xF0) << 4) + EDIDdata[66]; |
029 |
HeightMm = ((EDIDdata[68] & 0x0F) << 8) + EDIDdata[67]; |
030 |
|
031 |
return true ; // valid EDID found |
032 |
} |
033 |
|
034 |
return false ; // EDID not found |
035 |
} |
036 |
|
037 |
bool GetSizeForDevID( const CString& TargetDevID, short & WidthMm, short & HeightMm) |
038 |
{ |
039 |
HDEVINFO devInfo = SetupDiGetClassDevsEx( |
040 |
&GUID_CLASS_MONITOR, //class GUID |
041 |
NULL, //enumerator |
042 |
NULL, //HWND |
043 |
DIGCF_PRESENT, // Flags //DIGCF_ALLCLASSES| |
044 |
NULL, // device info, create a new one. |
045 |
NULL, // machine name, local machine |
046 |
NULL); // reserved |
047 |
|
048 |
if (NULL == devInfo) |
049 |
return false ; |
050 |
|
051 |
bool bRes = false ; |
052 |
|
053 |
for ( ULONG i=0; ERROR_NO_MORE_ITEMS != GetLastError(); ++i) |
054 |
{ |
055 |
SP_DEVINFO_DATA devInfoData; |
056 |
memset (&devInfoData,0, sizeof (devInfoData)); |
057 |
devInfoData.cbSize = sizeof (devInfoData); |
058 |
|
059 |
if (SetupDiEnumDeviceInfo(devInfo,i,&devInfoData)) |
060 |
{ |
061 |
HKEY hDevRegKey = SetupDiOpenDevRegKey(devInfo,&devInfoData, |
062 |
DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); |
063 |
|
064 |
if (!hDevRegKey || (hDevRegKey == INVALID_HANDLE_VALUE)) |
065 |
continue ; |
066 |
|
067 |
bRes = GetMonitorSizeFromEDID(hDevRegKey, WidthMm, HeightMm); |
068 |
|
069 |
RegCloseKey(hDevRegKey); |
070 |
} |
071 |
} |
072 |
SetupDiDestroyDeviceInfoList(devInfo); |
073 |
return bRes; |
074 |
} |
075 |
|
076 |
int _tmain( int argc, _TCHAR* argv[]) |
077 |
{ |
078 |
short WidthMm, HeightMm; |
079 |
|
080 |
DISPLAY_DEVICE dd; |
081 |
dd.cb = sizeof (dd); |
082 |
DWORD dev = 0; // device index |
083 |
int id = 1; // monitor number, as used by Display Properties > Settings |
084 |
|
085 |
CString DeviceID; |
086 |
bool bFoundDevice = false ; |
087 |
while (EnumDisplayDevices(0, dev, &dd, 0) && !bFoundDevice) |
088 |
{ |
089 |
DISPLAY_DEVICE ddMon; |
090 |
ZeroMemory(&ddMon, sizeof (ddMon)); |
091 |
ddMon.cb = sizeof (ddMon); |
092 |
DWORD devMon = 0; |
093 |
|
094 |
while (EnumDisplayDevices(dd.DeviceName, devMon, &ddMon, 0) && !bFoundDevice) |
095 |
{ |
096 |
if (ddMon.StateFlags & DISPLAY_DEVICE_ACTIVE && |
097 |
!(ddMon.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)) |
098 |
{ |
099 |
DeviceID.Format (L "%s" , ddMon.DeviceID); |
100 |
DeviceID = DeviceID.Mid (8, DeviceID.Find (L "\\" , 9) - 8); |
101 |
|
102 |
bFoundDevice = GetSizeForDevID(DeviceID, WidthMm, HeightMm); |
103 |
} |
104 |
devMon++; |
105 |
|
106 |
ZeroMemory(&ddMon, sizeof (ddMon)); |
107 |
ddMon.cb = sizeof (ddMon); |
108 |
} |
109 |
|
110 |
ZeroMemory(&dd, sizeof (dd)); |
111 |
dd.cb = sizeof (dd); |
112 |
dev++; |
113 |
} |
114 |
|
115 |
return 0; |
116 |
} |