这几天开始做BREW开发了,刚开始挺晕的。又是C指针,又是BREW的SDK文档,还有环境配置,一大堆东东,真是让人手忙脚乱。好不容易配好了环境,写出了第一个Hello world!程序。感觉还不错,就把代码和想法贴出来,和大家分享,希望大家指点下。
需求:一进入应用程序,展示的页面是灰色的背景,屏幕的正中央输出白色的Hello world!字样。在屏幕的下方,留有30px高的一块空白来放置菜单栏。
需求分析及具体实现:
- 是黑色的背景,所以先给整个背景(除了最底下)填充灰色。填充背景色所需要用到的方法:IDISPLAY接口的IDISPLAY_FillRect(IDisplay *po,AEERect * pRect, RGBVAL clrFill )方法。第一个参数是一个指向IDisplay接口的指针,第二个参数是要使用指定颜色填充的矩形的有效指针,第三个参数是用于填充矩形的颜色。第二个参数的使用:先是申明一个AEERECT类型的变量rect,然后用SETAEERECT宏来初始化rect变量(用法参见SDK)。第三个参数的用法:可以用MAKE_RGB宏来设置RGB值(用法参见SDK)。
- 输出Hello world!字样。先定义一个字符数组用来存储Hello world!。然后把其输出屏幕,这里用到了IDISPLAY接口的IDISPLAY_DrawText(IDisplay *po, AEEFont Font,
const AECHAR * pcText, int nChars, int x, int y, const AEERect * prcBackground, uint32 dwFlags )方法,这里没有特别说明的,详细请参见SDK。
- 最后,将屏幕更新,将输出显示出来。这里用到了IDISPLAY接口的IDISPLAY_Update(Idisplay *pIDisplay)方法。
- 完毕。
需要注意的事项:
- 实现中多处用到了指向IDISPLAY接口的指针。在程序自动生成的结构体定义里有AEEApplet a ;的定义。因为IDISPLAY、ISHELL、IModule这三个接口经常用到,所以它们已经包含在AEEApplet的结构定义中。所以,在程序中要引用指向这三个接口的指针,可以使用pMe->a.pIDisplay、pMe->a.pIShell、pMe->a.pIModule来调用(这里的pMe是指向本程序的指针)。另,如果嫌这样麻烦或名称没有顾名思义性,可以在程序结构体的定义里加上自己定义的指向所需接口的指针。如:IShell* pIShell。但是注意,如果这样定义了,在使用前一定得给它们赋于实际的值。如:pMe->pIShell=pMe->a.pIShell;。
- BREW不支持全局变量和静态变量,用上述的第二种方法可以变通的实现全局变量。
程序如下(去掉了自动生成的大篇幅的注释部分):
代码
1 #include "AEEModGen.h" // Module interface definitions
2 #include "AEEAppGen.h" // Applet interface definitions
3 #include "AEEShell.h" // Shell interface definitions
4 #include "AEE.h"
5 #include "AEEMenu.h"
6
7 #include "studycontinue.bid"
8 #define TITLE_BACK_COLOR MAKE_RGB(28,28,28)//MAKE_RGB(222,222,222)
9 #define TITLE_HEIGHT 30
10 /*-------------------------------------------------------------------
11 Applet structure. All variables in here are reference via "pMe->"
12 -------------------------------------------------------------------*/
13 // create an applet structure that's passed around. All variables in
14 // here will be able to be referenced as static.
15 typedef struct _studycontinue {
16 AEEApplet a ; // First element of this structure must be AEEApplet
17 AEEDeviceInfo DeviceInfo; // always have access to the hardware device information
18
19 // add your own variables here...
20
21 IShell *pIShell;
22 AEERect m_rScreenRect; // Screen Rect
23 IMenuCtl *pIMenuCtl;
24 IMenuCtl* m_pMenu; // Main Menu
25 IMenuCtl* pSoftCtl;
26
27 boolean bMenuIsRoot;
28 } studycontinue;
29
30 /*-------------------------------------------------------------------
31 Function Prototypes
32 -------------------------------------------------------------------*/
33 static boolean studycontinue_HandleEvent(studycontinue* pMe,
34 AEEEvent eCode, uint16 wParam,
35 uint32 dwParam);
36 boolean studycontinue_InitAppData(studycontinue* pMe);
37 void studycontinue_FreeAppData(studycontinue* pMe);
38 static void DrawEverything(studycontinue* pMe);
39
40 /*===============================================================================
41 FUNCTION DEFINITIONS
42 =============================================================================== */
43 int AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *po, void **ppObj)
44 {
45 *ppObj = NULL;
46
47 if( ClsId == AEECLSID_STUDYCONTINUE )
48 {
49 // Create the applet and make room for the applet structure
50 if( AEEApplet_New(sizeof(studycontinue),
51 ClsId,
52 pIShell,
53 po,
54 (IApplet**)ppObj,
55 (AEEHANDLER)studycontinue_HandleEvent,
56 (PFNFREEAPPDATA)studycontinue_FreeAppData) ) // the FreeAppData function is called after sending EVT_APP_STOP to the HandleEvent function
57
58 {
59 //Initialize applet data, this is called before sending EVT_APP_START
60 // to the HandleEvent function
61 if(studycontinue_InitAppData((studycontinue*)*ppObj))
62 {
63 //Data initialized successfully
64 return(AEE_SUCCESS);
65 }
66 else
67 {
68 //Release the applet. This will free the memory allocated for the applet when
69 // AEEApplet_New was called.
70 IAPPLET_Release((IApplet*)*ppObj);
71 return EFAILED;
72 }
73
74 } // end AEEApplet_New
75
76 }
77
78 return(EFAILED);
79 }
80
81
82 static boolean studycontinue_HandleEvent(studycontinue* pMe, AEEEvent eCode, uint16 wParam, uint32 dwParam)
83 {
84 if(pMe->pIMenuCtl && IMENUCTL_IsActive(pMe->pIMenuCtl) && IMENUCTL_HandleEvent(pMe->pIMenuCtl,eCode,wParam,dwParam))
85 return TRUE;
86 if(pMe->pSoftCtl && IMENUCTL_IsActive(pMe->pSoftCtl) && IMENUCTL_HandleEvent(pMe->pSoftCtl,eCode,wParam,dwParam))
87 return TRUE;
88 switch (eCode)
89 {
90 // App is told it is starting up
91 case EVT_APP_START:
92 // Add your code here...
93 DrawEverything(pMe);
94 DrawMenu(pMe,TRUE);
95 return(TRUE);
96
97
98 // App is told it is exiting
99 case EVT_APP_STOP:
100 // Add your code here...
101
102 return(TRUE);
103
104
105 // App is being suspended
106 case EVT_APP_SUSPEND:
107 // Add your code here...
108
109 return(TRUE);
110
111
112 // App is being resumed
113 case EVT_APP_RESUME:
114 // Add your code here...
115
116 return(TRUE);
117
118
119 // An SMS message has arrived for this app. Message is in the dwParam above as (char *)
120 // sender simply uses this format "//BREW:ClassId:Message", example //BREW:0x00000001:Hello World
121 case EVT_APP_MESSAGE:
122 // Add your code here...
123
124 return(TRUE);
125
126 // A key was pressed. Look at the wParam above to see which key was pressed. The key
127 // codes are in AEEVCodes.h. Example "AVK_1" means that the "1" key was pressed.
128 case EVT_KEY:
129 // Add your code here...
130
131 return(TRUE);
132 case EVT_COMMAND:
133 return TRUE;
134
135
136 // If nothing fits up to this point then we'll just break out
137 default:
138 break;
139 }
140
141 return FALSE;
142 }
143
144
145 // this function is called when your application is starting up
146 boolean studycontinue_InitAppData(studycontinue* pMe)
147 {
148 IShell * pIShell = pMe->a.m_pIShell; // Cache Shell Pointer
149 // Get the device information for this handset.
150 // Reference all the data by looking at the pMe->DeviceInfo structure
151 // Check the API reference guide for all the handy device info you can get
152 pMe->DeviceInfo.wStructSize = sizeof(pMe->DeviceInfo);
153 ISHELL_GetDeviceInfo(pMe->a.m_pIShell,&pMe->DeviceInfo);
154
155 // Insert your code here for initializing or allocating resources...
156
157
158 /*if((ISHELL_CreateInstance(pIShell, AEECLSID_MENUCTL, (void**)(&pMe->m_pMenu)) != SUCCESS))
159 return FALSE;*/
160 if((ISHELL_CreateInstance(pIShell, AEECLSID_SOFTKEYCTL, (void**)(&pMe->pSoftCtl)) != SUCCESS))
161 return FALSE;
162
163 // if there have been no failures up to this point then return success
164 return TRUE;
165 }
166
167 // this function is called when your application is exiting
168 void studycontinue_FreeAppData(studycontinue* pMe)
169 {
170 // insert your code here for freeing any resources you have allocated...
171
172 // example to use for releasing each interface:
173 // if ( pMe->pIMenuCtl != NULL ) // check for NULL first
174 // {
175 // IMENUCTL_Release(pMe->pIMenuCtl) // release the interface
176 // pMe->pIMenuCtl = NULL; // set to NULL so no problems trying to free later
177 // }
178 //
179 /*if(pMe->m_pMenu)
180 {
181 IMENUCTL_Release(pMe->m_pMenu);
182 pMe->m_pMenu = NULL;
183 }*/
184 if(pMe->pSoftCtl)
185 {
186 IMENUCTL_Release(pMe->pSoftCtl);
187 pMe->pSoftCtl = NULL;
188 }
189 }
190
191 static void DrawEverything(studycontinue* pMe)
192 {
193 AECHAR helloworld[] = {'H','e','l','l','o',',','W','o','r','l','d','\0'};
194 AEERect rect;
195 SETAEERECT(&rect,0,0,pMe->DeviceInfo.cxScreen,pMe->DeviceInfo.cyScreen-30);
196
197 IDISPLAY_FillRect(pMe->a.m_pIDisplay,&rect,TITLE_BACK_COLOR);
200 IDISPLAY_DrawText(pMe->a.m_pIDisplay,AEE_FONT_BOLD,helloworld,-1,0,0,NULL,IDF_ALIGN_CENTER|IDF_ALIGN_MIDDLE|IDF_TEXT_INVERTED);
201 IDISPLAY_Update(pMe->a.m_pIDisplay);
202 }
2 #include "AEEAppGen.h" // Applet interface definitions
3 #include "AEEShell.h" // Shell interface definitions
4 #include "AEE.h"
5 #include "AEEMenu.h"
6
7 #include "studycontinue.bid"
8 #define TITLE_BACK_COLOR MAKE_RGB(28,28,28)//MAKE_RGB(222,222,222)
9 #define TITLE_HEIGHT 30
10 /*-------------------------------------------------------------------
11 Applet structure. All variables in here are reference via "pMe->"
12 -------------------------------------------------------------------*/
13 // create an applet structure that's passed around. All variables in
14 // here will be able to be referenced as static.
15 typedef struct _studycontinue {
16 AEEApplet a ; // First element of this structure must be AEEApplet
17 AEEDeviceInfo DeviceInfo; // always have access to the hardware device information
18
19 // add your own variables here...
20
21 IShell *pIShell;
22 AEERect m_rScreenRect; // Screen Rect
23 IMenuCtl *pIMenuCtl;
24 IMenuCtl* m_pMenu; // Main Menu
25 IMenuCtl* pSoftCtl;
26
27 boolean bMenuIsRoot;
28 } studycontinue;
29
30 /*-------------------------------------------------------------------
31 Function Prototypes
32 -------------------------------------------------------------------*/
33 static boolean studycontinue_HandleEvent(studycontinue* pMe,
34 AEEEvent eCode, uint16 wParam,
35 uint32 dwParam);
36 boolean studycontinue_InitAppData(studycontinue* pMe);
37 void studycontinue_FreeAppData(studycontinue* pMe);
38 static void DrawEverything(studycontinue* pMe);
39
40 /*===============================================================================
41 FUNCTION DEFINITIONS
42 =============================================================================== */
43 int AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *po, void **ppObj)
44 {
45 *ppObj = NULL;
46
47 if( ClsId == AEECLSID_STUDYCONTINUE )
48 {
49 // Create the applet and make room for the applet structure
50 if( AEEApplet_New(sizeof(studycontinue),
51 ClsId,
52 pIShell,
53 po,
54 (IApplet**)ppObj,
55 (AEEHANDLER)studycontinue_HandleEvent,
56 (PFNFREEAPPDATA)studycontinue_FreeAppData) ) // the FreeAppData function is called after sending EVT_APP_STOP to the HandleEvent function
57
58 {
59 //Initialize applet data, this is called before sending EVT_APP_START
60 // to the HandleEvent function
61 if(studycontinue_InitAppData((studycontinue*)*ppObj))
62 {
63 //Data initialized successfully
64 return(AEE_SUCCESS);
65 }
66 else
67 {
68 //Release the applet. This will free the memory allocated for the applet when
69 // AEEApplet_New was called.
70 IAPPLET_Release((IApplet*)*ppObj);
71 return EFAILED;
72 }
73
74 } // end AEEApplet_New
75
76 }
77
78 return(EFAILED);
79 }
80
81
82 static boolean studycontinue_HandleEvent(studycontinue* pMe, AEEEvent eCode, uint16 wParam, uint32 dwParam)
83 {
84 if(pMe->pIMenuCtl && IMENUCTL_IsActive(pMe->pIMenuCtl) && IMENUCTL_HandleEvent(pMe->pIMenuCtl,eCode,wParam,dwParam))
85 return TRUE;
86 if(pMe->pSoftCtl && IMENUCTL_IsActive(pMe->pSoftCtl) && IMENUCTL_HandleEvent(pMe->pSoftCtl,eCode,wParam,dwParam))
87 return TRUE;
88 switch (eCode)
89 {
90 // App is told it is starting up
91 case EVT_APP_START:
92 // Add your code here...
93 DrawEverything(pMe);
94 DrawMenu(pMe,TRUE);
95 return(TRUE);
96
97
98 // App is told it is exiting
99 case EVT_APP_STOP:
100 // Add your code here...
101
102 return(TRUE);
103
104
105 // App is being suspended
106 case EVT_APP_SUSPEND:
107 // Add your code here...
108
109 return(TRUE);
110
111
112 // App is being resumed
113 case EVT_APP_RESUME:
114 // Add your code here...
115
116 return(TRUE);
117
118
119 // An SMS message has arrived for this app. Message is in the dwParam above as (char *)
120 // sender simply uses this format "//BREW:ClassId:Message", example //BREW:0x00000001:Hello World
121 case EVT_APP_MESSAGE:
122 // Add your code here...
123
124 return(TRUE);
125
126 // A key was pressed. Look at the wParam above to see which key was pressed. The key
127 // codes are in AEEVCodes.h. Example "AVK_1" means that the "1" key was pressed.
128 case EVT_KEY:
129 // Add your code here...
130
131 return(TRUE);
132 case EVT_COMMAND:
133 return TRUE;
134
135
136 // If nothing fits up to this point then we'll just break out
137 default:
138 break;
139 }
140
141 return FALSE;
142 }
143
144
145 // this function is called when your application is starting up
146 boolean studycontinue_InitAppData(studycontinue* pMe)
147 {
148 IShell * pIShell = pMe->a.m_pIShell; // Cache Shell Pointer
149 // Get the device information for this handset.
150 // Reference all the data by looking at the pMe->DeviceInfo structure
151 // Check the API reference guide for all the handy device info you can get
152 pMe->DeviceInfo.wStructSize = sizeof(pMe->DeviceInfo);
153 ISHELL_GetDeviceInfo(pMe->a.m_pIShell,&pMe->DeviceInfo);
154
155 // Insert your code here for initializing or allocating resources...
156
157
158 /*if((ISHELL_CreateInstance(pIShell, AEECLSID_MENUCTL, (void**)(&pMe->m_pMenu)) != SUCCESS))
159 return FALSE;*/
160 if((ISHELL_CreateInstance(pIShell, AEECLSID_SOFTKEYCTL, (void**)(&pMe->pSoftCtl)) != SUCCESS))
161 return FALSE;
162
163 // if there have been no failures up to this point then return success
164 return TRUE;
165 }
166
167 // this function is called when your application is exiting
168 void studycontinue_FreeAppData(studycontinue* pMe)
169 {
170 // insert your code here for freeing any resources you have allocated...
171
172 // example to use for releasing each interface:
173 // if ( pMe->pIMenuCtl != NULL ) // check for NULL first
174 // {
175 // IMENUCTL_Release(pMe->pIMenuCtl) // release the interface
176 // pMe->pIMenuCtl = NULL; // set to NULL so no problems trying to free later
177 // }
178 //
179 /*if(pMe->m_pMenu)
180 {
181 IMENUCTL_Release(pMe->m_pMenu);
182 pMe->m_pMenu = NULL;
183 }*/
184 if(pMe->pSoftCtl)
185 {
186 IMENUCTL_Release(pMe->pSoftCtl);
187 pMe->pSoftCtl = NULL;
188 }
189 }
190
191 static void DrawEverything(studycontinue* pMe)
192 {
193 AECHAR helloworld[] = {'H','e','l','l','o',',','W','o','r','l','d','\0'};
194 AEERect rect;
195 SETAEERECT(&rect,0,0,pMe->DeviceInfo.cxScreen,pMe->DeviceInfo.cyScreen-30);
196
197 IDISPLAY_FillRect(pMe->a.m_pIDisplay,&rect,TITLE_BACK_COLOR);
200 IDISPLAY_DrawText(pMe->a.m_pIDisplay,AEE_FONT_BOLD,helloworld,-1,0,0,NULL,IDF_ALIGN_CENTER|IDF_ALIGN_MIDDLE|IDF_TEXT_INVERTED);
201 IDISPLAY_Update(pMe->a.m_pIDisplay);
202 }
关于菜单栏的实现,我下次再发,现在还没有想好怎么做。嘻嘻~