ApplicationCommandManager 3-1

本小节内容涉及以下类:

  • ApplicationCommandManager 命令管理器,数据容器,保存快捷键集合对象
  • KeyPressMappingSet 快捷键集合,保存所有命令及其详细信息
  • ApplicationCommandInfo 命令信息,代表一条具体的命令
  • ApplicationCommandManagerListener 捕获命令管理器所产生的消息(通常无需直接使用)
  • ApplicationCommandTarget 命令目标,定义所有命令,并执行具体的功能
  • InvocationInfo 命令目标所调用的命令信息

JUCE程序中的各类命令和快捷键可集中管理和统一调度,主要用到ApplicationCommandTarget(程序命令目标,抽象基类)和ApplicationCommandManager(程序命令管理器类,大小64字节)这两个类。任意组件均可成为程序命令目标,而命令管理器则用于注册程序中的所有命令目标并提供组件所需的KeyListener。

程序命令功能的实质是取代各组件实际执行的功能性代码,如果该组件继承了程序命令目标类,则具体执行的功能性代码在该类的有关函数中集中编码,并可为每条命令添加快捷键等信息。按钮、菜单项等控件可直接添加具体的命令项,用来触发自身。

实现程序命令功能的关键有3点

1、要接受命令或快捷键的组件类需继承自ApplicationCommandTarget程序命令目标类,继承而来的4个纯虚函数要实现。这4个函数的作用分别是:
(1)命令ID的集合(数组)
(2)命令的文字描述
(3)命令所执行的具体功能
(4)如果本类无法处理该命令,则传递给下一个命令目标

命令目标组件往往包含按钮、菜单等控件,此时,按钮和各个菜单项可设置触发自身的命令,而无需再手工添加常规的判断处理。

2、声明并定义全局性的ApplicationCommandManager命令管理器对象,或者将其置于最顶层的窗口框架类(此时需为public数据成员),或者干脆将其封装为一个单例类。该对象异常关键。如果声明为全局性的指针,则声明的同时可初始化为nullptr,而后在主程序类的initialise()函数中实例化。其它编译单元可使用extern关键字在文件开始处声明,使本文件可以使用。无论如何声明,命令管理器对象均需在窗口框架类的构造函数中注册本程序的所有命令目标类对象,有多少注册多少。可将注册理解为“命令目标的所有命令添加到命令管理器中,以便集中调度和统一派遣”。

3、命令管理器注册命令目标后,窗口框架类或其他顶级组件类需绑定自身的按键捕获器,使本组件收到的所有按键信息均可被按键捕获器捕获并处理(即按键捕获器将按键信息转发给命令管理器,命令管理器根据已添加的命令目标,对按键信息进行最佳派遣和调度)。

由上可知,实现程序命令和快捷键功能需2个核心类和1个关键点,为理清思路,再次解释如下:

  1. ApplicationCommandTarget程序命令目标类,即接收并处理命令的目标类。要实现命令和快捷键集中管理与调度的类,比如用户界面(组件)类,需继承自本类并实现本类的4个纯虚函数。并且,该类所容纳并管理的按钮、菜单、工具栏按钮等等,在设置这些控件的时候,可通过程序命令管理器来设置其快捷键并指定所执行的命令(基于命令管理器中的命令条目的索引值)。
  2. ApplicationCommandManager程序命令管理器,用于注册本程序中所有的程序命令目标类对象,管理和调度这些目标类的所有命令。
  3. 顶级组件(比如窗口框架类)需addKeyListener()绑定KeyPressMappingSet对象,所收到的按键信息将由该对象捕获并处理。而该对象是命令管理器对象的数据成员之一,可利用命令管理器的getKeyMappings()函数返回之。

ApplicationCommandManager命令管理器及其在顶级组件中的用法示例:(略)