Chinaunix首页 | 论坛 | 博客
  • 博客访问: 849631
  • 博文数量: 190
  • 博客积分: 7021
  • 博客等级: 少将
  • 技术积分: 1752
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-17 19:26
文章分类

全部博文(190)

文章存档

2014年(9)

2011年(32)

2010年(149)

我的朋友

分类: 嵌入式

2010-06-11 17:23:26

/*====================================================================
FILE: helloworld.c
====================================================================*/

 
/*====================================================================
INCLUDES AND VARIABLE DEFINITIONS
====================================================================*/

#include "AEEModGen.h" // Module interface definitions

#include "AEEAppGen.h" // Applet interface definitions

#include "AEEShell.h" // Shell interface definitions

 
#include "helloworld.bid"
 
/*-------------------------------------------------------------------
Applet structure. All variables in here are reference via "pMe->"
-------------------------------------------------------------------*/

// create an applet structure that's passed around. All variables in

// here will be able to be referenced as static.

typedef struct _helloworld {
       AEEApplet a ; // First element of this structure must be AEEApplet

    AEEDeviceInfo DeviceInfo; // always have access to the hardware device information

 
   // add your own variables here...

} helloworld;
 
/*-------------------------------------------------------------------
Function Prototypes
-------------------------------------------------------------------*/

static boolean helloworld_HandleEvent( helloworld* pMe,
                                  AEEEvent eCode, uint16 wParam,
                                  uint32 dwParam);
boolean helloworld_InitAppData(helloworld* pMe);
void helloworld_FreeAppData(helloworld* pMe);
 
/*====================================================================
FUNCTION DEFINITIONS
==================================================================== */

 
/*====================================================================
FUNCTION: AEEClsCreateInstance
 
DESCRIPTION
       This function is invoked while the app is being loaded. All Modules must provide this
       function. Ensure to retain the same name and parameters for this function.
       In here, the module must verify the ClassID and then invoke the AEEApplet_New() function
       that has been provided in AEEAppGen.c.
 
   After invoking AEEApplet_New(), this function can do app specific initialization. In this
   example, a generic structure is provided so that app developers need not change app specific
   initialization section every time except for a call to IDisplay_InitAppData().
   This is done as follows: InitAppData() is called to initialize AppletData
   instance. It is app developers responsibility to fill-in app data initialization
   code of InitAppData(). App developer is also responsible to release memory
   allocated for data contained in AppletData -- this can be done in
   IDisplay_FreeAppData().
 
PROTOTYPE:
   int AEEClsCreateInstance(AEECLSID ClsId,IShell * pIShell,IModule * po,void ** ppObj)
 
PARAMETERS:
       clsID: [in]: Specifies the ClassID of the applet which is being loaded
 
       pIShell: [in]: Contains pointer to the IShell object.
 
       pIModule: pin]: Contains pointer to the IModule object to the current module to which
       this app belongs
 
       ppObj: [out]: On return, *ppObj must point to a valid IApplet structure. Allocation
       of memory for this structure and initializing the base data members is done by AEEApplet_New().
 
DEPENDENCIES
 none
 
RETURN VALUE
 AEE_SUCCESS: If the app needs to be loaded and if AEEApplet_New() invocation was
     successful
 EFAILED: If the app does not need to be loaded or if errors occurred in
     AEEApplet_New(). If this function returns FALSE, the app will not be loaded.
 
SIDE EFFECTS
 none
====================================================================*/

int AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *po, void **ppObj)
{
       *ppObj = NULL;
 
       if( ClsId == AEECLSID_HELLOWORLD )
       {
              // Create the applet and make room for the applet structure

              if( AEEApplet_New(sizeof(helloworld),
                          ClsId,
                          pIShell,
                          po,
                          (IApplet**)ppObj,
                          (AEEHANDLER)helloworld_HandleEvent,
                          (PFNFREEAPPDATA)helloworld_FreeAppData) )
              {
                     //Initialize applet data, this is called before sending EVT_APP_START

            // to the HandleEvent function

                     if(helloworld_InitAppData((helloworld*)*ppObj))
                     {
                            //Data initialized successfully

                            return(AEE_SUCCESS);
                     }
                     else
                     {
                            //Release the applet. This will free the memory allocated for the applet when

                            // AEEApplet_New was called.

                            IAPPLET_Release((IApplet*)*ppObj);
                            return EFAILED;
                     }
        } // end AEEApplet_New

    }
       return(EFAILED);
}
 
/*====================================================================
FUNCTION SampleAppWizard_HandleEvent
 
DESCRIPTION
       This is the EventHandler for this app. All events to this app are handled in this
       function. All APPs must supply an Event Handler.
 
PROTOTYPE:
       boolean SampleAppWizard_HandleEvent(IApplet * pi, AEEEvent eCode, uint16 wParam, uint32 dwParam)
 
PARAMETERS:
       pi: Pointer to the AEEApplet structure. This structure contains information specific
       to this applet. It was initialized during the AEEClsCreateInstance() function.
 
       ecode: Specifies the Event sent to this applet
 
   wParam, dwParam: Event specific data.
 
DEPENDENCIES
 none
 
RETURN VALUE
 TRUE: If the app has processed the event
 FALSE: If the app did not process the event
 
SIDE EFFECTS
 none
====================================================================*/

static boolean helloworld_HandleEvent(helloworld* pMe, AEEEvent eCode, uint16 wParam, uint32 dwParam)
{
       AECHAR szBuf[] = {'H','e','l','l','o',' ',
                      'W','o','r','l','d','\0'};
 
    switch (eCode)
       {
        // App is told it is starting up

        case EVT_APP_START:
                  // Add your code here...

                     // Clear the display.

                     IDISPLAY_ClearScreen( pMe->a.m_pIDisplay );
                     // Display string on the screen

                     IDISPLAY_DrawText( pMe->a.m_pIDisplay, // What

                                                    AEE_FONT_BOLD, // What font

                                                    szBuf, // How many chars

                                                    -1, 0, 0, 0, // Where & clip

                                                    IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE );
                     // Redraw the display to show the drawn text

                     IDISPLAY_Update (pMe->a.m_pIDisplay);
            return(TRUE);
 
        // App is told it is exiting

        case EVT_APP_STOP:
            // Add your code here...

                 return(TRUE);
 
        // App is being suspended

        case EVT_APP_SUSPEND:
                  // Add your code here...

                 return(TRUE);
 
        // App is being resumed

        case EVT_APP_RESUME:
                  // Add your code here...

 
                 return(TRUE);
 
        // A key was pressed. Look at the wParam above to see which key was pressed. The key

        // codes are in AEEVCodes.h. Example "AVK_1" means that the "1" key was pressed.

        case EVT_KEY:
                  // Add your code here...

                 return(TRUE);
 
        // If nothing fits up to this point then we'll just break out

        default:
            break;
   }
 
   return FALSE;
}
 
// this function is called when your application is starting up

boolean helloworld_InitAppData(helloworld* pMe)
{
    // Get the device information for this handset.

    // Reference all the data by looking at the pMe->DeviceInfo structure

    // Check the API reference guide for all the handy device info you can get

    pMe->DeviceInfo.wStructSize = sizeof(pMe->DeviceInfo);
    ISHELL_GetDeviceInfo(pMe->a.m_pIShell,&pMe->DeviceInfo);
 
    // Insert your code here for initializing or allocating resources...

 
    // if there have been no failures up to this point then return success

    return TRUE;
}
 
// this function is called when your application is exiting

void helloworld_FreeAppData(helloworld* pMe)
{
    // insert your code here for freeing any resources you have allocated...

}

这个文件当中的代码大部分是经过BREW向导产生的,为了方便排版,我对里面的代码进行了一些小改动。由于这是第一次展示BREW应用程序,因此保留了向导生成的注释等内容,目的是让您能够看到BREW应用的全貌。今后的应用程序展示,将只使用骨干程序,以节省版面空间并减少对您钱财的浪费。

       正如前面我们所见的,在这个文件中共有四个BREW骨干函数存在,它们分别是:AEEClsCreateInstancehelloworld_HandleEventhelloworld_InitAppData以及helloworld_FreeAppData。它们在整个BREW应用程序中扮演着不同的角色,而且AEEClsCreateInstance***_HandleEvent函数还是每一个动态应用程序必不可少的。接下来让我们来看看它们各自的作用以及相互之间的关系。

       AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *po, void **ppObj)函数是整个BREW应用程序的一个入口点,在其内部调用了AEEApplet_New函数用来创建应用程序实例。AEEApplet_New函数在AEEAppGen.c文件中,这个函数可以指定一个事件处理函数和一个资源释放函数,在这个程序中指定的分别是helloworld_HandleEventhelloworld_FreeAppData函数。在AEEClsCreateInstance函数中将几个重要的参数传进了BREW应用程序中,如IShell指针pIShell、要创建的Class ID ClsId、模块指针po以及应用程序实例返回指针ppObj等。我们还可以看到在AEEApplet_New函数调用成功后,将执行helloworld_InitAppData函数,用来初始化数据,这就是这个初始化函数得到执行的地方。

       helloworld.c文件中,还定义了一个helloworld结构体。由于BREW实现原理上的特点,这个结构体就成为了BREW应用程序存储全局变量的地方。如果我们需要在我们的应用程序运行期间保存数据,请在这个结构体中增加变量,而不要使用全局函数。在运行时,AEEApplet_New函数会根据这个结构体的大小分配存储空间。这个结构体中默认声明的第一个变量是AEEApplet结构,这个声明的顺序不可以改变。AEEApplet的定义如下(参考AEEAppGen.h文件):


struct _AEEApplet
{
   //

   // NOTE: These 3 fields must be declared in this order!

  //

   DECLARE_VTBL(IApplet)
   AEECLSID clsID;
   
   uint32 m_nRefs; // Applet reference counter

   IShell * m_pIShell; // pointer to IShell

   IModule * m_pIModule; // pointer to IModule

       IDisplay * m_pIDisplay; // pointer to IDisplay

 
       //Pointer to Handle Event Function

   AEEHANDLER pAppHandleEvent;
 
// Pointer to FreeAppData function. This will be invoked when the

   // reference count of the App goes to zero. This function is supplied

   // by the app developer.

   // NOTE: Apps should NOT directly call their FreeAppData function.

   PFNFREEAPPDATA pFreeAppData;
};


这个结构体中的成员变量都是在AEEApplet_New函数中进行填充的,我们可以看到里面有IDisplay接口指针定义,由于对于每一个BREW应用程序来说,IDisplay接口是必备的,因此AEEApplet_New函数里面会创建这个接口的实例,这样我们就不必在我们的应用程序中再次创建这些接口了。在这个结构体里面还有一个AEEHANDLER类型的变量,这其实是一个函数指针,用来保存我们通过AEEApplet_New函数传递进来的应用程序中捕获事件的函数,在这里面指定的是helloworld_HandleEvent函数。还有一个PFNFREEAPPDATA类型的变量,这也是一个回调函数的变量,用来保存释放资源的函数,在应用程序退出时将会调用这个函数执行指定的资源释放函数,在本例中这个函数就是helloworld_FreeAppData函数。m_pIShellm_pIModule变量分别存储了BREW Shell和模块接口的指针,我们可以在调用BREW Shell接口函数(定义在AEEShell.h中的ISHELL_开头的接口)的时候可以使用这个指针,因为IShell指针是通过应用程序的入口函数传递进来的,而不需要创建(IShell是不能够自己创建自己的)。关于IModule指针我们会在第三部分的Shell内幕中有详细的介绍,这里就不多说了。其他的变量是BREW规定的,在这里面我们也不多说了(我们才刚刚开始啊)。

       BREW应用程序启动后,会首先向应用程序中发送EVT_APP_START事件,这个事件是应用程序收到的第一个BREW事件。由于我们指定的应用程序事件捕获函数是helloworld_HandleEvent,因此在这里将由此函数处理这个事件。在这个事件里我们可以进行应用程序的初始化操作,例如,显示一个界面、创建一个接口实例等等。在本例中我们调用了三个IDisplay接口的方法:IDISPLAY_ClearScreenIDISPLAY_ DrawText以及IDISPLAY_Update方法,它们的作用依次是清除屏幕显示、在屏幕上绘制文字以及刷新屏幕。运行后,这段代码会在屏幕的中央显示“Hello World”字样。在处理进行完成之后,需要使用“return TRUE”来告知BREW应用程序已经启动成功了,可以接收其他事件了。否则表示应用程序启动失败了,程序将不能正常运行。

       在应用程序启动成功之后,可以接收BREW传递给应用程序的其他事件了,例如用户点击了键盘,则会有EVT_KEY事件发送。当应用程序结束的时候,BREW会向应用程序的事件捕获函数发送EVT_APP_STOP事件。如果我们在EVT_APP_START事件中创建了接口实例,那么与此相对应的,我们应该在EVT_APP_STOP事件中释放这些接口实例。这个事件也要求捕获者返回TRUE,以表示应用程序已经成功停止运行了。注意,BREW内部支持的Unicode的字符编码,Unicode编码是国际标准的双字节字符编码,越来越多的系统都开始支持Unicode编码了。双字节宽度的Unicode字符与单字节的ASCII编码相比,Unicode可以支持最多65536个字符(单字节最多256个),几乎可以囊括全世界不同语言的全部字符,中文从Unicode编码的0x4E00编号开始。

       现在我们只需要简单的几步就已经创建了一个BREW应用程序了,不要惊奇,一切就是这么简单!

 

ps:以上内容来自 《深入BREW开发》 作者:焦玉海

阅读(1527) | 评论(0) | 转发(0) |
0

上一篇:使用Applet和模块

下一篇:BREW开发初步

给主人留下些什么吧!~~