在Delphi中開發使用多顯示器的應用程式
Windows 還支援克隆顯示方式,每個顯示器輸出同樣的內容,這對某些應用也是有意義的。還有些顯示卡雖然也支援兩個顯示器,不過他們並不是真正意義上的多顯示器,而是虛擬高解析度顯示模式(如 2048 × 768 或者 1024 × 1536 ),通過顯示卡將畫面分別顯示到兩個顯示器上。這兩種顯示模式都不是本文介紹的 zhongdian ,而且也非常簡單,所以我們也就不再贅述了。
Windows 最多支援 10 個顯示器, Windows 將所有顯示器對映為一個大的虛擬桌面。可以將顯示器理解為桌面某個區域性的檢視。在顯示屬性中可以根據顯示器的物理位置任意排布這些顯示器。如果顯示器的排列不規則,虛擬桌面上的某些部分可能無法顯示在任何一個顯示器上。為了不使一個窗體顯示在兩個顯示器之間等原因的考慮, Windows 將一個顯示器作為主顯示器。啟動計算機時,登入對話方塊就顯示在主顯示器中。絕大多數程式啟動示,都會顯示在主監視器中。
根據上述介紹,不難發現幾個重要的概念:桌面、顯示器、主顯示器等。首先必須先弄清楚這些概念以及他們之前的關係。這是掌握多顯示器應用程式開發方法的重點。理解了這些概念,其他的部分就非常好理解了。
桌面實際上是指 Windows 可顯示的邏輯區域。實際上是可以將一個窗體顯示到桌面之外的。然而這並不是說桌面的所有部分都會顯示在某臺顯示器上(原因如前所述);但反過來說,任何一個顯示器顯示的內容都必然是桌面的一部分。
桌面是一個矩形區域,可以通過頂點座標( Top , Left )和寬高來描述桌面的尺寸。為什麼還需要頂點座標呢?因為頂點座標不是想當然的( 0,0 )。那麼( 0,0 )在哪裡呢?說來話長,還是讓我們先來回顧一下剛才提到地一個概念--主顯示器吧。 Windows 希望一般的程式初始的時候顯示到主顯示器,因為人們習慣於關注一個離自己最近的顯示器。而 Windows 也不可能強制使用者把最左邊一個顯示器作為主顯示器,這樣一來應用程式為了把自己顯示到主顯示器,就需要費腦筋的計算。然而,多數使用者都只有一個顯示器(兩個顯示器實在太佔地方了),而一般的應用程式也不希望大費周章的去計算主顯示器在哪裡,自己應該顯示在什麼位置。所以 Windows 提出了一個合理的解決方案:以主顯示器的頂點座標作為座標系的原點。這樣一來,普通的程式之需要想在單顯示器環境中一樣考慮問題就可以了。
顯示器是桌面的區域性檢視。就好像透過窗戶看窗外的風景,站在不同的窗前就可以看到不同的畫面。同樣的,顯示器也是一個矩形區域,同樣可以通過頂點座標( Top , Left )和寬高來描述它的尺寸。頂點座標是相對於桌面座標系原點的,也就是相對於主顯示器的頂點。
工作區的概念比較簡單,它是指顯示器中除了任務條和其他停靠在桌面上的窗體之外的矩形區域。
Windows 為多顯示器應用程式的開發提供了一組 API 。 VCL 將這些 API 封裝起來,非常自然的融入整個 Framework 之中,使得開發多顯示器應用程式變得非常簡單。下面就介紹與之相關的內容。
在 VCL 之中大家最熟悉的恐怕非 TCustomForm 莫屬了,它是所有窗體的基類。 TCustomForm 的 Position 屬性用來設定窗體的現實位置,其可選值中有兩個是值得關心的:一個是 poScreenCenter ,當 Position 屬性被設定成 poScreenCenter 時,窗體會顯示到主顯示器的中央;另一個是 poDesktopCenter ,當 Position 屬性被設定成 poDesktopCenter 時,窗體顯示在整個桌面的中央。如果把這個屬性設成 poDesktopCenter ,程式又執行在一個有多臺顯示器的系統上,那麼這個視窗就會顯示在兩個顯示器之間,會給使用者帶來不必要的麻煩。因此即使我們的程式不是針對多顯示器而設計的,也應該細心處理這個值。另外一個屬性是 DefaultMonitor ,它的作用與 Position 有些類似,決定視窗最初顯示在哪個顯示器內。它有四個備選值: dmDesktop , dmPrimary , dmMainForm 和 dmActiveForm 。他們的含義如下:
Value | Meaning |
dmDesktop | 不特別處理 |
dmPrimary | 將窗體顯示到第一個顯示器上。這又是一個陷阱,字面上理解是主顯示器,而事實上它是指 Screen.Monitor[0] 這個顯示器。 |
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 是以主顯示器的左上角為座標系原點的,所以主顯示器的相對位置必然是( 0 , 0 )。
除了這些屬性之外,還要介紹 TScreen 的三個成員函式: MonitorFromPoint , MonitorFromRect 和 MonitorFromWindow 。顧名思義,他們分別是獲取個座標、某個區域和某個視窗所在的顯示器的例項。在實際的開發中可能也會用到。
最好,再來看看 TMonitor 類。它封裝了物理顯示器的有關屬性--這些屬性都是隻讀的。下表簡單介紹了這些屬性的含義,它們對編寫多顯示器應用程式非常有用:
屬性 | 說明 |
Handle | 獲取該顯示器的 Windows 控制程式碼 |
MonitorNum | 獲取顯示器的編號 |
Primary | 獲取該顯示器是否是主顯示器。又且僅有一個顯示器的 Primary 是 True 。 |
Top | 獲取顯示器的上邊界 |
Left | 獲取顯示器的左邊界 |
Height | 獲取顯示器的高度 |
Width | 獲取顯示器的寬度 |
BoundsRect | 獲取顯示器的對應桌面的區域,它與上面四個屬性是等價的 |
WorkareaRect | 獲取顯示器的工作區對應桌面的區域。 |
清楚地瞭解了 TScreen 和 TMonitor 之後,前面的問題也就自然解決了。到這裡,本文已經介紹了開發多顯示器應用程式所需的全部知識。相信你可以利用這些知識開發出非常實用的軟體產品。
附:你可以下載一個 DEMO ,幫助理解本文。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1792358
相關文章
- Delphi在dbgrideh中新增Img顯示blobIDE
- 用 autoplank 在多個顯示器上使用 Plank 擴充套件塢套件
- 顯示卡伺服器現在普遍應用伺服器
- ping 多臺伺服器並在類似 top 的介面中顯示伺服器
- 大神教你用 autoplank 在多個顯示器上使用 Plank 擴充套件塢套件
- Wireshark在多媒體開發中的使用
- SourceGenerator的應用: .Net多程式開發庫 - JuxtaposeUX
- MVC應用程式顯示Flash(swf)影片MVC
- 直播系統開發,實現在進度條中顯示文字顯示進度
- Win10工作列不顯示應用圖示怎麼辦 應用已經在執行但不顯示Win10
- 使用delphi開發人工智慧程式(參考資料)人工智慧
- 探討敏捷開發在軟體開發中的應用敏捷
- 機器學習將在遊戲開發中的6種應用機器學習遊戲開發
- 如何在 Sway 中設定多個顯示器
- 【Qt開發】更改應用程式圖示和工作列圖示QT
- 在零程式碼開發平臺上如何開發應用程式
- 直播電商平臺開發,vue顯示列表中的多張本地照片Vue
- 登入觸發器不生效,只在alert日誌中顯示觸發器
- Render函式在Vue多頁面應用中的應用函式Vue
- TypeScript 在開發應用中的實踐總結TypeScript
- 小程式開發中雲函式的應用!函式
- Windows10中多屏顯示器型號獲取並與Screen對應Windows
- win10系統更改文字、應用等專案在顯示器上的大小的方法Win10
- 在Vue中使用highlight.js高亮顯示程式碼VueJS
- 為什麼vue列印的物件在瀏覽器中顯示...Vue物件瀏覽器
- 在優麒麟上使用 Electron 開發桌面應用
- 如何讓Mac的Dock僅顯示正在執行的應用程式?Mac
- 使用 Tye 輔助開發 dotnet 應用程式
- JSON資料格式及其在WEB開發中的應用JSONWeb
- 前沿探索|AI 在 API 開發測試中的應用AIAPI
- 使用shell指令碼在Linux中管理Java應用程式指令碼LinuxJava
- 使用OT開發的頁面顯示不全的問題
- Android應用開發中如何使用隱藏的APIAndroidAPI
- 聯合體在微控制器程式設計中的應用程式設計
- 資料夾無法刪除顯示在另一程式中開啟
- socket程式設計在TCP中的應用程式設計TCP
- Java中的編譯器外掛開發與應用Java編譯
- 如何使用 VS Code 開發.NET Core應用程式
- 淺談canvas在web開發中的應用與優化CanvasWeb優化