在Delphi中
開發(fā)使用多顯示器的
應(yīng)用程序 Windows可以將多個(gè)顯示器映射為
虛擬桌面,使
我們可以利用這一點(diǎn)
設(shè)計(jì)出方便工作的
應(yīng)用程 序。例如PowerPo
int就充分發(fā)揮了雙顯示器的
優(yōu)勢(shì)(大多數(shù)的
筆記本電腦都支持),它可以在一個(gè)顯示器上播放幻燈片,而在另一個(gè)顯示器上顯示備注, 可以
控制播放的進(jìn)程,使使用者做商務(wù)演說的時(shí)候非常等心應(yīng)手。那么我們?cè)趺撮_發(fā)這種應(yīng)用程序呢?這篇
文章將向你展示如果用Delphi實(shí)現(xiàn)使用多顯示器的 應(yīng)用程序。 Windows還支持克隆顯示方式,每個(gè)顯示器輸出同樣的
內(nèi)容,這對(duì)某些應(yīng)用也是有意義的。還有些顯卡雖然也支持兩個(gè)顯示器,
不過他們并 不是真正意義上的多顯示器,而是虛擬高分辨率顯示模式(如2048×768或者1024×1536),通過顯卡將畫面分別顯示到兩個(gè)顯示器上。這兩種顯示 模式都不是本文介紹的zhongdian,而且也非常簡(jiǎn)單,所以我們也就不再贅述了?! indows最多支持10個(gè)顯示器,Windows將所有顯示 器映射為一個(gè)大的虛擬桌面??梢詫@示器
理解為桌面某個(gè)局部的視圖。在顯示屬性中可以根據(jù)顯示器的物理位置任意排布這些顯示器。如果顯示器的排列不規(guī)則, 虛擬桌面上的某些部分可能無法顯示在
任何一個(gè)顯示器上。為了不使一個(gè)窗體顯示在兩個(gè)顯示器之間等原因的考慮,Windows將一個(gè)顯示器作為主顯示器。啟 動(dòng)
計(jì)算機(jī)時(shí),登錄對(duì)話框就顯示在主顯示器中。絕大多數(shù)程序啟動(dòng)示,都會(huì)顯示在主監(jiān)視器中。 根據(jù)上述介紹,不難發(fā)現(xiàn)幾個(gè)
重要的概念:桌面、顯示器、主顯 示器等。首先
必須先弄清楚這些概念以及他們之前的
關(guān)系。這是
掌握多顯示器應(yīng)用
程序開發(fā)方法的重點(diǎn)。理解了這些概念,其他的部分就非常好理解了。 桌面實(shí) 際上是指Windows可顯示的邏輯區(qū)域。實(shí)際上是可以將一個(gè)窗體顯示到桌面之外的。然而這并不是說桌面的所有部分都會(huì)顯示在某臺(tái)顯示器上(原因如前所 述);但反過來說,任何一個(gè)顯示器顯示的內(nèi)容都必然是桌面的一部分?! ∽烂媸且粋€(gè)矩形區(qū)域,可以通過頂點(diǎn)坐標(biāo)(Top,Left)和寬高來
描述桌面的尺 寸。為什么還需要頂點(diǎn)坐標(biāo)呢?因?yàn)轫旤c(diǎn)坐標(biāo)不是想當(dāng)然的(0,0)。那么(0,0)在哪里呢?說來話長(zhǎng),還是讓我們先來回顧一下剛才提到地一個(gè)概念——主 顯示器吧。Windows希望一般的程序初始的時(shí)候顯示到主顯示器,因?yàn)槿藗兞?xí)慣于
關(guān)注一個(gè)離自己最近的顯示器。而Windows也不可能強(qiáng)制
用戶把最左 邊一個(gè)顯示器作為主顯示器,這樣一來應(yīng)用程序?yàn)榱税炎约猴@示到主顯示器,就需要費(fèi)腦筋的計(jì)算。然而,多數(shù)用戶都只有一個(gè)顯示器(兩個(gè)顯示器實(shí)在太占
地方 了),而一般的應(yīng)用程序也不希望大費(fèi)周章的去計(jì)算主顯示器在哪里,自己應(yīng)該顯示在什么位置。所以Windows提出了一個(gè)合理的
解決方案:以主顯示器的頂 點(diǎn)坐標(biāo)作為坐標(biāo)系的原點(diǎn)。這樣一來,普通的程序之需要想在單顯示器環(huán)境中一樣考慮
問題就可以了?! ★@示器是桌面的局部視圖。就好像透過窗戶看窗外的風(fēng) 景,站在不同的窗前就可以看到不同的畫面。同樣的,顯示器也是一個(gè)矩形區(qū)域,同樣可以通過頂點(diǎn)坐標(biāo)(Top,Left)和寬高來描述它的尺寸。頂點(diǎn)坐標(biāo)是 相對(duì)于桌面坐標(biāo)系原點(diǎn)的,也就是相對(duì)于主顯示器的頂點(diǎn)?! 」ぷ鲄^(qū)的概念比較簡(jiǎn)單,它是指顯示器中除了任務(wù)條和其他停靠在桌面上的窗體之外的矩形區(qū)域?!? Windows為多顯示器應(yīng)用程序的開發(fā)
提供了一組
API。
VCL將這些API封裝起來,非常自然的融入整個(gè)Framework之中,使得開發(fā)多顯示器 應(yīng)用程序變得非常簡(jiǎn)單。下面就介紹與之相關(guān)的內(nèi)容?! ≡赩CL之中大家最熟悉的恐怕非TCustomForm莫屬了,它是所有窗體的基類。 TCustomForm的Position屬性用來設(shè)置窗體的現(xiàn)實(shí)位置,其可選值中有兩個(gè)是值得關(guān)心的:一個(gè)是poScreenCenter,當(dāng) Position屬性被設(shè)置成poScreenCenter時(shí),窗體會(huì)顯示到主顯示器的中央;另一個(gè)是poDesktopCenter,當(dāng) Position屬性被設(shè)置成poDesktopCenter時(shí),窗體顯示在整個(gè)桌面的中央。如果把這個(gè)屬性設(shè)成poDesktopCenter,程序又 運(yùn)行在一個(gè)有多臺(tái)顯示器的
系統(tǒng)上,那么這個(gè)窗口就會(huì)顯示在兩個(gè)顯示器之間,會(huì)給用戶帶來不必要的麻煩。因此即使我們的程序不是針對(duì)多顯示器而設(shè)計(jì)的,也應(yīng) 該
細(xì)心處理這個(gè)值。
另外一個(gè)屬性是DefaultMonitor,它的
作用與Position有些類似,決定窗口最初顯示在哪個(gè)顯示器內(nèi)。它有四個(gè)備選 值:dmDesktop,dmPrimary,dmMainForm和dmActiveForm。他們的含義如下:ValueMeaning
dmDesktop不
特別處理
dmPrimary將窗體顯示到第一個(gè)顯示器上。這又是一個(gè)
陷阱,字面上理解是主顯示器,而事實(shí)上它是指Screen.Monitor[0]這個(gè)顯示器
dmMainForm將窗體顯示到主窗體所在的顯示器
dmActiveForm將窗體顯示到桌面上活動(dòng)窗體所在的顯示器
TCustomForm還有一個(gè)只讀的共有屬性(沒有Published)Monitor,它提供了
訪問窗體所在顯示器實(shí)例的引用,這個(gè)值與 DefaultMonitor是有緊密的關(guān)聯(lián)的?! ∧敲丛趺丛谑勾绑w在不同的顯示器之間
移動(dòng)呢?這并不困難,估計(jì)你也想到了。這里介紹兩種方法: 第 一, 可以設(shè)置TCustomForm的Top和Left使窗體顯示在桌面的任意位置。正如前面所述,桌面是由所有顯示器組成的。它們有共同的坐標(biāo)系,所 以可以根據(jù)顯示器的邏輯位置決定窗體的位置。現(xiàn)在的問題是如何獲得每個(gè)顯示器的邏輯位置和尺寸,后面就會(huì)介紹。 第二, 可以調(diào)用 TCustomForm的MakeFullyVisible方法將窗體完全顯示到指定的顯示器之中??梢酝ㄟ^這個(gè)方法
避免窗口在兩個(gè)顯示器上各顯示一部 分?! 偛盼覀兲岢隽艘粋€(gè)問題:如何獲得每個(gè)顯示器的邏輯位置和尺寸。為了解答這個(gè)問題,需要再介紹連個(gè)類:TScreen和TMonitor。 TScreen:描述與顯示設(shè)備有關(guān)的
一些信息,我們主要關(guān)心與顯示器邏輯位置和尺寸有關(guān)的信息。其他
方面的內(nèi)容可以在Delphi的文檔中獲知。在程序 運(yùn)行的時(shí)候VCL自動(dòng)創(chuàng)建一個(gè)TScreen的實(shí)例——全局變量,所以通常情況下程序是不需要實(shí)例化TScreen的。 TScreen有一組形如 Desktop*的屬性,這些屬性描述了整個(gè)桌面的尺寸和各頂點(diǎn)坐標(biāo)。還有對(duì)開發(fā)多顯示器應(yīng)用程序有重要意義的連個(gè)屬性:MonitorCount和 Monitors。通過這兩個(gè)屬性我們可以枚舉出系統(tǒng)中所有的顯示器(TMonitor)的實(shí)例,每個(gè)實(shí)例都反映了相應(yīng)顯示器的相對(duì)位置和分辨率等信息 (后文會(huì)詳細(xì)說明)。 在TScreen的眾多屬性之中,我們會(huì)找到Height和Width這兩個(gè)屬性。要特別警惕它們不是指整個(gè)桌面的尺寸,而是指 主顯示器的高度和寬度。這非常
容易讓人產(chǎn)生錯(cuò)覺,無以為是整個(gè)桌面的尺寸。與之類似的還有形如WorkArea*的一組屬性,它們描述了主顯示器的工作區(qū) 域的尺寸和各頂點(diǎn)坐標(biāo)。是不是覺得少了什么?為什么沒有
獲取主顯示器相對(duì)位置的屬性?原因就像前面所說的:Windows是以主顯示器的左上角為坐標(biāo)系原 點(diǎn)的,所以主顯示器的相對(duì)位置必然是(0,0)。 除了這些屬性之外,還要介紹TScreen的三個(gè)成員函 數(shù):MonitorFromPoint,MonitorFromRect和MonitorFromWindow。顧名思義,他們分別是獲取個(gè)坐標(biāo)、某個(gè)區(qū) 域和某個(gè)窗口所在的顯示器的實(shí)例。在實(shí)際的開發(fā)中可能也會(huì)用到。 最好,再來看看TMonitor類。它封裝了物理顯示器的有關(guān)屬性——這些屬性都是只 讀的。下表簡(jiǎn)單介紹了這些屬性的含義,它們對(duì)編寫多顯示器應(yīng)用程序非常有用:屬性說明
Handle獲取該顯示器的Windows句柄
MonitorNum獲取顯示器的編號(hào)
Primary獲取該顯示器是否是主顯示器。又且僅有一個(gè)顯示器的Primary是True
Top獲取顯示器的上邊界
Left獲取顯示器的左邊界
Height獲取顯示器的高度
Width獲取顯示器的寬度
BoundsRect獲取顯示器的對(duì)應(yīng)桌面的區(qū)域,它與上面四個(gè)屬性是等價(jià)的
WorkareaRect獲取顯示器的工作區(qū)對(duì)應(yīng)桌面的區(qū)域
清楚地了解了TScreen和TMonitor之后,前面的問題也就自然解決了。到這里,本文已經(jīng)介紹了開發(fā)多顯示器應(yīng)用程序所需的全部知識(shí)。相信你可以利用這些知識(shí)開發(fā)出非常
實(shí)用的
軟件產(chǎn)品。