Windows 多顯示器下的編程

來源:互聯網
上載者:User
概要
本文分步驟介紹如何在 Windows XP 中配置和使用多台監視器。

Windows XP 可通過使用多台監視器擴大您的案頭,進而提高您的工作效率。一台電腦上可串連多達十台單獨的監視器,藉助於這些監視器,您的案頭可以有充足的空間容納大量的程式或視窗。通過將項目從一台監視器移動到另一台監視器或將其擴充到多台監視器,您可以輕鬆地同時執行多項任務。您可以在一台監視器上編輯映像或文本,同時在另外一台監視器上查看 Web 活動。或者,您還可以開啟一篇長文檔的多個頁,將這些頁拖動到多台監視器中,以便輕鬆查看文字布局和映像。您亦可以將 Microsoft Excel 試算表在兩台監視器間拖動,這樣無需使用捲軸便可以查看多個列的資訊。

串連多台監視器

將一台監視器用作主監視器,它將在您啟動電腦後顯示“登入”對話方塊。此外,多數程式會在您首次開啟時在主監視器上顯示程式視窗。您可以為每台監視器選擇不同的螢幕解析度和顏色品質設定。可以將多台監視器串連到各自的視頻適配器,也可以串連到支援多輸出的一個單獨的視頻適配器。若要串連多台監視器並進行配置,請按照下列步驟操作:

1. 單擊“開始”,然後單擊“控制台”。
2. 單擊“外觀和主題”,然後單擊“顯示”。
3. 在“設定”選項卡上,單擊“識別”,以在每台監視器上顯示一個大型數字。此數字表明各監視器對應的表徵圖。
4. 單擊監視器表徵圖並將該表徵圖拖動到不同的位置上,這些位置分布代表了您希望在兩台監視器間移動項目的方式。然後單擊“確定”或“應用”來查看更改。

注意:表徵圖位置決定了您在兩台監視器間移動項目的方式。例如,如果您正在使用兩台監視器,並希望通過左右拖動的方式將項目從一台監視器移到另一台監視器中,請將表徵圖並列排放。若要以上下拖動的方式在兩台監視器間移動項目,請將表徵圖上下排放。表徵圖的位置不必與監視器的物理位置對應。即使您的監視器並排放置,也可以將表徵圖上下排列。

 

更改主監視器


1. 在“顯示內容”對話方塊的“設定”選項卡上,單擊代表要指定為主監視器的監視器的表徵圖。
2. 通過單擊選中“使用該裝置作為主監視器”複選框。注意,如果您選中的監視器表徵圖當前已設定為主監視器,則此複選框不可用。

在多台監視器中查看同一案頭


1. 在“顯示內容”對話方塊的“設定”選項卡上,單擊代表除主監視器外還需要使用的其他監視器的表徵圖。
2. 通過單擊選中“將 Windows 案頭擴充到該監視器上”複選框。啟用此功能後,您可以在螢幕上將項目拖動到其他監視器上,也可以調整視窗的大小,將視窗擴充到多台監視器上。

在多台監視器間移動項目


1. 在“顯示內容”對話方塊的“設定”選項卡上,單擊“識別”,以在每台監視器上顯示一個大型數字。此數字表明各監視器對應的表徵圖。
2. 單擊監視器表徵圖並將表徵圖拖動到不同的位置上,這些位置分布代表了您希望在兩台監視器間移動項目的方式。然後單擊“確定”或“應用”。
3. 在螢幕上拖動案頭上的項目,直到它出現在另一台監視器上。也可以調整視窗的大小,將視窗擴充到多台監視器上。

使用雙視屏

在多數攜帶型電腦和某些台式電腦(一個視訊卡上帶有兩個視頻連接埠)上,您可以使用雙視屏將顯示地區擴充到另一台監視器上。雙視屏與多台監視器的功能十分相近,不同之處是您無法選擇主顯示器。在攜帶型電腦上,主監視器始終是 LCD 顯示螢幕。在台式電腦上,第一個視頻輸出連接埠串連的是主監視器。當您串連了第二台監視器並開啟電腦後,使用“控制台”中的“顯示”工具對您的設定進行配置,步驟與配置多台監視器相同。您可以在有接埠或無接埠的攜帶型電腦上使用雙視屏。

 

以上摘自【如何在 Windows XP 中配置和使用多台監視器】
http://support.microsoft.com/kb/307873/zh-cn

Win 98之後開始支援多顯示器(Multiple Display)。Windows多顯示器情況分為兩種,一是單顯卡多顯示器,一是多顯卡多顯示器。前一種的多顯示器依靠顯卡的多個介面,一般顯卡有D-Sub介面+DVI-I介面(相關資料請看顯卡介面一文)。後一種通過不同的顯示器接到不同的顯卡來實現。 多顯示器的情況就給編些GUI帶來了困難,但是多顯示器也帶來了好處,可以將多個顯示器組合起來做成大面積螢幕,可以看電影了,只是這樣成本高了點。

 一般PC配有一塊顯卡和一台顯示器,但是可以在主板上再插一塊顯卡,然後使用兩個顯示器。後加入的顯示器被Windows設定為主顯示器(主屏),另外的顯示器叫做副顯示器(副屏)。其中主屏的座標被設為(0,0),開啟控制台->顯示,開啟顯示對話方塊,進入設定面板,可以看到多個顯示器,同時可以知道哪個是主屏,哪個是副屏,並且可以通過滑鼠拖動副屏來調整副屏相對於主屏的位置。如果只有一塊顯卡,該顯卡有多個輸出介面,可以將不同的顯示器接到不同的輸出介面來實現多屏,此時主屏不能選擇,筆記本上主顯示器是LCD(液晶屏),台式機為串連顯卡第一個輸出介面的顯示器。 下面就我實際開發中遇到的問題,結合《Programming for Multiple Monitors in Windows 98》這樣一篇文章,講述一下多顯示器情況下的編程。為方便描述,現假設PC原有一台顯示器,座標解析度為(1024*768),然後再添加一顯卡和顯示器,解析度為(800*600),這樣(800*600)的顯示器成為主屏,(1024*768)的顯示器成為副屏。下面以此例進行描述,為了便於理解,有些以螢幕取代顯示器: 一、虛擬桌面(Virtual desktop)一台顯示器時,虛擬桌面就是所看到的案頭,座標(0,0),大小(1024,768)。2台顯示器時,副屏座標為(800,0),大小為(1024*768),虛擬桌面座標(0,0),大小 (1824,768),此時的虛擬桌面並非你看到的2個顯示器中的任何一個。如下: 由可見,Virtual desktop是兩者拼接起來的結果。二、多顯示器相關API1.       資料類型HMONITOR 顯示器的控制代碼MONITORINFO 顯示器資訊MONITORINFOEX 顯示器資訊(上面結構的擴充)typedef struct tagMONITORINFO {DWORD cbSize;RECT rcMonitor;RECT rcWork;DWORD dwFlags;} MONITORINFO, *LPMONITORINFO;typedef struct tagMONITORINFOEXA{MONITORINFO;TCHAR szDevice[CCHDEVICENAME];} MONITORINFOEX, *LPMONITORINFOEX; 2.       獲得某點所在的螢幕HMONITOR MonitorFromPoint(POINT pt,DWORD dwFlags);Pt為點座標dwFlags可取下面的值,表示沒有任何顯示器包含該點時,返回什麼值MONITOR_DEFAULTTONULL(返回NULL)MONITOR_DEFAULTTOPRIMARY(返回主屏)MONITOR_DEFAULTTONEAREST(返回最靠近該目標的螢幕)3.       擷取某矩形地區,視窗所在螢幕HMONITOR MonitorFromRect(LPRECT lprc,DWORD dwFlags);lprc為指定矩形地區dwFlags含義與2相同 HMONITOR MonitorFromWindow(HWND hWnd,DWORD dwFlags);hWnd為指定視窗dwFlags含義同2這兩個介面返回包含目標最多的螢幕,如果沒有任何螢幕包含目標,那麼根據第二個參數返回具體的值。4.       擷取顯示器資訊BOOL GetMonitorInfo( HMONITOR hmonitor, LPMONITORINFO lpmi);hmonitor 顯示器控制代碼lpmi MONITORINFO或MONITORINFOEX結構指標 注意MONITORINFOEX是MONITORINFO的超集,作為參數時需先設定它的cbSize屬性,使它等於自身的大小。 可以這樣使用MONITORINFOEX mix;mix.cbSize = sizeof(mix);GetMonitorInfo(hMonitor, (LPMONITORINFO)&mix);5.       擷取顯示器的寬和高GetSystemMetrics(int nIndex);使用SM_CXSCREEN,SM_CYSCREEN可以擷取主屏大小(800, 600)如果要獲得虛擬桌面的大小,需要使用SM_CXVIRTUALSCREEN,SM_CYVIRTUALSCREEN,此時擷取的大小為(1824, 768)6.       擷取工作區大小BOOL SystemParametersInfo( UINT uiAction, // system parameter to retrieve or set UINT uiParam,   // depends on action to be taken PVOID pvParam, // depends on action to be taken UINT fWinIni    // user profile update option); 上面函數對使用uiAction為SPI_GETWORKAREA,SPI_SETWORKAREA時,做了改進,以前總是對主屏進行操作。 現在要擷取其他螢幕的屬性,可以使用GetMonitorInfo,要設定其他螢幕可以在uiAction為SPI_SETWORKAREA時,將RECT作為pvParam,這樣就可以設定包含該RECT的顯示器。7.       便利相關顯示器BOOL WINAPI EnumDisplayMonitors(HDC hdc,LPCRECT lprcClip,MONITORENUMPROC lpfnEnum,LPARAM dwData); hdc 裝置環境lprcClip 矩形地區lpfnEnum 回呼函數dwData 傳給回呼函數的參數 回呼函數需要有下面的形式BOOL CALLBACK MonitorEnumProc(HMONITOR hmonitor,HDC hdcMonitor,LPRC lprcMonitor,DWORD dwData); 下面引用《Programming for Multiple Monitors in Windows 98》的原文說明The MONITORENUMPROC callback is called for each monitor that intersects the visible region of hdc and the lprcClip parameter. If the lprcClip parameter is NULL, then no additional clipping is performed. The dwData parameter is for user-defined data and is passed through to the dwData parameter in the callback function. MONITORENUMPROC is a user-defined callback function that must have the following signature:BOOL CALLBACK MonitorEnumProc(HMONITOR hmonitor,HDC hdcMonitor,LPRC lprcMonitor,DWORD dwData);If the hdc passed to EnumDisplayMonitors was NULL, then hdcMonitor is NULL. Otherwise, hdcMonitor contains a valid device context whose color attributes match the display monitor defined by hmonitor. If hdcMonitor is NULL, then lprcMonitor is in virtual-desktop coordinates. It is important to note that no application needs to use EnumDisplayMonitors to handle monitors of differing bit depths, since Windows automatically dithers high-color images on lower-color devices. You should use this function only if you want to do custom dithering to ensure the best possible display. In order to help you understand exactly how EnumDisplayMonitors is used, I will present a couple of code snippets illustrating common usage scenarios.One use for EnumDisplayMonitors is to make sure that images are drawn optimally on lower-color devices. The best way to do this is to change how your window's WndProc handles the WM_PAINT message.case WM_PAINT:HDC hdc;hdc = BeginPaint(hWnd,&paintStruct);EnumDisplayMonitors(hdc, NULL, monitorEnumPaintProc, 0);EndPaint(&paintStruct);Inside your callback, you query the passed device context to determine its capabilities and display area and do your drawing accordingly.8.       枚舉顯示器裝置BOOL WINAPI EnumDisplayDevices(PVOID Unused,        //Reversed, Set to NULLDWORD iDevNum, //index of monitor to query informationPDISPLAY_DEVICE lpDisplayDevice, //output informationDWORD dwFlags); //set to 0其中iDevNum是指查詢裝置的索引,以0為基數,如果有該裝置存在則填充lpDisplayDevice,返回TRUE;如果沒有該裝置,則返回FALSE。如果要枚舉所有的裝置,那麼需要讓iDevNum從0開始一直調用該函數,知道返回FALSE為止。第三個參數的結構定義如下:typedef struct _DISPLAY_DEVICE {DWORD cb;BYTE DeviceName[32];   //name of the device. Same as value get by GetMonitorInfoBYTE DeviceString[128]; //Firendly name of the deviceDWORD StateFlags; //不詳} DISPLAY_DEVICE, *PDISPLAY_DEVICE,*LPDISPLAY_DEVICE;StateFlags參數含義不詳,但是可以通過它的取值看出些漢以來:#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP0x00000001#define DISPLAY_DEVICE_MULTI_DRIVER0x00000002#define DISPLAY_DEVICE_PRIMARY_DEVICE0x00000004#define DISPLAY_DEVICE_MIRRORING_DRIVER0x00000008#define DISPLAY_DEVICE_VGA_COMPATIBLE0x00000010 下面引用《Programming for Multiple Monitors in Windows 98》的原文說明Since EnumDisplayDevices allows you to query devices that aren't part of the desktop, your application can use monitors in an exclusive manner, without having to share the screen with the desktop. To do this, find a device that doesn't have the DISPLAY_DEVICE_ATTACHED_TO_DESKTOP bit set and call the Win32 API function CreateDC, passing the name returned in the DeviceName member of lpDisplayDevice. If you create a device context in this manner, you should delete it when you're done with it by calling DeleteDC.9.        三、GUI編程注意事項GUI編程使用了顯示器,此時如果不考慮多顯示器情況,可能出現顯示問題。例如使用者當前將任務條拖放到副屏上,在副屏上進行操作,運行程式後程式出現在主屏上,這會讓使用者感覺程式沒有運行,但這並不是主要問題。 當使用者將主屏上的視窗拖放到副屏後,點擊某個按鈕或菜單,此時程式進行了動態位置調整,座標設想為(0,0),那麼視窗又從副屏跑回主屏了,此時我想使用者會覺得惱火。 具體的做法可以在視窗建立的時候和視窗移動的時候,擷取視窗所處螢幕資訊,並記錄下當前顯示屏的原點。例如:CPOINT m_ ptOrg; //在.h檔案中聲明變數 //在WM_MOVE或者視窗初始化時調用, 儲存原點資訊HMONITOR hWndMonitor = MonitorFromWindow(GetSafeHwnd(), MONITOR_DEFAULTTONULL);         MONITORINFOEX monitorInfo;         if (hWndMonitor == NULL) return;         monitorInfo.cbSize = sizeof(MONITORINFOEX);                  GetMonitorInfo(hWndMonitor, &monitorInfo); m_ptOrg.x = monitorInfo.leftm_ptOrg.y = monitorInfo.top  當調用SetWindowPos時,需要注意此時傳遞的RECT的原點應該以哪個計算。四、多視窗的一些有趣的事情一般第二個視窗的原點橫座標是第一個視窗的寬,工作列和案頭顯示在主屏上。預設情況下,副屏在主屏的右邊,滑鼠可以向左移動出主屏外。並且可以將工作列拖到副屏中。 多視窗時,Control Panel會記住上次的位置,下次開啟的時候還在原來的螢幕上出現。例如開啟Control Panel,此時顯示在主屏上,如果將它移動到副屏上,然後關閉,再次開啟的時候會出現在副屏上。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.