李青松
(第七一五研究所,杭州,310023)
基于JARI_EGK圖形開(kāi)發(fā)系統(tǒng)在聲吶多功能顯控臺(tái)中的應(yīng)用
李青松
(第七一五研究所,杭州,310023)
為了解決VxWorks系統(tǒng)中直接利用WindML開(kāi)發(fā)圖形界面很困難,滿足艦艇中聲吶多功能顯控臺(tái)用戶提出的代碼開(kāi)發(fā)簡(jiǎn)單及維護(hù)方便的要求,采用了JARI_EGK圖形開(kāi)發(fā)系統(tǒng)這種方法。該開(kāi)發(fā)系統(tǒng)已經(jīng)在針對(duì)某型聲吶的某型顯控臺(tái)中得到了應(yīng)用,實(shí)踐情況表明JARI_EGK能夠較好地滿足目前艦艇中聲吶多功能顯控臺(tái)的需求。
JARI_EGK;聲吶;顯控臺(tái);WindML;人機(jī)界面程序
雖然VxWorks的圖形開(kāi)發(fā)組件WindML在圖形界面開(kāi)發(fā)中的功能很強(qiáng)大,但由于WindML的開(kāi)發(fā)很底層[1],如果在聲吶多功能顯控臺(tái)中直接利用WindML進(jìn)行人機(jī)界面圖形開(kāi)發(fā),那么不僅需要程序開(kāi)發(fā)人員熟悉外部的輸入輸出事件,而且程序開(kāi)發(fā)的工作量將會(huì)很大,大量代碼重復(fù),維護(hù)成本高,無(wú)法滿足艦艇中聲吶多功能顯控臺(tái)不斷提高的用戶需求。針對(duì)這種問(wèn)題,我們利用了在WindML基礎(chǔ)上基于控件技術(shù)的人機(jī)界面圖形開(kāi)發(fā)庫(kù)JARI_EGK(JARI Embedded GUI Kit),實(shí)現(xiàn)了基本控件集。本文將介紹JARI_EGK的工作原理及其在聲吶多功能顯控臺(tái)中的應(yīng)用。
同微軟MFC等其它人機(jī)界面開(kāi)發(fā)工具一樣,JARI_EGK也是基于窗口和控件的,同樣也有事件處理以及圖形刷新。本節(jié)重點(diǎn)討論JARI_EGK中的窗口和控件關(guān)系、事件傳遞機(jī)制、窗口和控件狀態(tài)更新機(jī)制。
1.1 窗口和控件類關(guān)系
JARI_EGK采用了面向?qū)ο蟮脑O(shè)計(jì)方法,包含了人機(jī)界面中基本的窗口和控件,它包括四個(gè)主要的類:Egk_Widget(控件基類)、Egk_Group(控件組類)、Egk_Window(窗口類)和Egk(全局類)。
Egk_Widget類是JARI_EGK其他所有小窗口類的基類,它包含有控件的基本屬性,如X坐標(biāo)、Y坐標(biāo)、寬度和高度;控件的回調(diào)函數(shù)、顯示、隱藏和是否可見(jiàn)等方法。另外還包括兩個(gè)重要的虛函數(shù)virtual void draw()和virtual void handle(int event),派生類可以重載這兩個(gè)函數(shù),分別用來(lái)重畫(huà)控件和處理控件的消息事件。Egk_Group類是由Egk_Widget類派生出來(lái)的,而Egk_Window類是Egk_Group類的子類。Egk類為JARI_EGK提供了許多靜態(tài)方法,包含了許多通用的靜態(tài)函數(shù),方便用戶獲取和設(shè)置當(dāng)前應(yīng)用的狀態(tài),其中一個(gè)重要的靜態(tài)成員函數(shù)static int run(),用來(lái)分發(fā)控件的消息。
當(dāng)創(chuàng)建窗口的時(shí)候,在Egk類這個(gè)全局靜態(tài)變量鏈表里面增加一個(gè)窗口類指針[2],窗口包含一個(gè)控件指針數(shù)組,控件指針數(shù)組的第一個(gè)指針指向窗口本身,余下的依次指向其它控件以及控件組,控件組又可以包含其他的控件(即其他控件指針)。窗口創(chuàng)建結(jié)束后控件指針數(shù)組設(shè)置結(jié)束標(biāo)識(shí),整個(gè)窗口、控件、控件組形成一個(gè)整體。
1.2 事件傳遞機(jī)制
JARI_EGK事件處理如圖1所示[3]。JARI_EGK采用的是面向?qū)ο蟮脑O(shè)計(jì)理念,事件傳遞的方法是通過(guò)重載Egk_Widget控件基類的事件處理函數(shù)virtual void handle(int event)來(lái)實(shí)現(xiàn)的。
圖1 JARI_EGK事件處理圖
外部消息,比如鼠標(biāo)、鍵盤(pán)信息,首先發(fā)送給窗口后由WindML窗口管理器處理。Egk類靜態(tài)成員函數(shù)Egk::run()根據(jù)窗口的ID號(hào)將這些消息發(fā)送到相應(yīng)的窗口類。窗口類里面的控件組成員變量包含了所有加載到本窗口的控件指針,窗口類遍歷控件指針,根據(jù)控件基類位置信息判斷給哪個(gè)控件發(fā)送消息,然后發(fā)送消息給該控件,控件基類指針指向要選中的控件,這樣執(zhí)行事件處理函數(shù)就可以響應(yīng)消息了。比如當(dāng)窗口接收到鼠標(biāo)在某個(gè)控件中移動(dòng)鼠標(biāo)時(shí),執(zhí)行鼠標(biāo)的事件處理函數(shù)handle來(lái)實(shí)現(xiàn)鼠標(biāo)移動(dòng)事件。
1.3 窗口和控件更新原理
窗口控件的行為和窗口一樣,即能夠接收鍵盤(pán)和鼠標(biāo)等外部輸入,也可以在自己的區(qū)域內(nèi)進(jìn)行輸出,只是它們的所有活動(dòng)被限制在主窗口中??丶痛翱趧?chuàng)建完畢后,循環(huán)等待各種外部事件。窗口和控件狀態(tài)更新實(shí)現(xiàn)機(jī)理如圖2所示[3]。在控件基類Egk_Widget里包含一個(gè)成員變量damage_,當(dāng)控件需要更新時(shí),我們把控件的damage_變量設(shè)置成EGK_DAMAGE_CHILD,同時(shí)將控件所隸屬窗口的damage_變量值也設(shè)置為EGK_DAMAGE_ CHILD。當(dāng)控件需要更新時(shí),發(fā)送消息告訴窗口需要更新但不是全部更新;Egk::run()循環(huán)檢測(cè)到窗口的更新信息(只是更新控件);窗口類查詢每個(gè)控件更新信息后,調(diào)用控件的Draw函數(shù)更新控件。當(dāng)整個(gè)窗口需要更新時(shí),我們把窗口的damage_變量變成EGK_DAMAGE_ALL,這時(shí)窗口類更新整個(gè)窗口及其控件,這種機(jī)制保證了窗口和控件及時(shí)有效的重繪。
圖2 窗口更新流程圖
聲吶顯控臺(tái)的主要功能是將前端信號(hào)處理機(jī)的處理結(jié)果在顯示器中顯示出來(lái),方便觀看和操作,有利于發(fā)現(xiàn)目標(biāo)并對(duì)目標(biāo)進(jìn)行判斷。本節(jié)主要介紹利用JARI_EGK來(lái)開(kāi)發(fā)聲吶顯控臺(tái)人機(jī)界面的方法。在聲吶多功能顯控臺(tái)中,最常用的是包含上下兩個(gè)顯示器的顯控臺(tái),下面我們以雙屏顯示器為例來(lái)介紹開(kāi)發(fā)方法。使用JARI_EGK開(kāi)發(fā)時(shí),我們可以將整個(gè)雙屏顯示器看成一個(gè)Egk_Window窗口,將整個(gè)上屏或者下屏顯示器看成Egk_Group控件組。在聲吶顯控臺(tái)中,實(shí)際使用的畫(huà)面有幾個(gè)甚至十幾個(gè),因此用戶需要反復(fù)的切換顯示器畫(huà)面來(lái)觀看聲吶圖形,我們可以通過(guò)調(diào)用Egk_Widget控件基類的hide()和show()方法來(lái)隱藏或者顯示某個(gè)聲吶畫(huà)面。根據(jù)第一節(jié)介紹的窗口和控件的關(guān)系,我們可以在每個(gè)聲吶畫(huà)面組中添加JARI_EGK的控件對(duì)象或者添加從Egk_Widget控件基類派生出來(lái)的自定義類的控件對(duì)象。當(dāng)每個(gè)聲吶顯示畫(huà)面創(chuàng)建完畢后,我們調(diào)用Egk_Group類的成員函數(shù)end()來(lái)結(jié)束顯示畫(huà)面控件組的創(chuàng)建工作。當(dāng)所有的聲吶顯示畫(huà)面都創(chuàng)建完畢后,我們?cè)僬{(diào)用Egk_Window類的end()方法來(lái)結(jié)束整個(gè)窗口的創(chuàng)建。最后,通過(guò)調(diào)用Egk::run()函數(shù)來(lái)實(shí)現(xiàn)整個(gè)聲吶顯控臺(tái)人機(jī)界面的圖形刷新。假設(shè)聲吶顯控臺(tái)中有M個(gè)畫(huà)面(M為正整數(shù)),那么基于JARI_EGK的具體的開(kāi)發(fā)方法流程圖如圖3所示。
圖3 人機(jī)界面開(kāi)發(fā)方法流程圖
在聲吶多功能顯控臺(tái)中,常常包含著多種圖形,例如主動(dòng)聲吶的主動(dòng)全向搜索掃描圖。掃描圖是一種顯示聲吶回聲數(shù)據(jù)的常見(jiàn)形式[3],本節(jié)我們通過(guò)一個(gè)主動(dòng)聲吶的掃描圖實(shí)例來(lái)說(shuō)明JARI_EGK具體的開(kāi)發(fā)方法。聲吶掃描圖是根據(jù)用戶特定需要開(kāi)發(fā)的,因此我們需要從Egk_Widget控件基類中派生自定義的掃描圖類CScanDraw,具體的類定義如下。
在聲吶顯控臺(tái)中,用戶通常需要在主動(dòng)掃描圖中處理相應(yīng)的光標(biāo)事件,對(duì)此我們可以通過(guò)下面的handle()函數(shù)來(lái)處理。
創(chuàng)建掃描圖控件對(duì)象,創(chuàng)建主動(dòng)掃描圖數(shù)據(jù)刷新管理任務(wù)tRefresh和JARI_EGK消息管理任務(wù)tEgkRun。
該掃描圖對(duì)象實(shí)時(shí)重畫(huà)的方法如下:
ARI_EGK圖形開(kāi)發(fā)系統(tǒng)不僅可以在聲吶多功能顯控臺(tái)中使用,而且也適用于艦艇其他設(shè)備的顯控臺(tái)軟件開(kāi)發(fā)。本文內(nèi)容對(duì)于將要采用JARI_EGK來(lái)開(kāi)發(fā)顯控臺(tái)軟件的用戶具有一定的參考意義。雖然該工具已經(jīng)比直接使用WindML開(kāi)發(fā)圖形界面簡(jiǎn)單了很多,但是使用該工具創(chuàng)建控件時(shí)需要全部用代碼寫(xiě)出來(lái),并沒(méi)有微軟MFC控件那樣方便,因此后續(xù)工作中還需要進(jìn)一步完善該工具的使用。
[1]魏銀英.基于VxWorks的成像聲吶顯控軟件技術(shù)研究[J].哈爾濱工程大學(xué)學(xué)報(bào),2008,(1).
[2]劉東濤,肖峰.基于VxWorks的人機(jī)界面圖形開(kāi)發(fā)系統(tǒng)設(shè)計(jì)[J].指揮控制與仿真,2011,33(4).
[3]魯詣斌,戴若星.嵌入式圖形系統(tǒng)在聲吶顯示中的應(yīng)用[J].聲學(xué)與電子工程,2009,(1):20-23.