다국어 언어 리소스가 필요한 곳에 __L 매크로를 이용하여 간단히 초기화 할 수 있다.
StringBundle.h
#pragma once
#include <atlstr.h>
class StringBundle
{
public:
StringBundle(void);
virtual ~StringBundle(void);
virtual CAtlString GetString( const CAtlString& id ) = 0;
};
// 다국어 리소스 xml 파일을 로드함
bool LoadStringBundle(LPCTSTR bundleFilePath);
// StringBundle 싱글톤
StringBundle* GetStringBundle();
#define __L(id) GetStringBundle()->GetString( id )
StringBundle.cpp
#include "stdafx.h"
#include "StringBundle.h"
#include <RxHelper.h>
#include <map>
StringBundle::StringBundle(void)
{
}
StringBundle::~StringBundle(void)
{
}
class StringBundleImpl : public StringBundle
{
public:
virtual CAtlString GetString( const CAtlString& id )
{
std::map<CAtlString, CAtlString>::iterator it = m_map.find(id);
if( it != m_map.end())
{
#ifdef _DEBUG
// for local debugging
return __T("`") + it->second;
#else
return it->second;
#endif
}
return id;
}
bool Load(LPCTSTR path)
{
CRxDoc doc;
bool isOk = toBool(doc.LoadFile(path));
DCHECK(isOk) << "xml loading failed: " << path;
if( isOk )
{
m_map.clear();
CRxEle root = doc.Root();
CRxEle item = root.Child(_T("string"));
while( item )
{
CAtlString id = item.Attribute(_T("id"));
CAtlString value = item.Text();
// \n 처리
value.Replace(_T("\\n"), L"\n");
DCHECK(id.GetLength());
if( id.GetLength())
{
m_map[ id ] = value;
}
item = item.Next( _T("string"));
}
}
return isOk;
}
private:
std::map<CAtlString, CAtlString> m_map;
};
StringBundleImpl g_StringBundle;
bool LoadStringBundle( LPCTSTR bundleFilePath )
{
return g_StringBundle.Load(bundleFilePath);
}
StringBundle* GetStringBundle()
{
return &g_StringBundle;
}