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

  这一周可真背,先是硬盘坏了,接着主板都坏了!害得我花了一周的时间才把机器搞好,BREW的环境安装好,这才做了第二个BREW程序。

   

  • 设置并输出菜单

需求:开发的BREW程序有自己的图标,不使用系统的图标。一进入系统,先是显示一个图标及程序名称。这个画面停留两秒钟后,进入主页面。主页面的结构为:最上面30像素高的地方是显示标题用的;最下面也有三十像素高的地方来显示操作菜单,有确定和退出;然后中间是三个菜单显示的地方。

需求分析及具体实现:

  • 需要定义的变量:在程序中都有详细注释,这里就不多讲了。
  • 需要初始化的东东:因为有两处菜单显示(中间的和底部的),并且这两处菜单的样式等都不一样,所以,在初始化函数里得创建两个IMenuCtl的对象,并且初始化显示这两块菜单的矩形样式。在后面的显示过程中,因为有显示位置的计算,所以再初始化一个整形的变量来存储粗体字的高度。设置一个获取全屏的矩形变量,这在后面多处会用到。
  • 需要释放的东东:因为在SDK里的IMenuCtl接口说明里有提到:不再需要菜单控件,要用IMenuCtl_Release()函数将其释放。所以,在初始化时创建的两个IMenuCtl对象,在最后要释放掉。
  • 一进入程序显示二秒钟的画面,用ISHELL_SetTimer()函数实现。先是将整个屏幕填充背景颜色,然后将图片从数据库里读出,再显示到屏幕的正中。在图片的下边,显示程序的名称(文字和图片之间相隔6像素)。
  • 因为程序中都有详细的注释说明,在这里就不多说了。

需要注意的事项:

  • 标题因为只是文字,所以使用了IDISPLAY_DrawText()方法来绘制。而中间和底部的菜单除了文字,还有系统默认的事件(比如点击手机键盘上的上、下键或使用滚轮,不同的菜单会在选取和不取消选取状态之间切换,等等),所以,得用指向IMenuCtl的指针,并且调用IMenuCtl接口的相关方法来绘制(绘制的相关过程在SDK上都有详细的说明,详情请参见SDK)。
  • 如果是菜单项响应系统事件,那么,就交于系统去处理。处理完成后,仍交于系统即可。每个事件的处理,如果要是处理完毕,还想交给系统处理,就返回FALSE,如果不想系统处理,就返回TRUE,这个时候就代表用户处理完毕,系统将不会处理。对于挂起和恢复的事件,要特别注意的是屏幕需要重新绘制,某些资源需要释放或者是重新载入。
  • 我将绘制标题的动作封装了一个方法,是因为标题在每一页显示基本上都会有。而且,它们都有很多的共性。这样方便我们修改代码,也使流程清晰化。

 

程序代码如下(省略了大段系统自动生成的注释后):

 

ExpandedBlockStart.gif 代码
  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  }

 

 

 

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

  

转载于:https://www.cnblogs.com/wchhuangya/archive/2010/01/09/1643099.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值