Windows可以將多個顯示器映射為虛擬桌面
使我們可以利用這一點設計出方便工作的應用程序
例如PowerPoint就充分發揮了雙顯示器的優勢(大多數的筆記本電腦都支持)
它可以在一個顯示器上播放幻燈片
而在另一個顯示器上顯示備注
可以控制播放的進程
使使用者做商務演說的時候非常等心應手
那麼我們怎麼開發這種應用程序呢?這篇文章將向你展示如果用Delphi實現使用多顯示器的應用程序
Windows還支持克隆顯示方式每個顯示器輸出同樣的內容這對某些應用也是有意義的還有些顯卡雖然也支持兩個顯示器不過他們並不是真正意義上的多顯示器而是虛擬高分辨率顯示模式(如×或者×)通過顯卡將畫面分別顯示到兩個顯示器上這兩種顯示模式都不是本文介紹的zhongdian而且也非常簡單所以我們也就不再贅述了
Windows最多支持個顯示器Windows將所有顯示器映射為一個大的虛擬桌面可以將顯示器理解為桌面某個局部的視圖在顯示屬性中可以根據顯示器的物理位置任意排布這些顯示器如果顯示器的排列不規則虛擬桌面上的某些部分可能無法顯示在任何一個顯示器上為了不使一個窗體顯示在兩個顯示器之間等原因的考慮Windows將一個顯示器作為主顯示器啟動計算機時登錄對話框就顯示在主顯示器中絕大多數程序啟動示都會顯示在主監視器中
根據上述介紹不難發現幾個重要的概念桌面顯示器主顯示器等首先必須先弄清楚這些概念以及他們之前的關系這是掌握多顯示器應用程序開發方法的重點理解了這些概念其他的部分就非常好理解了
桌面實際上是指Windows可顯示的邏輯區域實際上是可以將一個窗體顯示到桌面之外的然而這並不是說桌面的所有部分都會顯示在某台顯示器上(原因如前所述)但反過來說任何一個顯示器顯示的內容都必然是桌面的一部分
桌面是一個矩形區域可以通過頂點坐標(TopLeft)和寬高來描述桌面的尺寸為什麼還需要頂點坐標呢?因為頂點坐標不是想當然的()那麼()在哪裡呢?說來話長還是讓我們先來回顧一下剛才提到地一個概念——主顯示器吧Windows希望一般的程序初始的時候顯示到主顯示器因為人們習慣於關注一個離自己最近的顯示器而Windows也不可能強制用戶把最左邊一個顯示器作為主顯示器這樣一來應用程序為了把自己顯示到主顯示器就需要費腦筋的計算然而多數用戶都只有一個顯示器(兩個顯示器實在太占地方了)而一般的應用程序也不希望大費周章的去計算主顯示器在哪裡自己應該顯示在什麼位置所以Windows提出了一個合理的解決方案以主顯示器的頂點坐標作為坐標系的原點這樣一來普通的程序之需要想在單顯示器環境中一樣考慮問題就可以了
顯示器是桌面的局部視圖就好像透過窗戶看窗外的風景站在不同的窗前就可以看到不同的畫面同樣的顯示器也是一個矩形區域同樣可以通過頂點坐標(TopLeft)和寬高來描述它的尺寸頂點坐標是相對於桌面坐標系原點的也就是相對於主顯示器的頂點
工作區的概念比較簡單它是指顯示器中除了任務條和其他停靠在桌面上的窗體之外的矩形區域
Windows為多顯示器應用程序的開發提供了一組APIVCL將這些API封裝起來非常自然的融入整個Framework之中使得開發多顯示器應用程序變得非常簡單下面就介紹與之相關的內容
在VCL之中大家最熟悉的恐怕非TCustomForm莫屬了它是所有窗體的基類TCustomForm的Position屬性用來設置窗體的現實位置其可選值中有兩個是值得關心的一個是poScreenCenter當Position屬性被設置成poScreenCenter時窗體會顯示到主顯示器的中央另一個是poDesktopCenter當Position屬性被設置成poDesktopCenter時窗體顯示在整個桌面的中央如果把這個屬性設成poDesktopCenter程序又運行在一個有多台顯示器的系統上那麼這個窗口就會顯示在兩個顯示器之間會給用戶帶來不必要的麻煩因此即使我們的程序不是針對多顯示器而設計的也應該細心處理這個值另外一個屬性是DefaultMonitor它的作用與Position有些類似決定窗口最初顯示在哪個顯示器內它有四個備選值dmDesktopdmPrimarydmMainForm和dmActiveForm他們的含義如下
Value
Meaning
dmDesktop
不特別處理
dmPrimary
將窗體顯示到第一個顯示器上
這又是一個陷阱
字面上理解是主顯示器
而事實上它是指Screen
Monitor[
]這個顯示器
dmMainForm
將窗體顯示到主窗體所在的顯示器
dmActiveForm
將窗體顯示到桌面上活動窗體所在的顯示器
TCustomForm還有一個只讀的共有屬性(沒有Published)Monitor它提供了訪問窗體所在顯示器實例的引用這個值與DefaultMonitor是有緊密的關聯的
那麼怎麼在使窗體在不同的顯示器之間移動呢?這並不困難估計你也想到了這裡介紹兩種方法
第一 可以設置TCustomForm的Top和Left使窗體顯示在桌面的任意位置正如前面所述桌面是由所有顯示器組成的它們有共同的坐標系所以可以根據顯示器的邏輯位置決定窗體的位置現在的問題是如何獲得每個顯示器的邏輯位置和尺寸後面就會介紹
第二 可以調用TCustomForm的MakeFullyVisible方法將窗體完全顯示到指定的顯示器之中可以通過這個方法避免窗口在兩個顯示器上各顯示一部分
剛才我們提出了一個問題如何獲得每個顯示器的邏輯位置和尺寸為了解答這個問題需要再介紹連個類TScreen和TMonitor
TScreen描述與顯示設備有關的一些信息我們主要關心與顯示器邏輯位置和尺寸有關的信息其他方面的內容可以在Delphi的文檔中獲知在程序運行的時候VCL自動創建一個TScreen的實例——全局變量所以通常情況下程序是不需要實例化TScreen的
TScreen有一組形如Desktop*的屬性這些屬性描述了整個桌面的尺寸和各頂點坐標還有對開發多顯示器應用程序有重要意義的連個屬性MonitorCount和Monitors通過這兩個屬性我們可以枚舉出系統中所有的顯示器(TMonitor)的實例每個實例都反映了相應顯示器的相對位置和分辨率等信息(後文會詳細說明)
在TScreen的眾多屬性之中我們會找到Height和Width這兩個屬性要特別警惕它們不是指整個桌面的尺寸而是指主顯示器的高度和寬度這非常容易讓人產生錯覺無以為是整個桌面的尺寸與之類似的還有形如WorkArea*的一組屬性它們描述了主顯示器的工作區域的尺寸和各頂點坐標是不是覺得少了什麼?為什麼沒有獲取主顯示器相對位置的屬性?原因就像前面所說的Windows是以主顯示器的左上角為坐標系原點的所以主顯示器的相對位置必然是()
除了這些屬性之外還要介紹TScreen的三個成員函數MonitorFromPointMonitorFromRect和MonitorFromWindow顧名思義他們分別是獲取個坐標某個區域和某個窗口所在的顯示器的實例在實際的開發中可能也會用到
最好再來看看TMonitor類它封裝了物理顯示器的有關屬性——這些屬性都是只讀的下表簡單介紹了這些屬性的含義它們對編寫多顯示器應用程序非常有用
屬性
說明
Handle
獲取該顯示器的Windows句柄
MonitorNum
獲取顯示器的編號
Primary
獲取該顯示器是否是主顯示器
又且僅有一個顯示器的Primary是True
Top
獲取顯示器的上邊界
Left
獲取顯示器的左邊界
Height
獲取顯示器的高度
Width
獲取顯示器的寬度
BoundsRect
獲取顯示器的對應桌面的區域
它與上面四個屬性是等價的
WorkareaRect
獲取顯示器的工作區對應桌面的區域
清楚地了解了TScreen和TMonitor之後前面的問題也就自然解決了到這裡本文已經介紹了開發多顯示器應用程序所需的全部知識相信你可以利用這些知識開發出非常實用的軟件產品
附你可以下載一個DEMO幫助理解本文
http://mytocom/yukin/download/MultiMonitorDemorar
From:http://tw.wingwit.com/Article/program/Delphi/201311/24817.html