提出问题:
建立一个名为HelloWorld的GUI应用程序
进入程序后点击菜单项“Test”,弹出内容为”HelloWorld”的对话框,如果想将显示内容改为”中国”两个字
现有三种方法可以解决:
解决方法:
第一种方法:
一、HelloWorld.loc做出以下几个改动
1、在其中增加一行
CHARACTER_SET UTF8
2、将#define R_MESSAGE_TEXT_STRING "HelloWorld";
改为 #define R_MESSAGE_TEXT_STRING "中国";
3、最终将HelloWorld.loc另存为(UTF-8 - 无BOM)编码,,不要另存为UTF-8, 否则编译通不过,具体原因不清楚, 希望有人补充下
二、HelloWorldAppui.cpp::HandleCommandL()中有以下代码,现做一定解释
// Load localized message from the resource file 从资源文件中读取文本
HBufC* message = CEikonEnv::Static()->AllocReadResourceLC(R_MESSAGE_TEXT);
// Show information note dialog 执行对话框
CAknInformationNote* note = new (ELeave) CAknInformationNote;
note->ExecuteLD(message->Des());
// 弹栈并销毁
CleanupStack::PopAndDestroy(message);
另外 从资源文件中读取文本 还有两种方法
1、将HBufC* message = CEikonEnv::Static()->AllocReadResourceLC(R_MESSAGE_TEXT);
改为 HBufC* message = iEikonEnv->AllocReadResourceLC(R_MESSAGE_TEXT);
2、HelloWorldAppui.cpp 中增加 #include <StringLoader.h>
将HBufC* message = CEikonEnv::Static()->AllocReadResourceLC(R_MESSAGE_TEXT);
改为HBufC* message = StringLoader::LoadLC(R_MESSAGE_TEXT);
三、补充
1、使用CEikonEnv::Static()->AllocReadResourceLC(R_MESSAGE_TEXT);
需要#include <eikenv.h >,相应的eikcore.lib
我们发现在mmp中有了eikcore.lib,但在整个项目里面没有发现<eikenv.h >,
我们看下
#include "HelloWorldAppui.h" 中有
#include <aknappui.h> 中有
#include <Eikspane.h> 中有
#include <eikspmod.h> 中有
#include <eiksrvc.h> 中有
#include <eiksrvs.h> 中有
#include <eikenv.h> 终于找到了
2、iEikonEnv->AllocReadResourceLC(R_MESSAGE_TEXT);
iEikonEnv在<eikdef.h>定义了,我们看下#include <eikenv.h>,发现包含有#include <eikdef.h>
第二种方法:
一、定义一个新的文件
1、将要显示的中文定义在一个头文件中(如CharacterString.h)
其中包含如下代码
#include <utf.h>
_LIT8(KZGText8, "中国");
2、将CharacterString.h文件用 UltraEdit-32工具将其转换为 UTF-8编码
HelloWorldAppui.cpp::HandleCommandL()
二、在HelloWorldAppui.cpp中
1、增加一行 #include "CharacterString.h"
2、将第一种方法中的HelloWorldAppui.cpp::HandleCommandL()中的相应代码改为如下代码:
TBuf<10> BufTemp;
// 将UTF-8编码转换为Unicode编码, CnvUtfConverter类对应的头文件是<utf.h>,这就是为// 什么在CharacterString.h中要有#include <utf.h>
CnvUtfConverter::ConvertToUnicodeFromUtf8 (BufTemp, KZGText8);
CAknInformationNote* note = new (ELeave) CAknInformationNote;
note->ExecuteLD(BufTemp);
3、CnvUtfConverter::ConvertToUnicodeFromUtf8()作用是将UTF-8编码转换为Unicode编码, CnvUtfConverter类对应的头文件是<utf.h>,这就是为什么在CharacterString.h中要有#include <utf.h>,但是这时运行会出错,因为还没有添加lib文件,<utf.h>相应的lib文件是charconv.lib,请把该文件添加到mmp文件LIBRARY行中
4、注意事项:
不知为什么,在CharacterString.h中, 如果将_LIT8(KZGText8, "中国");改为_LIT8(KZGText8, "中国人");将会出现
C:/Symbian/8.0a/S60_2nd_FP2_SC/Examples/MyExamples/Exercise/TBUF/inc/Common.h(3): error C2001: 常数中有换行符
C:/Symbian/8.0a/S60_2nd_FP2_SC/Examples/MyExamples/Exercise/TBUF/inc/Common.h(3): fatal error C1057: 宏展开中遇到意外的文件结束
错误,但只要在“人”字后面加个空格或'/0'字符又可以通过了,,
第三种方法
一、定义一个新的文件,命名为Common.h
其中包含如下代码
// 因为要使用CCnvCharacterSetConverter类,相应的lib文件和<utf.h>相同都是 charconv.lib
#include <charconv.h>
void ConvertToUnicode(TDes& aTarget, const TDesC8& aSource)
{
CCnvCharacterSetConverter *converter = CCnvCharacterSetConverter::NewLC();
if(converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGbk, CEikonEnv::Static()->FsSession()) != CCnvCharacterSetConverter::EAvailable)
{
User::Leave(KErrNotSupported);
}
TInt state = CCnvCharacterSetConverter::KStateDefault;
converter->ConvertToUnicode (aTarget, aSource, state);
CleanupStack::PopAndDestroy();
}
二、在HelloWorldAppui.cpp中
1、增加一行 #include "Common.h"
2、将第一种方法中的HelloWorldAppui.cpp::HandleCommandL()中的相应代码改为如下代码:
_LIT8(KText8, "中国");
TBuf<10> BufTemp;
ConvertToUnicode(BufTemp, KText8);
CAknInformationNote* note = new (ELeave) CAknInformationNote;
note->ExecuteLD(BufTemp);
方法比较:
1、效率性:
第一种方法和第二种方法差不多,第三种方法效率明显低于前两种,主要表现在执行ConvertToUnicode(BufTemp, KText8);时
2、灵活性:
第一种应该是最麻烦的,主要表现在定义字符串常量时,需在rsst和loc两个文件中定义
第三种方法最方便,尤其是对动态变化的文字,可以随时定义,随时更改,比较灵活,
建议:
1、对于标准控件上需要显示的中文采用第一种方法,如菜单、对话框等上的文字,系统提供了定义标准控件时要用到的一系列结构体,如MENU、DIALOG等,
2、对于自定义控件需要显示的中文,不会或很少变化的中文采用第二种方法
3、对于动态变化的文字,采用第三种方法,但是能采用第二种的尽量采用第二种,因为第三种方法实在是太慢了,在N6670真机上,当执行ConvertToUnicode(BufTemp, KText8);9次时,差不多需要1秒时间