모니터가 여러 개인 경우 directdraw api 를 사용해 모니터별로 열거할수 있다.
getScreen() 함수는 지정한 RECT 에 해당하는 모니터를 찾고 모니터 오프셋 값을 RECT 에 넣어줌
//----------------------------------------------------------------------------------
#define MAX_MONITOR (4)
struct Monitor {
HMONITOR hMon;
GUID guid;
};
class MonitorManager {
Monitor monitor[MAX_MONITOR];
int nScreen;
...
int getScreen(RECT *rect);
};
// Enumerate Monitor
struct EnumInfo
{
BOOL bMultimonSupported;
HRESULT hr;
};
BOOL WINAPI DDEnumCallbackEx( GUID* pGuid, LPTSTR pszDesc, LPTSTR pszDriverName,
VOID* pContext, HMONITOR hmon )
{
MONITORINFO mi;
if (pGuid != NULL && hmon != NULL) {
mi.cbSize = sizeof(mi);
GetMonitorInfo(hmon, &mi);
MonitorManager *manager = (MonitorManager *)pContext;
manager->monitor[manager->nScreen].guid = *pGuid;
manager->monitor[manager->nScreen].hMon = hmon;
manager->nScreen++;
}
return TRUE; // Keep enumerating
}
BOOL WINAPI DDEnumCallback( GUID* pGuid, LPTSTR pszDesc, LPTSTR pszDriverName,
VOID* pContext )
{
DDEnumCallbackEx(pGuid, pszDesc, pszDriverName, pContext, NULL);
return FALSE; // Stop enumerating -- For this sample, we don't want any non-display devices
}
HRESULT EnumerateScreens(MonitorManager *manager)
{
HRESULT hr;
HMODULE hModule = NULL;
LPDIRECTDRAWENUMERATEEX pDDEnumEx = NULL;
EnumInfo enumInfo;
ZeroMemory(&enumInfo, sizeof(enumInfo));
hModule = LoadLibrary( TEXT("ddraw.dll") );
// If ddraw.dll doesn't exist in the search path,
// then DirectX probably isn't installed, so fail.
if (hModule == NULL)
return E_FAIL;
pDDEnumEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hModule,
#ifdef UNICODE
"DirectDrawEnumerateExW"
#else
"DirectDrawEnumerateExA"
#endif
);
manager->nScreen = 0;
if (pDDEnumEx == NULL)
{
// We must be running on an old version of DirectDraw.
// Therefore MultiMon isn't supported. Fall back on
// DirectDrawEnumerate to enumerate standard devices on a
// single-monitor system.
enumInfo.bMultimonSupported = FALSE;
hr = DirectDrawEnumerate(DDEnumCallback, manager);
}
else
{
enumInfo.bMultimonSupported = TRUE;
hr = pDDEnumEx(DDEnumCallbackEx, manager, DDENUM_ATTACHEDSECONDARYDEVICES);
}
// If something failed inside the enumeration, be sure to return that HRESULT
FreeLibrary(hModule);
return hr;
}
int MonitorManager::getScreen(RECT *rect)
{
MONITORINFO mi;
HMONITOR hMon = MonitorFromRect(rect, MONITOR_DEFAULTTONEAREST);
for (int i=0; i < nScreen; i++) {
if (hMon == monitor[i].hMon) {
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMon, &mi);
OffsetRect(rect, -mi.rcMonitor.left, -mi.rcMonitor.top);
return i;
}
}
return -1;
}
댓글 없음:
댓글 쓰기