|
#pragma once
#include <comdef.h>
#include <locale.h>
/* This class saves the current CRT locale state and restores it when the object
goes out of scope.
This class was kept separate from CTempLocale because it may be useful on
it's own.
*/
class CCrtLocaleSwitch {
public:
//Constructor. Optionally switches to a new LCID.
CCrtLocaleSwitch(LCID lcNew=0);
//Desstructor. Restores original locale settings.
virtual ~CCrtLocaleSwitch(){
restore();
}
//Loads a _bstr_t with a string compatible with CRT setlocale function.
static LPCTSTR loadLocaleId(LCID lcid, _bstr_t& bstrRetBuf);
//Set the locale for the CRT using a Windows LCID.
static bool setLocale(LCID lcNew);
//Restores the locale set at the time the class instantiated.
bool restore(){
return setlocale(LC_ALL, _strLocale) ? true : false;
}
protected:
_bstr_t _strLocale;
};
/* This class saves the current thread's LCID and CRT state, then restores
it when it goes out of scope.
*/
class CTempLocale {
public:
CTempLocale(LCID lcid=0) : _crt(0)
{
_lcOrig = GetThreadLocale();
if( lcid != _lcOrig ){
SetThreadLocale(lcid);
_crt.setLocale(lcid);
}
}
//Restores the LCID before instantiation
virtual ~CTempLocale(){
restore();
}
//Set the thread's locale and CRT state back to what it was
void restore(){
if( _lcOrig != GetThreadLocale() )
SetThreadLocale(_lcOrig);
_crt.restore();
}
//Changes the locale. Does not affect the LCID set by restore().
void setLocale(LCID lcid){
if( lcid == GetThreadLocale() )
return;
restore();
SetThreadLocale(lcid);
_crt.setLocale(lcid);
}
//Writes a double to a string in the current locale with nPrec decimal
//places. Stores an LCID identifier at the end of the string.
LPCTSTR packDouble(double dbl, int nPrec, _bstr_t& bstrBufRes);
//Reads a double based on LCID information at the end of string, if present.
bool readDouble(LPCTSTR lpszText, double& dblRes);
//Reads a double and returns a default upon failure.
double readDoubleDef(LPCTSTR lpszText, double defVal){
double dRes;
if( readDouble(lpszText, dRes) )
return dRes;
return defVal;
}
LPCTSTR packLong(LONG lVal, _bstr_t& bstrBufRes);
bool readLong(LPCTSTR lpszText, LONG& lRes);
LONG readLongDef(LPCTSTR lpszText, LONG lDef){
LONG lRes;
if( readLong(lpszText, lRes) )
return lRes;
return lDef;
}
//Trims LCID information from the end of a packed long or double string.
static LPCTSTR trimLcid(LPCTSTR lpszNum, _bstr_t& bstrRetBuf);
//Utilities
//Gets the LCID's language name in English
static bool getLangName(LCID lcid, OUT _bstr_t& bstrLanguage);
//Gets the LCID's two letter language identifier
static bool getShortLangName(LCID lcid, OUT _bstr_t& bstrLanguage);
//Gets the LCID's region name in English
static bool getRegionName(LCID lcid, OUT _bstr_t& bstrLanguage);
//Gets the LCID's two letter region identifier
static bool getShortRegionName(LCID lcid, OUT _bstr_t& bstrLanguage);
protected:
LCID _lcOrig;
CCrtLocaleSwitch _crt;
};
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Director of Software Engineering for a startup software/hardware solution provider based in Silicon Valley. Currently in search of a new position with another company.