C++程式設計實現多顯示器控制(複製、橫屏、縱屏,顯示器個數)等
阿新 • • 發佈:2021-02-07
技術標籤:軟體設計及需求
需求的提出:
最近做了個三維的程式,部署到客戶機器上,客戶看了後,現場提出這樣的一個需求:程式能智慧探測接入的顯示器個數,當有新的顯示器接入時,現有的只在一個顯示器上顯示的三維場景能投遞到新插入的顯示器上顯示。類似在桌面上點選滑鼠右鍵,選擇“顯示設定”選單,彈出的如下介面:
然後在此介面,對顯示器進行復制、橫向、縱向等處理。
可以在程式中開啟一個執行緒,進行探測,探測到顯示器個數增加後,呼叫SetDisplayConfig(0, NULL, 0, NULL, SDC_TOPOLOGY_CLONE | SDC_APPLY);函式進行復制顯示器,一旦顯示器複製成功,三維程式就會投遞到新插入的顯示器上,程式碼如下:
void checkDisplayNumsChangedFun(); // 獲取本機顯示卡接入的顯示器個數 int getAllMonitors(); // 上次查詢時顯示器的個數 int g_nMonitorCount = 0; int main(int argc, char *argv[]) { QApplication a(argc, argv); std::thread* pDisplay = new std::thread(checkDisplayNumsChangedFun); return a.exec(); } // 檢測顯示器個數是否變化了,如果檢測到顯示器數目增多了,就複製顯示器 void checkDisplayNumsChangedFun() { while (true) { std::this_thread::sleep_for(std::chrono::milliseconds(5000)); int nMonitorCount = getAllMonitors(); // 顯示器個數減少了,直接返回,不處理顯示器減少的情況,也許是某個顯示器被人撥掉了 if (g_nMonitorCount >= nMonitorCount) { continue; } CLogToolKits::getInstance()->writeLog(L"有新的顯示器插入到主機!"); //change to the clone topology SetDisplayConfig(0, NULL, 0, NULL, SDC_TOPOLOGY_CLONE | SDC_APPLY); g_nMonitorCount = nMonitorCount; } } int getAllMonitors() { std::list<DISPLAY_DEVICE> devices; std::list<DEVMODE> modes; int devId = 0; bool ret = false; bool isPrimary = false; int nPrimaryNum = 0; //list all DisplayDevices (Monitors) do { DISPLAY_DEVICE displayDevice; ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE)); displayDevice.cb = sizeof(displayDevice); ret = EnumDisplayDevices(NULL, devId, &displayDevice, 0); if (ret == true) { if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) { devices.push_back(displayDevice); isPrimary = ((displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) == DISPLAY_DEVICE_PRIMARY_DEVICE); if (isPrimary) { nPrimaryNum = devId; } } } devId++; } while (ret); list<DISPLAY_DEVICE> dev_list; dev_list = devices; std::list<DISPLAY_DEVICE>::iterator it; for (it = dev_list.begin(); it != dev_list.end(); it++) { DEVMODE deviceMode; deviceMode.dmSize = sizeof(DEVMODE); deviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS; // | DM_DISPLAYORIENTATION; EnumDisplaySettings(it->DeviceName, (int)ENUM_REGISTRY_SETTINGS, &deviceMode); modes.push_back(deviceMode); } return modes.size(); }
更多對顯示器的操作,請參考《VC++程式設計實現多顯示器控制(複製、橫屏、縱屏,顯示器個數)》