WEB开发网
开发学院WEB开发ASP BREW的第二个程序--菜单显示练习 阅读

BREW的第二个程序--菜单显示练习

 2010-01-11 10:45:24 来源:WEB开发网   
核心提示:这一周可真背,先是硬盘坏了,BREW的第二个程序--菜单显示练习,接着主板都坏了!害得我花了一周的时间才把机器搞好,BREW的环境安装好,后面自己写的代码处理, 95 if( pMe->p_MainMenuCtl && IMENUCTL_HandleEvent( pMe->p_MainMenuCtl, eC
这一周可真背,先是硬盘坏了,接着主板都坏了!害得我花了一周的时间才把机器搞好,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 }






  本程序主要是菜单的显示,对于菜单的操作,下次再发吧!

  

Tags:BREW 第二个 程序

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接