天天看點

管理加速鍵和焦點矩形的 UI 狀态

今天繼續研究界面開發中的細節。

從 Windows 2000 開始,預設情況下,帶下劃線的快捷鍵和焦點矩形(統稱為“鍵盤提示”)等鍵盤訓示器處于隐藏狀态,并且僅在你開始使用鍵盤時才會顯示。你可以從控制台中控制此行為,設定路徑是:“外觀” / “效果” / “隐藏帶下劃線的字母以進行鍵盤導航,直到我按 Alt 鍵”。

請注意,此設定實際上同時控制帶下劃線的字母和焦點矩形,即使文本僅描述其中一種效果也是如此。下劃線将隐藏,直到你按 ALT 鍵,焦點矩形将隐藏,直到按 ALT 鍵或按 TAB 鍵。

下面是它們的工作原理。

在 Win32 中,有三種界面狀态消息,它們分别是:WM_CHANGEUISTATE, WM_QUERYUISTATE 和 WM_UPDATEUISTATE。在我看來,第三個消息有點讓人誤解。它真的應該被稱為類似 WM_UISTATECHANGED,因為它是發生了某事的通知消息,而不是你發送的導緻某事發生的消息。

當通過滑鼠單擊顯示對話框或菜單時,鍵盤提示将被隐藏;如果對話框或菜單是通過按鍵顯示的,則鍵盤提示可見。此決定是通過向主視窗發送帶有 UIS_INITIALIZE 标志的WM_CHANGEUISTATE 消息來做出的。這是由對話框管理器自動完成的,但是如果你正在執行自己的自定義視窗,則必須自己發送。

WM_CHANGEUISTATE 消息将一直傳遞到頂層視窗,該視窗會相應地更改視窗 UI 狀态,然後将 WM_UPDATEUISTATE 消息廣播到其所有子視窗,以通知它們狀态已更改。(當然,如果 WM_CHANGEUISTATE 消息沒有效果(例如,隐藏已隐藏的内容),則WM_UPDATEUISTATE 消息将被優化掉。

當繪制鍵盤提示的視窗收到 WM_UPDATEUISTATE 消息時,它通常會使自身失效,以便可以根據新狀态重新繪制/擦除提示。

在繪制時,繪制鍵盤提示的視窗可以使用 WM_QUERYUISTATE 消息來确定哪些鍵盤提示可見,哪些鍵盤提示是隐藏的,并相應地繪制其内容。如果焦點矩形處于隐藏狀态,則視窗應跳過對繪制焦點矩形函數的調用。如果鍵盤下劃線處于隐藏狀态,則視窗将在其文本繪圖中禁止顯示下劃線。如果視窗使用 DrawText 函數,它可以傳遞DT_HIDEPREFIX 标志來禁止顯示下劃線。如果要響應 WM_DRAWITEM 消息,則應檢查ODS_NOACCEL 和 ODS_NOFOCUSRECT 标志,以确定是應繪制下劃線快捷鍵還是焦點矩形。

最後,在執行過程中,你可能會發現使用者已使用鍵盤在你的控件内進行導航。例如,清單視圖控件可能已經注意到使用者已使用箭頭鍵切換目前選中行。發生這種情況時,控件會向自身發送一個 WM_CHANGEUISTATE 指定應顯示哪些鍵盤提示。如上所述,如果視窗狀态需要更改,則 WM_CHANGEUISTATE 消息最終會導緻視窗樹中的所有視窗都收到WM_UPDATEUISTATE 消息。

IsDialogMessage 函數會根據需要發送 WM_CHANGEUISTATE 消息,是以對話框和其他調用 IsDialogMessage 的代碼都可以免費獲得鍵盤提示資訊。

總結

我想,今天的内容僅适合 Windows 進階玩家或者骨灰級玩家。

普通使用者,不會注意到這個操作細節。

對于開發者來說,如果你看到不是太懂,沒關系的啊:還是先花精力把主要業務功能做好。

最後