上下文相关帮助本地化方案
上下文相关帮助(Context Sensitive Help)可以根据用户选择显示相应的帮助,用于解决在操作过程中所遇到的疑难问题。在实际当中,某个应用的使用者可能来自不同的国家和地区,使用着不同的语言文字,有着不同的习惯。如果我们希望自己开发的应用获得最大的用户群,则必须在用户界面(UI)的设计上考虑到这一可能的事实。为不同国家和地区的潜在用户设计适合其使用的界面便成了开发者们必然的选择,这在Symbian /C++开发中被称之为“本地化”(Localization)。
本地化应用不同于平时所用的电脑中的那些不同语言版本的同一软件,(例如英文版、简体中文版、繁体中文版)。也并非真的为每个语种设计单独的用户界面或单独应用,而是针对同一用户界面在不同语种环境中的不同要求而做一些变化。其基本原理就是,根据设备的语言设置调用其相应的经过编译的资源文件,以合成适合该语种的用户界面,使得应用象专门为使用该语言的人群而设计的一样。最典型的应用是对用户界面组件中显示字串的本地化,也就是%EPOCROOT%\Examples\toolsandutilities\localize\和%EPOCROOT%\Series60Ex\language\这两个例程中所做的那样。
不过在应用中不仅是字串有本地化的要求,同样被要求的还有帮助、图标、图片,甚至是动画、音频、视频。当然,动画、音频、视频的本地化在现今的硬件条件下我个人不主张,因为那样做会使应用占据过多的存储空间,这对在资源受限设备上的开发来说是不利的。图标、图片倒还可以接受,但即便是本地化图标和图片,它们也应该尽量小和少。
可是帮助不同于以上所说的资源,它基本上只是些文本,只要语言精练就占不了多大空间,所以帮助本地化和字串本地化是很类似的,特别是当用简单的弹出对话框显示帮助则几乎完全是一回事,也就是字串长度长一些。但如果涉及到上下文相关帮助的本地化,其和单纯的字串本地化相比,虽然基本原理相同,但所采用的具体方法就有所区别了。
用过上下文相关帮助的开发者都知道,首先应该为应用建立帮助源文件(.rtf),以及帮助项目文件(.cshlp)和可选的样式自定义文件(custom.xml),通过cshlpcmp编译后会生成相应的帮助文件(.hlp)和帮助标志头文件(.hlp.hrh)。在应用中程序会根据用户选择调用CCoeAppUi::AppHelpContextL, 之后系统会利用帮助标志作为参数调用被覆盖的CCoeAppUI::HelpContextL或CCoeControl::GetHelpContext方法从帮助文件中获取该标志所标识的帮助内容,再通过HlpLauncher::LaunchHelpApplicationL显示相应的帮助。
那怎样本地化帮助呢?根据本地化的一般方法,开发者必须为不同的语种建立不同的帮助,也就是为同一帮助项建立不同语种的内容。众所周知,系统必须通过帮助标志才能在帮助文件中找到相应的帮助内容。而帮助标志是什么?从帮助标志头文件中可以获知,它们其实是上下文的字串描述符,也就是一些字串。基于以上情况,我们完全可以舍弃帮助标志头文件,而直接在资源文件中建立相应的帮助标志字串资源,模仿%EPOCROOT%\Series60Ex\language\这个例程,通过本地化帮助标志字串,来实现上下文相关帮助的本地化。
下面就以Series 60 2nd Edition SDK for Symbian OS Supporting Feature Pack 3 for C++中大家所熟知的例程Help Example为基础(之所以选择这个SDK是因为其支持简体中文),对其进行中文简体本地化,籍此来谈谈上下文相关帮助的本地化。
首先,为不同语种建立不同的帮助源文件,即.rtf文件,用不同的帮助标志作为区别。将
%EPOCROOT%\Series60Ex \helpexample\help\下的
helpexample.rtf更名为
helpexample01.rtf,内容作如下修改(主要是帮助标志):
Code:
Author: Nokia
Date: 23 July 2002
Version: 1
HelpExample
0x10005B93
Application Help
¢ ContextApplication01 The Application
i HelpExample Application
When there are no controls in focus with help available, this message is shown.
Helpful Form
¢ ContextHelpfulForm01 The form
i HelpExample Form
This is a form implementing context-sensitive help. Special help is available when the first two controls have focus. This message is shown otherwise.
Edwin 1
¢ ContextEdwin101 Control 1 on form
i HelpExample Edwin 1
This is help for the first control on the form.
Edwin 2
¢ ContextEdwin201 Control 2 on form
i HelpExample Edwin 2
This is help for the second control on the form.
然后将
helpexample01.rtf另存为
helpexample31.rtf,内容修改为简体中文的帮助:
Code:
Author: Nokia
Date: 23 July 2002
Version: 1
HelpExample
0x10005B93
应用帮助
¢ ContextApplication31 The Application
i 帮助示例应用
当获得焦点的控制没有可用帮助时显示此信息。
帮助表格
¢ ContextHelpfulForm31 The form
i 帮助示例表格
这是一个执行上下文相关帮助的表格。当前两个控制获得焦点时会有相应的帮助。此信息在例外的情况下显示。
编辑框一
¢ ContextEdwin131 Control 1 on form
i 帮助示例编辑框一
这是表格中控制一的帮助。
编辑框二
¢ ContextEdwin231 Control 2 on form
i 帮助示例编辑框二
这是表格中控制二的帮助。
相应的帮助项目文件
helpexample.cshlp修改为:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<?xml:stylesheet href="..\..\..\epoc32\tools\cshlpcmp\xsl\CSHproj.xsl" title="CS-Help project" type="text/xsl"?>
<!DOCTYPE cshproj SYSTEM "..\..\..\epoc32\tools\cshlpcmp\dtd\cshproj.dtd">
<cshproj>
<helpfileUID>0x10005B94</helpfileUID>
<directories>
<input></input>
<output></output>
<graphics>pictures/</graphics>
<working></working>
</directories>
<files>
<source>
<file>HelpExample01.rtf</file>
<file>HelpExample31.rtf</file>
</source>
<destination>HelpExample.hlp</destination>
<customization>custom.xml</customization>
</files>
</cshproj>
可选的样式自定义文件
custom.xml在此无须修改。
接着修改
%EPOCROOT%\Series60Ex \helpexample\Group\helpexample.mmp
Code:
/* Copyright (c) 2004, Nokia. All rights reserved */
TARGET HelpExample.app
TARGETTYPE app
UID 0x100039CE 0x10005B93
TARGETPATH \system\apps\helpexample
.
.
.
SOURCEPATH ..\help
DOCUMENT HelpExample01.rtf
DOCUMENT HelpExample31.rtf
DOCUMENT HelpExample.cshlp
DOCUMENT Custom.xml
.
.
.
LIBRARY euser.lib
LIBRARY apparc.lib
LIBRARY cone.lib
LIBRARY eikcore.lib
LIBRARY avkon.lib
LIBRARY eikdlg.lib
LIBRARY eikcoctl.lib
LIBRARY hlplch.lib
LANG 01 31
AIF HelpExample.aif ..\aif HelpExampleAif.rss c12 qgn_help_demo_cxt.bmp qgn_help_demo_cxt_mask.bmp qgn_help_demo_lst.bmp qgn_help_demo_lst_mask.bmp
上下文相关帮助本地化方案
因为不再使用帮助标志头文件
HelpExample.hlp.hrh,所以
%EPOCROOT%\Series60Ex \helpexample\data\中的
helpexample.rss必须加入新的帮助标志字串资源,
%EPOCROOT%\Series60Ex \helpexample\data\helpexample.rss
Code:
/* Copyright (c) 2004, Nokia. All rights reserved */
NAME HELP
// INCLUDES #include <eikon.rh> #include <avkon.rh> #include <avkon.rsg>
#include "HelpExample.hrh" #include "HelpExample.loc"
// RESOURCE DEFINITIONS // ---------------------------------------------------------------------------- // // Define the resource file signature // This resource should be empty. // // ---------------------------------------------------------------------------- // RESOURCE RSS_SIGNATURE {}
. . .
RESOURCE DIALOG r_helpful_dialog { . . .
}
// ---------------------------------------------------------------------------- // // r_helpful_dialog_form // Form with three entries, 2 of which will provide context // sensitive help // // ---------------------------------------------------------------------------- // RESOURCE FORM r_helpful_dialog_form { items = { . . .
}; } //帮助标志字串资源 RESOURCE TBUF32 r_kca { buf=qtn_kca; } RESOURCE TBUF32 r_kce1 { buf=qtn_kce1; } RESOURCE TBUF32 r_kce2 { buf=qtn_kce2; } RESOURCE TBUF32 r_kchf { buf=qtn_kchf; }
// End of File
之后通过同一目录的字串文件实现帮助标志字串的本地化,将
helpexample.loc另存为
helpexample.l01并修改为:
Code:
/* Copyright (c) 2004, Nokia. All rights reserved */
// LOCALISATION STRINGS
// MENU TEXTS
//d:Command in options list. //d:Show form. #define qtn_help_helpexample_ShowForm "Show Form"
//d:Command in options list. //d:Help. #define qtn_help_helpexample_Help "Help"
//d:Command in options list. //d:Exit. #define qtn_help_helpexample_Exit "Exit"
// OPTIONS TEXTS IN VIEWING FORM
//d: Menu for "Options" when in viewing form //d: Help #define qtn_help_helpexample_ViewHelp "Help"
//d:Caption string for app. #define qtn_help_caption_string "Help Example"
//d:Short caption string for app. #define qtn_help_short_caption_string "Help"
// d:Dialog Form. // d: Names listed in Dialog. #define qtn_help_dialog1_prompt "Edwin 1" #define qtn_help_dialog2_prompt "Edwin 2" #define qtn_help_dialog3_prompt "Edwin 3"
//帮助标志字串 #define qtn_kca "ContextApplication01" #define qtn_kce1 "ContextEdwin101" #define qtn_kce2 "ContextEdwin201" #define qtn_kchf "ContextHelpfulForm01"
// End of File
再将
helpexample.l01
用UTF-8编码另存为
helpexample.l31,写入简体中文字串:
Code:
/* Copyright (c) 2004, Nokia. All rights reserved */
// LOCALISATION STRINGS
// MENU TEXTS
//d:Command in options list. //d:Show form. #define qtn_help_helpexample_ShowForm "显示表格"
//d:Command in options list. //d:Help. #define qtn_help_helpexample_Help "帮助"
//d:Command in options list. //d:Exit. #define qtn_help_helpexample_Exit "退出"
// OPTIONS TEXTS IN VIEWING FORM
//d: Menu for "Options" when in viewing form //d: Help #define qtn_help_helpexample_ViewHelp "帮助"
//d:Caption string for app. #define qtn_help_caption_string "帮助示例"
//d:Short caption string for app. #define qtn_help_short_caption_string "帮助"
// d:Dialog Form. // d: Names listed in Dialog. #define qtn_help_dialog1_prompt "编辑框一" #define qtn_help_dialog2_prompt "编辑框二" #define qtn_help_dialog3_prompt "编辑框三"
//帮助标志字串 #define qtn_kca "ContextApplication31" #define qtn_kce1 "ContextEdwin131" #define qtn_kce2 "ContextEdwin231" #define qtn_kchf "ContextHelpfulForm31"
// End of File
最后
helpexample.loc修改为:
Code:
/* Copyright (c) 2004, Nokia. All rights reserved */
CHARACTER_SET UTF8
#ifdef LANGUAGE_01 #include "helpexample.l01" #endif
#ifdef LANGUAGE_31 #include "helpexample.l31" #endif
// End of File
同时
%EPOCROOT%\Series60Ex\helpexample\src\中的
helpexampleappui.cpp和
helpfulform.cpp处理帮助标志字串的方法也必须改为从资源文件中读取,
%EPOCROOT%\Series60Ex \helpexample\src\helpexampleappui.cpp
Code:
/* Copyright (c) 2004, Nokia. All rights reserved */
// INCLUDE FILES #include <e32std.h> #include <hlplch.h> #include <Helpexample.rsg>
#include "HelpExample.pan" #include "HelpExampleAppUi.h" #include "HelpExampleAppView.h" #include "HelpExampleApplication.h" #include "HelpExample.hrh" #include "HelpfulForm.h" //#include "HelpExample.hlp.hrh"
. . .
// ----------------------------------------------------------------------------- // CArrayFix <TCoeHelpContext> // Return the help context for this application. // ----------------------------------------------------------------------------- // CArrayFix <TCoeHelpContext>* CHelpExampleAppUi::HelpContextL() const { CArrayFixFlat <TCoeHelpContext>* array = new ( ELeave )CArrayFixFlat <TCoeHelpContext> ( 1 ); CleanupStack::PushL( array ); HBufC16* p = iEikonEnv->AllocReadResourceLC( R_KCA ); array->AppendL( TCoeHelpContext( KUidHelpExampleApp, (TBufC16<32>) *p ) ); CleanupStack::PopAndDestroy( p ); CleanupStack::Pop( array ); return array; }
// End of File
%EPOCROOT%\Series60Ex \helpexample\src\helpfulform.cpp
Code:
/* Copyright (c) 2004, Nokia. All rights reserved */
// INCLUDE FILES #include <AknAppUi.h> #include <Avkon.rsg> #include <eikmenup.h> #include <Helpexample.rsg>
#include "HelpfulForm.h" #include "HelpExampleApplication.h" #include "HelpExample.hrh" //#include "HelpExample.hlp.hrh"
. . .
// ----------------------------------------------------------------------------- // CHelpfulForm::GetHelpContext() // Gets the control's help context. Returns a NULL context by default. // ----------------------------------------------------------------------------- // void CHelpfulForm::GetHelpContext( TCoeHelpContext& aContext ) const { // Get any special help context for the control with focus, else a default aContext.iMajor = KUidHelpExampleApp;
switch ( IdOfFocusControl() ) { case EHelpExampleEdwin1: // Provide special help context if first control has focus { HBufC16* pce1 = iEikonEnv->AllocReadResourceLC( R_KCE1 ); aContext.iContext = (TBufC16<32>) *pce1; } break;
case EHelpExampleEdwin2: // Provide special help context if second control has focus { HBufC16* pce2 = iEikonEnv->AllocReadResourceLC( R_KCE2 ); aContext.iContext = (TBufC16<32>) *pce2; } break;
default: // Provide default help context for this dialog otherwise { HBufC16* pchf = iEikonEnv->AllocReadResourceLC( R_KCHF ); aContext.iContext = (TBufC16<32>) *pchf; } break; } CleanupStack::PopAndDestroy( 1 ); }
. . .
// End of File
如果要制作安装包(.SIS),则
%EPOCROOT%\Series60Ex\helpexample\sis\helpexample.pkg文件也必须作如下修改:
Code:
;/* Copyright (c) 2004, Nokia. All rights reserved */ ; Installation file for HelpExample application ; HelpExample.pkg ;
;Language - standard language definitions &EN
;Standard SIS file header #{"HelpExample"},(0x10005B93),1,0,0
;Supports Series 60 v 2.0 (0x101F7960), 0, 0, 0, {"Series60ProductID"}
; "..\..\..\epoc32\release\thumb\urel\HelpExample.APP" -"!:\system\apps\HelpExample\HelpExample.app" "..\..\..\epoc32\data\z\system\apps\HelpExample\HelpExample.r01" -"!:\system\apps\HelpExample\HelpExample.r01" "..\..\..\epoc32\data\z\system\apps\HelpExample\HelpExample.r31" -"!:\system\apps\HelpExample\HelpExample.r31" "..\help\HelpExample.hlp" -"!:\system\help\helpexample.hlp" "..\..\..\epoc32\data\z\system\apps\HelpExample\HelpExample_caption.r01" -"!:\system\apps\HelpExample\HelpExample_caption.r01" "..\..\..\epoc32\data\z\system\apps\HelpExample\HelpExample_caption.r31" -"!:\system\apps\HelpExample\HelpExample_caption.r31" "..\..\..\epoc32\data\z\system\apps\HelpExample\HelpExample.aif" -"!:\system\apps\HelpExample\HelpExample.aif"
至此,例程Help Example中文简体本地化的工作就完成了,修改后的例程在Series 602nd Edition Supporting Feature Pack 3 平台的模拟器和真机上均运行正常。其它版本SDK中的Help Example也可照此方法中文简体本地化,但也许会略有不同。
S60平台本身支持上下文相关帮助的本地化,所以最简的步骤是: 1. 做好英文版的HLP文件 2. 拷贝RTF文件并翻译成其它语种(帮助标识不变),并生成HLP文件 3. 将帮助文件的后缀按其语种改为h01和h31等 4. 打包
|