分享
 
 
 

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

王朝学院·作者佚名  2010-01-12
窄屏简体版  字體: |||超大  

这一周可真背,先是硬盘坏了,接着主板都坏了!害得我花了一周的时间才把机器搞好,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 }

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有