/*! \file 

Copyright (C) Siemens AG 1994-2003  ALL RIGHTS RESERVED

  This software is protected by the inclusion of the above copyright
  notice. This software may not be provided or otherwise made available
  to, or used by, any other person. No title to or ownership of the
  software is  hereby  transferred.
  The information contained in this document is considered the
  CONFIDENTIAL and PROPRIETARY information of Siemens AG and may
  not be disclosed or discussed with anyone who is not employed by
  Siemens AG, unless the individual / company
  (i) has an express need to know such information, and
  (ii) disclosure of information is subject to the terms of a duly
  executed Confidentiality and Non-Disclosure Agreement between
  Siemens AG and the individual / company.

.AUTHOR zhang qi fan(ICM.MP.VC(beijing))

.FILENAME LocalizationCtrl.cpp

.VERSION 01.00.00

.DATE 2003-10-22

.SHORT_DESCR:   Localization Class and APIs

.SW_COMPONENT:  SMTK EMULATOR

.SW_TYPE 

.CHANGE_CONTROL 
Version  Date        Changed by
         Reason of change

01.00.00 2003-10-22 zhang qi fan(ICM.MP.VC(beijing))          
01.00.01 2004-02-19 zhang qi fan(ICM.MP.VC(beijing))          
         Localization interface upgrade
01.00.02 2004-06-09 Fang Yunchao(PEK))          
         Add UNICODE support
01.00.03 2004-06-24 Fang Yunchao(PEK))          
         Modification for SMTK Localization support
01.00.04 2004-06-25 Fang Yunchao(PEK))          
         Modification for SMTK Localization support
01.00.05 2004-06-28 Fang Yunchao(PEK))          
         Move language DLL to C_mobsim bin directory
01.00.06 2004-07-15 Fang Yunchao(PEK))          
         modify to enum languages dll and write related
	 information to registry 
01.00.07 2004-08-11 Fang Yunchao(PEK))          
         remove a bug of release version and modified the languages' dll position 

*/
#ifdef LOCALIZATION_SUPPORT


#include "localizationctrl.h"
#include "sms_res.h"
#include "ChangeUILanguageDlg.h"
#include <io.h>
#include "info_main.h"
#ifdef UNICODE
#include "atlconv.h"
#endif
extern "C" void ReadSimulatorRegistryString ( char* Name, char* Value, int &result);
int ReadRegistry(HKEY hKey, char* SubKey, char* Name, int &result);
int WriteRegistry(HKEY hKey, char* SubKey, char* Name, int Value);

//static CLocalizationMap CLocalizationCtrl::map;

//IMPLEMENT_LANGMAP
	DELCEAR_LANGMAP
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_SAUDI_ARABIA,"ARSA",IDS_LANGDES_ARABIC)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_IRAQ,"ARIQ",IDS_LANGDES_ARABIC_IRAQ)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_EGYPT,"AREG",IDS_LANGDES_ARABIC_EGYPT)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_LIBYA,"ARLY",IDS_LANGDES_ARABIC_LIBYA)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_ALGERIA,"ARDZ",IDS_LANGDES_ARABIC_ALGERIA)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_MOROCCO,"ARMA",IDS_LANGDES_ARABIC_MOROCCO)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_TUNISIA,"ARTN",IDS_LANGDES_ARABIC_TUNISIA)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_OMAN,"AROM",IDS_LANGDES_ARABIC_OMAN)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_SYRIA,"ARSY",IDS_LANGDES_ARABIC_SYRIA)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_JORDAN,"ARJO",IDS_LANGDES_ARABIC_JORDAN)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_LEBANON,"ARLB",IDS_LANGDES_ARABIC_LEBANON)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_KUWAIT,"ARKW",IDS_LANGDES_ARABIC_KUWAIT)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_UAE,"ARAE",IDS_LANGDES_ARABIC_UAE)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_BAHRAIN,"ARBH",IDS_LANGDES_ARABIC_BAHRAIN)
		ADDITEM(LANG_ARABIC,SUBLANG_ARABIC_QATAR,"ARQA",IDS_LANGDES_ARABIC_QATAR)
		ADDITEM(LANG_ARMENIAN,0,"HY",IDS_LANGDES_AMENIAN)
		ADDITEM(LANG_ASSAMESE,0,"AS",IDS_LANGDES_ASSAMESE)
		ADDITEM(LANG_AZERI,SUBLANG_AZERI_LATIN,"AZLA",IDS_LANGDES_AZERI_LATIN)
		ADDITEM(LANG_AZERI,SUBLANG_AZERI_CYRILLIC,"AZCY",IDS_LANGDES_AZERI_CYRILLIC)
		ADDITEM(LANG_BASQUE,0,"EU",IDS_LANGDES_BASQUE)
		ADDITEM(LANG_BELARUSIAN,0,"BE",IDS_LANGDES_BELARUSIAN)
		ADDITEM(LANG_BENGALI,0,"BN",IDS_LANGDES_BENGALI)
		ADDITEM(LANG_BULGARIAN,0,"BG",IDS_LANGDES_BULGARAIN)
		ADDITEM(LANG_CATALAN,0,"CA",IDS_LANGDES_CATALAN)
		ADDITEM(LANG_CHINESE,SUBLANG_CHINESE_TRADITIONAL,"ZHTW",IDS_LANGDES_CHINESE_TRADITIONAL)
		ADDITEM(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED,"ZHCN",IDS_LANGDES_CHINESE_SIMPLIFIED)
		ADDITEM(LANG_CHINESE,SUBLANG_CHINESE_HONGKONG,"ZHHK",IDS_LANGDES_CHINESE_HONGKONG)
		ADDITEM(LANG_CHINESE,SUBLANG_CHINESE_SINGAPORE,"ZHSG",IDS_LANGDES_CHINESE_SINGAPORE)
		ADDITEM(LANG_CHINESE,SUBLANG_CHINESE_MACAU,"ZHMO",IDS_LANGDES_CHINESE_MACAU)
		ADDITEM(LANG_CROATIAN,0,"HR",IDS_LANGDES_CROATIAN)
		ADDITEM(LANG_CZECH,0,"CS",IDS_LANGDES_CZECH)
		ADDITEM(LANG_DANISH,0,"DA",IDS_LANGDES_DANISH)
		ADDITEM(LANG_DUTCH,SUBLANG_DUTCH,"NLNL",IDS_LANGDES_DUTCH)
		ADDITEM(LANG_DUTCH,SUBLANG_DUTCH_BELGIAN,"NLBE",IDS_LANGDES_DUTCH_BELGIAN)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_US,"ENUS",IDS_LANGDES_ENGLISH_US)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_UK,"ENGB",IDS_LANGDES_ENGLISH_UK)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_AUS,"ENAU",IDS_LANGDES_ENGLISH_AUS)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_CAN,"ENCA",IDS_LANGDES_ENGLISH_CAN)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_NZ,"ENNZ",IDS_LANGDES_ENGLISH_NZ)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_EIRE,"ENIE",IDS_LANGDES_ENGLISH_EIRE)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_SOUTH_AFRICA,"ENZA",IDS_LANGDES_ENGLISH_SOUTH_AFRICA)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_JAMAICA,"ENJM",IDS_LANGDES_ENGLISH_JAMAICA)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_CARIBBEAN,"ENCR",IDS_LANGDES_ENGLISH_CARIBBEAN)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_BELIZE,"ENBZ",IDS_LANGDES_ENGLISH_BELIZE)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_TRINIDAD,"ENTT",IDS_LANGDES_ENGLISH_TRINIDAD)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_ZIMBABWE,"ENZM",IDS_LANGDES_ENGLISH_ZIMBABWE)
		ADDITEM(LANG_ENGLISH,SUBLANG_ENGLISH_PHILIPPINES,"ENPH",IDS_LANGDES_ENGLISH_PHIPLPPINES)
		ADDITEM(LANG_ESTONIAN,0,"ET",IDS_LANGDES_ESTONIAN)
		ADDITEM(LANG_FAEROESE,0,"FO",IDS_LANGDES_FAEROESE)
		ADDITEM(LANG_FARSI,0,"FY",IDS_LANGDES_FARSI)
		ADDITEM(LANG_FINNISH,0,"FI",IDS_LANGDES_FINNISH)
		ADDITEM(LANG_FRENCH,SUBLANG_FRENCH,"FRFR",IDS_LANGDES_FRENCH)
		ADDITEM(LANG_FRENCH,SUBLANG_FRENCH_CANADIAN,"FRCA",IDS_LANGDES_FRENCH_CANADIAN)
		ADDITEM(LANG_FRENCH,SUBLANG_FRENCH_SWISS,"FRCH",IDS_LANGDES_FRENCH_SWISS)
		ADDITEM(LANG_FRENCH,SUBLANG_FRENCH_LUXEMBOURG,"FRLU",IDS_LANGDES_FRENCH_LUXEMBOURG)
		ADDITEM(LANG_FRENCH,SUBLANG_FRENCH_MONACO,"FRMC",IDS_LANGDES_FRENCH_MONACO)
		ADDITEM(LANG_GEORGIAN,0,"KA",IDS_LANGDES_GEORGIAN)
		ADDITEM(LANG_GERMAN,SUBLANG_GERMAN,"DEDE",IDS_LANGDES_GERMAN)
		ADDITEM(LANG_GERMAN,SUBLANG_GERMAN_SWISS,"DECH",IDS_LANGDES_GERMAN_SWISS)
		ADDITEM(LANG_GERMAN,SUBLANG_GERMAN_AUSTRIAN,"DEAT",IDS_LANGDES_GERMAN_AUSTRIAN)
		ADDITEM(LANG_GERMAN,SUBLANG_GERMAN_LUXEMBOURG,"DELU",IDS_LANGDES_GERMAN_LUXEMBOURG)
		ADDITEM(LANG_GERMAN,SUBLANG_GERMAN_LIECHTENSTEIN,"DELI",IDS_LANGDES_GERMAN_LIECHTENSTEIN)
		ADDITEM(LANG_GREEK,0,"EL",IDS_LANGDES_GREEK)
		ADDITEM(LANG_GUJARATI,0,"GU",IDS_LANGDES_GUJARATI)
		ADDITEM(LANG_HEBREW,0,"HE",IDS_LANGDES_HEBREW)
		ADDITEM(LANG_HINDI,0,"HI",IDS_LANGDES_HINDI)
		ADDITEM(LANG_HUNGARIAN,0,"HU",IDS_LANGDES_HUNGAUIAN)
		ADDITEM(LANG_ICELANDIC,0,"IS",IDS_LANGDES_ICELANDIC)
		ADDITEM(LANG_INDONESIAN,0,"ID",IDS_LANGDES_INDONESIAN)
		ADDITEM(LANG_ITALIAN,SUBLANG_ITALIAN,"ITIT",IDS_LANGDES_ITALIAN)
		ADDITEM(LANG_ITALIAN,SUBLANG_ITALIAN_SWISS,"ITCH",IDS_LANGDES_ITALIAN_SWISS)
		ADDITEM(LANG_JAPANESE,0,"JA",IDS_LANGDES_JAPANESE)
		ADDITEM(LANG_KANNADA,0,"KN",IDS_LANGDES_KANNADA)
		ADDITEM(LANG_KASHMIRI,SUBLANG_KASHMIRI_INDIA,"KSIN",IDS_LANGDES_KASHMIRI)
		ADDITEM(LANG_KAZAK,0,"KK",IDS_LANGDES_KAZAK)
		ADDITEM(LANG_KONKANI,0,"KN",IDS_LANGDES_KONKANI)
		ADDITEM(LANG_KOREAN,0,"KO",IDS_LANGDES_KOREAN)
		ADDITEM(LANG_LATVIAN,0,"LV",IDS_LANGDES_LATVIAN)
		ADDITEM(LANG_LITHUANIAN,SUBLANG_LITHUANIAN,"LTLT",IDS_LANGDES_LITHUANIAN)
//		ADDITEM(LANG_LITHUANIAN,SUBLANG_LITHUANIAN_CLASSIC,"LTCL",0)
		ADDITEM(LANG_MACEDONIAN,0,"MK",IDS_LANGDES_MACEDONIAN)
		ADDITEM(LANG_MALAY,SUBLANG_MALAY_MALAYSIA,"MSMY",IDS_LANGDES_MALAY_MALAYSIA)
		ADDITEM(LANG_MALAY,SUBLANG_MALAY_BRUNEI_DARUSSALAM,"MSBN",IDS_LANGDES_MALAY_BRUNEI_DARUSSALAM)
		ADDITEM(LANG_MALAYALAM,0,"ML",IDS_LANGDES_MALAYALAM)
		ADDITEM(LANG_MANIPURI,0,"MA",IDS_LANGDES_MANIPURI)
		ADDITEM(LANG_MARATHI,0,"MR",IDS_LANGDES_MARATHI)
		ADDITEM(LANG_NEPALI,SUBLANG_NEPALI_INDIA,"NEIN",IDS_LANGDES_NAPALI_INDIA)
		ADDITEM(LANG_NORWEGIAN,SUBLANG_NORWEGIAN_BOKMAL,"NOBO",IDS_LANGDES_NORWEGIAN_BOKMAL)
		ADDITEM(LANG_NORWEGIAN,SUBLANG_NORWEGIAN_NYNORSK,"NONY",IDS_LANGDES_NORWEGIAN_NUNORSK)
		ADDITEM(LANG_ORIYA,0,"OR",IDS_LANGDES_ORIYA)
		ADDITEM(LANG_POLISH,0,"PL",IDS_LANGDES_POLISH)
		ADDITEM(LANG_PORTUGUESE,SUBLANG_PORTUGUESE,"PTPT",IDS_LANGDES_PROTUGUESE)
		ADDITEM(LANG_PORTUGUESE,SUBLANG_PORTUGUESE_BRAZILIAN,"PTBR",IDS_LANGDES_PROTUGUESE_BRAZILIAN)
		ADDITEM(LANG_PUNJABI,0,"PA",IDS_LANGDES_PUNJABI)
		ADDITEM(LANG_ROMANIAN,0,"RO",IDS_LANGDES_ROMANIAN)
		ADDITEM(LANG_RUSSIAN,0,"RU",IDS_LANGDES_RUSSIAN)
		ADDITEM(LANG_SANSKRIT,0,"SA",IDS_LANGDES_SANSKRIT)
		ADDITEM(LANG_SERBIAN,SUBLANG_SERBIAN_LATIN,"SRLA",IDS_LANGDES_SERBIAN_LATIN)
		ADDITEM(LANG_SERBIAN,SUBLANG_SERBIAN_CYRILLIC,"SRCY",IDS_LANGDES_SERBIAN_CYRILLIC)
		ADDITEM(LANG_SINDHI,0,"SD",IDS_LANGDES_SINDHI)
		ADDITEM(LANG_SLOVAK,0,"SK",IDS_LANGDES_SLOVAK)
		ADDITEM(LANG_SLOVENIAN,0,"SL",IDS_LANGDES_SLOVENIAN)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH,"ESES",IDS_LANGDES_SPANISH)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_MEXICAN,"ESMX",IDS_LANGDES_SPANISH_MEXICAN)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_MODERN,"ESMO",IDS_LANGDES_SPANISH_MODERN)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_GUATEMALA,"ESGT",IDS_LANGDES_SPANISH_GUATEMALA)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_COSTA_RICA,"ESCR",IDS_LANGDES_SPANISH_RICA)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_PANAMA,"ESPA",IDS_LANGDES_SPANISH_PANAMA)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_DOMINICAN_REPUBLIC,"ESDO",IDS_LANGDES_SPANISH_DOMINCAN_REPUBLIC)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_VENEZUELA,"ESVE",IDS_LANGDES_SPANISH_VENEZUELA)	
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_COLOMBIA,"ESCO",IDS_LANGDES_SPANISH_COLOMBIA)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_PERU,"ESPE",IDS_LANGDES_SPANISH_PERU)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_ARGENTINA,"ESAR",IDS_LANGDES_SPANISH_ARGENTINA)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_ECUADOR,"ESEC",IDS_LANGDES_SPANISH_ECUADOR)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_CHILE,"ESCL",IDS_LANGDES_SPANISH_CHILE)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_URUGUAY,"ESUY",IDS_LANGDES_SPANISH_URUGUAY)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_PARAGUAY,"ESPY",IDS_LANGDES_SPANISH_PARAGUAY)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_BOLIVIA,"ESBO",IDS_LANGDES_SPANISH_BOLIVIA)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_EL_SALVADOR,"ESSV",IDS_LANGDES_SPANISH_SALVADOR)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_HONDURAS,"ESHN",IDS_LANGDES_SPANISH_HONDURAS)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_NICARAGUA,"ESNI",IDS_LANGDES_SPANISH_NICARAGUA)
		ADDITEM(LANG_SPANISH,SUBLANG_SPANISH_PUERTO_RICO,"ESPR",IDS_LANGDES_SPANISH_PUERTO_RICO)
		ADDITEM(LANG_SWAHILI,0,"SW",IDS_LANGDES_SWAHILI)
		ADDITEM(LANG_SWEDISH,SUBLANG_SWEDISH,"SVSV",IDS_LANGDES_SWEDISH)
		ADDITEM(LANG_SWEDISH,SUBLANG_SWEDISH_FINLAND,"SVFI",IDS_LANGDES_SWEDISH_FINLAND)
		ADDITEM(LANG_TAMIL,0,"TA",IDS_LANGDES_TAMIL)
		ADDITEM(LANG_TATAR,0,"TT",IDS_LANGDES_TATAR)
		ADDITEM(LANG_TELUGU,0,"TE",IDS_LANGDES_TELUGU)
		ADDITEM(LANG_THAI,0,"TH",IDS_LANGDES_THAI)
		ADDITEM(LANG_TURKISH,0,"TR",IDS_LANGDES_TURKISH)
		ADDITEM(LANG_UKRAINIAN,0,"UK",IDS_LANGDES_UKRAINIAN)
		ADDITEM(LANG_URDU,SUBLANG_URDU_PAKISTAN,"URPK",IDS_LANGDES_URDU_PAKISTAN)
		ADDITEM(LANG_URDU,SUBLANG_URDU_INDIA,"URIN",IDS_LANGDES_URDU_INDIA)
		ADDITEM(LANG_UZBEK,SUBLANG_UZBEK_LATIN,"UZLA",IDS_LANGDES_UZBEK_LATIN)
		ADDITEM(LANG_UZBEK,SUBLANG_UZBEK_CYRILLIC,"UZCY",IDS_LANGDES_UZBEK_CYRILLIC)
		ADDITEM(LANG_VIETNAMESE,0,"VI",IDS_LANGDES_VIETNANESE)
	ENDDECLEAR_LANGMAP


///copy from winpdisp.cpp
static HKEY         mg_hKey             = HKEY_CURRENT_USER;      // makes registry settings dependent on user

LocalizationMap CLocalizationCtrl::m_LangMap;
CLocalizationCtrl * CLocalizationCtrlInterface::m_pCtrlLoader = NULL;

static CLocalizationCtrlInterface LocCtrlInterface(COMMON_LANGMAP_DIRKEY,EXT_LANGMAP_DIRKEY,MAINLASTDEFAULTKEYDIR,LAST_DEFALUT_REG_STRING,EXTENSION_LANG_AVAILABLE,SMTK_DIRKEY);

static void ReadRegistryString_L( HKEY hKey, LPCTSTR SubKey, LPCTSTR Name, _TCHAR * Value, int &result)
{
#ifndef _UNICODE
	ReadRegistryString(hKey,(char *)SubKey,(char *)Name,Value,result);
#else
USES_CONVERSION;
	char ValueTemp[128];	
	ReadRegistryString(hKey,W2A((LPCWSTR)SubKey),W2A((LPCWSTR)Name),ValueTemp,result);	
	wcscpy(Value,A2W(ValueTemp));
#endif
}

static int WriteRegistryString_L( HKEY hKey, LPCTSTR SubKey, LPCTSTR Name, LPCTSTR Value)
{
#ifndef _UNICODE
	return WriteRegistryString(hKey,(char *)SubKey,(char *)Name,(char *)Value);
#else
USES_CONVERSION;
	return WriteRegistryString(hKey,W2A((LPCWSTR)SubKey),W2A((LPCWSTR)Name),W2A((LPCWSTR)Value));
#endif
}

static int ReadRegistry_L(HKEY hKey, LPCTSTR SubKey, LPCTSTR Name, int &result)
{
#ifndef _UNICODE
	return ReadRegistry(hKey,(char *)SubKey,(char *)Name,result);
#else
USES_CONVERSION;
	return ReadRegistry(hKey,W2A((LPCWSTR)SubKey),W2A((LPCWSTR)Name),result);
#endif
}

static int WriteRegistry_L(HKEY hKey, LPCTSTR SubKey, LPCTSTR Name, int Value)
{
#ifndef _UNICODE
	return WriteRegistry(hKey,(char *)SubKey,(char *)Name,Value);
#else
USES_CONVERSION;
	return WriteRegistry(hKey,W2A((LPCWSTR)SubKey),W2A((LPCWSTR)Name),Value);
#endif
}


int EnumAvailableLanguage(LangEnum lpEnumFuncPro,void *UI)
{
	return LocCtrlInterface.EnumAvailableLang(lpEnumFuncPro,UI);
}

LocalizationMap::LocalizationMap()
{
	m_Map.InitHashTable(31);
	LocalizationMap::DeclearLangMap(this);	
};

BOOL LocalizationMap::GetInformationByAbbr(LPCTSTR Abb,USHORT &RetPri,USHORT &RetSub, CString &Path, DWORD &FullNameID,int &result)
{
	LangMapItem * pItem;
	BOOL res = m_Map.Lookup(Abb,pItem);
	if(res){
		RetPri = pItem->PrimLang;
		RetSub = pItem->SubLang;
		FullNameID = pItem->FullNameID;
		res = GetDLLPathByAbbr(Abb,Path,result);
	}
	return res;
};

BOOL LocalizationMap::GetInformationByAbbr(LPCTSTR Abb,DWORD &FullNameID,int &result)
{
/*	LangMapItem * pItem;
	BOOL res = m_Map.Lookup(Abb,pItem);
	if(res){
		FullNameID = pItem->FullNameID;
	}
	return res;*/
	LangMapItem * pItem;
	BOOL res = m_Map.Lookup(Abb,pItem);
	if(res){
		USHORT RetPri = pItem->PrimLang;
		USHORT RetSub = pItem->SubLang;
		FullNameID = MAKELCID(MAKELANGID(RetPri,RetSub),SORT_DEFAULT);
	}
	return res;

};

BOOL LocalizationMap::GetInformationByLCID(LCID lcid, CString & Abb)
{
	LangMapItem * pItem;
	CString key;
	POSITION pos;
	
	for( pos = m_Map.GetStartPosition(); pos != NULL; )
	{
		m_Map.GetNextAssoc( pos, key, (LangMapItem *)pItem );
		USHORT RetPri = pItem->PrimLang;
		USHORT RetSub = pItem->SubLang;
		DWORD LCID_InMap = MAKELCID(MAKELANGID(RetPri,RetSub),SORT_DEFAULT);
		if(LCID_InMap == lcid){
			Abb = key;
			return TRUE;
		}						
	}
	
	return FALSE;
};

//add by Fang Yunchao 2004/7/14
BOOL LocalizationMap::GetLanguagesAbbrfromLangMap(CString & langEnum )
{
	LangMapItem * pItem;
	CString key;
	POSITION pos;
	int i=0;
	for( pos = m_Map.GetStartPosition(); pos != NULL; )
	{
		m_Map.GetNextAssoc( pos, key, (LangMapItem *)pItem );
		if(langEnum== key)
			return true;
	
	}
	
	return FALSE;
};

int LocalizationMap::EnumAvailableLang(LangEnum lpEnumFuncPro,void *UI)
{
	HKEY ReadKey;
	DWORD dwType, cchValue, cbData,dwDispos;
	DWORD iValue = 0;
	_TCHAR szValue[128]=_T("\0");
	TCHAR  szData[128]=_T("\0"); 
	long result;
	DWORD FullNameID;
	CString KeyValue;
	BOOL res;

	long lSuccess = RegOpenKeyEx(mg_hKey,m_sCommonLangMapKeyDir, 0, KEY_QUERY_VALUE,&ReadKey); 	

	if ( lSuccess != NO_ERROR ){  
		RegCreateKeyEx(mg_hKey, m_sCommonLangMapKeyDir, 0, szValue,
					REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
					NULL, &ReadKey, &dwDispos);
		return 0;
	}

	while(TRUE){
		cchValue = sizeof(szValue);     
		cbData = sizeof(szData); 
		lSuccess = RegEnumValue(ReadKey, iValue, szValue, &cchValue, NULL,&dwType, (LPBYTE)szData, &cbData);
		if (lSuccess == ERROR_NO_MORE_ITEMS) 
			break; 
		if (lSuccess != ERROR_SUCCESS)
			break;
		KeyValue.Format(_T("%s"),szValue);
		res = this->GetInformationByAbbr(KeyValue,FullNameID,(int&)result);
		if(!res){
			TRACE("errors at Enum avaiable DLL process,please check windows registry!\r\n");
			continue;
		}
		//(*lpEnumFuncPro)(UI,iValue,KeyValue,FullNameID);
		CChangeUILanguageDlg pChangeUILanguageDlg;
		pChangeUILanguageDlg.EnumLang(UI,iValue,KeyValue,FullNameID);
		iValue++;
	}
	return 1;

};

BOOL LocalizationMap::GetDLLPathByAbbr(LPCTSTR Abb,CString &Path,int &result)
{
	_TCHAR path[256];	

	ReadRegistryString_L(mg_hKey,m_sCommonLangMapKeyDir,Abb,path,result);

	if(result != ERROR_SUCCESS){
		TRACE("can't find language DLL value which indentify DLL full name!error code is %d, please check windows registry!\n\r", result);
		//delete by Fang Yunchao 2004/7/14				
		// WriteRegistryString_L( mg_hKey, m_sCommonLangMapKeyDir, _T("ENUS"), _T("langenus.dll"));
		// WriteRegistryString_L( mg_hKey, m_sCommonLangMapKeyDir, _T("ZHCN"), _T("langzhcn.dll"));
		// WriteRegistryString_L( mg_hKey, m_sCommonLangMapKeyDir, _T("DEDE"), _T("langdede.dll"));
		return FALSE;
	}
	else{		
		_TCHAR Install_Path[256];
		ReadRegistryString_L(mg_hKey,m_sCommonKeyDir,COMMON_LANG_INSTALL_PATH_STRING,Install_Path,result);
		if(result != ERROR_SUCCESS){			
			ReadRegistryString_L(mg_hKey,m_sLastDefaultKeyDir,INSTALL_PATH_REG_STRING,Install_Path,result);
			_TCHAR WriteInstallPath[256];

			_stprintf(WriteInstallPath,_T("%s%s"),Install_Path,_T("\\CommonLangMap\\"));
			WriteRegistryString_L(mg_hKey,m_sCommonKeyDir,COMMON_LANG_INSTALL_PATH_STRING,WriteInstallPath);
			Path.Format(_T("%s%s%s"),Install_Path,_T("\\CommonLangMap\\"),path);

		}
		else{
			Path.Format(_T("%s%s"),Install_Path,path);
		}
		WIN32_FIND_DATA  findData;		
		HANDLE handle = ::FindFirstFile(Path,&findData);
		if(handle == INVALID_HANDLE_VALUE){
			TRACE("Language DLL can't be found,check your filesystem and windows registry!!\n\r");
			result = -1;
		}
	}
	return TRUE;
}

BOOL LocalizationMap::GetExtensionDLLPathByAbbr(LPCTSTR Abb,CString &Path,int &result)
{
	_TCHAR path[256];

	ReadRegistryString_L(mg_hKey,m_sExtLangMapKeyDir,Abb,path,result);
	
	if(result != ERROR_SUCCESS){
		WriteRegistryString_L(mg_hKey,m_sExtLangMapKeyDir,Abb,_T("extlangenus.dll"));
		TRACE("can't find Extension language DLL value,check windows registry!error code is %d\n\r", result);
		return FALSE;
	}
	else{
		WIN32_FIND_DATA  findData;
		_TCHAR Install_Path[256];
		ReadRegistryString_L(mg_hKey,m_sLastDefaultKeyDir,INSTALL_PATH_REG_STRING,Install_Path,result);
		Path.Format(_T("%s\\ExtLangMap\\%s"),Install_Path,path);
		HANDLE handle = ::FindFirstFile(Path,&findData);
		if(handle == INVALID_HANDLE_VALUE){
			TRACE("Language extension DLL can't be found!check your windows registry,and filesystem!\n\r");
			result = -1;
			return FALSE;
		}
	}
	return TRUE;
}

BOOL LocalizationMap::GetLastDefaultDLLPathByAbbr(CString &Path,CString &Abb,int &result)
{
	_TCHAR abb[10];
	int res;
	ReadRegistryString_L(mg_hKey,m_sLastDefaultKeyDir,m_sLastDefaultValue,abb,res);
	if(res != ERROR_SUCCESS){
		TRACE("can't find internal default abbreviation value!error code is %d\n\r", res);		
		WriteRegistryString_L(mg_hKey,m_sLastDefaultKeyDir,m_sLastDefaultValue,_T("ENUS"));
		return FALSE;
	}
	else{
		BOOL res;
		res = GetDLLPathByAbbr(abb,Path,result);
		if(!res)
			return FALSE;
		Abb.Format(_T("%s"),abb);
	}
	return TRUE;
}

int LocalizationMap::SetLastDefaultDLLPathByAbbr(LPCTSTR Abb)
{
	return WriteRegistryString_L(mg_hKey,m_sLastDefaultKeyDir,m_sLastDefaultValue,Abb);
}


///////////////////////////////////////////////////////////////////////////////////////
//localization resource handle module
///////////////////////////////////////////////////////////////////////////////////////
CLocalizationCtrl::CLocalizationCtrl(void)
{
	m_hInst = NULL;		
}

CLocalizationCtrl::~CLocalizationCtrl(void)
{
	if(m_hInst)
		FreeLibrary(m_hInst);
	BOOL res = m_LangMap.SetLastDefaultDLLPathByAbbr(m_sCurrentAbb);
		
}


BOOL CLocalizationCtrl::CtrlQueryDialog(LPCTSTR lpszResourceName,CDialog *pDialog, BOOL Model,CWnd *pParentWnd)
{
	BOOL res = TRUE;
	
	HGLOBAL hGlobal = _LoadResourceEx(lpszResourceName,RT_DIALOG);
	VERIFYHGLOBAL
	DLGTEMPLATE * DialogTempl = (DLGTEMPLATE * )::LockResource(hGlobal);		
//	res = pDialog->CreateIndirect(DialogTempl);
	if(Model)
		res = pDialog->InitModalIndirect(DialogTempl);
	else{
		res = pDialog->CreateIndirect(DialogTempl,pParentWnd);
	}
	FREEHRSRC
#ifdef INTERNAL_LANGDLL_SUPPORT
	if(m_InternalDefaulthInst){
		FreeLibrary(m_InternalDefaulthInst);
		m_InternalDefaulthInst = NULL;
	}
#endif
	return TRUE;
}

HWND CLocalizationCtrl::CtrlQueryModalessDialog(UINT nIDTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	HWND hWnd = NULL;
	HGLOBAL hGlobal = _LoadResourceEx(nIDTemplate,RT_DIALOG);
	VERIFYHGLOBAL
	DLGTEMPLATE * DialogTempl = (DLGTEMPLATE * )::LockResource(hGlobal);		
	if(!m_hTempInst)
		hWnd = ::CreateDialogIndirectParam(m_hTempInst,DialogTempl,hWndParent,lpDialogFunc,dwInitParam);
	FREEHRSRC
#ifdef INTERNAL_LANGDLL_SUPPORT
	if(m_InternalDefaulthInst){
		FreeLibrary(m_InternalDefaulthInst);
		m_InternalDefaulthInst = NULL;
	}
#endif
	return hWnd;
}

int CLocalizationCtrl::CtrlQueryModalDialog(UINT nIDTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	int res = NULL;
	HGLOBAL hGlobal = _LoadResourceEx(nIDTemplate,RT_DIALOG);
	VERIFYHGLOBAL
	DLGTEMPLATE * DialogTempl = (DLGTEMPLATE * )::LockResource(hGlobal);		
	if(!m_hTempInst)
		res = ::DialogBoxIndirectParam(m_hTempInst,DialogTempl,hWndParent,lpDialogFunc,dwInitParam);
	FREEHRSRC
#ifdef INTERNAL_LANGDLL_SUPPORT
	if(m_InternalDefaulthInst){
		FreeLibrary(m_InternalDefaulthInst);
		m_InternalDefaulthInst = NULL;
	}
#endif
	return res;
}

HGLOBAL CLocalizationCtrl::CtrlQueryDialogInitInfo(LPCTSTR lpszResourceName)
{
	HGLOBAL hGlobal = _LoadResourceEx(lpszResourceName,RT_DLGINIT);
	VERIFYHGLOBAL
	return hGlobal;
}

BOOL CLocalizationCtrl::CtrlQueryMenu(LPCTSTR lpszResourceName,CMenu *pMenu)
{
	BOOL res = TRUE;
	
	HGLOBAL hGlobal = _LoadResourceEx(lpszResourceName,RT_MENU);
	VERIFYHGLOBAL
	MENUTEMPLATE * MenuTempl = (MENUTEMPLATE *)::LockResource(hGlobal);
	res = pMenu->LoadMenuIndirect(MenuTempl);
	FREEHRSRC	
#ifdef INTERNAL_LANGDLL_SUPPORT
	if(m_InternalDefaulthInst){
		FreeLibrary(m_InternalDefaulthInst);
		m_InternalDefaulthInst = NULL;
	}
#endif
	return TRUE;
}

struct CToolBarData
{
	WORD wVersion;
	WORD wWidth;
	WORD wHeight;
	WORD wItemCount;
	//WORD aItems[wItemCount]

	WORD* items()
		{ return (WORD*)(this+1); }
};

BOOL CLocalizationCtrl::CtrlQueryToolbar(LPCTSTR lpszResourceName,CToolBar * pToolbar)
{	
	HGLOBAL hGlobal = _LoadResourceEx(lpszResourceName,RT_TOOLBAR);
	VERIFYHGLOBAL
	CToolBarData * pData = (CToolBarData*)::LockResource(hGlobal);		
	if(!pData)
		return FALSE;

	UINT* pItems = new UINT[pData->wItemCount];
	for (int i = 0; i < pData->wItemCount; i++)
		pItems[i] = pData->items()[i];
	BOOL bResult = pToolbar->SetButtons(pItems, pData->wItemCount);
	delete[] pItems;

	if (bResult)
	{
		// set new sizes of the buttons
		CSize sizeImage(pData->wWidth, pData->wHeight);
		CSize sizeButton(pData->wWidth + 7, pData->wHeight + 7);
		pToolbar->SetSizes(sizeButton, sizeImage);
	}

	FREEHRSRC
#ifdef INTERNAL_LANGDLL_SUPPORT
	if(m_InternalDefaulthInst){
		FreeLibrary(m_InternalDefaulthInst);
		m_InternalDefaulthInst = NULL;
	}
#endif
	return TRUE;
}

#define RGB_TO_RGBQUAD(r,g,b)   (RGB(b,g,r))
#define CLR_TO_RGBQUAD(clr)     (RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)))
#define _countof(array) (sizeof(array)/sizeof(array[0]))

struct AFX_COLORMAP
{
	// use DWORD instead of RGBQUAD so we can compare two RGBQUADs easily
	DWORD rgbqFrom;
	int iSysColorTo;
};

const AFX_COLORMAP _afxSysColorMap[] =
{
	// mapping from color in DIB to system color
	{ RGB_TO_RGBQUAD(0x00, 0x00, 0x00),  COLOR_BTNTEXT },       // black
	{ RGB_TO_RGBQUAD(0x80, 0x80, 0x80),  COLOR_BTNSHADOW },     // dark gray
	{ RGB_TO_RGBQUAD(0xC0, 0xC0, 0xC0),  COLOR_BTNFACE },       // bright gray
	{ RGB_TO_RGBQUAD(0xFF, 0xFF, 0xFF),  COLOR_BTNHIGHLIGHT }   // white
};

HBITMAP CLocalizationCtrl::QueryBitmap(LPCTSTR lpszResourceName)
{
	HBITMAP hBm  = NULL;
	HGLOBAL hGlobal = _LoadResourceEx(lpszResourceName,RT_BITMAP);
	VERIFYHGLOBAL

	BOOL bMono = FALSE;
	LPBITMAPINFOHEADER lpBitmap = (LPBITMAPINFOHEADER)LockResource(hGlobal);
	if (lpBitmap == NULL)
		return NULL;
	// make copy of BITMAPINFOHEADER so we can modify the color table
	const int nColorTableSize = 16;
	UINT nSize = lpBitmap->biSize + nColorTableSize * sizeof(RGBQUAD);
	LPBITMAPINFOHEADER lpBitmapInfo = (LPBITMAPINFOHEADER)::malloc(nSize);
	if (lpBitmapInfo == NULL)
		return NULL;
	memcpy(lpBitmapInfo, lpBitmap, nSize);

	// color table is in RGBQUAD DIB format
	DWORD* pColorTable =
		(DWORD*)(((LPBYTE)lpBitmapInfo) + (UINT)lpBitmapInfo->biSize);
	
	for (int iColor = 0; iColor < nColorTableSize; iColor++)
	{
		// look for matching RGBQUAD color in original
		for (int i = 0; i < _countof(_afxSysColorMap); i++)
		{
			if (pColorTable[iColor] == _afxSysColorMap[i].rgbqFrom)
			{
				if (bMono)
				{
					// all colors except text become white
					if (_afxSysColorMap[i].iSysColorTo != COLOR_BTNTEXT)
						pColorTable[iColor] = RGB_TO_RGBQUAD(255, 255, 255);
				}
				else
					pColorTable[iColor] =
						CLR_TO_RGBQUAD(::GetSysColor(_afxSysColorMap[i].iSysColorTo));
				break;
			}
		}
	}
	
	int nWidth = (int)lpBitmapInfo->biWidth;
	int nHeight = (int)lpBitmapInfo->biHeight;
	HDC hDCScreen = ::GetDC(NULL);
	HBITMAP hbm = ::CreateCompatibleBitmap(hDCScreen, nWidth, nHeight);

	if (hbm != NULL)
	{
		HDC hDCGlyphs = ::CreateCompatibleDC(hDCScreen);
		HBITMAP hbmOld = (HBITMAP)::SelectObject(hDCGlyphs, hbm);

		LPBYTE lpBits;
		lpBits = (LPBYTE)(lpBitmap + 1);
		lpBits += (1 << (lpBitmapInfo->biBitCount)) * sizeof(RGBQUAD);

		StretchDIBits(hDCGlyphs, 0, 0, nWidth, nHeight, 0, 0, nWidth, nHeight,
			lpBits, (LPBITMAPINFO)lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
		SelectObject(hDCGlyphs, hbmOld);
		::DeleteDC(hDCGlyphs);
	}
	::ReleaseDC(NULL, hDCScreen);
	// free copy of bitmap info struct and resource itself
	::free(lpBitmapInfo);

	FREEHRSRC
#ifdef INTERNAL_LANGDLL_SUPPORT
	if(m_InternalDefaulthInst){
		FreeLibrary(m_InternalDefaulthInst);
		m_InternalDefaulthInst = NULL;
	}
#endif
	return hbm;	
}

CStringW CLocalizationCtrl::CtrlQueryStringW(UINT ResID)
{
	UINT num = ResID & 0xf;	

	HGLOBAL hGlobal = _LoadResourceEx(ResID,RT_STRING);
	if (hGlobal == NULL) {		
			DWORD x = GetLastError();  
			TRACE("Loadresource error!The code is %d\n\r", x);  
			return CStringW(_T("default"));        
	}                            

	LPWSTR Str = (LPWSTR)::LockResource(hGlobal);
	wchar_t wzBuf[256];
	if(Str){
		for (UINT i = 0; i < num; i++)     Str += *Str + 1; 
		wcsncpy(wzBuf, Str + 1, min(256 - 1, *Str));
	}
	wzBuf[min(256-1, *Str) ] = '\0';

	CStringW returnStr((LPCWSTR)wzBuf);
	
	FREEHRSRC

	return returnStr;
}

CString CLocalizationCtrl::CtrlQueryString(UINT ResID)
{
	UINT num = ResID & 0xf;	

	HGLOBAL hGlobal = _LoadResourceEx(ResID,RT_STRING);
	if (hGlobal == NULL) {		
			DWORD x = GetLastError();  
			TRACE("Loadresource error!The code is %d\n\r", x);  
			return CString("default");        
	}                            

	LPWSTR Str = (LPWSTR)::LockResource(hGlobal);
	for (UINT i = 0; i < num; i++)     Str += *Str + 1; 
	
	CHAR tmp[128];
	LPSTR szBuf = (LPSTR)tmp;
	int len = WideCharToMultiByte(CP_THREAD_ACP/*CP_ACP*/,   WC_COMPOSITECHECK,   Str + 1, *Str,   szBuf, 128,   NULL, NULL); 
	szBuf[len] = '\0';
	
	CString returnStr(szBuf);
	FREEHRSRC
#ifdef INTERNAL_LANGDLL_SUPPORT
	if(m_InternalDefaulthInst){
		AfxFreeLibrary(m_InternalDefaulthInst);
		m_InternalDefaulthInst = NULL;
	}
#endif
	return returnStr;
}


BOOL CLocalizationCtrl::InitLoadLastDefault()
{
	BOOL res;
	CString path,Abb,tmp1;
	int result;
#ifdef LOCALIZATION_SUPPORT
	res = m_LangMap.GetLastDefaultDLLPathByAbbr(path,Abb,result);
	if(!res){
		TRACE("Can't load last default DLL!\n\r");
		m_hInst = NULL;
		return FALSE;
	}
#else
	LCID lcid = ::GetUserDefaultLCID();
	res = m_LangMap.GetInformationByLCID(lcid, Abb);
	if(!res){
		TRACE("Can't load last default DLL!\n\r");
		m_hInst = NULL;
		return FALSE;
	}
#endif
	res = ChangeCurrentLang(Abb);
	return res;
}

HGLOBAL CLocalizationCtrl::_LoadResourceEx(LPCTSTR lpszResourceName,LPCTSTR ResType)
{
	m_hTempInst = NULL;
	if(!m_hInst)							
		goto fallback4;						
	
	HRSRC hRsrc;							
	HINSTANCE hInst;
	
	hRsrc = _CtrlFindResourceEX(m_hInst,ResType,lpszResourceName);  
	if(!hRsrc){//res not founded at specific language dll
//fallback step4
fallback4:
		#ifndef INTERNAL_LANGDLL_SUPPORT
			hInst = ::AfxGetInstanceHandle();
			this->m_hTempInst = hInst;
		#else
			if(hRsrc == NULL)
				res = map.GetDLLPathByAbbr(DEFAULT_LANG,path,result);
			if(!res){
				ASSERT(FALSE);
				return NULL;
			}
			m_InternalDefaulthInst = LoadLibrary(path);
			hInst = m_InternalDefaulthInst;
		#endif
			if(!hInst){
				ASSERT(FALSE);
				return NULL;
			}
			hRsrc = ::FindResource(hInst,lpszResourceName,ResType);
			this->m_hTempSrc = hRsrc;
	}
	else
		hInst = m_hInst;
	HGLOBAL hGlobal = LoadResource(hInst, hRsrc);   
	return hGlobal;
}

HGLOBAL CLocalizationCtrl::_LoadResourceEx(UINT ResID,LPCTSTR ResType)
{	
	LPTSTR ss;
	if(ResType == RT_STRING)					
		ss = MAKEINTRESOURCE((ResID>>4)+1);  
	else
		ss = MAKEINTRESOURCE(ResID);
	return _LoadResourceEx(ss,ResType);
}

HRSRC CLocalizationCtrl::_CtrlFindResourceEX(HINSTANCE RscInst,LPCTSTR lpType,LPCTSTR lpName)
{
	DWORD errorCode;
	HRSRC hRsrc = NULL;
	m_hTempInst = NULL;
	m_hTempSrc = NULL;
//fallback step1
	hRsrc = ::FindResourceEx(RscInst,lpType,lpName,MAKELANGID(m_CurrentLanguagePriID,m_CurrentLanguageSubID));	
//fallback step2
	if(hRsrc == NULL){
		errorCode = GetLastError();
		hRsrc = ::FindResourceEx(RscInst,lpType,lpName,MAKELANGID(m_CurrentLanguagePriID,SUBLANG_NEUTRAL));
	}
	else{
		goto SUCCESS;
	}
//fallback step3
	if(hRsrc == NULL){
		errorCode = GetLastError();
		hRsrc = ::FindResource(RscInst,lpName,lpType);
	}

SUCCESS:
	this->m_hTempInst = RscInst;
	this->m_hTempSrc = hRsrc;
	return hRsrc;
}

BOOL CLocalizationCtrl::ChangeCurrentLang(LPCTSTR Abbre)
{
	CString path,tmp1;
	DWORD tmp2;
	HINSTANCE hInst;
	int result;
	BOOL res;

/*	if(m_hInst == NULL){ //initalized
		res = InitLoadLastDefault();
		if (!res)
			return FALSE;
	}*/
	res = m_LangMap.GetDLLPathByAbbr(Abbre,path,result);
	if(res){   //successful change
		if((m_sCurrentDLLPath.Compare(path)!= 0)||(m_sCurrentAbb.Compare(Abbre)!= 0))
		{
			hInst = LoadLibrary(path);
			if(hInst){
				if(m_hInst)
					FreeLibrary(m_hInst);
				m_hInst = hInst;
//				AfxSetResourceHandle(hInst);
				m_sCurrentAbb = Abbre;
				m_sCurrentDLLPath = path;
				res = this->m_LangMap.GetInformationByAbbr(Abbre,m_CurrentLanguagePriID,m_CurrentLanguageSubID,tmp1,tmp2,result);	
				SetThreadLocale(MAKELCID(MAKELANGID(m_CurrentLanguagePriID,m_CurrentLanguageSubID),SORT_DEFAULT));
				return res;
			}
			else{
				DWORD error = GetLastError();
				TRACE("loading res dll failed! error code is %d,please check if DLL is valid!",error);
				/*Fang Yunchao 2004/7/14,change the default language	begin		   */
				m_sCurrentAbb = "ENUS";
				if(m_hInst)
					FreeLibrary(m_hInst);
				m_hInst = ::AfxGetInstanceHandle();
				/*Fang Yunchao 2004/7/14,change the default language	end		   */
			}
		}
		else{
				m_sCurrentAbb = Abbre;
				res = m_LangMap.GetInformationByAbbr(Abbre,m_CurrentLanguagePriID,m_CurrentLanguageSubID,tmp1,tmp2,result);	
				return res;
		}
	}
	else{      //failure
		if (result == -1)
			TRACE("Can't locate language DLL file!\n\r");
	}	
	return res;  //if not init session, nothing changed if failuer happended
}

int CLocalizationCtrl::EnumAvailableLang(LangEnum lpEnumFuncPro,void *UI)
{
	return m_LangMap.EnumAvailableLang(lpEnumFuncPro,UI);
}

CString CLocalizationCtrl::GetCurrentLangFullName()
{
	int result;
	DWORD FullNameID;
	CString FullName;

	LPCTSTR abb = GetCurrentAbb();

	BOOL res = m_LangMap.GetInformationByAbbr(abb,FullNameID,result);
	if(!res)
		FullName.Format(_T("Default"));
	else{
#ifndef _UNICODE
		FullName = CtrlQueryString(FullNameID);
#else
	_TCHAR				AvailableLangName[128];

	if( GetLocaleInfoW(FullNameID,LOCALE_SNATIVELANGNAME,AvailableLangName,128)) {					
		FullName.Format(_T("%s"),AvailableLangName);
	}		
#endif
	}
	if(FullName.IsEmpty())
		FullName.Format(_T("Default"));			

	return FullName;
}

/////////////////////////////////////////////////////////////////////////////////////////
//extension localization resource handle module
///////////////////////////////////////////////////////////////////////////////////////
CLocalizationCtrlExtension::CLocalizationCtrlExtension()
{	
	m_hCurrentExtLangDLL = NULL;
}

CLocalizationCtrlExtension::~CLocalizationCtrlExtension()
{
	if(m_hCurrentExtLangDLL)
		FreeLibrary(m_hCurrentExtLangDLL);
}


HGLOBAL CLocalizationCtrlExtension::_LoadResourceEx(LPCTSTR lpszResourceName,LPCTSTR ResType)
{
	m_hTempInst = NULL;
	if(!m_hCurrentExtLangDLL)							
		goto fallback;
	
	HRSRC hRsrc;							
	AfxSetResourceHandle(m_hCurrentExtLangDLL);
	hRsrc = _CtrlFindResourceEX(m_hCurrentExtLangDLL,ResType,lpszResourceName);  
	if(!hRsrc)
		goto fallback;
	HGLOBAL hGlobal = LoadResource(m_hCurrentExtLangDLL, hRsrc);
	if(!hGlobal)
		goto fallback;

	return hGlobal;
//fallback step4
fallback:
	return CLocalizationCtrl::_LoadResourceEx(lpszResourceName,ResType);
}

BOOL CLocalizationCtrlExtension::ChangeCurrentLang(LPCTSTR Abbre)
{
	BOOL res = CLocalizationCtrl::ChangeCurrentLang(Abbre);
	if(!res)
		return FALSE;
	int result;
	CString path;
	res = this->m_LangMap.GetExtensionDLLPathByAbbr(Abbre,path,result);

	if(res){   //successful change
		if(m_hCurrentExtLangDLL){
			FreeLibrary(m_hCurrentExtLangDLL);
			m_hCurrentExtLangDLL = NULL;
		}			
		HINSTANCE hInst = LoadLibrary(path);
		m_hCurrentExtLangDLL = hInst;
	}
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
//  Localization Interface and public APIS are see below
/////////////////////////////////////////////////////////////////////////////////////////////////////
#include "cfg_svn.h"
CLocalizationCtrlInterface::CLocalizationCtrlInterface(LPCTSTR CommonLangMapDir, LPCTSTR ExtLangMapDir,LPCTSTR ExtLangOptionsKeyDir,LPCTSTR LastDefaKeyValue,LPCTSTR ExtLangAvaiMark,LPCTSTR CommonKeyValue)
{
	ResponsiableForDel = FALSE;
       // Add by Fang Yunchao for SMTK Localization support
	Info_InitInfoMain();
	if(this->m_pCtrlLoader != NULL)
		return;
	CString ExtLangMapDir_format,ExtLangOptionsKeyDir_format;
	ExtLangMapDir_format.Format(ExtLangMapDir,_T(SW_OFFICIAL_NAME));
#ifndef _UNICODE
	ExtLangOptionsKeyDir_format.Format(ExtLangOptionsKeyDir,Info_GetProductName());
#else
	USES_CONVERSION;
	ExtLangOptionsKeyDir_format.Format(ExtLangOptionsKeyDir,A2W((LPCSTR)Info_GetProductName()));
#endif

//Add by Fang Yunchao 2004/7/14 begin
/*Enum all the DLL files and write the information into registry */	

	//gain the directory of languages' DLL
	_TCHAR Install_Path[256];
		int result;
		ReadRegistryString_L(mg_hKey,CommonKeyValue,COMMON_LANG_INSTALL_PATH_STRING,Install_Path,result);
		if(result != ERROR_SUCCESS)
		{			
		  TCHAR exePath[256];
		  TCHAR *ptrOld;
		  TCHAR *ptrNew;

		  GetModuleFileNameW( NULL, exePath, sizeof( exePath));
  		  ptrOld = exePath;
		  ptrNew = (TCHAR*) _tcsrchr( (TCHAR*) ptrOld,_T( '\\') );
		  *ptrNew = _T('\0');

		  _stprintf( Install_Path, 256, _T("%s"), exePath);
		  
		  _TCHAR WriteInstallPath[256];


		 _stprintf(WriteInstallPath,_T("%s%s"),Install_Path,_T("\\CommonLangMap\\"));
		 WriteRegistryString_L(mg_hKey,CommonKeyValue,COMMON_LANG_INSTALL_PATH_STRING,WriteInstallPath);
		
		 _wchdir(WriteInstallPath);
	   }
	   else
	   {
		 _wchdir(Install_Path);
	   }
	
	
	   /* browse and list all the resource files of  \Localization\RC\ dirctory */
 	    struct _finddata_t c_file;
		long hFile;
		CString temp;
		CString langKey;
		LocalizationMap m_LangMap;
		
		if( (hFile = _findfirst( "*.*", &c_file )) == -1L )
		{
			TRACE("there are no files in current directory!\n\r");	
		}
		else
		{
			 // check whether the first find entity is a dll file(c_file.name is the name of the found entity) 
			if( !(::GetFileAttributesA(c_file.name)& _A_SUBDIR))
		    {
				langKey='\0';
				temp='\0';
				langKey=c_file.name;
				temp=langKey.Right(langKey.GetLength()-4);
				langKey='\0';
				langKey=temp.Left(temp.GetLength()-4);
				langKey.MakeUpper();
				
				if(m_LangMap.GetLanguagesAbbrfromLangMap(langKey))
					{
						ReadRegistryString_L(mg_hKey,CommonLangMapDir,langKey,Install_Path,result);
						if(result != ERROR_SUCCESS)
						{	
#ifndef _UNICODE
							WriteRegistryString_L( mg_hKey,CommonLangMapDir,langKey, c_file.name);
#else
							USES_CONVERSION;
							WriteRegistryString_L( mg_hKey, CommonLangMapDir,langKey, A2W(c_file.name));
#endif
						}		
					}

			}				
			
			/* Find the rest of the DLL files */
            while( _findnext( hFile, &c_file ) == 0 )
            {
       		 // check whether the found entity is a dll file(c_file.name is the name of the found entity) 
			if( !(::GetFileAttributesA(c_file.name)& _A_SUBDIR))
		    {
				langKey='\0';
				temp='\0';
				langKey=c_file.name;
				temp=langKey.Right(langKey.GetLength()-4);
				langKey='\0';
				langKey=temp.Left(temp.GetLength()-4);
				langKey.MakeUpper();
				if(m_LangMap.GetLanguagesAbbrfromLangMap(langKey))
					{
						ReadRegistryString_L(mg_hKey,CommonLangMapDir,langKey,Install_Path,result);
						if(result != ERROR_SUCCESS)
						{	
#ifndef _UNICODE
							WriteRegistryString_L( mg_hKey,CommonLangMapDir,langKey, c_file.name);
#else
							USES_CONVERSION;
							WriteRegistryString_L( mg_hKey, CommonLangMapDir,langKey, A2W(c_file.name));
#endif
						}		
					}
		
			}
            
			}

			_findclose( hFile );
			//chdir("..\\..\\");
		}
	//Add by Fang Yunchao 2004/7/14 end
	
	CLocalizationCtrl::m_LangMap.SetLangMapInfo(CommonLangMapDir,ExtLangMapDir_format,ExtLangOptionsKeyDir_format,LastDefaKeyValue,CommonKeyValue);
	ExtensionLangMarkAvai(ExtLangOptionsKeyDir_format,ExtLangAvaiMark);		
	ResponsiableForDel = TRUE;
}

CLocalizationCtrlInterface::~CLocalizationCtrlInterface(void)
{
	if(ResponsiableForDel){
		if(m_pCtrlLoader)
			delete m_pCtrlLoader;
		m_pCtrlLoader = NULL;
	}
}

HGLOBAL CLocalizationCtrlInterface::GetDialogInitIformation(LPCTSTR lpszResourceName)
{
	return m_pCtrlLoader->CtrlQueryDialogInitInfo(lpszResourceName);
}

HINSTANCE CLocalizationCtrlInterface::GetCurrentLoadedResourceInstance()
{
	return m_pCtrlLoader->m_hTempInst;
}

HRSRC CLocalizationCtrlInterface::GetCurrentLoadedResourceHandle()
{
	return m_pCtrlLoader->m_hTempSrc;
}

BOOL CLocalizationCtrlInterface::SetCurrentLanguage(LPCTSTR Abb)
{
	return m_pCtrlLoader->ChangeCurrentLang(Abb);
}

BOOL CLocalizationCtrlInterface::LoadMenu(LPCTSTR lpszResourceName,CMenu *pMenu)
{
	return m_pCtrlLoader->CtrlQueryMenu(lpszResourceName,pMenu);
}

BOOL CLocalizationCtrlInterface::LoadMenu(UINT ResID,CMenu *pMenu)
{
	return m_pCtrlLoader->CtrlQueryMenu(MAKEINTRESOURCE(ResID),pMenu);
}

BOOL CLocalizationCtrlInterface::LoadString(UINT ResID,CString &str)
{
	str = m_pCtrlLoader->CtrlQueryString(ResID);
	if(str.IsEmpty())
		return FALSE;
	return TRUE;
}

BOOL CLocalizationCtrlInterface::LoadStringWC(UINT ResID,CStringW &str)
{
	str = m_pCtrlLoader->CtrlQueryStringW(ResID);
	if(str.IsEmpty())
		return FALSE;
	return TRUE;
}

CString CLocalizationCtrlInterface::GetStringFromID(UINT ResID)
{
	CString tmp;
	LoadString(ResID,tmp);
	return tmp;
}

CStringW CLocalizationCtrlInterface::GetWStringFromID(UINT ResID)
{
	return m_pCtrlLoader->CtrlQueryStringW(ResID);
}

BOOL CLocalizationCtrlInterface::QueryModelDialog(UINT ResID, CDialog * pDialog,CWnd *pParentWnd)
{	
	return m_pCtrlLoader->CtrlQueryDialog(MAKEINTRESOURCE(ResID),pDialog,TRUE,pParentWnd);
}

BOOL CLocalizationCtrlInterface::QueryModelDialog(LPCTSTR lpszResourceName, CDialog * pDialog,CWnd *pParentWnd)
{	
	return m_pCtrlLoader->CtrlQueryDialog(lpszResourceName,pDialog,TRUE,pParentWnd);
}

BOOL CLocalizationCtrlInterface::QueryModelessDialog(LPCTSTR lpszResourceName, CDialog * pDialog,CWnd *pParentWnd)
{	
	return m_pCtrlLoader->CtrlQueryDialog(lpszResourceName,pDialog,FALSE,pParentWnd);
}

BOOL CLocalizationCtrlInterface::QueryModelessDialog(UINT ResID, CDialog * pDialog,CWnd *pParentWnd)
{	
	return m_pCtrlLoader->CtrlQueryDialog(MAKEINTRESOURCE(ResID),pDialog,FALSE,pParentWnd);
}

int CLocalizationCtrlInterface::EnumAvailableLang(LangEnum lpEnumFuncPro,void *UI)
{
	return m_pCtrlLoader->EnumAvailableLang(lpEnumFuncPro,UI);
}

BOOL CLocalizationCtrlInterface::ExtensionLangMarkAvai(LPCTSTR ExtLangOptionsKeyDir,LPCTSTR ExtLangAvaiMark)
{
    int result;

	int qValue = ReadRegistry_L(mg_hKey,ExtLangOptionsKeyDir,ExtLangAvaiMark,result);
	if(result != ERROR_SUCCESS)
	{
		WriteRegistry_L(mg_hKey,ExtLangOptionsKeyDir,ExtLangAvaiMark,0);
		qValue = 0;
	}

	if(qValue)
		m_pCtrlLoader = new CLocalizationCtrlExtension();
	else
		m_pCtrlLoader = new CLocalizationCtrl();
	m_pCtrlLoader->InitLoadLastDefault();
	return TRUE;
}

LPCTSTR CLocalizationCtrlInterface::GetCurrentAbb()
{
	return m_pCtrlLoader->GetCurrentAbb();
}

HBITMAP CLocalizationCtrlInterface::LoadBitmap(LPCTSTR lpszResourceName)
{
	return m_pCtrlLoader->QueryBitmap(lpszResourceName);
}

BOOL CLocalizationCtrlInterface::LoadToolBar(UINT ResID,CToolBar * pToolbar)
{
	return m_pCtrlLoader->CtrlQueryToolbar(MAKEINTRESOURCE(ResID),pToolbar);
}

BOOL CLocalizationCtrlInterface::LoadToolBar(LPCTSTR lpszResourceName,CToolBar * pToolbar)
{
	return m_pCtrlLoader->CtrlQueryToolbar(lpszResourceName,pToolbar);
}

CString CLocalizationCtrlInterface::GetCurrentLangFullName()
{
	return m_pCtrlLoader->GetCurrentLangFullName();
}

HWND CLocalizationCtrlInterface::CreateLocalizationDialog(UINT nIDTemplate,HWND hWndParent,DLGPROC lpDialogFunc)
{
	return m_pCtrlLoader->CtrlQueryModalessDialog(nIDTemplate,hWndParent,lpDialogFunc);
}

HWND CLocalizationCtrlInterface::CreateLocalizationDialogParam(UINT nIDTemplate,HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam)
{
	return m_pCtrlLoader->CtrlQueryModalessDialog(nIDTemplate,hWndParent,lpDialogFunc,dwInitParam);
}

int CLocalizationCtrlInterface::LocalizationDialogBox(UINT nIDTemplate,HWND hWndParent,DLGPROC lpDialogFunc)
{
	return m_pCtrlLoader->CtrlQueryModalDialog(nIDTemplate,hWndParent,lpDialogFunc);
}

int CLocalizationCtrlInterface::LocalizationDialogBoxParam(UINT nIDTemplate, HWND hWndParent,DLGPROC lpDialogFunc,LPARAM dwInitParam )
{
	return m_pCtrlLoader->CtrlQueryModalDialog(nIDTemplate,hWndParent,lpDialogFunc,dwInitParam);
}

HGLOBAL CLocalizationCtrlInterface::LoadResouceEX(LPCTSTR lpszResourceName,LPCTSTR ResType)
{
	return m_pCtrlLoader->_LoadResourceEx(lpszResourceName,ResType);
}


HWND CreateLocalizationDialog(UINT nIDTemplate,HWND hWndParent,DLGPROC lpDialogFunc)
{
	return CLocalizationCtrlInterface::CreateLocalizationDialog(nIDTemplate,hWndParent,lpDialogFunc);
}

int LocalizationDialogBox(UINT nIDTemplate,HWND hWndParent,DLGPROC lpDialogFunc)
{
	return CLocalizationCtrlInterface::LocalizationDialogBox(nIDTemplate,hWndParent,lpDialogFunc);
}


#ifdef LOCALIZATION_SUPPORT
void ChangeUILanguageOption()
{
	CChangeUILanguageDlg dlg(NULL);
	dlg.DoModal();
}
#endif

#endif
