在SOUI中使用動態多語言切換

動態語言切換是不少國際化產品的需求,SOUI以前的版本支持靜態多語言翻譯,經過在程序啓動時設置好語言翻譯模塊,在程序中打開的UI都會自動調用該翻譯模塊進行文字翻譯,可是不支持運行進語言切換。app

最近幾個網友都提到這個需求,仍是決定在SOUI實現一套動態多語言切換機制。ide

先看看運行效果:ui

多語言切換首先須要在語言翻譯模塊管理對象,SOUI中使用一個擴展接口ITranslatorMgr處理。spa

下面是新版本的語言翻譯接口:翻譯

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)=0;
        /**
         * name
         * @brief    獲取翻譯資源的name
         * @return   SOUI::SStringW 翻譯資源的name
         *
         * Describe  
         */
        virtual SStringW name()=0;
        /**
         * guid
         * @brief    獲取翻譯資源的ID
         * @return   GUID 翻譯資源的ID
         *
         * Describe  
         */
        virtual GUID     guid()=0;
        /**
         * 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)=0;
    };


/** 
     * @struct     ITranslatorMgr
     * @brief      語言翻譯接口管理器
     *
     * Describe
     */
    struct ITranslatorMgr : public IObjRef
    {
        /**
        * SetLanguage
        * @brief    設置翻譯模塊當前接受的語言
        * @param [in] const SStringW & strLang --  翻譯語言
        *
        * Describe 自動清除語言和目標語言不一樣的模塊
        */
        virtual void SetLanguage(const SStringW & strLang) = 0;

        /**
        * GetLanguage
        * @brief    獲取翻譯模塊當前接受的語言
        * @return SStringW  --  翻譯語言
        *
        * Describe 
        */
        virtual SStringW GetLanguage() const = 0;

        /**
         * CreateTranslator
         * @brief    建立一個語言翻譯對象
         * @param [out] ITranslator * * ppTranslator --  接收語言翻譯對象的指針
         * @return   BOOL true-成功,false-失敗
         *
         * Describe  
         */
        virtual BOOL CreateTranslator(ITranslator ** ppTranslator)=0;
        /**
         * InstallTranslator
         * @brief    向管理器中安裝一個語言翻譯對象
         * @param    ITranslator * ppTranslator -- 語言翻譯對象
         * @return   BOOL true-成功,false-失敗
         *
         * Describe  
         */

        virtual BOOL InstallTranslator(ITranslator * ppTranslator) =0;
        /**
         * UninstallTranslator
         * @brief    從管理器中卸載一個語言翻譯對象
         * @param    REFGUID id --  語言翻譯對象的ID
         * @return   BOOL true-成功,false-失敗
         *
         * Describe  
         */
        virtual BOOL UninstallTranslator(REFGUID id) =0;
        
        /**
         * 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)=0;


    };

}


用戶切換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 }
 

參見上面紅色代碼。3d

須要切換語言時,以下加載新的翻譯模塊便可:指針

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+版本支持。code

相關文章
相關標籤/搜索