在SOUI中使用动态多语言切换
动态语言切换是很多国际化产品的需求,SOUI之前的版本支持静态多语言翻译,通过在程序启动时设置好语言翻译模块,在程序中打开的UI都会自动调用该翻译模块进行文字翻译,但是不支持运行进语言切换。
最近几个网友都提到这个需求,还是决定在SOUI实现一套动态多语言切换机制。
先看看运行效果:

多语言切换首先需要在语言翻译模块管理对象,SOUI中使用一个扩展接口ITranslatorMgr处理。
下面是新版本的语言翻译接口:
namespace SOUI
{
/**
* @struct ITranslator
* @brief 语言翻译接口
*
* Describe
*/
struct ITranslator : public IObjRef
{
/**
* Load
* @brief 从资源中加载语言翻译数据
* @param LPVOID pData -- 资源指针,具体含义由接口的实现来解释
* @param UINT uType -- 资源类型,具体含义由接口的实现来解释
* @return BOOL true-加载成功, false-加载失败
*
* Describe
*/
virtual BOOL Load(LPVOID pData,UINT uType)=;
/**
* name
* @brief 获取翻译资源的name
* @return SOUI::SStringW 翻译资源的name
*
* Describe
*/
virtual SStringW name()=;
/**
* guid
* @brief 获取翻译资源的ID
* @return GUID 翻译资源的ID
*
* Describe
*/
virtual GUID guid()=;
/**
* tr
* @brief 执行翻译的接口
* @param const SStringW & strSrc -- 原字符串
* @param const SStringW & strCtx -- 翻译上下文
* @param SStringW & strRet -- 翻译后的字符串
* @return BOOL true-翻译成功,false-翻译失败
*
* Describe
*/
virtual BOOL tr(const SStringW & strSrc,const SStringW & strCtx,SStringW & strRet)=;
}; /**
* @struct ITranslatorMgr
* @brief 语言翻译接口管理器
*
* Describe
*/
struct ITranslatorMgr : public IObjRef
{
/**
* SetLanguage
* @brief 设置翻译模块当前接受的语言
* @param [in] const SStringW & strLang -- 翻译语言
*
* Describe 自动清除语言和目标语言不同的模块
*/
virtual void SetLanguage(const SStringW & strLang) = ; /**
* GetLanguage
* @brief 获取翻译模块当前接受的语言
* @return SStringW -- 翻译语言
*
* Describe
*/
virtual SStringW GetLanguage() const = ; /**
* CreateTranslator
* @brief 创建一个语言翻译对象
* @param [out] ITranslator * * ppTranslator -- 接收语言翻译对象的指针
* @return BOOL true-成功,false-失败
*
* Describe
*/
virtual BOOL CreateTranslator(ITranslator ** ppTranslator)=;
/**
* InstallTranslator
* @brief 向管理器中安装一个语言翻译对象
* @param ITranslator * ppTranslator -- 语言翻译对象
* @return BOOL true-成功,false-失败
*
* Describe
*/ virtual BOOL InstallTranslator(ITranslator * ppTranslator) =;
/**
* UninstallTranslator
* @brief 从管理器中卸载一个语言翻译对象
* @param REFGUID id -- 语言翻译对象的ID
* @return BOOL true-成功,false-失败
*
* Describe
*/
virtual BOOL UninstallTranslator(REFGUID id) =; /**
* tr
* @brief 翻译字符串
* @param const SStringW & strSrc -- 原字符串
* @param const SStringW & strCtx -- 翻译上下文
* @return SOUI::SStringW 翻译后的字符串
*
* Describe 调用ITranslator的tr接口执行具体翻译过程
*/
virtual SStringW tr(const SStringW & strSrc,const SStringW & strCtx)=; }; }
用户切换UI语言后,使用SDispatchMessage方法向所有SWindow发送UM_SETLANGUAGE消息。
SWindow收到该消息后对窗口中需要做语言翻译的对象重新翻译语言后更新显示。 要在SOUI中使用多语言切换,首先需要在winmain里设置翻译模块: 1 int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int /*nCmdShow*/) 2 {
3 HRESULT hRes = OleInitialize(NULL);
4 SASSERT(SUCCEEDED(hRes));
5
6 int nRet = 0;
7
8 SComMgr *pComMgr = new SComMgr;
9
10 //将程序的运行路径修改到项目所在目录所在的目录
11 TCHAR szCurrentDir[MAX_PATH] = { 0 };
12 GetModuleFileName(NULL, szCurrentDir, sizeof(szCurrentDir));
13 LPTSTR lpInsertPos = _tcsrchr(szCurrentDir, _T('\\'));
14 _tcscpy(lpInsertPos + 1, _T("..\\SouiWizard1"));
15 SetCurrentDirectory(szCurrentDir);
16 {
17 BOOL bLoaded=FALSE;
18 CAutoRefPtr<SOUI::IImgDecoderFactory> pImgDecoderFactory;
19 CAutoRefPtr<SOUI::IRenderFactory> pRenderFactory;
20 CAutoRefPtr<ITranslatorMgr> trans; //多语言翻译模块,由translator.dll提供
21
22 bLoaded = pComMgr->CreateRender_GDI((IObjRef**)&pRenderFactory);
23 SASSERT_FMT(bLoaded,_T("load interface [render] failed!"));
24 bLoaded=pComMgr->CreateImgDecoder((IObjRef**)&pImgDecoderFactory);
25 SASSERT_FMT(bLoaded,_T("load interface [%s] failed!"),_T("imgdecoder"));
26 bLoaded = pComMgr->CreateTranslator((IObjRef**)&trans);
27 SASSERT_FMT(bLoaded, _T("load interface [%s] failed!"), _T("translator"));
28
29 pRenderFactory->SetImgDecoderFactory(pImgDecoderFactory);
30 SApplication *theApp = new SApplication(pRenderFactory, hInstance);
31 //从DLL加载系统资源
32 HMODULE hModSysResource = LoadLibrary(SYS_NAMED_RESOURCE);
33 if (hModSysResource)
34 {
35 CAutoRefPtr<IResProvider> sysResProvider;
36 CreateResProvider(RES_PE, (IObjRef**)&sysResProvider);
37 sysResProvider->Init((WPARAM)hModSysResource, 0);
38 theApp->LoadSystemNamedResource(sysResProvider);
39 FreeLibrary(hModSysResource);
40 }else
41 {
42 SASSERT(0);
43 }
44
45 CAutoRefPtr<IResProvider> pResProvider;
46 #if (RES_TYPE == 0)
47 CreateResProvider(RES_FILE, (IObjRef**)&pResProvider);
48 if (!pResProvider->Init((LPARAM)_T("uires"), 0))
49 {
50 SASSERT(0);
51 return 1;
52 }
53 #else
54 CreateResProvider(RES_PE, (IObjRef**)&pResProvider);
55 pResProvider->Init((WPARAM)hInstance, 0);
56 #endif
57
58 theApp->InitXmlNamedID(namedXmlID,ARRAYSIZE(namedXmlID),TRUE);
59 theApp->AddResProvider(pResProvider);
60
61 if (trans)
62 {//加载中文语言翻译包
63 theApp->SetTranslator(trans);
64 pugi::xml_document xmlLang;
65 if (theApp->LoadXmlDocment(xmlLang, _T("cn"), _T("lang")))
66 {
67 CAutoRefPtr<ITranslator> langCN;
68 trans->CreateTranslator(&langCN);
69 langCN->Load(&xmlLang.child(L"language"), 1);//1=LD_XML
70 trans->InstallTranslator(langCN);
71 }
72 }
73 // BLOCK: Run application
74 {
75 CMainDlg dlgMain;
76 dlgMain.Create(GetActiveWindow());
77 dlgMain.SendMessage(WM_INITDIALOG);
78 dlgMain.CenterWindow(dlgMain.m_hWnd);
79 dlgMain.ShowWindow(SW_SHOWNORMAL);
80 nRet = theApp->Run(dlgMain.m_hWnd);
81 }
82
83 delete theApp;
84 }
85
86 delete pComMgr;
87
88 OleUninitialize();
89 return nRet;
90 }
参见上面红色代码。
需要切换语言时,如下加载新的翻译模块即可:
void CMainDlg::OnLanguage(int nID)
{
ITranslatorMgr *pTransMgr = SApplication::getSingletonPtr()->GetTranslator();
bool bCnLang = nID == R.id.lang_cn; pugi::xml_document xmlLang;
if (SApplication::getSingletonPtr()->LoadXmlDocment(xmlLang, bCnLang?_T("cn"):_T("en"), _T("lang")))
{
CAutoRefPtr<ITranslator> lang;
pTransMgr->CreateTranslator(&lang);
lang->Load(&xmlLang.child(L"language"), 1);//1=LD_XML
pTransMgr->SetLanguage(lang->name());
pTransMgr->InstallTranslator(lang);
SDispatchMessage(UM_SETLANGUAGE,0,0); //soui2.6 新增加的方法。
} }
注: 该功能只在SOUI 2.6+版本支持。
在SOUI中使用动态多语言切换的更多相关文章
- vue-i18n vue-cli项目中实现国际化 多语言切换功能 一
vue-cli项目中引入vue-i18n 安装: npm install vue-i18n可参考vue-i18n官网文档 main.js中引入: import Vue from 'vue' impor ...
- Silverlight中本地化的实现(语言切换)
对于本地化这个功能我个人一直觉得在需求阶段就要确定该项目需不需要实行本地化,这样后面就可以减轻许多工作量,Sl中对本地化功能的支持与ASP.NET 中一样,主要使用CultureInfo类来完成的. ...
- vue-i18n 国际化语言切换
vue-i18n 用于前端vue项目中,需要多语言切换的场景 安装方法(npm) npm install vue-i18n 简单使用 1.在vue项目的main.ts文件中实例化 i18n imp ...
- 动态语言切换(续)-designer中的retranslateUi(带源码)
本站所有文章由本站和原作者保留一切权力,仅在保留本版权信息.原文链接.原文作者的情况下允许转载,转载请勿删改原文内容, 并不得用于商业用途. 谢谢合作.原文链接:动态语言切换(续)-designer中 ...
- 在使用Qt5.8完成程序动态语言切换时遇到的问题
因为之前了解过一些Qt国际化的东西,所以在写程序的时候需要显示给用户的字符都使用了 tr(" ")的形式,然后使用 Qt Linguist得到相应的 qm(Qt message)文 ...
- 关于在静态html中实现语言切换的思路与实现
在项目中只用到了三种语言:英文.中文简体.中文繁体.所以我首先想到了最笨的方法:1.直接将三种语言写在html中,显示当前设置的语言隐藏其它两种来实现.2.使用css伪元素的content:attr( ...
- (待续)C#语言中的动态数组(ArrayList)模拟常用页面置换算法(FIFO、LRU、Optimal)
目录 00 简介 01 算法概述 02 公用方法与变量解释 03 先进先出置换算法(FIFO) 04 最近最久未使用(LRU)算法 05 最佳置换算法(OPT) 00 简介 页面置换算法主要是记录内存 ...
- 第九篇:在SOUI中使用多语言翻译
为UI在不同地区显示不同的语言是产品国际化的一个重要要求. 在SOUI中实现了一套类似QT的多语言翻译机制:布局XML不需要调整,程序代码也不需要调整,只需要为不同地区的用户提供不同的语言翻译文件即可 ...
- 以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组
学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简 ...
随机推荐
- 老男孩Python全栈学习 S9 日常作业 011
1.编写装饰器,为函数加上统计时间的功能 import time def Decoration(func): def Timmer(): # 开始时间 Start = time.time() func ...
- js根据毫米/厘米算像素px
<html><meta http-equiv="content-type" content="text/html;charset=utf-8" ...
- maven仓库有jar包还是报错怎么办?
出现这种情况通常是jar不能自动下载 一.下载jar包外的其他文件,并放到仓库对应路径下: 点击View All,下载其他文件并放到仓库 二.这样仓库这个对应jar包的文件就齐全了.如果还是报错,请检 ...
- MySql分页查询慢|这里告诉你答案
一.背景 我们在开发的过程中使用分页是不可避免的,通常情况下我们的做法是使用limit加偏移量:select * from table where column=xxx order by xxx li ...
- DirectX11--教程项目无法编译、运行的解决方法
综述 对于Win10系统的大多数用户来说,可以直接编译本教程对应的项目并运行.但也有部分用户由于某些原因可能会出现无法编译的情况. DirectX11 With Windows SDK完整目录 欢迎加 ...
- vue md5
安装 cnpm install js-md5 --save 使用 import md5 from 'js-md5' md5('要加密的内容')
- python2编码问题
前言:python3解决了编码的问题,但python2还存在很多编码问题,用P2写爬虫爬了网页,解析时常有不同字符混着编码,导致解码问题成为爬虫程序员的噩梦... 但咱们要用robot framewo ...
- Python自动化中的元素定位xpath(二)
1.Xpath元素定位 1)ele = b.find_element_by_xpath(‘/html/body/from/input[1]’) 2)Ele = b.find_element_by_xp ...
- Python中字符串二三事
首先说两个运算符: " == " 运算符测试值的等价性,递归地比较所有内嵌对象 " is " 表达式测试对象的同一性,测试两者是否为同一对象(是否为同一地址) ...
- java学习笔记03-基本语法
编写java程序时,应注意以下点: 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的. 类名:对于所有的类来说,类名的首字母应该大写.如果类名由若干单词组成,那么每个 ...