獲取(實時)顯示器的句柄假設我有3個顯示器。我如何才能通過索引獲得第二個句柄? EnumDisplayMonitors()將無法工作,因爲它枚舉僞設備以及EnumDisplayDevices()不給我處理。通過索引
通過索引
回答
您需要使用EnumDisplayMonitors()
而不是EnumDisplayDevices()
來訪問每個監視器的HMONITOR
句柄。
但是,監視器不是按索引標識的。 GetMonitorInfo()
可以告訴你哪個顯示器是「主要」,但僅此而已。沒有辦法知道哪個監視器是「第二」,「第三」等。並且不能使用監視器位置來確定,作爲「第二」監視器可以定位在與「主」監視器,然後可以將「第三」監視器定位在與「第一」或「第二」監視器相關的任何位置。
所以你要希望EnumDisplayMonitors()
列舉了該顯示器的安裝順序,那麼你可以做這樣的事情:
struct sEnumInfo
{
int iIndex;
HMONITOR hMonitor;
};
BOOL CALLBACK GetMonitorByIndex(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
sEnumInfo *info = (sEnumInfo*) dwData;
if (--info->iIndex < 0)
{
info->hMonitor = hMonitor;
return FALSE;
}
return TRUE;
}
sEnumInfo info;
info.index = 1;
info.hMonitor = NULL;
EnumDisplayMonitors(NULL, NULL, GetMonitorByIndex, (LPARAM)&info);
if (info->hMonitor != NULL)
{
//...
}
您可以EnumDisplayMonitors()
枚舉設備和檢查它是否是僞顯示器EnumDisplayDevices()
當您使用012迭代顯示監視器你可以得到MONITORINFOEX
與顯示器的設備的名稱。
然後使用EnumDisplayDevices()
你可以得到DISPLAY_DEVICE
包含StateFlags
與信息,如果電流監控器是一個僞監視器(或在情況下波紋管連接到桌面)
BOOL DispayEnumeratorProc(_In_ HMONITOR hMonitor, _In_ HDC hdcMonitor, _In_ LPRECT lprcMonitor, _In_ LPARAM dwData)
{
TClass* self = (TClass*)dwData;
if (self == nullptr)
return FALSE;
MONITORINFOEX monitorInfo;
::ZeroMemory(&monitorInfo, sizeof(monitorInfo));
monitorInfo.cbSize = sizeof(monitorInfo);
BOOL res = ::GetMonitorInfo(hMonitor, &monitorInfo);
if (res == FALSE)
return TRUE;
DISPLAY_DEVICE displayDevice;
::ZeroMemory(&displayDevice, sizeof(displayDevice));
displayDevice.cb = sizeof(displayDevice);
res = ::EnumDisplayDevices(monitorInfo.szDevice, 0, &displayDevice, 0);
if (res == FALSE)
return TRUE;
if (displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
self->RegisterDisplay(monitorInfo);
return TRUE;
}
void TClass::EnumerateDisplayMonitors()
{
BOOL res = ::EnumDisplayMonitors(NULL, NULL, &DispayEnumeratorProc, (LPARAM)this);
if (res == FALSE)
Print("Failed");
}
您也可以通過EnumDisplayDevices()
迭代您的監視器進行排序
如果您將NULL
作爲第一個參數傳遞給EnumDisplayDevices()
,它將根據第二個參數返回適配器的信息。在這種情況下,您的設備將確定訂單。
您可以從DISPLAY_DEVICE
與szDevice
從MONITORINFOEX
你之前存儲的比較DeviceName
排序您HMONITORs
void TClass::SortDisplayMonitors()
{
DISPLAY_DEVICE displayDevice;
::ZeroMemory(&displayDevice, sizeof(displayDevice));
displayDevice.cb = sizeof(displayDevice);
std::map<std::string, DWORD> devices;
for (DWORD iDevNum = 0; ::EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0) != FALSE; ++iDevNum)
devices.insert({displayDevice.DeviceName, iDevNum});
auto compare = [&devices](MONITORINFOEX& l, MONITORINFOEX& r)
{
DWORD il = -1;
DWORD ir = -1;
auto foundL = devices.lower_bound(l.szDevice);
if (foundL != devices.end())
il = foundL->second;
auto foundR = devices.lower_bound(r.szDevice);
if (foundR != devices.end())
ir = foundR->second;
return (il < ir);
};
std::sort(m_monitors.begin(), m_monitors.end(), compare);
}
PS:你可以寫
DWORD IL =的std :: numeric_limits < DWORD> :: MAX( );
insted
DWORD il = -1;
但不要忘記在包含Windows.h之前定義NOMINMAX
我認爲你應該添加一個解釋,爲什麼你做了你所做的。 – 2017-10-23 19:51:07
- 1. 通過索引
- 2. 通過索引
- 3. 通過索引
- 4. 通過索引
- 5. 通過索引
- 6. 通過索引
- 7. 通過索引
- 8. 通過索引
- 9. 通過索引
- 10. WebHeaderCollection,通過索引
- 11. 通過索引AS3
- 12. 通過檢索索引
- 13. apache nutch通過REST索引到索引
- 14. 通過索引動作
- 15. 通過的數組索引
- 16. UPSERT通過索引MongoDB中
- 17. 如何通過索引
- 18. 無法通過索引
- 19. 如何通過索引
- 20. d3.js通過索引
- 21. JavaScript的:通過索引
- 22. 如何通過索引
- 23. RapidJSON庫通過其索引
- 24. 項目通過索引
- 25. 通過索引攻絲UITableViewHeader
- 26. 複印通過索引
- 27. 通過給列索引
- 28. 通過索引錯誤
- 29. 通過索引讀取NSDictionary
- 30. 的Python通過索引
怎麼樣'MonitorFromRect','MonitorFromPoint'或'MonitorFromWindow'?他們中的任何一個會爲你工作嗎?他們都返回一個'HMONITOR'。 – 2015-04-02 12:59:57
不幸的是,我需要的索引 – Grisu47 2015-04-02 14:59:52