程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> ASP編程 >> ASP技巧 >> BREW的第二個程序--菜單顯示練習

BREW的第二個程序--菜單顯示練習

編輯:ASP技巧

 這一周可真背,先是硬盤壞了,接著主板都壞了!害得我花了一周的時間才把機器搞好,BREW的環境安裝好,這才做了第二個BREW程序。

   

設置並輸出菜單
需求:開發的BREW程序有自己的圖標,不使用系統的圖標。一進入系統,先是顯示一個圖標及程序名稱。這個畫面停留兩秒鐘後,進入主頁面。主頁面的結構為:最上面30像素高的地方是顯示標題用的;最下面也有三十像素高的地方來顯示操作菜單,有確定和退出;然後中間是三個菜單顯示的地方。

需求分析及具體實現:

需要定義的變量:在程序中都有詳細注釋,這裡就不多講了。
需要初始化的東東:因為有兩處菜單顯示(中間的和底部的),並且這兩處菜單的樣式等都不一樣,所以,在初始化函數裡得創建兩個IMenuCtl的對象,並且初始化顯示這兩塊菜單的矩形樣式。在後面的顯示過程中,因為有顯示位置的計算,所以再初始化一個整形的變量來存儲粗體字的高度。設置一個獲取全屏的矩形變量,這在後面多處會用到。
需要釋放的東東:因為在SDK裡的IMenuCtl接口說明裡有提到:不再需要菜單控件,要用IMenuCtl_Release()函數將其釋放。所以,在初始化時創建的兩個IMenuCtl對象,在最後要釋放掉。
一進入程序顯示二秒鐘的畫面,用ISHELL_SetTimer()函數實現。先是將整個屏幕填充背景顏色,然後將圖片從數據庫裡讀出,再顯示到屏幕的正中。在圖片的下邊,顯示程序的名稱(文字和圖片之間相隔6像素)。
因為程序中都有詳細的注釋說明,在這裡就不多說了。
需要注意的事項:

標題因為只是文字,所以使用了IDISPLAY_DrawText()方法來繪制。而中間和底部的菜單除了文字,還有系統默認的事件(比如點擊手機鍵盤上的上、下鍵或使用滾輪,不同的菜單會在選取和不取消選取狀態之間切換,等等),所以,得用指向IMenuCtl的指針,並且調用IMenuCtl接口的相關方法來繪制(繪制的相關過程在SDK上都有詳細的說明,詳情請參見SDK)。
如果是菜單項響應系統事件,那麼,就交於系統去處理。處理完成後,仍交於系統即可。每個事件的處理,如果要是處理完畢,還想交給系統處理,就返回FALSE,如果不想系統處理,就返回TRUE,這個時候就代表用戶處理完畢,系統將不會處理。對於掛起和恢復的事件,要特別注意的是屏幕需要重新繪制,某些資源需要釋放或者是重新載入。
我將繪制標題的動作封裝了一個方法,是因為標題在每一頁顯示基本上都會有。而且,它們都有很多的共性。這樣方便我們修改代碼,也使流程清晰化。


程序代碼如下(省略了大段系統自動生成的注釋後):

 

代碼
  1 #include "AEEModGen.h"          // Module interface definitions
  2 #include "AEEAppGen.h"          // Applet interface definitions
  3 #include "AEEShell.h"           // Shell interface definitions
  4
  5 #include "AEEMenu.h"
  6 #include "menuctltest.brh"
  7
  8 #include "menuctltest.bid"
  9
10 #define        MAIN_TITLE_HEIGHT    30//最上面標題的高度
11 #define        SOFT_KEY_HEIGHT        30//最下面菜單的高度
12
13 #define        RES_STR_MAX_LEN        16//資源文件字符串的最大長度       
14
15 #define TITLE_BACK_COLOR        MAKE_RGB(28,28,28)//最上面標題欄的背景顏色
16 #define ITEM_BACK_COLOR            MAKE_RGB(44,44,44)//中間菜單區域的
17 #define ITEM_TEXT_COLOR            MAKE_RGB(255,255,255)//中間菜單文本的顏色
18 #define ITEM_SEL_BACK_COLOR        MAKE_RGB(46,90,185)//已經選擇文本的背景顏色
19 #define ITEM_SEL_TEXT_COLOR        MAKE_RGB(255,255,255)//已經選擇文本的字體顏色
20 #define ITEM_FRAME_COLOR        MAKE_RGB(83,162,241)//邊框顏色
21
22 /*-------------------------------------------------------------------
23 Applet structure. All variables in here are reference via "pMe->"
24 -------------------------------------------------------------------*/
25 // create an applet structure that's passed around. All variables in
26 // here will be able to be referenced as static.
27 typedef struct _menuctltest {
28     AEEApplet      a ;           // First element of this structure must be AEEApplet
29     AEEDeviceInfo  DeviceInfo; // always have Access to the hardware device information
30
31     // add your own variables here...
32     IMenuCtl*        p_MainMenuCtl;//指向IMenuCtl的指針,用來顯示和控制中間主要的菜單項
33     IMenuCtl*        p_SoftKeyCtl;//指向IMenuCtl的指針,用來顯示和控制底部的菜單項
34     AEERect            p_WholeScreen;//定義一個全屏的矩形變量
35     AECHAR            p_MainTitle[RES_STR_MAX_LEN];//定義獲取標題資源字符串的數組
36     int                r_BlodFontHeight;//定義獲取粗體字字符高度的變量
37 } menuctltest;
38
39 /*-------------------------------------------------------------------
40 Function PRototypes
41 -------------------------------------------------------------------*/
42 static  boolean menuctltest_HandleEvent(menuctltest* pMe,
43                                                    AEEEvent eCode, uint16 wParam,
44                                                    uint32 dwParam);
45 boolean menuctltest_InitAppData(menuctltest* pMe);
46 void    menuctltest_FreeAppData(menuctltest* pMe);
47 static void InitMainMenu(menuctltest* pMe);//初始化放置中間主菜單和底部菜單的矩形樣式的方法
48 static void ShowAnimation(menuctltest* pMe);//一開始顯示程序圖標及文字的方法
49 static void ShowMain(menuctltest* pMe);//顯示主要界面的方法
50 static void DrawTitle(menuctltest* pMe);//繪制最上面標題文字的方法
51 /*===============================================================================
52 FUNCTION DEFINITIONS
53 =============================================================================== */
54 int AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *po, void **ppObj)
55 {
56     *ppObj = NULL;
57
58     if( ClsId == AEECLSID_MENUCTLTEST )
59     {
60         // Create the applet and make room for the applet structure
61         if( AEEApplet_New(sizeof(menuctltest),
62                           ClsId,
63                           pIShell,
64                           po,
65                           (IApplet**)ppObj,
66                           (AEEHANDLER)menuctltest_HandleEvent,
67                           (PFNFREEAPPDATA)menuctltest_FreeAppData) ) // the FreeAppData function is called after sending EVT_APP_STOP to the HandleEvent function
68                          
69         {
70             //Initialize applet data, this is called before sending EVT_APP_START
71             // to the HandleEvent function
72             if(menuctltest_InitAppData((menuctltest*)*ppObj))
73             {
74                 //Data initialized successfully
75                 return(AEE_SUCCESS);
76             }
77             else
78             {
79                 //Release the applet. This will free the memory allocated for the applet when
80                 // AEEApplet_New was called.
81                 IAPPLET_Release((IApplet*)*ppObj);
82                 return EFAILED;
83             }
84
85         } // end AEEApplet_New
86
87     }
88
89     return(EFAILED);
90 }
91
92 static boolean menuctltest_HandleEvent(menuctltest* pMe, AEEEvent eCode, uint16 wParam, uint32 dwParam)
93 { 
94     //菜單控件對象處理接收事件的系統方法。如果是典型按鍵按下事件,則將由系統處理;如果不是,後面自己寫的代碼處理。
95     if( pMe->p_MainMenuCtl && IMENUCTL_HandleEvent( pMe->p_MainMenuCtl, eCode, wParam, dwParam) )
96         return TRUE;
97
98     switch (eCode)
99     {
100         // App is told it is starting up
101         case EVT_APP_START:                       
102             // Add your code here...
103             ShowAnimation(pMe);
104             return(TRUE);
105
106
107         // App is told it is exiting
108         case EVT_APP_STOP:
109             // Add your code here...
110
111               return(TRUE);
112
113
114         // App is being suspended
115         case EVT_APP_SUSPEND:
116             // Add your code here...
117
118               return(TRUE);
119
120
121         // App is being resumed
122         case EVT_APP_RESUME:
123             // Add your code here...
124
125               return(TRUE);
126
127
128         // An SMS message has arrived for this app. Message is in the dwParam above as (char *)
129         // sender simply uses this format "//BREW:ClassId:Message", example //BREW:0x00000001:Hello World
130         case EVT_APP_MESSAGE:
131             // Add your code here...
132
133               return(TRUE);
134
135         // A key was pressed. Look at the wParam above to see which key was pressed. The key
136         // codes are in AEEVCodes.h. Example "AVK_1" means that the "1" key was pressed.
137         case EVT_KEY:
138             // Add your code here...
139
140               return(TRUE);
141
142
143         // If nothing fits up to this point then we'll just break out
144         default:
145             break;
146    }
147
148    return FALSE;
149 }
150
151
152 // this function is called when your application is starting up
153 boolean menuctltest_InitAppData(menuctltest* pMe)
154 {
155     // Get the device information for this handset.
156     // Reference all the data by looking at the pMe->DeviceInfo structure
157     // Check the API reference guide for all the handy device info you can get
158     pMe->DeviceInfo.wStructSize = sizeof(pMe->DeviceInfo);
159     ISHELL_GetDeviceInfo(pMe->a.m_pIShell,&pMe->DeviceInfo);
160
161     // Insert your code here for initializing or allocating resources...
162     // 創建了兩個IMenuCtl對象
163     if( ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_MENUCTL, (void**)(&pMe->p_MainMenuCtl)) != SUCCESS)
164         return FALSE;
165     if( ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_SOFTKEYCTL, (void**)(&pMe->p_SoftKeyCtl)) != SUCCESS)
166         return FALSE;
167
168     //獲取粗體字字符的高度
169     pMe->r_BlodFontHeight = IDISPLAY_GetFontMetrics( pMe->a.m_pIDisplay, AEE_FONT_BOLD, NULL, NULL) + 1;
170     //初始化獲取全屏的矩形變量
171     SETAEERECT( &pMe->p_WholeScreen, 0, 0, pMe->DeviceInfo.cxScreen, pMe->DeviceInfo.cyScreen);
172     InitMainMenu(pMe);
173     // if there have been no failures up to this point then return success
174     return TRUE;
175 }
176
177 // this function is called when your application is exiting
178 void menuctltest_FreeAppData(menuctltest* pMe)
179 {
180     // insert your code here for freeing any resources you have allocated...
181
182     // example to use for releasing each interface:
183     // if ( pMe->pIMenuCtl != NULL )         // check for NULL first
184     // {
185     //    IMENUCTL_Release(pMe->pIMenuCtl)   // release the interface
186     //    pMe->pIMenuCtl = NULL;             // set to NULL so no problems trying to free later
187     // }
188     //
189     //釋放IMenuCtl指針資源
190     if ( pMe->p_MainMenuCtl != NULL)
191     {
192         IMENUCTL_Release(pMe->p_MainMenuCtl);
193         pMe->p_MainMenuCtl = NULL;
194     }
195     if( pMe->p_SoftKeyCtl != NULL)
196     {
197         IMENUCTL_Release(pMe->p_SoftKeyCtl);
198         pMe->p_SoftKeyCtl = NULL;
199     }
200 }
201
202 static void InitMainMenu(menuctltest* pMe)
203 {
204     AEEMenuColors colors;
205     AEEItemStyle style1,style2;
206     AEERect rect;
207
208     SETAEERECT( &rect, 0, MAIN_TITLE_HEIGHT, pMe->DeviceInfo.cxScreen, pMe->DeviceInfo.cyScreen - MAIN_TITLE_HEIGHT - SOFT_KEY_HEIGHT);
209     IMENUCTL_SetRect( pMe->p_MainMenuCtl, &rect );
210     SETAEERECT( &rect, 0, pMe->DeviceInfo.cyScreen - SOFT_KEY_HEIGHT, pMe->DeviceInfo.cxScreen, SOFT_KEY_HEIGHT );
211     IMENUCTL_SetRect( pMe->p_SoftKeyCtl, &rect);
212
213     //設置顯示文字的樣式
214     colors.cBack = ITEM_BACK_COLOR;
215     colors.cText = ITEM_TEXT_COLOR;
216     colors.cSelBack = ITEM_SEL_BACK_COLOR;
217     colors.cSelText = ITEM_SEL_TEXT_COLOR;
218     colors.cFrame = ITEM_FRAME_COLOR;
219     colors.wMask = MC_BACK|MC_TEXT|MC_SEL_BACK|MC_SEL_TEXT|MC_FRAME;
220     IMENUCTL_SetColors( pMe->p_MainMenuCtl, &colors);
221     colors.cBack = TITLE_BACK_COLOR;
222     colors.cText = ITEM_TEXT_COLOR;
223     colors.cSelBack = ITEM_SEL_BACK_COLOR;
224     colors.cSelText = ITEM_SEL_TEXT_COLOR;
225     colors.cFrame = ITEM_FRAME_COLOR;
226     colors.wMask = MC_BACK|MC_TEXT|MC_SEL_BACK|MC_SEL_TEXT|MC_FRAME;
227     IMENUCTL_SetColors( pMe->p_SoftKeyCtl, &colors);
228
229     //設置主菜單和底部菜單已選擇的菜單樣式和一般菜單樣式
230     style1.ft = AEE_FT_NONE;
231     style1.roImage = AEE_RO_NOT;
232     style1.xOffset = 4;
233     style1.yOffset = 4;
234     style2.ft = AEE_FT_BOX;
235     style2.roImage = AEE_RO_NOT;
236     style2.xOffset = 4;
237     style2.yOffset = 4;
238     IMENUCTL_SetStyle(pMe->p_MainMenuCtl, &style1, &style2);
239     IMENUCTL_SetStyle(pMe->p_SoftKeyCtl, &style1, &style2);
240 }
241
242 static void ShowAnimation(menuctltest* pMe)
243 {
244     IImage* p_Image = NULL;
245     AEEImageInfo rImageInfo;
246    
247     //讀取資源文件裡的圖片資源
248     p_Image = ISHELL_LoadResImage( pMe->a.m_pIShell, MENUCTLTEST_RES_FILE, IDI_START_IMG);
249
250     if( p_Image)
251     {
252         int x,y;
253         AECHAR tempArr[RES_STR_MAX_LEN];
254
255         //先將要顯示開始動畫的區域填充顏色
256         IDisplay_FillRect( pMe->a.m_pIDisplay, &pMe->p_WholeScreen, ITEM_BACK_COLOR );
257         //得到圖片的相關信息
258         IIMAGE_GetInfo( p_Image, &rImageInfo);
259         //設置圖片出現在屏幕上的左上角位置(在屏幕中水平、豎直都居中)
260         x = (pMe->p_WholeScreen.x + pMe->p_WholeScreen.dx - rImageInfo.cx) / 2;
261         y = (pMe->p_WholeScreen.y + pMe->p_WholeScreen.dy - rImageInfo.cy) / 2 - pMe->r_BlodFontHeight;
262         //將圖片顯示出來
263         IIMAGE_Draw( p_Image, x, y );
264         //讀取資源中的文本
265         ISHELL_LoadResString( pMe->a.m_pIShell, MENUCTLTEST_RES_FILE, IDS_START_TITLE, tempArr, RES_STR_MAX_LEN * sizeof(AECHAR));
266         //確定圖片下文本的位置
267         x = (pMe->DeviceInfo.cxScreen - IDisplay_MeasureText( pMe->a.m_pIDisplay, AEE_FONT_NORMAL, tempArr)) / 2;
268         y += rImageInfo.cy + 6;
269         //將文本顯示出來
270         IDisplay_DrawText( pMe->a.m_pIDisplay, AEE_FONT_NORMAL, tempArr, -1, x, y, NULL, IDF_TEXT_INVERTED | IDF_TEXT_TRANSPARENT);
271         //更新屏幕用於顯示
272         IDisplay_Update(pMe->a.m_pIDisplay);
273         //釋放IImage對象
274         IImage_Release(p_Image);
275         //設置圖片顯示時間及顯示完成後調用的函數
276         ISHELL_SetTimer( pMe->a.m_pIShell, 2000, (PFNNOTIFY) ShowMain, (void *)pMe);
277     }
278     else
279     {
280         ShowMain(pMe);
281     }
282 }
283
284 static void ShowMain(menuctltest* pMe)
285 {
286     AEERect rect;
287
288     //設置標題的背景矩形並填充顏色
289     SETAEERECT( &rect, 0, 0, pMe->DeviceInfo.cxScreen, MAIN_TITLE_HEIGHT);
290     IDisplay_FillRect( pMe->a.m_pIDisplay, &rect, TITLE_BACK_COLOR);
291     //讀取資源文件中的標題文字
292     ISHELL_LoadResString( pMe->a.m_pIShell, MENUCTLTEST_RES_FILE, IDS_MAIN_TITLE, pMe->p_MainTitle, RES_STR_MAX_LEN * sizeof( AECHAR));
293     //將標題文字輸出
294     DrawTitle(pMe);
295
296     //從數據庫讀取中間菜單項並添加
297     IMENUCTL_AddItem( pMe->p_MainMenuCtl, MENUCTLTEST_RES_FILE, IDS_MAIN_MENU_ONE, IDS_MAIN_MENU_ONE, NULL, 0);
298     IMENUCTL_AddItem( pMe->p_MainMenuCtl, MENUCTLTEST_RES_FILE, IDS_MAIN_MENU_TWO, IDS_MAIN_MENU_TWO, NULL, 0);
299     IMENUCTL_AddItem( pMe->p_MainMenuCtl, MENUCTLTEST_RES_FILE, IDS_MAIN_MENU_THREE, IDS_MAIN_MENU_THREE, NULL, 0);
300     //將中間菜單項在頁面中間顯示出來
301     IMENUCTL_SetActive(pMe->p_MainMenuCtl, TRUE);
302     IMENUCTL_Redraw(pMe->p_MainMenuCtl);
303     //從數據庫讀取底部菜單項並添加
304     IMENUCTL_AddItem(pMe->p_SoftKeyCtl,MENUCTLTEST_RES_FILE, IDS_SOFT_OK, IDS_SOFT_OK, NULL, 0);
305     IMENUCTL_AddItem(pMe->p_SoftKeyCtl,MENUCTLTEST_RES_FILE, IDS_SOFT_EXIT, IDS_SOFT_EXIT, NULL, 0);
306     //將底部菜單項在頁面底部顯示出來
307     IMENUCTL_Redraw(pMe->p_SoftKeyCtl);
308     IDISPLAY_Update(pMe->a.m_pIDisplay);
309 }
310
311 static void DrawTitle(menuctltest* pMe)
312 {
313     AEERect rect;
314     int x,y;
315     //設置顯示標題文字的矩形
316     SETAEERECT( &rect, 0, 0, pMe->DeviceInfo.cxScreen, MAIN_TITLE_HEIGHT);
317     IDISPLAY_FillRect(pMe->a.m_pIDisplay, &rect, TITLE_BACK_COLOR);
318     //設置文字顯示的左上角坐標
319     x = (pMe->DeviceInfo.cxScreen - IDISPLAY_MeasureText( pMe->a.m_pIDisplay, AEE_FONT_BOLD, pMe->p_MainTitle)) / 2;
320     y = (MAIN_TITLE_HEIGHT - pMe->r_BlodFontHeight) / 2;
321     //將頭部標題文字顯示出來
322     IDISPLAY_DrawText( pMe->a.m_pIDisplay, AEE_FONT_BOLD, pMe->p_MainTitle, -1, x, y, NULL, IDF_TEXT_INVERTED | IDF_TEXT_TRANSPARENT);
323 }

 

 


  本程序主要是菜單的顯示,對於菜單的操作,下次再發吧!

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved