870920 Menu

JUCE类库之PopupMenu 3-2

弹出式菜单的异步回调

由上可知,使用弹出式菜单,show()函数非常关键,但它无法实现异步回调。弹出式菜单属于典型的模态组件,针对所有模态组件,JUCE类库有个异步回调的消息处理机制,体现在PopupMenu类中,就是可替代show()的showMenuAsync()函数。该函数有两个参数:1参为PopupMenu::Options结构体对象,用于设置菜单的各种属性:弹出的菜单附着于哪个组件、位于屏幕的哪个位置、最小宽度、最大列数、菜单项的高度、确保显示哪个菜单项。2参是一个回调函数的指针,其原型函数用于接收用户点选的菜单项ID并进行判断处理。先看一下具体的示例语句:

showMenuAsync()函数的2参详解:forComponent()是ModalCallbackFunction类的静态函数,其返回值为ModalComponentManager::Callback类的指针,也就是showMenuAsync()所需的2参。forComponent()需要两个参数:1参为回调函数的函数名,2参为1参函数的参数。1参回调函数必须符合两个条件:

  1. 必须是内容组件类的静态函数。内容组件即弹出菜单,运行showMenuAsync()函数的类。
  2. 该静态函数至少要有两个参数,1参为int类型,用于接收模态组件的返回值,该参数无需在forComponent()中指明。2参为某个组件类的指针,必须在forComponent()中指明,forComponent()的1参将调用该对象的某个成员函数来执行具体的功能。

若回调的静态函数menuItemChosenCallback()有3个参数,则showMenuAsync()的2参必须写为:

理清了思路,就好办了。现在所需的,是在内容组件类中写一个静态回调函数:

而后在menuItemChosenCallback()的2参对象所属的类中写performDemoMenuItem()函数,用于判断处理用户所点选的菜单项ID,并执行对应的代码。可将这两个函数都写在内容组件类中。这种情况下,forComponent()的2参写为this就行了。

这套复杂的机制最适合用于多线程环境中。即ModalCallbackFunction::forComponent()的2参是一个运行于后台线程的对象,该对象的成员函数由弹出菜单的内容组件类的静态函数menuItemChosenCallback()所回调。如果只是简单的单线程环境,则不必如此繁琐,直接使用show()函数弹出菜单并获取返回值即可。

注:文中有几处术语和概念使用不当的问题。比如某某组件或函数的指针,准确的中文说法应该是:某某组件类的实例对象在堆内存中的起始地址,某函数的内存寻址处,等等。关于C++中文术语与概念使用不当等问题,我先前曾发文做了说明,再次提及,请读者务必谅解。这一点,今后不再重复。