作用中協助工具和 Windows Vista 螢幕縮放

Windows Vista 可讓使用者變更每英吋的點數 (DPI) 設定,讓螢幕上的大部分 UI 元素看起來較大。 雖然這項功能已在 Microsoft Windows 中提供,但在舊版中,調整必須由應用程式實作。 在 Windows Vista 中,桌面視窗管理員會針對未處理自己的縮放比例的所有應用程式執行預設調整。 Microsoft Active Accessibility 用戶端應用程式必須將這項功能納入考慮。

Windows Vista 中的縮放比例

預設的 dpi 設定是 96,表示 96 像素會佔用一英吋的寬度或高度。 「英吋」的確切測量值取決於監視器的大小和實體解析度。 例如,在 12 英吋寬、1280 像素水平解析度的監視器上,96 像素的水平線長度約一英吋的 9/10。

變更 dpi 設定與變更畫面解析度是不同的。 使用 dpi 縮放比例時,畫面的實體像素數目會維持不變。 不過,縮放比例會套用至 UI 元素的大小和位置。 針對未明確要求不縮放的桌面和應用程式,桌面視窗管理員 (DWM) 會自動執行縮放。

實際上,當使用者將縮放因數設為 120 dpi 時,畫面的垂直或水平英吋會增大 25%。 所有維度都會因此調整。 視窗從螢幕頂端和左邊緣的位移增加 25%。 視窗的大小會以相同的比例增加,以及它所包含的所有 UI 元素的位移和大小。

根據預設,當使用者將 dpi 設為 120 時,DWM 不會針對非 dpi 感知的應用程式執行縮放,但當 dpi設為自訂值 144 或更高時就會執行縮放。 不過,使用者可以覆寫此預設行為。

針對重視畫面座標的應用程式,畫面縮放比例會產生新挑戰。 畫面現在包含兩個座標系統:實體和邏輯。 點的實體座標是來自原點左上方的實際位移 (以像素為單位)。 邏輯座標則是像素本身縮放時,跟著縮放的位移。

假設您設計的對話方塊在座標 (100, 48) 上有一個按鈕。 當這個對話方塊以預設 96 dpi 顯示時,按鈕位在實體座標 (100, 48)。 在 120 dpi 時,它位在實體座標 (125, 60)。 但邏輯座標在任何 dpi 設定時都是相同的:(100, 48)。

邏輯座標很重要,因為不論 dpi 設定為何,它們都會維持作業系統和應用程式的行為一致。 例如, System.Windows.Forms.Cursor.Position 通常會傳回邏輯座標。 如果您將游標移至對話方塊內的項目上,不論 dpi 設定為何,系統都會傳回相同的座標。 如果您在 (100, 100) 繪製控制項,系統會將控制項繪製到這些邏輯座標,不論 dpi 設定為何都會佔用相同的相對位置。

在作用中協助工具用戶端中調整

Microsoft Active Accessibility 不會使用邏輯座標。 下列方法和函式會傳回實體座標,或將其視為參數。

根據預設,在非 96 DPI 環境中執行的 Microsoft Active Accessibility 用戶端應用程式將無法從這些呼叫取得正確的結果。 例如,由於游標位置位於邏輯座標中,因此用戶端無法直接將這些座標傳遞至 AccessibleObjectFromPoint ,以取得游標底下的專案。

此外,在工作區外部建立視窗的應用程式,例如醒目提示焦點 UI 元素的協助工具應用程式,將不會在正確的螢幕位置建立視窗,因為視窗會放在邏輯座標,而不是 IAccessible::accLocation傳回的實體座標。

此解決方案分為兩個部分:

  • 讓用戶端應用程式「DPI 感知」。 若要這樣做,請在啟動時呼叫 SetProcessDPIAware 函 式。 這個語言函式會讓整個處理流程為 dpi 感知,也就是說,屬於該處理程序的所有視窗都沒有縮放。
  • 使用 DPI 感知的函式。 例如,若要取得游標座標,請呼叫 GetPhysicalCursorPos 函式。 請勿使用 GetCursorPos;其 DPI 感知應用程式中的行為未定義。

如果您的應用程式執行與非 DPI 感知應用程式的直接跨進程通訊,您可以使用 PhysicalToLogicalPointLogicalToPhysicalPoint 函式,在邏輯和實體座標之間轉換。