DisplayProfileManager
C# WPF Windows API P/Invoke
問題
多螢幕工作環境下,切換顯示器配置是一件反覆且繁瑣的操作。接上投影機要調整解析度和排列方式,回到工位又要切回原本的三螢幕配置。Windows 內建的顯示設定每次都要手動拖拉、確認,對於頻繁切換的情境效率極低。
解決方案
開發了 DisplayProfileManager,一個 WPF 桌面應用程式,讓使用者儲存多組顯示器配置(profile),透過一鍵或系統匣圖示快速切換。
核心功能:
- 偵測目前連接的所有顯示器及其能力(解析度、更新率、色彩深度)
- 儲存完整的顯示器配置為 profile(包含位置、主螢幕設定、縮放比例)
- 一鍵套用已儲存的 profile
- 系統匣常駐,支援快捷鍵觸發
- 顯示器熱插拔偵測,自動建議套用對應 profile
技術挑戰
Windows Display API
Windows 沒有提供高階的「儲存並還原顯示器配置」API。實際操作需要透過 P/Invoke 呼叫底層 Win32 函式:
EnumDisplayDevices:列舉顯示裝置EnumDisplaySettingsEx:取得顯示設定ChangeDisplaySettingsEx:套用顯示設定
其中 ChangeDisplaySettingsEx 的 flag 組合對行為影響極大。要實現多螢幕同時切換且不閃爍,需要使用 CDS_UPDATEREGISTRY | CDS_NORESET 先寫入所有設定,最後一次呼叫 CDS_SET_PRIMARY 完成套用。
螢幕座標系統
Windows 的螢幕座標以主螢幕左上角為原點。當主螢幕改變時,所有螢幕的絕對座標都會重新計算。Profile 儲存的是相對位置關係,套用時需要根據當前主螢幕重新計算絕對座標。
成果
- 切換時間從手動操作的 30-60 秒降到 1 秒以內
- 在公司內部約 15 位同事使用,處理了會議室投影機、測試工位、個人辦公桌三種常見場景