李青松
(第七一五研究所,杭州,310023)
基于JARI_EGK图形开发系统在声呐多功能显控台中的应用
李青松
(第七一五研究所,杭州,310023)
为了解决VxWorks系统中直接利用WindML开发图形界面很困难,满足舰艇中声呐多功能显控台用户提出的代码开发简单及维护方便的要求,采用了JARI_EGK图形开发系统这种方法。该开发系统已经在针对某型声呐的某型显控台中得到了应用,实践情况表明JARI_EGK能够较好地满足目前舰艇中声呐多功能显控台的需求。
JARI_EGK;声呐;显控台;WindML;人机界面程序
虽然VxWorks的图形开发组件WindML在图形界面开发中的功能很强大,但由于WindML的开发很底层[1],如果在声呐多功能显控台中直接利用WindML进行人机界面图形开发,那么不仅需要程序开发人员熟悉外部的输入输出事件,而且程序开发的工作量将会很大,大量代码重复,维护成本高,无法满足舰艇中声呐多功能显控台不断提高的用户需求。针对这种问题,我们利用了在WindML基础上基于控件技术的人机界面图形开发库JARI_EGK(JARI Embedded GUI Kit),实现了基本控件集。本文将介绍JARI_EGK的工作原理及其在声呐多功能显控台中的应用。
同微软MFC等其它人机界面开发工具一样,JARI_EGK也是基于窗口和控件的,同样也有事件处理以及图形刷新。本节重点讨论JARI_EGK中的窗口和控件关系、事件传递机制、窗口和控件状态更新机制。
1.1 窗口和控件类关系
JARI_EGK采用了面向对象的设计方法,包含了人机界面中基本的窗口和控件,它包括四个主要的类:Egk_Widget(控件基类)、Egk_Group(控件组类)、Egk_Window(窗口类)和Egk(全局类)。
Egk_Widget类是JARI_EGK其他所有小窗口类的基类,它包含有控件的基本属性,如X坐标、Y坐标、宽度和高度;控件的回调函数、显示、隐藏和是否可见等方法。另外还包括两个重要的虚函数virtual void draw()和virtual void handle(int event),派生类可以重载这两个函数,分别用来重画控件和处理控件的消息事件。Egk_Group类是由Egk_Widget类派生出来的,而Egk_Window类是Egk_Group类的子类。Egk类为JARI_EGK提供了许多静态方法,包含了许多通用的静态函数,方便用户获取和设置当前应用的状态,其中一个重要的静态成员函数static int run(),用来分发控件的消息。
当创建窗口的时候,在Egk类这个全局静态变量链表里面增加一个窗口类指针[2],窗口包含一个控件指针数组,控件指针数组的第一个指针指向窗口本身,余下的依次指向其它控件以及控件组,控件组又可以包含其他的控件(即其他控件指针)。窗口创建结束后控件指针数组设置结束标识,整个窗口、控件、控件组形成一个整体。
1.2 事件传递机制
JARI_EGK事件处理如图1所示[3]。JARI_EGK采用的是面向对象的设计理念,事件传递的方法是通过重载Egk_Widget控件基类的事件处理函数virtual void handle(int event)来实现的。
图1 JARI_EGK事件处理图
外部消息,比如鼠标、键盘信息,首先发送给窗口后由WindML窗口管理器处理。Egk类静态成员函数Egk::run()根据窗口的ID号将这些消息发送到相应的窗口类。窗口类里面的控件组成员变量包含了所有加载到本窗口的控件指针,窗口类遍历控件指针,根据控件基类位置信息判断给哪个控件发送消息,然后发送消息给该控件,控件基类指针指向要选中的控件,这样执行事件处理函数就可以响应消息了。比如当窗口接收到鼠标在某个控件中移动鼠标时,执行鼠标的事件处理函数handle来实现鼠标移动事件。
1.3 窗口和控件更新原理
窗口控件的行为和窗口一样,即能够接收键盘和鼠标等外部输入,也可以在自己的区域内进行输出,只是它们的所有活动被限制在主窗口中。控件和窗口创建完毕后,循环等待各种外部事件。窗口和控件状态更新实现机理如图2所示[3]。在控件基类Egk_Widget里包含一个成员变量damage_,当控件需要更新时,我们把控件的damage_变量设置成EGK_DAMAGE_CHILD,同时将控件所隶属窗口的damage_变量值也设置为EGK_DAMAGE_ CHILD。当控件需要更新时,发送消息告诉窗口需要更新但不是全部更新;Egk::run()循环检测到窗口的更新信息(只是更新控件);窗口类查询每个控件更新信息后,调用控件的Draw函数更新控件。当整个窗口需要更新时,我们把窗口的damage_变量变成EGK_DAMAGE_ALL,这时窗口类更新整个窗口及其控件,这种机制保证了窗口和控件及时有效的重绘。
图2 窗口更新流程图
声呐显控台的主要功能是将前端信号处理机的处理结果在显示器中显示出来,方便观看和操作,有利于发现目标并对目标进行判断。本节主要介绍利用JARI_EGK来开发声呐显控台人机界面的方法。在声呐多功能显控台中,最常用的是包含上下两个显示器的显控台,下面我们以双屏显示器为例来介绍开发方法。使用JARI_EGK开发时,我们可以将整个双屏显示器看成一个Egk_Window窗口,将整个上屏或者下屏显示器看成Egk_Group控件组。在声呐显控台中,实际使用的画面有几个甚至十几个,因此用户需要反复的切换显示器画面来观看声呐图形,我们可以通过调用Egk_Widget控件基类的hide()和show()方法来隐藏或者显示某个声呐画面。根据第一节介绍的窗口和控件的关系,我们可以在每个声呐画面组中添加JARI_EGK的控件对象或者添加从Egk_Widget控件基类派生出来的自定义类的控件对象。当每个声呐显示画面创建完毕后,我们调用Egk_Group类的成员函数end()来结束显示画面控件组的创建工作。当所有的声呐显示画面都创建完毕后,我们再调用Egk_Window类的end()方法来结束整个窗口的创建。最后,通过调用Egk::run()函数来实现整个声呐显控台人机界面的图形刷新。假设声呐显控台中有M个画面(M为正整数),那么基于JARI_EGK的具体的开发方法流程图如图3所示。
图3 人机界面开发方法流程图
在声呐多功能显控台中,常常包含着多种图形,例如主动声呐的主动全向搜索扫描图。扫描图是一种显示声呐回声数据的常见形式[3],本节我们通过一个主动声呐的扫描图实例来说明JARI_EGK具体的开发方法。声呐扫描图是根据用户特定需要开发的,因此我们需要从Egk_Widget控件基类中派生自定义的扫描图类CScanDraw,具体的类定义如下。
在声呐显控台中,用户通常需要在主动扫描图中处理相应的光标事件,对此我们可以通过下面的handle()函数来处理。
创建扫描图控件对象,创建主动扫描图数据刷新管理任务tRefresh和JARI_EGK消息管理任务tEgkRun。
该扫描图对象实时重画的方法如下:
ARI_EGK图形开发系统不仅可以在声呐多功能显控台中使用,而且也适用于舰艇其他设备的显控台软件开发。本文内容对于将要采用JARI_EGK来开发显控台软件的用户具有一定的参考意义。虽然该工具已经比直接使用WindML开发图形界面简单了很多,但是使用该工具创建控件时需要全部用代码写出来,并没有微软MFC控件那样方便,因此后续工作中还需要进一步完善该工具的使用。
[1]魏银英.基于VxWorks的成像声呐显控软件技术研究[J].哈尔滨工程大学学报,2008,(1).
[2]刘东涛,肖峰.基于VxWorks的人机界面图形开发系统设计[J].指挥控制与仿真,2011,33(4).
[3]鲁诣斌,戴若星.嵌入式图形系统在声呐显示中的应用[J].声学与电子工程,2009,(1):20-23.