Changing application's language at runtime--运行过程中改变应用程序的语言

本文介绍了一种在应用程序运行过程中动态更改语言的方法。通过分离资源文件并利用特定函数扫描可用的本地化资源文件,实现了语言的动态切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Changing application's language at runtime.

运行过程中改变应用程序的语言

There're many examples that show how to write multi-language applications. The basic idea is getting the proper language at installation time, or through the use of optional packs. Sometimes, there's a need to change languages dynamically while the application is running. This may seem like a difficult task, but following some basic guidelines it'll prove to be very easy.

有很多例子介绍如何写支持多语言的应用程序。基本的思路是:在安装时获取合适的语言,或者通过使用可选包来改变程序语言。有时候,需要在应用程序运行时动态改变语言。这貌似是一个不容易的工作,但是如果你遵照下面的指导来进行,那么动态改变程序语言将变得非常容易。

First off, we'll need to separate the default resource file into two pieces. Depending on the way you choose to allow the user to toggle among languages, you'll provide the default resource file of the corresponding structures. For example purposes, I've chosen a listbox dialog, which is the first control shown upon execution. Depending on the language selected, the corresponding secondary resource file will be loaded. This second resource file will be the provider of the localized content.
So back to our example, the default resource file will look like:

首先,我们需要把默认的资源文件分成两部分。根据你选择的允许用户在多种语言之间进行切换的方式,你需要提供对应结构的默认资源文件。为举例说明,我选择了程序运行时第一个出现的控件-----列表对话框。依据选择的语言,加载相应的第二个资源文件。这第二个资源文件提供本地化内容。因此,回到我们的例子中来,默认的资源文件将会是这样:

NAME TEST
#include <eikon.rh>
#include <avkon.rsg>
#include <avkon.rh>
#include <avkon.mbg>
#include "Test.hrh"
#include "Test.loc"
RESOURCE RSS_SIGNATURE { }
RESOURCE TBUF { buf = qtn_app_caption_string; }
RESOURCE EIK_APP_INFO
{
    cba = R_AVKON_SOFTKEYS_OPTIONS_BACK;
    menubar = r_dummy_menubar;
}
 
RESOURCE MENU_BAR r_dummy_menubar
{
    titles=
    {
        MENU_TITLE { menu_pane = r_dummy_menupane; txt=""; }
    };
}
 
RESOURCE MENU_PANE r_dummy_menupane
{
    items=
    {
        MENU_ITEM { command = EAknCmdExit; txt = qtn_cmd_exit; }
    };
}
 
RESOURCE DIALOG r_list_dialog
{
    flags = EAknDialogSelectionList | EEikDialogFlagWait;
    buttons = R_AVKON_SOFTKEYS_SELECT_CANCEL;
 
    items = 
    {
        DLG_LINE
        {
            type = EAknCtSingleListBox;
            id = ESelectionListControl;
            control = LISTBOX
            {
                flags = EAknListBoxSelectionList;
            };
        }
    };
}
 

 

First thing to note is the use of cba and menubar in the EIK_APP_INFO resource structure. This is a

convenience, as it delegates construction and layout of both CBA and menu bar to the application's UI.

Otherwise, we'd have to perform this action manually (which means calculating the screen area and

location for each of these controls, among other things) which is also specific to the UI used (Avkon,

Qikon, etc). The last resource structure defined corresponds to the dialog that will allow us to select the

language dynamically.

 需要注意的第一件事是在EIK_APP_INFO 资源结构中使用命令按钮域(CBA:Command Button Area)和菜单栏。这样很方便,因为它指定了应用程序用户界面中的命令按钮域和菜单栏的创建和布局。否则,我们将不得不手动执行这些特定于所使用的用户接口(Avkon,Qikon,等等)的操作(这意味着我们需要在其他控件中计算出每一个这样的控件的屏幕区域和位置)。最后定义的资源结构,和允许我们动态选择语言的对话框是对应的。

Now we define a second resource file, which will contain the rest of the resources used by the

application. Most controls should be in this resource file:

现在我们定义第二个资源文件,它将包含应用程序使用的其他资源。大部分的控件应该包含在这个资源文件里面:

NAME EXTR
 
#include <eikon.rh>
#include <avkon.rsg>
#include <avkon.rh>
#include <avkon.mbg>
 
#include "Test.hrh"
#include "Test.loc"
 
RESOURCE RSS_SIGNATURE { }
 
RESOURCE CBA r_softkeys
{
    buttons =
    {
        AVKON_CBA_BUTTON { id = EAknSoftkeyOptions; txt = qtn_softkey_options; },
        AVKON_CBA_BUTTON { id = EAknSoftkeyExit; txt = qtn_softkey_exit; }
    };
}
 
RESOURCE MENU_BAR r_menubar
{
    titles=
    {
        MENU_TITLE { menu_pane = r_menupane; txt=""; }
    };
}
 
RESOURCE MENU_PANE r_menupane
{
    items=
    {
        MENU_ITEM { command = ECmdLang; txt = qtn_cmd_lang; },
        MENU_ITEM { command = ECmdTest; txt = qtn_cmd_test; },
        MENU_ITEM { command = EAknCmdExit; txt = qtn_cmd_exit; }
    };
}
 
RESOURCE TBUF r_text_greeting
{
    buf = qtn_text_greeting;
}
 

 

Also note we need to provide a NAME and RSS_SIGNATURE, otherwise we'd get a panic (internally,

CONE's AddResourceFileL() uses RResourceFile and RResourceFile::ConfirmSignatureL() to verify the

signature and initialize the offset)

另外注意,我们需要提供一个NAME和RSS_SIGNATURE,否则程序将发生异常

(在程序内部,CONE 的AddResourceFileL() 函数使

用RResourceFile和RResourceFile::ConfirmSignatureL() 来验证签名,并初始化偏

移量)。

 

And this is the function that will scan the available localized resource files. For simplicity, the list dialog

shows the corresponding file names. You may want to provide some mapping to more user-friendly

names. Also, for clarity's sake, only basic error handling is done.

这是一个扫描可用本地化资源文件的函数。为了简化起见,列表对话框显示了

相应的文件名称。你可能需要提供一些使其更加用户友好型的名字的映射。另

外,为了清楚起见,仅作了基本的错误处理。

 
void CTestAppUi::ChooseLanguageL()
{
    HBufC* appName = Application()->AppFullName().AllocLC();
    TParsePtrC parse(*appName);
 
    // Construct search path
    _LIT(KExtra, "Extra.r??");
    TFileName file;
    file.Copy(parse.DriveAndPath());
    file.Append(KExtra);
 
    RFs& fs = iCoeEnv->FsSession();
    CDir* entries;
    fs.GetDir(file, KEntryAttNormal, ESortByName, entries);
  
   CleanupStack::PushL(entries);

    CDesCArray* list = new(ELeave) CDesCArrayFlat(5);
    CleanupStack::PushL(list);
 
    // Fill up listbox
    for (TInt i = 0; i < entries->Count(); ++i)
    {
        _LIT(KFormat, "/t%S");
        file.Format(KFormat, &(*entries)[i].iName);
        list->AppendL(file);
    }
 
    TInt index;
    CAknSelectionListDialog* dialog = CAknSelectionListDialog::NewL(index, list, 0);
    if (dialog->ExecuteLD(R_LIST_DIALOG))
    {
        file.Copy(parse.DriveAndPath());
        file.Append((*entries)[index].iName);
        // Replace resource file
        if (iOffset)
            iCoeEnv->DeleteResourceFile(iOffset);
 
        iOffset = iCoeEnv->AddResourceFileL(file);
 
        // Load cba, menu, etc as necessary
        iEikonEnv->AppUiFactory()->Cba()->SetCommandSetL(R_SOFTKEYS);
        iEikonEnv->AppUiFactory()->MenuBar()->SetMenuTitleResourceId(R_MENUBAR);
    }
 
    CleanupStack::PopAndDestroy(3, appName);    // list, entries, appName
}
 

 

Here are some screenshots of the example project:

Emulator Emulator Emulator

You may download the project here你可以在这里下载这个项目:
Source code  源码: DynLang.zip
Application  可执行应用程序: DynLang.SIS
Language pack  语言包: DynLang_Language_Pack.SIS

All emulator builds have been compiled & linked using Microsoft Visual C++ 6.0 compiler. In some cases, some small changes might be required to make it work with your toolchain. I'm not responsible for your use of the information contained in or linked from these web pages. 

 所有的基于模拟器的创建都已经通过Microsoft Visual C++ 6.0编译器编译和连接

。在有些情况下,为了能在你的程序中正常运行,你需要作一些小小的改动。

对于你使用这些网页包含的信息或者链接,我不负有任何责任。

      注:本文由wave于2007年12月13日翻译,对于翻译中存在的任何问题,希望能够不吝赐教。

我的E-mai:wave_1102@126.com

 

原文地址:http://www.pushl.com/developers/dynlang.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值