天天看点

管理加速键和焦点矩形的 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 高级玩家或者骨灰级玩家。

普通用户,不会注意到这个操作细节。

对于开发者来说,如果你看到不是太懂,没关系的啊:还是先花精力把主要业务功能做好。

最后