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