1引言
大多數嵌入式系統,僅提供幾個按鍵和像素點較少的LCD,同時處理器運算能力有限(如8/16位單片機),不宜運行商用的GUI圖形庫(如uC/GUI、miniGUI、QT等),但仍然得為用戶提供GUI功能。一個具有代表的硬件平臺如下,提供6個輸入按鍵:上移、下移、左移、右移、確定和取消;有一LCD,不限制物理尺寸與像素點數。如工業儀器需要設置參數一樣,GUI需要支持用戶輸入,本文為滿足這種需要設計圖形控件。
2圖形控件基類
面向對象是C++和JAVA之類的高級語言話題,在這里為什么需要用C語言來實現呢,原因在于嵌入式環境下往往不支持C++和JAVA語言,況且嵌入式工程師對C語言十分親切,減少了學習成本。圖形構件因為其關聯性比較強(繼承),往往將數據和操作組織在一起(封裝),同時為高效實現經常將異構的控件統一操作(多態),基于面向對象來實現是順其自然的。[1]
下面結合圖形控件基類的設計探討C語言實現面向對象的原理。
圖1圖形控件基類的設計
當我們用C語言將上述控件用結構體來組織時,實際上就完成了封裝。這時,對一個對象的操作僅需要調用它的方法,如例1所示。
例1 設定義如下圖形控件基類
typedef struct _graphic_ctrl {……} GRAPHIC_CTRL;
定義一個圖形控件對象:GRAPHIC_CTRL stGCtrl;
可以操作這個對象的方法:gctrl_Create(&stGCtrl,NULL),這個方法根據對象的CtrlSort自動選擇對應的派生類的創建函數。
如果另外需要定義一個類,如文本輸入框,它除了繼承基類外,還有自己的屬性和方法,C語言的實現是將基類包含在子類的結構體中,例2說明了繼承的實現。
例2文本輸入類繼承基類
typedef struct _text_edit
{
GRAPHIC_CTRL stGCtrl;
char *p_chBuf;?
……? ? /* Other attributes of TextEditor */
} TEXT_EDIT;
定義一個文本輸入框對象:TEXT_EDIT stTextEdit;它可以操作父類的方法,如gctrl_Create(&stTextEdit,NULL)。
一個按鈕和一個文本輸入框的回車響應動作是不同的,如何實現控件這種需求呢?改變它調用方法的實現細節,這就是多態的特性。
例3 重載RespBtn方法實現多態
void EnterBtn(void);??
void EnterTextEdit(void);
GRAPHIC_CTRL stBtn;
TEXT_EDIT stTextEdit;
ConstructBtn(&stBtn, EnterBtn);
ConstructTextEdit(&stTextEdit, EnterTextEdit);
現在,終于可以展現一下面向對象帶來的優勢了。設系統響應用戶的“回車”按鍵,軟件可以不考慮控件對象的類別而統一調用RespBtn ()方法,這就實現了軟件開發的精髓之一:高度抽象把復雜的事情簡單化,例4描述了這種統一操作。
例4 統一響應控件的回車操作
gctrl_RespBtn((GRAPHIC_CTRL *)&stBtn);
gctrl_RespBtn((GRAPHIC_CTRL *)&stTextEdit);
有了上述C語言實現面向對象的基礎后,我們再來考慮設計圖形控件就變得容易多了。
3按鈕
如右圖4個按鈕:
按鈕是簡單的控件,它直接繼承GRAPHIC_CTRL父類就能實現。當執行Create()方法時,先將字符串打印在區域中間,后畫出一個矩形;Destroy()方法是空操作,不需要實現;執行Active()方法時,將字符串和矩形區域反白顯示“上一頁”;Inactive()方法同Create()方法一樣,打印字符串和繪制矩形;RespBtn()方法中,它響應“確定”按鍵的具體動作,針對上/下/左/右方向按鍵它向調用者(如窗口)返回切換控件的消息;擴展的Enter()方法實現不同按鍵的“確定”動作響應,從而實現多態技術。
圖2按鍵類的設計
4下拉菜單
Create()方法創建的下拉選擇框如右圖,
除繪制矩形框和框內字符串外,還需要打印框外的文本(定義為STATIC_TEXT),因而在類的屬性中需要添加STATIC_TEXT的指針。Active()方法表現的效果是“MU識別 MAC”,和按鈕激活的動作相似;Inactive()方法與Create()方法相同,Refresh()方法與Create()方法也相同。
在響應按鍵消息時就有區別了。如果“確定”鍵已經被按下,那么控件將呈現圖3左邊的選擇項,這時需要計算是否有空間向下繪制選擇項(可能會超過LCD的下端),如果沒有空間將向上繪制選擇項。“上/下按鍵”可以操作選擇項,圖3右顯示了“下按鍵”操作的結果,因此也需要一個記錄上下鍵位置的數據。再次按下“確定”鍵完成選擇操作“MU識別 APPID”,如,而“取消”鍵隨時可以退出操作過程。
圖3下拉選擇項
如果“確定”鍵沒有被按下,“上/下/左/右按鍵”的響應簡單為向調用者(如窗口)返回切換控件的消息。
很明顯,響應按鍵操作需要一個狀態機,因此類的屬性中將添加BtnStat。
控件的Destroy()方法就變得繁忙了,它有三件事要干:首先向控件返回被選擇項的索引,如果是“確定”鍵將返回有效下標,如果是“取消”鍵將返回無效下標;其次清除選擇項繪制的整個區域;最后得把被選擇項區域破壞的其他控件恢復。
恢復被破壞的控件將是一個值得商榷的話題,理想的方法是先將被破壞的區域保存起來再予以恢復,但這種方法需要操作像素VRAM區,我們將采用這種方法。它的硬件實現原理是LCD的控件器一般都支持READ_LCD_DATA()操作,當指定特定區域的位置和大小后,就可以讀取該區域的像素數據并予以保存;軟件上需要實現類似“壓棧/彈棧”的操作,棧的深度依賴于需要保存VRAM的遞歸次數。有了軟硬件的支持后,先把即將被破壞的區域予以壓棧保存,當需要恢復該區域時,調用彈棧函數恢復該區域。
總結下拉選擇框的類定義如圖4所示:
圖4下拉選擇框類的設計
5文本輸入框
右圖顯示了一個文本輸入框的實例:,
除去矩形框前后的靜態文本顯示外,它和按鈕的顯示是很相似的。
文本輸入框需要一緩沖區來存儲用戶的輸入,此外響應“確定”按鍵時調用軟鍵盤,當軟鍵盤退出時拷貝輸入的字符串,它還需要限定輸入字符串的個數,檢查輸入值的有效性,當輸入非法時需要提示正確的數值范圍。它的類定義如圖5所示。
圖5文本輸入框類的定義
6 軟鍵盤
圖6顯示了一個軟鍵盤的實例,它分為四部分:標題欄、輸入欄、操作集和選項集。標題欄顯示輸入對象的名稱;輸入欄顯示當前已經輸入的文本集,光標可以在輸入字符的任意位置;操作集從左到右是:光標左移、光標右移、退格、下一頁和回車,光標左移和光標右移控制光標在輸入欄中進行移動,退格可以刪除光標前的字符,下一頁就是顯示下一頁選項集(如果有分頁),回車退出軟鍵盤并返回所輸入的字符串,選項集是用戶能進行選擇操作的字符集。
圖6軟鍵盤實例
當軟鍵盤Create()時,它從調用者的對象中獲取標題欄字符串,再根據選項集的數目計算頁數與行數;Destroy()方法與下拉選擇框相同,除清除自己外還需要通知刷新窗口內的所有控件。RespBtn()方法依賴不同的按鍵操作:上/下按鍵修改行索引,左/右按鍵修改列索引,當索引被修改時,先注銷前一個選項(表現為失焦),后激活當前選項(表現為獲焦)。當前激活項是選項集時,“確定”按鍵將該選項的字符添加到輸入欄中;當前激活項是操作集時,“確定”按鍵執行對應的操作。“取消”按鍵可以隨時退出軟鍵盤。
軟鍵盤類的定義如圖7所示:
圖7軟鍵盤類的定義
7 圖形控件的使用
上述設計了4種常用的圖形控件,現在講解調用它們的一般方法。
首先需要為該圖形對象申明并開辟內存,如:
static BTN s_stBC91MExit =
{
.stGCtrl =
{
.chID = BC91M_EXIT,
.chItemNum = 1,
.chSelIx = 0,
.nAddrX = CHAR_LEN * 33,
.nAddrY = BTN_CTRL_Y,
.nSizeW = BTN_CTRL_W,
.nSizeH = CHAR_WIDE,
.pp_chBtnStr = &a_strBC91MBtnStr[3],??
},
};
其次需要調用方法初始化該圖形對象,如下所示:
gctrl_ConsBtn(&s_stBC91MExit, BC91MBtnEnter);
創建窗口時也會調用控件的創建函數:
gctrl_Create(&s_stBC91MExit, NULL);
當用戶按鍵選中該按鈕時,gctrl_Active(&s_stBC91MExit, NULL)會被調用,以便于激活該對象;同樣,gctrl_Inactive(&s_stBC91MExit, NULL)用于注銷該對象;如果本按鈕是激活對象,那么任何用戶按鍵消息將會傳遞給它,即調用方法gctrl_RespBtn(&s_stBC91MExit,
&uRtn);最后當窗口退出時會調用按鈕的銷毀方法,gctrl_Destroy(&s_stBC91MExit, NULL)。
7 結束語
本文設計的輕量級嵌入式圖形控件已經在某工業控制產品中穩定使用多年,該產品選用TRULY公司320x240像素的LCD。采用面向對象的設計,使軟件系統容易開發;簡單化的設計使系統異常穩定;另外占用資源很少,這是商業GUI無法比擬的。需要了解LCD硬件連接與驅動以及窗口系統的實現,可以參見姊妹篇論文《一種輕量級嵌入式GUI設計》。
參 考 文 獻
[1] Steve McConnell. Code Complete. Second Edition. 金戈等譯。電子工業出版社,2006.3
評論
查看更多