c++builder的多国语言实现

本文介绍了一个用于应用程序国际化的类`TEcLanguage`的设计与实现。该类通过读取配置文件加载不同语言的资源字符串,并能够为应用程序的不同界面设置相应的语言包。此外,还提供了保存当前界面字符串到指定语言文件的功能。

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

Language.h


#ifndef EcLanguageH
#define EcLanguageH
//---------------------------------------------------------------------------

#include <Forms.hpp>
#include <IniFiles.hpp>

#include <tchar.h>

// Language Class
class TEcLanguage
{
private:
	String m_sLangPath;             // Language file name
	String m_sCurFile;
	TStringList* m_pLangs;
	TStringList* m_pExts;
	String m_sLang;
	int m_nCurID;

	bool HasProperty(TComponent* aObject,String PropStr);
	int GetOperSystemLanID();

protected:
	// Load string for control
	virtual bool LoadLangFile(TForm* pFrm);
	// Save control caption to language file
	virtual void SetLangFile(TForm* pFrm);

public:
	TEcLanguage(String sConfigPath);
	~TEcLanguage();

	bool SetLangID(int nID);
	int GetCurID(){return m_nCurID;};
	TStringList* GetLangs(){return m_pLangs;};
	String GetLanFile(){return m_sCurFile;};

	// Load UI Language for one form
	bool LoadLanguage(TForm* pFrm){return LoadLangFile(pFrm);}
	// Save UI string and control size to specific file
	void SetLanguage(TForm* pFrm){SetLangFile(pFrm);};

	// Load resource string for others except control
	String GetStr(int nNo, String sSection=_T("ResourceString"), String sKey=_T("Str"));
};


Language.cpp

#include <vcl.h>

#pragma hdrstop
#include "EcLanguage.h"

#pragma package(smart_init)

TEcLanguage::TEcLanguage(String sConfigPath)
{
	// Languageファイルの場所を取って
	m_sLangPath = sConfigPath+_T("\\Language\\");

	String sLang = m_sLangPath + _T("Lang.ini");

	m_pExts = new TStringList;
	m_pExts->Clear();

	m_pLangs = new TStringList;
	m_pLangs->Clear();

	TIniFile* iniFile = new TIniFile(sLang);
	m_sLang = iniFile->ReadString("General", "AppName", "Daq3");
	m_nCurID = iniFile->ReadInteger("General", "CurID", GetOperSystemLanID());
	int nLangs = iniFile->ReadInteger("General", "Number", 4);
	String sTmp,sTmp1,sTmp2;
	for(int i=0;i<nLangs;++i){
		sTmp.sprintf(_T("%03d_Ext"),i);
		sTmp1 = iniFile->ReadString("Lang", sTmp, "");
		if(sTmp1=="") continue;
		sTmp.sprintf(_T("%s%s.%s"),m_sLangPath.c_str(),m_sLang.c_str(),sTmp1.c_str());
		if(!FileExists(sTmp)) continue;

		sTmp.sprintf(_T("%03d_Name"),i);
		sTmp2 = iniFile->ReadString("Lang", sTmp, "");
		if(sTmp2=="") continue;

		m_pExts->Add(sTmp1);
		m_pLangs->Add(sTmp2);
	}
	delete iniFile;

	int nCnt = m_pLangs->Count;
	if(m_nCurID<0 || m_nCurID>=nCnt)
		m_nCurID = 0;
	if(nCnt==0){
		m_nCurID = -1;
	}else{
		m_sCurFile.sprintf(_T("%s%s.%s"),m_sLangPath.c_str(),m_sLang.c_str(),m_pExts->Strings[m_nCurID].c_str());
	}
}


TEcLanguage::~TEcLanguage()
{
	String sLang = m_sLangPath + "Lang.ini";
	TIniFile* iniFile = new TIniFile(sLang);
	iniFile->WriteInteger("General", "CurID", m_nCurID);
	delete iniFile;

	delete m_pLangs;
	delete m_pExts;
}

// ==========================================================================
// Check specific property in the Object
// return : ture -  have the property
//          false - have not the property
// ==========================================================================
bool TEcLanguage::HasProperty(TComponent* aObject,String PropStr)
{
	return (GetPropInfo(aObject, PropStr) != NULL);

}

// ==========================================================================
// Name			: LoadLangFile
// Summary		: Load Language string for one form
// Call			: LoadLangFile(this);
// Parameter	: pFrm : Form object opinter
// Return		: true / false
// --------------------------------------------------------------------------
// [modify history]:
// ==========================================================================
bool TEcLanguage::LoadLangFile(TForm* pFrm)
{
	if(-1==m_nCurID) return false;
	TIniFile*   iniFile;
	iniFile = new TIniFile(m_sCurFile);
	if(!iniFile) return false;
	String sComponName = _T("None");

	try{
		String sTmp;
		String sFrmName = pFrm->Name;
		if(sFrmName==_T("")){
			return false;
		}

		pFrm->Font->Name    = TFontName(iniFile->ReadString(_T("General"), _T("FontName"), _T("Arial")));
		pFrm->Font->Charset = TFontCharset(iniFile->ReadInteger(_T("General"), _T("Charset"), 1));
		pFrm->Font->Size    = iniFile->ReadInteger(_T("General"), _T("FontSize"), 9);

		sTmp = iniFile->ReadString(sFrmName,sFrmName,_T(""));
		if ((sTmp!=_T("")) && (pFrm->BorderStyle!=bsNone))
			pFrm->Caption = sTmp;

		TControl*   pControl;
		TFont*      pFont;
		int nCount = pFrm->ComponentCount;
		for(int ix =0 ;ix<nCount;ix++){

			if (HasProperty(pFrm->Components[ix],_T("Caption"))){
				sComponName=_T("");
				sComponName = pFrm->Components[ix]->Name;
				if(sComponName==_T("")) continue;
				sTmp = iniFile->ReadString(sFrmName,sComponName,"");
				if(sTmp!="")
					SetStrProp(pFrm->Components[ix],_T("Caption"), sTmp);

				if (!HasProperty(pFrm->Components[ix],_T("ParentFont"))) continue;
				pControl =dynamic_cast<TControl*>(pFrm->Components[ix]);
				if(((TForm*)pControl)->ParentFont) continue;

				pFont =  dynamic_cast<TFont*>(GetObjectProp(pControl,_T("Font")));
				pFont->Charset = pFrm->Font->Charset;
				pFont->Name = pFrm->Font->Name;
				SetObjectProp(pFrm->Components[ix],_T("Font"),pFont);
			}

			//if (HasProperty(pFrm->Components[ix],"ParentFont"))
			//{
			//    pControl =dynamic_cast<TControl*>(pFrm->Components[ix]);
			//    if(((TForm*)pControl)->ParentFont) continue;
			//
			//    pFont =  dynamic_cast<TFont*>(GetObjectProp(pControl,"Font"));
			//    pFont->Charset = pFrm->Font->Charset;
			//    pFont->Name = pFrm->Font->Name;
			//    SetObjectProp(pFrm->Components[ix],"Font",pFont);
			//
			//}
		}
		pFrm->Update();
	}catch (Exception &exception){

		Application->ShowException(&exception);

	}catch (...){
		try{

			throw Exception("");

		}catch (Exception &exception){

			Application->ShowException(&exception);
		}
	}
	delete iniFile;

	return true;
}


// ==========================================================================
// Name			: SetLangFile
// Summary		: Save controls stirng of form to Language file
// Call			: SetLangFile(this);
// Parameter	: pFrm : Form object opinter
// Return		: void
// --------------------------------------------------------------------------
// [modify history]:
// ==========================================================================
void TEcLanguage::SetLangFile(TForm* pFrm)
{
	if(-1==m_nCurID) return;
	String sCaption;
	TIniFile* iniFile = new TIniFile(m_sCurFile);
	try{

		iniFile->WriteString(pFrm->Name,pFrm->Name,pFrm->Caption);
		iniFile->WriteInteger("General", "Charset", pFrm->Font->Charset);
		iniFile->WriteString("General", "FontName", pFrm->Font->Name);
		iniFile->WriteInteger("General", "FontSize", pFrm->Font->Size);

		for(int ix =0 ;ix< pFrm->ComponentCount;ix++){

			if (HasProperty(pFrm->Components[ix],_T("Caption")) ){

				sCaption = GetStrProp(pFrm->Components[ix],_T("Caption"));
				if(sCaption!=""){
					iniFile->WriteString(pFrm->Name,pFrm->Components[ix]->Name,sCaption);
				}
			}
		}
	}catch (Exception &exception){

		Application->ShowException(&exception);

	}catch (...){
		try{

			throw Exception("");

		}catch (Exception &exception){

			Application->ShowException(&exception);
		}
	}
	delete iniFile;
}

// ==========================================================================
// Name			: GetResourceString
// Summary		: Get one resource string to language file
// Call			: GetResourceString(Str1,"Form1")
// Parameter	: TmpStr      : resoruce string
//                SectionStr  : Section string of ini file
// Return		: string which read form the language file
// --------------------------------------------------------------------------
// [modify history]:
// ==========================================================================
String TEcLanguage::GetStr(int nNo, String sSection, String sKey)
{

	if(-1==m_nCurID) return "***";
	String sText;
	TIniFile* iniFile = new TIniFile(m_sCurFile);
	sKey.sprintf(_T("%s%03d"),sKey.c_str(),nNo);
	sText = iniFile->ReadString(sSection,sKey,"");
	delete iniFile;

	return sText;
}

// ==========================================================================
// Name			: GetOperSystemLanID
// Summary		: get system language ID;
// Call			: GetOperSystemLanID();
// Parameter	: None;
// Return		: int
// --------------------------------------------------------------------------
// [modify history]:
// ==========================================================================
int TEcLanguage::GetOperSystemLanID()
{

	LCID lanid = GetSystemDefaultLCID(); //API fun
	int nlanid = lanid;
    int nLanType = 0;

    char szLan[10];
    itoa(nlanid,szLan,16);

    //english
    if (strcmp(szLan,"409")==0) nLanType=0;
    //simple chinese language
    if (strcmp(szLan,"804")==0) nLanType=1;
    //japan language
    if (strcmp(szLan,"411")==0) nLanType=2;
    //complicated chinese language
    if (strcmp(szLan,"404")==0) nLanType=3;
    //Spanish (Traditional Sort) language
    if (strcmp(szLan,"40a")==0) nLanType=4;
    //Spanish (Mexican) language
    if (strcmp(szLan,"80a")==0) nLanType=4;

    return nLanType;
}

bool TEcLanguage::SetLangID(int nID)
{
	if(m_nCurID==nID) return false;
	m_nCurID = nID;
	m_sCurFile.sprintf(_T("%s%s.%s"),m_sLangPath.c_str(),m_sLang.c_str(),m_pExts->Strings[m_nCurID].c_str());

	return true;

}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值