2013-01-22 71 views
4

我的任務是修改我們的C++產品之一,在Windows操作系統的特定顯示器上產生一個新窗口。這對於需要能夠配置平鋪多顯示器可視化的客戶端而言,其中每個顯示器都由單個計算機上的獨立顯卡驅動。如何在Windows中的特定顯示器上打開窗口?

在linux中,我可以通過在每個顯示器上啓動一個X服務器,然後使用DISPLAY env var適當地啓動多個可視化軟件實例來輕鬆完成此操作。但是,在Windows中這樣做時,我迷失了方向。任何指針/建議/例子?

+0

不知道是否有這是一個windows api,但我知道AMD催化劑控制面板和某些可以安裝的工具h支持以每個應用爲基礎定位特定屏幕的功能。如果你在這裏沒有得到任何幫助,可能想深入瞭解那些人如何做到他們的魔力。 –

回答

3

您需要枚舉所有監視器並檢查其在virtual screen (MSDN)上的映射。

通過致電EnumDisplayMonitors (MSDN)來列舉監視器。這將枚舉一系列HMONITOR句柄,您可以將它們傳遞給GetMonitorInfo (MSDN)以獲取虛擬屏幕上顯示器的位置。

還有一個多顯示器支持的完整指南,可能也值得一讀。

About Multiple Display Monitors (Windows) @ MSDN

一些注意事項:由於虛擬屏幕是用戶控制的映射,沒有什麼防止上的相對的物理側在監視器放置在虛擬座標空間中建立一個監視用戶的,並反之亦然,以及任何其他奇怪的放置場景。此外,某些顯示卡試圖假定顯示器在插入檢測時的位置,從軟件的角度來看這可能是錯誤的,但可能是由於用戶不注意哪個顯示端口映射到左側(如果它甚至被標記)。

2

您可以使用Win32 API中的EnumDisplayMonitors函數獲取每個顯示器的信息。

一旦你有你所需的顯示矩形,你知道該怎麼做=)

我敢肯定的顯示器才能一一列舉。但是如果你正在平鋪,你可以得到所有顯示矩形的矢量,然後對它們進行排序。

我有一個方便的包裝,我寫了一段時間後讓所有的顯示器的相關信息:

宣言

class CMonitorInfoEx : public MONITORINFOEX 
{ 
public: 
    CMonitorInfoEx(); 

    LPCRECT GetRect() const { return &rcMonitor; } 
    LPCRECT GetWorkRect() const { return &rcWork; } 
    LPCTSTR DeviceName() const { return szDevice; } 

    bool IsPrimary() const { return (dwFlags & MONITORINFOF_PRIMARY) ? true : false; } 

    int Width() const { return rcMonitor.right - rcMonitor.left; } 
    int Height() const { return rcMonitor.bottom - rcMonitor.top; } 
    int WorkWidth() const { return rcWork.right - rcWork.left; } 
    int WorkHeight() const { return rcWork.bottom - rcWork.top; } 
}; 


class CSysDisplays 
{ 
public: 
    CSysDisplays(); 

    void Update(); 

    int Count() const; 
    const CMonitorInfoEx& Get(int i) const; 

private: 
    std::vector<CMonitorInfoEx> mInfo; 
}; 

實施

BOOL CALLBACK MonitorEnumProc(__in HMONITOR hMonitor, __in HDC hdcMonitor, __in LPRECT lprcMonitor, __in LPARAM dwData) 
{ 
    std::vector<CMonitorInfoEx>& infoArray = *reinterpret_cast< std::vector<CMonitorInfoEx>* >(dwData); 
    CMonitorInfoEx info; 
    GetMonitorInfo(hMonitor, &info); 
    infoArray.push_back(info); 
    return TRUE; 
} 

CMonitorInfoEx::CMonitorInfoEx() 
{ 
    cbSize = sizeof(MONITORINFOEX); 
} 


CSysDisplays::CSysDisplays() 
{ 
    Update(); 
} 


void CSysDisplays::Update() 
{ 
    mInfo.clear(); 
    mInfo.reserve(::GetSystemMetrics(SM_CMONITORS)); 
    EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, reinterpret_cast<LPARAM>(&mInfo)); 
} 


int CSysDisplays::Count() const 
{ 
    return (int)mInfo.size(); 
} 


const CMonitorInfoEx& CSysDisplays::Get(int i) const 
{ 
    return mInfo[i]; 
} 
相關問題