关于键盘快捷键

快捷键与菜单密切相关, 两者都为用户提供了对应用程序的命令集的访问权限。 通常,用户依赖应用程序的菜单来了解命令集,然后在他们更熟练地使用应用程序时切换到使用加速器。 与菜单相比,加速器提供对命令的更快、更直接的访问。 应用程序至少应为更常用的命令提供加速器。 虽然加速器通常生成作为菜单项存在的命令,但它们也可以生成没有等效菜单项的命令。

此部分涵盖以下主题。

快捷键对应表

加速键表由 ACCEL 结构的数组组成,每个结构定义一个单独的加速器。 每个 ACCEL 结构包括以下信息:

  • 加速器的击键组合。
  • 加速器的标识符。
  • 各种标志。 这包括一个指定系统是否在使用快捷键时通过突出显示相应的菜单项(如果有)来提供视觉反馈的

若要处理指定线程的加速器击键,开发人员必须在与线程的消息队列关联的消息循环中调用 TranslateAccelerator 函数。 TranslateAccelerator 函数监视消息队列的键盘输入,检查与快捷键表中的条目匹配的组合键。 当 TranslateAccelerator 找到匹配项时,它会将键盘输入 (即WM_KEYUPWM_KEYDOWN消息) 转换为WM_COMMANDWM_SYSCOMMAND消息,然后将消息发送到指定窗口的窗口过程。 下图显示了如何处理加速器。

键盘快捷键处理模型

WM_COMMAND消息包括导致 TranslateAccelerator 生成消息的加速器的标识符。 窗口过程检查标识符以确定消息源,然后相应地处理消息。

快捷键表存在于两个不同的级别。 系统维护一个适用于所有应用程序的系统范围的加速器表。 应用程序无法修改系统加速器表。 有关系统加速器表提供的加速器的说明,请参阅 加速器击键分配

系统还为每个应用程序维护加速器表。 应用程序可以定义任意数量的快捷键表以用于自己的窗口。 唯一的 32 位句柄 (HACCEL) 标识每个表。 但是,对于指定线程,一次只能有一个快捷键表处于活动状态。 传递给 TranslateAccelerator 函数的快捷键表的句柄确定线程处于活动状态的快捷键表。 通过将不同的快捷键表句柄传递给 TranslateAccelerator,可以随时更改活动快捷键表。

Accelerator-Table创建

为应用程序创建加速器表需要几个步骤。 首先,资源编译器用于创建加速器表资源并将其添加到应用程序的可执行文件。 在运行时, LoadAccelerators 函数用于将加速器表加载到内存中并检索加速器表的句柄。 此句柄将传递给 TranslateAccelerator 函数以激活快捷键表。

还可以通过将 ACCEL 结构的数组传递给 CreateAcceleratorTable 函数,在运行时为应用程序创建加速器表。 此方法支持应用程序中的用户定义加速器。 与 LoadAccelerators 函数一样, CreateAcceleratorTable 返回可传递给 TranslateAccelerator 以激活快捷键表的快捷键表句柄。

系统会自动销毁 由 LoadAccelerator 加载由 CreateAcceleratorTable 创建的加速器表。 但是,应用程序可以在运行时释放资源,方法是通过调用 DestroyAcceleratorTable 函数销毁不再需要的加速器表。

可以复制和修改现有的快捷键表。 现有快捷键表是使用 CopyAcceleratorTable 函数复制的。 修改副本后,通过调用 CreateAcceleratorTable 检索新快捷键表的句柄。 最后,将句柄传递给 TranslateAccelerator 以激活新表。

快捷键击分配

ASCII 字符代码或虚拟键代码可用于定义加速器。 ASCII 字符代码使加速器区分大小写。 因此,使用 ASCII“C”字符将加速键定义为 Alt+C 而不是 Alt+c。 但是,区分大小写的加速器的使用可能会造成混淆。 例如,如果 CAPS LOCK 键关闭或 SHIFT 键按下,则生成 Alt+C 加速器,但如果两者都关闭,则不会生成。

通常,加速器不需要区分大小写,因此大多数应用程序使用虚拟键代码作为加速器,而不是 ASCII 字符代码。

避免使用与应用程序的菜单助记键冲突的加速键,因为加速键会替代助记键,这可能会使用户感到困惑。 有关菜单助记键的详细信息,请参阅 菜单

如果应用程序定义了也在系统加速器表中定义的加速器,则应用程序定义的加速器将替代系统加速器,但仅在应用程序的上下文中。 但是,请避免这种做法,因为它会阻止系统加速器在用户界面中执行其标准角色。 以下列表描述了系统范围的加速器:

加速器 说明
Alt + Esc 切换到下一个应用程序。
Alt + F4 关闭应用程序或窗口。
Alt+连字符 打开文档窗口的“ 窗口 ”菜单。
ALT+打印屏幕 将活动窗口中的图像复制到剪贴板上。
ALT+空格键 打开应用程序的main窗口的“窗口”菜单。
Alt+Tab 切换到下一个应用程序。
Ctrl+Esc 切换到“ 开始 ”菜单。
Ctrl+F4 关闭活动组或文档窗口。
F1 启动应用程序的帮助文件(如果存在)。
PRINT SCREEN 将屏幕上的图像复制到剪贴板上。
Shift+Alt+Tab 切换到上一个应用程序。 用户必须按住 Alt+Shift,同时按 TAB。

 

快捷键和菜单

使用快捷键与选择菜单项相同:这两个操作都会导致系统向相应的窗口过程发送 WM_COMMANDWM_SYSCOMMAND 消息。 WM_COMMAND消息包括窗口过程检查以确定消息源的标识符。 如果加速器生成了 WM_COMMAND 消息,则标识符为加速器的标识符。 同样,如果菜单项生成了 WM_COMMAND 消息,则标识符为菜单项的标识符。 由于加速器提供了用于从菜单中选择命令的快捷方式,因此应用程序通常会为加速器和相应的菜单项分配相同的标识符。

应用程序处理加速器 WM_COMMAND 消息的方式与相应菜单项 WM_COMMAND 消息完全相同。 但是, WM_COMMAND 消息包含一个标志,该标志指定消息是源自快捷键还是菜单项,以防加速器的处理方式必须与相应的菜单项不同。 WM_SYSCOMMAND消息不包含此标志。

标识符确定加速器是生成 WM_COMMAND 还是 WM_SYSCOMMAND 消息。 如果标识符的值与“系统”菜单中的菜单项相同,则加速器将生成 WM_SYSCOMMAND 消息。 否则,加速器将生成 WM_COMMAND 消息。

如果快捷键具有与菜单项相同的标识符,并且菜单项灰显或禁用,则快捷键将被禁用,并且不会生成 WM_COMMANDWM_SYSCOMMAND 消息。 此外,如果最小化相应的窗口,加速器不会生成命令消息。

当用户使用对应于菜单项的快捷键时,窗口过程将接收 WM_INITMENUWM_INITMENUPOPUP 消息,就像用户选择了菜单项一样。 有关如何处理这些消息的信息,请参阅 菜单

对应于菜单项的快捷键应包含在菜单项的文本中。

UI 状态

Windows 使应用程序能够在其 UI 中隐藏或显示各种功能。 这些设置称为 UI 状态。 UI 状态包括以下设置:

  • 焦点指示器 (,例如按钮上的焦点矩形)
  • 键盘快捷键 (控件标签中的下划线指示)

窗口可以发送消息以请求更改 UI 状态,可以查询 UI 状态,或对其子窗口强制实施特定状态。 这些消息如下所示。

消息 说明
WM_CHANGEUISTATE 指示 UI 状态应更改。
WM_QUERYUISTATE 检索窗口的 UI 状态。
WM_UPDATEUISTATE 更改 UI 状态。

 

默认情况下,顶级窗口的所有子窗口都是使用与其父窗口相同的 UI 状态创建的。

系统处理对话框中控件的 UI 状态。 创建对话框时,系统会相应地初始化 UI 状态。 所有子控件都继承此状态。 创建对话框后,系统会监视用户的击键。 如果 UI 状态设置处于隐藏状态,并且用户使用键盘导航,系统会更新 UI 状态。 例如,如果用户按 Tab 键将焦点移动到下一个控件,则系统会调用 WM_CHANGEUISTATE 以使焦点指示器可见。 如果用户按 Alt 键,系统会调用 WM_CHANGEUISTATE 以使键盘快捷键可见。

如果控件支持在其包含的 UI 元素之间导航,则可以更新自己的 UI 状态。 控件可以调用 WM_QUERYUISTATE 来检索和缓存初始 UI 状态。 每当控件收到 WM_UPDATEUISTATE 消息时,它都可以更新其 UI 状态,并将 WM_CHANGEUISTATE 消息发送到其父级。 每个窗口将继续将消息发送到其父级,直到到达顶级窗口。 顶级窗口将 WM_UPDATEUISTATE 消息发送到窗口树中的窗口。 如果窗口未传递 WM_CHANGEUISTATE 消息,则它不会到达顶级窗口,UI 状态也不会更新。