Facebook Twitter LinkedIn E-mail
magnify
Home Posts tagged "BREW"

BREW开发教程(15):其它及示例下载

除了上述介绍API基本功能外,BREW还提供了3D图形、游戏动画、GPS、摄像头等支持,可以参考API以获取详细信息。

下面的例子显示控件的用法以前IWinApp和IWindow程序框。

附件中Testsuite.zip文件中包含了这个程序源代码,及所有扩展接口的定义及实现

本教程Word文档 下载

示例下载及IRadioButton, IWinApp 等实现

 

BREW开发教程(14):关于BREW中多任务协调工作

BREW平台提供的是合作式多任务方式。这意味着Applet应用被设计成尽可能以最短的时间运行,在处理完消息后,退出以使其它活动得以进行。BREW环境正常情况下只能有一个Applet处于运行和可见(控制显示器),然而,多个Applet可以以后台方式运行当BREW暂停一个Applet,它将向Applet发送EVT_APP_SUSPEND消息。如果Applet处理该消息时返回TRUE, 表明该Applet已处理过该消息并且没有被调出内存。如果Applet不想处理EVT_APP_SUSPEND消息,可以返回FALSE,在这种情况下,BREW将停止该Applet,将向Applet发送EVT_APP_STOP消息,Applet将被载出内存。

因此采用一个特定的任务间消息处理机制,可以实现多个内存中任务同时运行。下面以一个简单的例子来说明如何实现BREW多任务协调工作。

现在两个应用程序,只是向屏幕中显示一个计数器。如下图所示:

为了区别起见,一个应用显示App1一个应用显示App2。

下面的两个是Soft Key按键。用于模拟向另一个应用发送消息。

假定App1主任务,App2为一从任务。

计数器的值定义在Applet结构中。程序启动时初始化为1

uint8                             m_nIndex;

这里定义了一个消息

#define EVT_START_APP (EVT_USER + 11)

App1的消息处理过程:

switch (eCode){

case EVT_APP_START:

MM_WRITE_LOG0(“Start\r\n”);

return OnStart(pme,eCode,wParam,dwParam);

break;

case  EVT_APP_STOP:

return TRUE;

case EVT_APP_RESUME:

MM_WRITE_LOG0(“Resume\r\n”);

pApp->m_nIndex++;

IWINAPP_SetWindow((IWinApp*)pApp,1,(void *)&rScreen);

return TRUE;

case EVT_START_APP:

MM_WRITE_LOG0(“Restart\r\n”);

ISHELL_StartApplet(pApp->a.m_pIShell,AEECLSID_APP1);

return TRUE;

case EVT_APP_SUSPEND:

MM_WRITE_LOG0(“Suspend\r\n”);

return TRUE;

case EVT_KEY:

case EVT_COMMAND:

return OnKey(pme,eCode,wParam,dwParam);

break;

App2的消息处理机制:

switch (eCode){

case EVT_APP_START:

MM_WRITE_LOG0(“Start\r\n”);

return OnStart(pme,eCode,wParam,dwParam);

break;

case EVT_START_APP:

MM_WRITE_LOG0(“Start the app\r\n”);

ISHELL_StartApplet(pApp->a.m_pIShell,AEECLSID_APP2);

return TRUE;

break;

case  EVT_APP_STOP:

return TRUE;

case EVT_APP_RESUME:

pApp->m_nIndex++;

MM_WRITE_LOG0(“Resume\r\n”);

IWINAPP_SetWindow((IWinApp*)pApp,1,(void *)&rScreen);

return TRUE;

case EVT_APP_SUSPEND:

MM_WRITE_LOG0(“Suspend\r\n”);

return TRUE;

case EVT_KEY:

case EVT_COMMAND:

return OnKey(pme,eCode,wParam,dwParam);

可以看出两个App1的消息处理非常类似。因些都可以作为主任务,另一个则为从任务。

在App1中按键Tuesday:

case AEE_IDS_TUESDAY:

bRet=ISHELL_PostEvent(pThis->m_pIShell,AEECLSID_APP2,EVT_START_APP,0,AEECLSID_APP1);

向App2发起一个启动/恢复命令。

在App2中按键Tuesday:

case AEE_IDS_TUESDAY:

bRet=ISHELL_PostEvent(pThis->m_pIShell,AEECLSID_APP1,EVT_START_APP,0,AEECLSID_APP2);

向App1发起一个启动/恢复命令

从两个Applet的消息处理函数中可以看出都调用了一个。

ISHELL_StartApplet

该函数将异步启动一个Applet,本例子都是让Applet启动自生。如果一个没在内存中,则BREW创建该Applet的一个实例,并发送EVT_APP_START,如果已在后台运行,则将发送EVT_APP_RESUME。

因此,如果BREW不支持前后台多个任务同时运行的话。每次激活一个Applet,其计数器总会显示1。我们在EVT_APP_RESUME消息中对计数加1。

实现运行显示了每次计算数都会加1。因些可以说明BREW中是可以多个任务同时运行的。需不会是一个任务被启动时,其它的任务必需从系统中载出。

如下图所示:

因此通过这种机制,是可以实现一个Applet在后台运行。

 

BREW开发教程(13):网络编程

BREW网络功能提供了Iweb接口以及Isocket接品,前者主要用于Http协议支持,后者则提供了一般的TCP/IP协议支持,可以参见API例子中NetDiagnostics。

 

BREW开发教程(12):数据库操作

IDBMgr 接口

IDBMgr接口函数用来创建、打开和删除数据库,数据库指的是多字段记录的集合。当数据库打开之后,就可以使用由Idatabase接口提供的函数来创建、检索及关闭数据库,并可以使用由IDRecord接口提供的函数来访问和更新单个记录。

注意:应用程序必需要有PL_FILE 和 PL_SYSTEM权限才能调用这个接口来打开、创建数据库。

IDBMGR_OpenDatabase()根据指定的数据库名称打开数据库,数据库名称为对应的包含数据库内容的BREW文件名称。当调用这个函数时,如果该数据库不存在就会创建一个新的数据库。

IDBMGR_OpenDatabaseEx()功能类似,但可以允许开发者指定最小记录大小和创建数据库时的最小记录数。该函数预留一些空间来保存指定数量的记录数。上述两个函数都返回一个指向Idatabase的指针,可以用来访问打开的数据库。

IDBMGR_Remove()通过删除包含记录的文件来删除一个数据库,如果数据库处于打开状态,必需先调用IDBMGR_Release() 先关闭数据库然后再删除它。

IDBMgr接口的使用步骤

  1. 调用ISHELL_CreateInstance()创建一个指向IDBMgr接口的指针。
  2. 调用IDBMGR_OpenDatabase()打开一个已存在的数据库或是新建一个数据库,如果需要为新创建的数据库指定最小记录数,使用IDBMGR_OpenDatabaseEx()。
  3. 使用由步骤2得到的Idatabase接口指针,使用Idatabase接口函数来创建、检索数据库中的记录。使用IDBRecord接口函数来访问和修改一条记录。
  4. 当不再需要使用数据库时调用IDATABASE_Release()来关闭一个数据库。
  5. 有必要时调用IDBMGR_Remove()删除一个数据库。
  6. 当不再需要使用IDBMgr接口指针时调用IDBMGR_Release()

IDatabase接口

IDatabase接口函数可以用来操作由IDBMgr接口打开或创建的数据库中的记录。首先调用IDBMGR_OpenDatabase()打开特定的数据库,然后使用由该函数返回的Idatabase接口指针来操作数据库,并可使用IDBRecord接口函数来访问单个数据库记录。当完成数据库操作时,调用IDATABASE_Release()关闭数据库。

IDATABASE_CreateRecord()创建一个新记录并在数据库中增加一条记录(函数IDBRECORD_Remove()用于在数据库中删除一条记录)。每条记录包含一个或多个字段,每个字段由一个AEEDBField结构定义,

AEEDBField结构定义

typedef enum

{

AEEDB_FT_NONE,

AEEDB_FT_BYTE,

AEEDB_FT_WORD,

AEEDB_FT_DWORD,

AEEDB_FT_STRING,

AEEDB_FT_BINARY,

AEEDB_FT_PHONE,

AEEDB_FT_BITMAP,

AEEDB_FT_MAX

} AEEDBFieldType

AEEDB_FT_BYTE Field contains an 8 bit value.
AEEDB_FT_WORD Field contains a 16 bit value.
AEEDB_FT_DWORD Field contains a 32 bit value.
AEEDB_FT_STRING Field contains an AECHAR array (NULL terminated).
AEEDB_FT_BINARY Field contains a Binary value.
AEEDB_FT_PHONE Field contains an AECHAR array (NULL terminate).
AEEDB_FT_BITMAP Field contains a bitmap in BMP format.

typedef enum

{

AEEDBFIELD_NONE,

AEEDBFIELD_FULLNAME,

AEEDBFIELD_LASTNAME,

AEEDBFIELD_FIRSTNAME,

AEEDBFIELD_HOME_PHONE,

AEEDBFIELD_WORK_PHONE,

AEEDBFIELD_MOBILE_PHONE,

AEEDBFIELD_FAX, AEEDBFIELD_ADDRESS,

AEEDBFIELD_EMAIL,

AEEDBFIELD_URL,

AEEDBFIELD_DATE_TIME,

AEEDBFIELD_CATEGORY,

AEEDBFIELD_ALARM,

AEEDBFIELD_PREF_ID,

AEEDBFIELD_PREF_VER,

AEEDBFIELD_PREF_DATA,

AEEDBFIELD_TITLE,

AEEDBFIELD_TEXT

} AEEDBFieldName;

AEEDBFIELD_FULLNAME Field contains a full name.
AEEDBFIELD_LASTNAME Field contains a last name.
AEEDBFIELD_FIRSTNAME Field contains a first name.
AEEDBFIELD_HOME_PHONE Field contains a home telephone number.
AEEDBFIELD_WORK_PHONE Field contains a work telephone number.
AEEDBFIELD_MOBILE_PHONE Field contains a mobile telephone number.
AEEDBFIELD_FAX Field contains a fax number.
AEEDBFIELD_ADDRESS Field contains a mailing address.
AEEDBFIELD_EMAIL Field contains an email address.
AEEDBFIELD_URL Field contains a URL.
AEEDBFIELD_DATE_TIME Field contains date and time.
AEEDBFIELD_CATEGORY Field contains a category specification.
AEEDBFIELD_ALARM Field contains an alarm.
AEEDBFIELD_PREF_ID Field contains a Preference ID.
AEEDBFIELD_PREF_VER Field contains a Preference Version Number.
AEEDBFIELD_PREF_DATA Field contains Preference Data (such as user preference).
AEEDBFIELD_TITLE Field contains a Title.
AEEDBFIELD_TEXT Field contains text.

在AEEDBField结构中包含了下面的元素:

typedef structure

{

AEEDBFieldType fType;

AEEDBFieldName fName;

uint16 wDataLen;

void * pBuffer;

} AEEDBField;

其中字段名称这字段内容的一个描述(如姓名、电话号码、Email地址等)AEEDBFieldName枚举类型定义一些常用的字段名称。

字段类型给出了该字段的数据类型(字节,字、双字、字符串,二进制数、电话号码或位图等)。

字段存贮区指针指向字段内容的首地址。

字段长度指出字段内容长度。

当创建一个记录时,首先将数据填充到一个AEEDBField结构数组中,给出记录的字段名、类型、内容及长度。然后调用IDATABASE_CreateRecord(),给出指向该数组的指针,IDATABASE_CreateRecord()返回一个指向IDBRecord接口的指针,可以用来访问和更新该记录,字段类型的指定是在创建或更新单个记录时分别指定的,并不要求数据库中每条记录具有相同的结构。

创建并在数据库中增加了记录之后,可以使用另外的Idatabase接口函数来检索数据库。

检索数据库的每条记录

  1. 首先调用IDATABASE_Reset()将数据记录指定指向0。
  2. 然后重复调用IDATABASE_GetNextRecord()来获得指向数据库中每条记录的IDBRecord接口指针,直到IDATABASE_GetNextRecord()返回空指针表明所有记录都已被遍历。

Idatabase接口使用步骤

  1. 如有必要,调用ISHELL_CreateInstance()来创建一个指向IDBMgr的指针。
  2. 调用IDBMGR_OpenDatabase()或IDBMGR_OpenDatabaseEx()来得到一个已存在或新建数据库的Idatabase接口指针。
  3. 调用IDATABASE_CreateRecord()在由2得到的数据库中创建并增加一条记录。
  4. 调用IDATABASE_Reset()和 IDATABASE_GetNextRecord() 来遍历整个数据库(比如查找满足某个条件的所用记录)。调用IDATABASE_GetRecordByID()可以根据指定的记录ID来检索某条记录。

结束数据库访问时调用IDATABASE_Release()来关闭数据库。

IDBRecord 接口

IDBRecord 接口包含了一组用于访问、更新数据库中记录的函数,使用IDatabase 接口函数来得到一个指向某条记录的IDBRecord接口实例指针,IDBRecord指针可以通过IDATABASE_CreateRecord()返回一个新记录指针,通过IDATABASE_GetNextRecord() 和 IDATABASE_GetRecordByID() 返回一个已存在记录的IDBRecord指针,得到IDBRecord指针之后,就可以使用IDBRecord 接口函数来操作记录的字段,结束对一个记录的访问之后,调用IDBRECORD_Release()来关闭它。

每条记录字段包含字段名、类型、内容指针及内容长度,记录操作函数针对的是当前字段,IDBRECORD_Reset()使用记录的第一个字段成为当前字段,IDBRECORD_NextField()将当前字段的下一个字段成为当前字段,该函数同样返回字段名称、类型及长度(不返加字段内容指针)。或者返回一个字段结束标识以表明记录的所用字段都已被遍历过。IDBRECORD_GetField()返回指向当前字段内容的指针,同时返回当前字段的名称、类型及长度。

IDBRecord接口也提供了一个简明函数来访问字段类型为已知的当前字段内容。

  • IDBRECORD_GetFieldWord()检索字段类型为Word型的字段内容。
  • IDBRECORD_GetFieldDWord()检索字段类型为DWord型的字段内容。
  • IDBRECORD_GetFieldString()检索字段类型为字符串型的字段内容。

上述函数在数据类型不匹配时返回一个错误信息。

IDBRecord接口函数用法

  1. 如需要,调用ISHELL_CreateInstance()创建一个指向IDBMgr的指针。
  2. 调用IDBMGR_OpenDatabase() 或 IDBMGR_OpenDatabaseEx()打开一个指向新建或已存在的Idatabase接口指针。
  3. 调用IDATABASE_CreateRecord(), IDATABASE_GetRecordByID()或 IDATABASE_GetNextRecord() 来得到一个 IDBRecord 接口指针用于操作该记录。

访问指定记录

  1. 调用IDBRECORD_Reset() 和 IDBRECORD_NextField()来遍历一条记录的所有字段以得字段名称、类型及内容长度。调用一个IDBRECORD_GetField()函数来取得当前字段的内容。
  2. 调用IDBRECORD_GetID()获得该记录的唯一索引。
  3. 调用IDBRECORD_Update()为一个记录提供新值。
  4. 调用IDBRECORD_Remove() 从数据库中删除一条记录。
  5. 当不需再访问某条记录时调用 IDBRECORD_Release() 来关闭它,如果如步骤4中删除一条记录,则不需要再调用IDBRECORD_Release() 来关闭它

IAddrBook 接口

IaddrBook 接口提供与OEM地址簿交互的能力,OEM地址簿为手机上的首选地址簿,它不支持多地址簿。

IaddrBook接口提供了对地址簿集合的访问,地址簿记录包含了存放于地址簿中数据,每条地址簿地录可以属于某个特定的分类(如私人或商业分类)。所支持的分类由OEM来控制,可以通过调用IADDRBOOK_EnumCategoryInit() 和 IADDRBOOK_EnumNextCategory() 来枚举出由OEM所支持的分类。

每个记录包含一组字段集合,每个字段具有一个FieldID和字段类型,FieldID由枚举类型AEEAddrFieldID来索引,OEM可以增加OEM特定的字段。

同一个字段不能包含多个值,如果一个地址簿记录需要记录多于一个HOME PHONE号码,则需要为每个号码给出一个字段。

同样的情形,如果一个号码既是家庭号码又是办公号码,需要两个不同的字段来表明家庭和工作信息。AEE_ADDRFIELD_PHONE_HOME,AEE_ADDRFIELD_PHONE_WORK。

IAddrBook提供了一个BREW接口用于访问指定的地址簿,地址簿为一条或多条地址记录的集合。

接口提供了:

  • 枚举地址簿分类的能力。
  • 枚举所支持字段字型的能力。
  • 在地址簿中增加一条记录。
  • 根据指定的字段或分类查找地址簿。
  • 浏览整个地址簿。

IAddrBook接口可以用于访问设备地址簿或在RUIM卡的地址簿,访问设备地址簿必需使用 AEECLSID_ADDRBOOK来创建IaddrBook接口指针,而需访问RUIM卡时,则为AEECLSID_ADDRBOOK_RUIM。

IAddrRec接口

IAddrRec提供了访问地址簿记录单个字段的能力:

  • 为记录增加一个字段。
  • 更新一个现存记录的字段。
  • 删除一个现存记录的字段。
  • 修改一个记录的分类。
 

BREW开发教程(11):文件系统

BREW提供了一个EFS接口,可以用于文件和目录管理及读写操作。

IFileMgr接口

IfileMgr接口函数用于创建、删除、重命名文件/目录。将提供了获取文件和目录信息的方法。能过指定Class ID为AEECLSID_FILEMGR调用ISHELL_CreateInstance()来得到一个指向IfileMgr接口的指针,IfileMgr指针可以用来访问应用程序目录下的文件。BREW AEE同样也提供了一个可以允许多个应用程序访问的共享目录。共享目当由AEE.h中宏AEE_SHARED_DIR定义(实际的文件名由设备制造商来指定)。

BREW AEE中文件名称是不区分大小写的,这意味着当使用IfileMgr或其它文件相关API时,它将使用小写字母为文件名。例如:以Foo.bar调用IFILEMGR_OpenFile(),文件将以foo.bar打开。

BREW支持的最长设备文件名长度由AEE_MAX_FILE_NAME指明,为64。

注:应用程序必需具有PL_FILE或PL_SYSTEM才能打开和创建文件和目录,必需具有PL_SHARD_WRITE或PL_SYSTEM才能对共享目录进行操作。

可以能过IFILEMGR_EnumInit()和 IFILEMGR_EnumNext()对某一目录进行枚举操作以得到该目录下所有的文件和目录。可以对所有指定扩展名的文件进行枚举操作,首先调用IFILEMGR_EnumInit()指明需要进行枚举操作的目录,每个后续的IFILEMGR_EnumNext()给出一个需要枚举的文件或目录的名称、大小、创建日期和属性。当该目录所有的文件和目录都遍历后IFILEMGR_EnumNext()返回FALSE。指明文件名通过调用IFILEMGR_GetInfo() 可以获得同样的文件信息。IFILEMGR_GetFreeSpace()函数返回设备文件系统中空闲空间字节大小。. IFILEMGR_GetLastError()返回上次错误代码。. IFILEMGR_Test()可以用来检测指定的文件或目录是否存在。

IFILEMGR_MkDir()创建一个目录。

IFILEMGR_RmDir()删除一个目当,在删除一个目录之前,必需删除该目录下所有文件及子目录。

IFILEMGR_OpenFile()创建一个新文件或者是打开一个现存的文件用于读或写操作。文件用相对于应用程序目录的文件名称来指定。IFILEMGR_OpenFile()返回一个指向打开的文件的Ifile接口指针,调用IFILEMGR_Release()来关闭一个打开的文件,. IFILEMGR_Rename() 重命名一个文件, IFILEMGR_Remove()删除一个文件,只有当文件关闭时才能被删除和重命名。如果文件被打开不止一次,每一个打开操作必需有与之对应的关闭操作,删除及重命名才能成功。

IfileMgr接口使用步骤

调用ISHELL_CreateInstance()创建一个IfileMgr接口指针。

调用上述的函数来取得应用程序目录下文件信息或取得当前文件系统空闲空间大小。

调用IFILEMGR_MkDir() 和 IFILEMGR_RmDir()来创建和删除一个目录。调用IFILEMGR_OpenFile(), IFILEMGR_Rename(), 和 IFILEMGR_Remove()打开、重命名或删除一个文件。

读取或修改文件内容

调用IFILEMGR_OpenFile()打开一个文件用于读或写。

调用 IFile 接口函数来修改文件内容。

当完成文件操作时调用IFILE_Release()来关闭文件。

不需使用IfileMgr时调用IFILEMGR_Release()关闭File Manager。

IAStream接口

IAStream从一个异步流中读取数据,该接口为一个抽象接口,实现该接口的类提供了一个当前可能还没有准备好需要进行异步操作的数据访问,当前Ifile和Isocket接口实现了Istream 接口定义,IImage和IsoundPlayer接口提供了IIMAGE_SetStream() 和 ISOUNDPLAYER_SetStream()函数指定某个Istream接口类作为Image和Sound的源。

IASTREAM_Read()从一个流中读取数据并返回读取的字节个数,如果当前没有可用于读取的数据,该函数将返回AEE_STREAM_WOULDBLOCK。在后一种情形下,调用IASTREAM_Readable()当有数据可读时调用一个回调函数。IASTREAM_Cancel()取消由IASTREAM_Readable()设置的回调函数。

使用IAStream接口异步读取数据

  1. 调用ISHELL_CreateInstance()创建一个实现了Iastream接口的类指针。
  2. 调用ASTREAM_Read()读取指定数量的数据,因为IAStream为一抽象接口,调用Ifile_Read来读文件,或ISOCKET_Read()来从一个Socket 中读取数据。
  3. 如果IASTREAM_Read()返回AEE_STREAM_WOULDBLOCK,调用IASTREAM_Readable()指明一个回调函数,
  4. 如果 IASTREAM_Read()返回的字节数比预计的要小,重复调用该函数以取得余下的数据。
  5. 重复2-4直至读取了所有的数据

IFile 接口

IFile接口提供了读取和修改文件内容的函数集合。通过调用IFILEMGR_OpenFile()来取指向某个文件的Ifile接口指针,再通过该指针调用Ifile接口函数。当完成对文件的操作后,调用IFILE_Release()来关闭该文件。

IFILE_GetInfo()返回打开文件的名称、大小、创建日期。如果文件未打开,通过调用IFILEMGR_GetInfo()可以获取同样的文件信息。

IFILE_Read()从文件中读取指定长度的数据到应用程序变量中。

IFILE_Write()将指定长度的数据写到文件中。所有的读写操作都是相对于当前文件指针而言的。文件打开时,文件指针指向文件头第一个字节(除非是以Append方式打开,此时文件指针为文件尾)。每个读写操作都将文件指针移到读或写的最后字节的下一个字符位置。通过IFILE_Seek()可以将文件指针移到特定的位置。

IFILE_Truncate()允许重新减小文件长度,它将抛弃截断位置后面的文件内容。

读写文件的三种读取方式

通过BREW提供的上述接口,可以以三种方式读取一个文件,一次性读取、按逻辑行读取,一次读取固定长度的字符串,分次读完文件。

一次性读取整个文件

该方法适用于文件比较小。

extern void       MM_UI_FILEEDIT_ReadFile(IWindow * po,char *pFileName)
{
IFileMgr * pIFileMgr;
int nErr;
FileInfo fileInfo;
MM_UI_FILEEDIT_T *  pThis = (MM_UI_FILEEDIT_T *)po;
MM_APPLET_INFO_T *pOwner=pThis->m_pOwner;
char* pzFileNameBuf = NULL;
IFile *pIFile;
AECHAR szFileName[]={‘o’,’p’,’e’,’r’,’a’,’t’,’i’,’o’,’n’,’.’,’t’,’x’,’t’, ‘\0’};
AECHAR *pFileContent=NULL;
char* pszLine;
int nRet;
ITEXTCTL_SetProperties(pThis->m_pStatic,TP_MULTILINE);
ISHELL_CreateInstance(pThis->m_pIShell,AEECLSID_FILEMGR,(void **)&pIFileMgr);
pzFileNameBuf=(char *)MALLOC(64);
STRCPY(pzFileNameBuf, AEE_SHARED_DIR);
STRCAT(pzFileNameBuf, “/operation.txt”);
pIFile=IFILEMGR_OpenFile(pIFileMgr,pzFileNameBuf,_OFM_READ);
if(pIFile)
{
IFILE_GetInfo(pIFile,&fileInfo);
pFileContent=(AECHAR *)MALLOC((fileInfo.dwSize+2)*sizeof(AECHAR));
pszLine=(char *)MALLOC((fileInfo.dwSize+1)*sizeof(char));
ZEROAT(pFileContent);
ZEROAT(pszLine);
nRet=IFILE_Read(pIFile,pszLine,fileInfo.dwSize+1);
STRTOWSTR(pszLine,pFileContent,(fileInfo.dwSize+2)*sizeof(AECHAR));
ITEXTCTL_SetMaxSize(pThis->m_pStatic, (uint16)fileInfo.dwSize*2);
ITEXTCTL_SetText(pThis->m_pStatic,pFileContent,-1);
FREEIF(pFileContent);
FREEIF(pszLine);
IFILE_Release(pIFile);
nErr=IFILEMGR_GetLastError(pIFileMgr);
DBGPRINTF(“%s -Error=%d”,”Error in creating a file”,nErr);
}
IFILEMGR_Release(pIFileMgr);
FREE(pzFileNameBuf);
}

按逻辑行读取

以回车换行符一行一行异步读取。

void OpenFile(AS_APP_MAINWIN_T * pi)
{
IFileMgr * pIFileMgr;
int nErr;
char* pzFileNameBuf = NULL;
IFile *pIFile;
ISourceUtil *pisu;
ISource *pisource;
AECHAR szFileName[]={‘o’,’p’,’e’,’r’,’a’,’t’,’i’,’o’,’n’,’.’,’t’,’x’,’t’, ‘\0’};
ISHELL_CreateInstance(pi->m_pIShell,AEECLSID_FILEMGR,(void **)&pIFileMgr);
ISHELL_CreateInstance(pi->m_pIShell,AEECLSID_SOURCEUTIL,(void **)&pisu);
WSTRTOSTR(szFileName,pzFileNameBuf,64);
pIFile=IFILEMGR_OpenFile(pIFileMgr,pzFileNameBuf,_OFM_READ);
if(pIFile)
{
ISOURCEUTIL_SourceFromAStream(pisu,(IAStream *)pIFile,&pisource);
ISOURCEUTIL_GetLineFromSource(pisu,pisource, 1100,
ISOURCE_Release(pisource);
ISOURCEUTIL_Release(pisu);
IFILE_Release(pIFile);
FileAction_ReadLines(pi);
}
else
{
nErr=IFILEMGR_GetLastError(pIFileMgr);
DBGPRINTF(“%s -Error=%d”,”Error in creating a file”,nErr);
}
AS_APP_RELEASEIF(pIFileMgr);
FREE(pzFileNameBuf);
}
static void FileAction_ReadLines(AS_APP_MAINWIN_T * pThis)
{
int        rv;
GetLine    gl;
// read a line
rv = IGETLINE_GetLine(pThis->piGetLine, &gl, IGETLINE_LF);
if (rv == IGETLINE_WAIT) {
CALLBACK_Init(&pThis->m_cb, WebAction_ReadLines, pThis);
IGETLINE_Peekable(pThis->piGetLine, &pThis->m_cb);
return;
}
DBGPRINTF(“%s\n”, gl.psz);
// if stream has not reached EOF or ERROR
if (!IGETLINE_Exhausted(rv)) {
// wait for more data
CALLBACK_Init(&pThis->m_cb, WebAction_ReadLines, pThis);
IGETLINE_Readable(pThis->piGetLine, &pThis->m_cb);
return;
}
}

固定长度读入文件

extern void       MM_UI_FILEVIEW_ReadFile(IWindow * po,char *pFileName)
{
IFileMgr * pIFileMgr;
int nErr;
MM_UI_FILEVIEW_T *  pThis = (MM_UI_FILEVIEW_T *)po;
MM_APPLET_INFO_T *pOwner=pThis->m_pOwner;
char* pzFileNameBuf = NULL;
IFile *pIFile;
AECHAR szFileName[]={‘o’,’p’,’e’,’r’,’a’,’t’,’i’,’o’,’n’,’.’,’t’,’x’,’t’, ‘\0’};
char szLine[80];
AECHAR szLine1[80];
int nRet;
ISTATIC_SetProperties(pThis->m_pStatic,ST_ASCII);
ISHELL_CreateInstance(pThis->m_pIShell,AEECLSID_FILEMGR,(void **)&pIFileMgr);
pzFileNameBuf=(char *)MALLOC(64);
// WSTRTOSTR(szFileName,pFileName,64);
pIFile=IFILEMGR_OpenFile(pIFileMgr,pFileName,_OFM_READ);
if(pIFile)
{
nRet=IFILE_Read(pIFile,szLine,80);
while(nRet)
{
szLine[nRet]=0;
STRTOWSTR(szLine,szLine1,80);
ISTATIC_SetTextEx(pThis->m_pStatic,(byte * )szLine,NULL,TRUE);
nRet=IFILE_Read(pIFile,szLine,80);
}
STRTOWSTR(szLine,szLine1,80);
//ISTATIC_SetTextEx(pThis->m_pStatic,(byte * )szLine,NULL,TRUE);
IFILE_Release(pIFile);
}
else
{
nErr=IFILEMGR_GetLastError(pIFileMgr);
DBGPRINTF(“%s -Error=%d”,”Error in creating a file”,nErr);
}
IFILEMGR_Release(pIFileMgr);
FREE(pzFileNameBuf);
}
 

BREW开发教程(10):用户界面

BREW AEE提供了一些用户界面控件:IStatic、IMenuCtl、ITextCtl、ITimeCtl等,所有这些控年都是从IControl接口派生出来的。目前的BREW SDK所提供可用控件不是很多,一些常用的如Checkbox, Radio box, Scroll bar, progress bar等都没有提供,在扩展这些控制,最好也从IControl接口派生出来,以实现统一的控件接口函数。

IControl接口

IControl接口是所有BREW控件类 (IDateCtl 、ImenuCtl、 IStatic 、 ITextCtl 和 ITimeCtl 等) 的抽象基类, 因为这个接口是一个抽象接口,所以不能直接创建该接口的实例。给定一个指向IControl的接口,可以调用IControl接口函数或是派生类接口函数。比如,重画一个菜单,可以调用ICONTROL_Redraw或 IMENUCTL_Redraw中任意一个。使用IControl接口一个好处是可以实现对不同类型的控件调用同一个接口函数。比如,有一个控件数组pControls[numControls]包含了指向不同类型的控件指针,而必需都显示在屏幕上,这时可以通过调用下面的循环来实现:

for (i = 0; i < numControls; i++)

ICONTROL_Redraw(pControls[i])

所有的BREW 控件类都必需实现由IControl接口定义的所有接口函数。然面每个控件类所定义的接口函数特性可以有所不同。

IControl接口定义了如下函数:

  • ICONTROL_HandleEvent()将消息传递给控件,BREW控件处理按键事件以允许用户输入文本、时间、日期或是选择某个菜单项。一个控件只有处于活动状态时才能接收按键事件。不同类型的控件对按键事件有不同的处理,除非控件是某个对话框的一部分,Applet必需在控件活动时将相应的按键事件传给它。
  • ICONTROL_Redraw()将控件绘制在屏幕上,这个函数也可以用于控件被覆盖后重画操作。
  • ICONTROL_SetActive()设定控件的活动状态,只有处于活动状态的控件才能接收并处理按键事件,在多控件的对话框中,只有获得焦点的控点是活动的。
  • ICONTROL_IsActive()用于判断控件是否处于活动状态。
  • ICONTROL_SetRect()设定控件所占据的矫形区域,某些控件提供在其中的内容超过控件区域时滚动的功能。正确设定控件矩形外框后,可以在屏幕上同时显示多个控件。
  • ICONTROL_GetRect()取得控件矩形区域。
  • ICONTROL_SetProperties()为控件设定属性,不同的控件所能设定的属性是不同,属性是一个32位整数来表示。
  • ICONTROL_GetProperties()则用于取得控件的当前属性。
  • ICONTROL_Reset()用于释放控件所占用的资源,但并不释放控件指针,一般用于控件的重新初始化。

下面简要介绍一下BREW提供的控件,并对扩展的控件一并作个介绍。

IDateCtl接口

IDateCtl用于需要用户输入日期时,具有两种类型的日期控件:

  • 标准类型日期控件,允许用户通过上、下、左、右键来选择指定的日、月、年。
  • 日期选择控件,显示以月为单位的日历,方向键用于一个月的某天,或是滚动到下个或上个月。

IDATECTL_HandleEvent()处理AVK_SELECT, AVK_UP, AVK_DOWN, AVK_LEFT和 AVK_RIGHT按键事件,当它收到AVK_SELECT按键事件时,将向Applet发送EVT_COMMAND表示用户已选择了某个日期。

IImageCtl接口

这个控件可以显示一个可滚动图象。是对IImage接口的一个封装类。

IMenuCtl接口

Menu控件允许用户从一个列表中作出选择,方向键用于指明某个选项。当前选中的菜单项是高亮形式表示。用于按下AVK_SELECT将向Applet发送EVT_COMMAND表明用户按下了某个菜单项。

有四种类型的菜单控件:

  • 标准的菜单控件。有如一般Window菜单。
  • 列表菜单控件,类似Window平台上不带下拉框的组合框控件。
  • 软按键,显示为在屏幕下方的按钮。
  • 图标菜单。类似Window平台上Listview以Icon形式。

IStatic接口

IStatic显示一个静态文本,和一般Window平台上的Cstatic具有类似的功能。

ITextCtl接口

编辑框控件,可以设置多行或单行,或是显示为密码输入框。

ITimeCtl接口

时间选择控件。有三种形式的时间控件。具体参见API。

上面为BREW提供的几种控件。在实际开发中远远不够使用。随本教程附带了几个扩展控件,它们大部分是从IControl派生出并实现了所有的IControl接口函数。

IButton接口

按钮控件,相当于Command Button。它和Soft Key不同是它可以显示在屏幕的任意地方,而不一定显示屏幕的最下方。可以为button控件指定Caption和背景颜色。

ICheckBox接口

Check box 控件。当其处于活动状态时,高亮显示。用户按下AVK_SELECT键时,切换选择和未选择状态。

IRadioBox接口

Radio box控件,为单选钮。可以在一组互拆的选项中选取其一。当其处于活动状态时,高亮显示。当其一个处于被选择状态时,该组其它按钮自动改为未选取状态。

IProgressBar接口

进程条控件。

IVScrollBar接口

垂直滚动条,该控件不是从IControl派生出来,一般不单独使用,而是作为其它容器类(IFormWin,IScrollWin和IContainer)的一部分,这些类在其中包括的控件超出范围时,自动显示滚动条。

IFormWin 和IScrollWin接口

这两个类都是IWindow的派生类,都是容器类,所谓容器类就是可以管理其它IControl派生类。它们都提供了一个AddControl接口函数。

PUBLIC boolean

ISCROLLWIN_AddControl(IScrollWin *pThis,IControl *pControl,boolean bTabStop=TRUE);

PUBLIC Boolean

IFORMWIN_AddControl(IFormWin *pThis,IControl *pControl,boolean bTabStop=TRUE);

可以将IControl派生类控件添加到这个窗口中。其中bTabStop 为真时,表示添加的控件可以获取焦点,为FALSE是不能获取焦点。

IformWin和IscrollWin都具有管理控件的能力,能过上、下键在不同的控件上切换焦点,以使控件变为活动状态。而且在控件超出范围时自动显示滚动条。

IformWin和IscrollWin不同之处在于对于控件的布局,IformWin允许控件自由放置位置,而IscollWin则是一行一行排列控件,并使控件宽度都窗口等宽。这两个窗口还可在屏幕下方添加一行SoftKey。

IContainer类

IContainer类为一容器控件,在其中可以添加其它IControl控件,但它本身是从IWindow派生出来。可以设置AEE_CP_ROWLAYOUT 、AEE_CP_BAGLAYOUT 分别类同IscrollWin和IformWin布局方法。它也提供了AddControl接口函数用于向其中添加IControl控件。能过上、下键在不同的控件上切换焦点,以使控件变为活动状态。而且在控件超出范围时自动显示滚动条。也可以在其中添加一行SoftKey。