zoukankan      html  css  js  c++  java
  • BREW的第二个程序菜单显示练习

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

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

      

  • 相关阅读:
    有关php.ini配置文件的安全设置
    零基础如何系统地学习前端开发?
    DEDE CMS 使用dede的sql标签 获取文章链接地址
    DedeCMS系统函数列表及用法详解
    日常生活中有哪些十分钟就能学会并可以终生受用的技能?(转)
    CSS-DOM
    Ajax和Hijax
    动态创建标记的三种方法
    关于最佳实践
    浅析DOM
  • 原文地址:https://www.cnblogs.com/wchhuangya/p/1643099.html
Copyright © 2011-2022 走看看