认识TBufC和TBuf
==================================================================================
example from "epoc32ex\Base\BufsAndStrings\Desc\buffer"
==================================================================================
1. 定义
Build independent non-modifiable buffer descriptor.
This is a descriptor class which provides a buffer of fixed length for containing and accessing TText data.
说明这是一个descriptor类,提供了固定长度的buffer,不可修改,用于访问和使用 TText 类型的数据。
2. 继承关系
根据是否为支持Unicode,TBufC继承自两个不同的类TBufCBase8,TBufCBase16。
TBufC--> TBufCBase16--> TDesC16。或者 TBufC--> TBufCBase8--> TDesC8
class TBufC: public TBufCBase16
...
protected:
TText iBuf[__Align(S)];
};
从类结构定义中可以看出,TBufC保存的是TText 类型的数据。而TText 的定义为:
typedef TText16 TText; 或者 typedef TText8 TText;
而扩展定义为 typedef unsigned char TText8; typedef unsigned short int TText16;可以看出,为了支持Unicode,TText16定义为
16 bits的字符。
从其继承的类结构中(TDesC16,TDesC8)也可以看出TBufC类具有当前数据长度。长度可以通过函数length获得。
但是size()根据不同的编译条件返回不同的字节数目,这一点和TBuf8不同,TBuf8中size()和length()返回的值永远相同。
3. 位置
如果声明为自动变量,则保存在stack上。
4. 使用
因为在TBufC中保存的是TText;类型,在Unicode下,也就是unsigned short int类型的数据,所以可以通过TText数组赋值。TText数组
包含C语言类型的字符串(NULL结尾),也可以放置Unicode码,用于初始化。如下所示:
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
TText cstr[13] = {0x0042, ''e'' ,''l'' ,''l'' ,''o'', '' '',
''W'', ''o'',''r'', ''l'', ''d'', ''!'', ''\0''};
TText cstr[3] = {0x0042, 0x53e4,0x0000};
// Construct a TBufC using the NULL
TBufC<16> bufc1(&cstr[0]);
/*------------------------另外一种赋值方法----------------------- -----------*/
TBufC<16> bufc2(KTxtHelloWorld);
/*-------------------------但是要注意替换的字符长度不能超过目标的长度 ------*/
_LIT(KTxtRepText,"Replacement text");
bufc2 = KTxtRepText;
取得长度和size
---------------------------------------------------------------------------------------------------
bufc1.Length(); // Length指的是存储的字符数目
------------------------------------------------------------------------------------------
数据段地址
------------------------------------------------------------------------------------------
bufc1.Ptr() // 可以利用Ptr()函数取得数据段的地址,Ptr()的返回值是
const TUint16
-----------------------------------------------------------------------------------------
Des()函数的使用和利用TPtr访问TBufC
----------------------------------------------------------------------------------------
// 可以利用Des()函数返回一个指向TBufC的TPtr。利用这个TPtr可以访问TBufC
TPtr ptr = bufc2.Des();
ptr.Ptr(), // 这个返回的地址和bufc2.Ptr()返回的地址相同
ptr.Length(),
ptr.Size()
ptr.MaxLength() // 可以取得最大的存储空间长度
// 可以利用Des()函数返回一个指向TBufC的TPtr。利用这个TPtr可以更改
TBufc的内部数据
_LIT(KTxtAndHi," & Hi");
ptr.Delete((ptr.Length()-1),1); // 删除其中的某个位
ptr.Append(KTxtAndHi); // append字符,注意不要超过空间限制
---------------------------------------------------------------------------------------
5. 存储方式
TBufC的存储方式如下所示:
| head | content |
class TDesC16
......
#if defined(__DESC_NO_BIT_FIELDS__)
TUint iLength;
#else
unsigned int iLength:28;
unsigned int iType:4;
#endif
__DECLARE_TEST;
};
其中head包括fixed length 和 type。从类的结构定义可以看出,head占用4个字节,其中长度为28个bit,而type为4个bit。
所以数据只能表示25千万个字符了。并且数据区和整个的descriptor的地址偏移4个字节。
6. TBuf
TBuf的基本属性和TBufC类似,只是TBuf可以允许更改。
------------------------------------------------------------------------------------------
初始化和赋值
------------------------------------------------------------------------------------------
TBuf<16> buf(KTxtHelloWorld);
------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------
// The data can be modified
buf.Append(''@'');
// Length can be changed;
// Length can be zeroised;
// The data can be replaced entirely using the assignment operator.
buf = KTxtRepText;
framework
其实在我看来,symbian OS之上的MMI编程和MFC类似,都是有个application framework,用户需要的就是在这个基础之上,对类进行继承,对函数进行重载,而framework完成了很多和系统进行交互的工作。This is the second document . on my opinion, there are same a little between MFC and symbian OS .They all own a application framework on their basic OS. Based on such framework, user only need to make their own derived class ,and reload the virtual functions. and the framework can help u hanle most work interacting with the OS.
===================================
这是文档中关于编译和运行的资料,我懒得翻译了。还有结合我开发中的问题
做了补充。
===================================
1. abld是利用项目文件(appname.mmp)进行编译的,所以,在你的mmp文件改动过后,一定要利用
abld makefile vc6
重新生成VC工程文件,然后才能够利用VC进行app的编译,否则会出错。
(手工修改VC的编译、连接设置不起作用,不知为何?)
一、编译和运行
1. Building and running the examples
This section explains how to build and run the SDK example applications. All the applications are built and run in the same way. The applications can be built to run on the Symbian OS emulator, or the target device.
2. Building for the Symbian OS emulator
The SDK and the example applications should be installed.
To build an application, do the following:
1. Create the abld file.
In a command window, go into the application''''s top level folder (the one which contains the bld.inf file) e.g. \animation\gui\group and enter the following command:
bldmake bldfiles
This will create the abld.bat file in the current directory.
2. Create the Wins build files and build the application.
In the application''''s top level folder enter the following command:
abld build wins udeb
This will create the necessary build files and build the application, including any resource files required. This stage may produce warnings. If it produces errors, a DLL component may not have had its exports frozen. Perform step 3, below.
3. If the application has a DLL component, freeze the exports.
If an application contains a DLL component this step must be performed, otherwise it can be skipped. In the application''''s top level folder enter the following command:
abld freeze
This will ensure that the exports are frozen. Then enter the following command (repeated from step 2):
abld build wins udeb
This will build against the newly frozen interface..
3. Running the application on the emulator
To run the application on the emulator, carry out the following steps:
1. Run the emulator.
From a command window, run the command
Epoc
to launch the debug emulator, or
epoc -rel
to launch the release emulator. The emulator window will appear.
2. Find the application folder.
When the emulator has started, a set of applications and folders will appear. Find the Other folder.
3. Run the application.
Select the Other folder, and then select the relevant application icon. This will run the application.
4. Running the application from Visual C++
The emulator can also be run from Microsoft Visual C++. This can be useful when modifying or debugging the application.
Create the Visual C++ workspace and project files.
In the application''''s top level folder enter the following command:
abld makefile vc6
This will create the Visual C++ project files in a subdirectory of the %EPOCROOT%epoc32\Build'''' directory, where %EPOCROOT% is the pathname of the emulator root; e.g. \Symbian\6.0\NokiaCPP\
(在我使用的siemens SX1中目录为Q:\Siemens\SX1\bin )
Run Microsoft Visual C++ and open the workspace file
The workspace file a pathname of the following form:
%EPOCROOT%Epoc32\Build\ApplicationPathname\Group\ApplicationName\Wins\ApplicationName.DSW
where:
%EPOCROOT% is the pathname of the emulator root; e.g. \Symbian\6.0\NokiaCPP\ (在我使用的siemens SX1中目录为Q:\Siemens\SX1\bin )
ApplicationPathname is the pathname of the example application folder; e.g. \Examples\animation
ApplicationName is the name of the example application. e.g. animation
So the whole pathname could be, e.g.
\Epoc32\Build\Examples\animation\Group\animation\Wins\animation.DSW
Select the Execute item from the Build menu.
When the ''''Executable for Debug Session'''' dialog box appears press the command button in the right of the dialog box and select browse from the pop-up menu. Using the browse dialog select the file %EPOCROOT%epoc32\release\wins\udeb\epoc.exe. The emulator will run. You only need to do this once. When you subsequently select execute for this application, the emulator will automatically run.5 Building for the target device
The SDK and the example applications should be installed.
To build the applications, do the following:
5.1 Create the abld file.
Go into the application''''s top level folder (the one which contains the bld.inf file) e.g. ''''\animation\gui\group'''' and enter the following command:
bldmake bldfiles
This will create the abld.bat file in the current directory.
5.2 Create the target build files and build the application.
In the application''''s top level folder enter one of the following commands, depending upon whether you wish to target the ARMI or THUMB instructions sets:
abld build armi urel
abld build thumb urel
This will create the necessary build files and build the application, including any resource files required. This stage may produce warnings. If it produces errors, a DLL component may not have had its exports frozen. Perform stage 3, below.
5.3 If the application has a DLL component, freeze the exports.
If an application contains a DLL component this step must be performed, otherwise
it can be skipped. In the application''''s top level folder enter the following command:
abld freeze
This will ensure that the exports are frozen. Then enter the following command (repeated from step 2):
abld build armi urel
abld build thumb urel
This will build against the newly frozen interface.document对象分析
Document分析「继承关系」——————————————————————————CAknDocument -> CEikDocument -> CApaDocument——————————————————————————「主要作用」
1) 是app的data model.
2) 在基于文件的app中,document提供了对于文件的访问(store/restore)
3) 负责创建AppUI,从而可以提供修改document的基础,CreateAppUiL()负责创建application的appUI对象。
实际上,document起到了一个中间层(intermediate layer)的作用。负责在appui和app model(engine)以及 file之间建立联系。
「AppUI」
----------------------- 『Document』
|「model」 <-> 「file」
「Document的管理」
1) OpenFileL()
这个函数的功能和app的资源文件中的TBUF段(segment)密切相关。
RESOURCE TBUF r_default_document_name { buf="";}这个segment决定了application关联的文件名。这里的文件名连同路径就作为参数传递给了OpenFileL() 函数。这就使得application在启动的时候能够调用缺省的file,如果这个segment是空的,那么缺省的document的名字和application的basename相同。这里需要注意的是series60只允许存在一个缺省的file.这个函数的返回值是CFileStore*,这是返回给application framework的指针,以方便application framework把它传递给其他函数。
「注」
注意OpenFileL() 需要三个参数,其中文件名(TDesC& aFilename)和file server session参数(RFs& aFs) 应当是由application framework自动创建的。但是另外一个参数怎么确定的呢?
2) NewDocumentL()
这个函数是由application framework来调用,用于初始化一个default document file.「注?」
这个函数是不是在资源文件没有文件名的情况下调用的?如果是这样,那么这个函数应当在OpenFileL()
之前被调用?
「解释」
我在Document函数里面重载了函数NewDocumentL()和OpenFileL(),并分别加上了断点跟踪调试。发现:(#) 如果在资源文件中没有文件名的话,那么这两个函数都不执行。
(#) 如果在资源文件存在文件名的话,那么首先执行的是OpenFileL()函数,但是这个时候的aOpen参数值是0,表明文件不存在或者文件没有打开。那么接下来调用NewDocumentL(),这个函数负责创建一个新的document file.接下来会调用document类的StoreL()函数。
(#) 在晚上上述的步骤之后,再重新运行这个app,那么启动的时候会调用OpenFileL()函数,这个时候aOpen参数值是1,表明文件存在,那么接下来就调用ReStoreL()函数对文件进行读写。
「对相关file的管理」
document类提供了两个函数对文件的mode访问和修改。AppFileMode()和SetAppFileMode()。
「对相关file的访问存取」
document类提供了如下函数对file进行访问:SaveL();StoreL();RestoreL();ExternalizeL();PrintL();其中SaveL()会在app退出的时候被调用,用于保存app相关的数据到file中去。
SaveL() ——> StoreL();而RestoreL()是在app启动的时候调用的,负责把文件的信息保存在document相关的model(engine)中去。
「具体的UI/engine的结构以后在仔细的研究一下:-)」