头文件"registry.h"
#include <string>
#include <Shlwapi.h>
#include <tchar.h>


/**//**
* \ingroup CommonClasses
* Base class for the registry classes.
*/
class CRegBase


{
public: //methods

/**//**
* Removes the whole registry key including all values. So if you set the registry
* entry to be HKCU\Software\Company\Product\key\value there will only be
* HKCU\Software\Company\Product key in the registry.
* \return ERROR_SUCCESS or an nonzero errorcode. Use FormatMessage() to get an error description.
*/

DWORD removeKey()
{ RegOpenKeyEx(m_base, m_path, 0, KEY_WRITE, &m_hKey); return SHDeleteKey(m_base, (LPCTSTR)m_path); }

/**//**
* Removes the value of the registry object. If you set the registry entry to
* be HKCU\Software\Company\Product\key\value there will only be
* HKCU\Software\Company\Product\key\ in the registry.
* \return ERROR_SUCCESS or an nonzero errorcode. Use FormatMessage() to get an error description.
*/

LONG removeValue()
{ RegOpenKeyEx(m_base, m_path, 0, KEY_WRITE, &m_hKey); return RegDeleteValue(m_hKey, (LPCTSTR)m_key); }

public: //members

HKEY m_base; /**////< handle to the registry base
HKEY m_hKey; ///< handle to the open registry key
CString m_key; ///< the name of the value
CString m_path; ///< the path to the key
};

class CRegDWORD : public CRegBase


{
public:
CRegDWORD(void);

/**//**
* Constructor.
* \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* \param def the default value used when the key does not exist or a read error occured
* \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegDWORD(CString key, DWORD def = 0, BOOL force = FALSE, HKEY base = HKEY_CURRENT_USER);
~CRegDWORD(void);

/**//**
* reads the assigned value from the registry. Use this method only if you think the registry
* value could have been altered without using the CRegDWORD object.
* \return the read value
*/

DWORD read(); /**////< reads the value from the registry
void write(); ///< writes the value to the registry

operator DWORD();
CRegDWORD& operator=(DWORD d);

CRegDWORD& operator+=(DWORD d)
{ return *this = *this + d;}

CRegDWORD& operator-=(DWORD d)
{ return *this = *this - d;}

CRegDWORD& operator*=(DWORD d)
{ return *this = *this * d;}

CRegDWORD& operator/=(DWORD d)
{ return *this = *this / d;}

CRegDWORD& operator%=(DWORD d)
{ return *this = *this % d;}

CRegDWORD& operator<<=(DWORD d)
{ return *this = *this << d;}

CRegDWORD& operator>>=(DWORD d)
{ return *this = *this >> d;}

CRegDWORD& operator&=(DWORD d)
{ return *this = *this & d;}

CRegDWORD& operator|=(DWORD d)
{ return *this = *this | d;}

CRegDWORD& operator^=(DWORD d)
{ return *this = *this ^ d;}
protected:


DWORD m_value; /**////< the cached value of the registry
DWORD m_defaultvalue; ///< the default value to use
BOOL m_read; ///< indicates if the value has already been read from the registry
BOOL m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
};

class CRegString : public CRegBase


{
public:
CRegString();

/**//**
* Constructor.
* \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* \param def the default value used when the key does not exist or a read error occured
* \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegString(CString key, CString def = _T(""), BOOL force = FALSE, HKEY base = HKEY_CURRENT_USER);
~CRegString(void);

CString read(); /**////< reads the value from the registry
void write(); ///< writes the value to the registry
operator CString();
CRegString& operator=(CString s);

CRegString& operator+=(CString s)
{ return *this = (CString)*this + s; }
protected:


CString m_value; /**////< the cached value of the registry
CString m_defaultvalue; ///< the default value to use
BOOL m_read; ///< indicates if the value has already been read from the registry
BOOL m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
};

class CRegRect : public CRegBase


{
public:
CRegRect();

/**//**
* Constructor.
* \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* \param def the default value used when the key does not exist or a read error occured
* \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegRect(CString key, CRect def = CRect(), BOOL force = FALSE, HKEY base = HKEY_CURRENT_USER);
~CRegRect(void);

CRect read(); /**////< reads the value from the registry
void write(); ///< writes the value to the registry
operator CRect();

operator LPCRECT()
{ return (LPCRECT)(CRect)*this; }

operator LPRECT()
{ return (LPRECT)(CRect)*this; }
CRegRect& operator=(CRect r);

CRegRect& operator+=(POINT r)
{ return *this = (CRect)*this + r;}

CRegRect& operator+=(SIZE r)
{ return *this = (CRect)*this + r;}

CRegRect& operator+=(LPCRECT r)
{ return *this = (CRect)*this + r;}

CRegRect& operator-=(POINT r)
{ return *this = (CRect)*this - r;}

CRegRect& operator-=(SIZE r)
{ return *this = (CRect)*this - r;}

CRegRect& operator-=(LPCRECT r)
{ return *this = (CRect)*this - r;}

CRegRect& operator&=(CRect r)
{ return *this = r & *this;}

CRegRect& operator|=(CRect r)
{ return *this = r | *this;}
protected:


CRect m_value; /**////< the cached value of the registry
CRect m_defaultvalue; ///< the default value to use
BOOL m_read; ///< indicates if the value has already been read from the registry
BOOL m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
};

class CRegPoint : public CRegBase


{
public:
CRegPoint();

/**//**
* Constructor.
* \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* \param def the default value used when the key does not exist or a read error occured
* \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegPoint(CString key, CPoint def = CPoint(), BOOL force = FALSE, HKEY base = HKEY_CURRENT_USER);
~CRegPoint(void);
CPoint read();

void write(); /**////< writes the value to the registry
operator CPoint();
CRegPoint& operator=(CPoint p);

CRegPoint& operator+=(CPoint p)
{ return *this = p + *this; }

CRegPoint& operator-=(CPoint p)
{ return *this = p - *this; }
protected:


CPoint m_value; /**////< the cached value of the registry
CPoint m_defaultvalue; ///< the default value to use
BOOL m_read; ///< indicates if the value has already been read from the registry
BOOL m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
};

#endif

typedef std::basic_string<TCHAR> stdstring;

class CRegStdBase


{
public: //methods

/**//**
* Removes the whole registry key including all values. So if you set the registry
* entry to be HKCU\Software\Company\Product\key\value there will only be
* HKCU\Software\Company\Product key in the registry.
* \return ERROR_SUCCESS or an nonzero errorcode. Use FormatMessage() to get an error description.
*/

DWORD removeKey()
{ RegOpenKeyEx(m_base, m_path.c_str(), 0, KEY_WRITE, &m_hKey); return SHDeleteKey(m_base, m_path.c_str()); }

/**//**
* Removes the value of the registry object. If you set the registry entry to
* be HKCU\Software\Company\Product\key\value there will only be
* HKCU\Software\Company\Product\key\ in the registry.
* \return ERROR_SUCCESS or an nonzero errorcode. Use FormatMessage() to get an error description.
*/

LONG removeValue()
{ RegOpenKeyEx(m_base, m_path.c_str(), 0, KEY_WRITE, &m_hKey); return RegDeleteValue(m_hKey, m_key.c_str()); }

public: //members

HKEY m_base; /**////< handle to the registry base
HKEY m_hKey; ///< handle to the open registry key
stdstring m_key; ///< the name of the value
stdstring m_path; ///< the path to the key
};

class CRegStdString : public CRegStdBase


{
public:
CRegStdString();

/**//**
* Constructor.
* \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* \param def the default value used when the key does not exist or a read error occured
* \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegStdString(stdstring key, stdstring def = _T(""), BOOL force = FALSE, HKEY base = HKEY_CURRENT_USER);
~CRegStdString(void);

stdstring read(); /**////< reads the value from the registry
void write(); ///< writes the value to the registry
operator stdstring();
CRegStdString& operator=(stdstring s);

CRegStdString& operator+=(stdstring s)
{ return *this = (stdstring)*this + s; }
operator LPCTSTR();
protected:


stdstring m_value; /**////< the cached value of the registry
stdstring m_defaultvalue; ///< the default value to use
BOOL m_read; ///< indicates if the value has already been read from the registry
BOOL m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
};

class CRegStdWORD : public CRegStdBase


{
public:
CRegStdWORD();

/**//**
* Constructor.
* \param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* \param def the default value used when the key does not exist or a read error occured
* \param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* \param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegStdWORD(stdstring key, DWORD def = 0, BOOL force = FALSE, HKEY base = HKEY_CURRENT_USER);
~CRegStdWORD(void);

DWORD read(); /**////< reads the value from the registry
void write(); ///< writes the value to the registry
operator DWORD();
CRegStdWORD& operator=(DWORD d);

CRegStdWORD& operator+=(DWORD d)
{ return *this = *this + d;}

CRegStdWORD& operator-=(DWORD d)
{ return *this = *this - d;}

CRegStdWORD& operator*=(DWORD d)
{ return *this = *this * d;}

CRegStdWORD& operator/=(DWORD d)
{ return *this = *this / d;}

CRegStdWORD& operator%=(DWORD d)
{ return *this = *this % d;}

CRegStdWORD& operator<<=(DWORD d)
{ return *this = *this << d;}

CRegStdWORD& operator>>=(DWORD d)
{ return *this = *this >> d;}

CRegStdWORD& operator&=(DWORD d)
{ return *this = *this & d;}

CRegStdWORD& operator|=(DWORD d)
{ return *this = *this | d;}

CRegStdWORD& operator^=(DWORD d)
{ return *this = *this ^ d;}
protected:


DWORD m_value; /**////< the cached value of the registry
DWORD m_defaultvalue; ///< the default value to use
BOOL m_read; ///< indicates if the value has already been read from the registry
BOOL m_force; ///< indicates if no cache should be used, i.e. always read and write directly from registry
};



registry.cpp
#include "stdafx.h"
#include "registry.h"

CRegDWORD::CRegDWORD(void)


{
m_value = 0;
m_defaultvalue = 0;
m_key = "";
m_base = HKEY_CURRENT_USER;
m_read = FALSE;
m_force = FALSE;
}


/**//**
* Constructor.
* @param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* @param def the default value used when the key does not exist or a read error occured
* @param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* @param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegDWORD::CRegDWORD(CString key, DWORD def, BOOL force, HKEY base)


{
m_value = 0;
m_defaultvalue = def;
m_force = force;
m_base = base;
m_read = FALSE;
key.TrimLeft(_T("\\"));
m_path = key.Left(key.ReverseFind(_T('\\')));
m_path.TrimRight(_T("\\"));
m_key = key.Right(key.GetLength() - key.ReverseFind(_T('\\')));
m_key.Trim(_T("\\"));
read();
}

CRegDWORD::~CRegDWORD(void)


{
//write();
}

DWORD CRegDWORD::read()


{
ASSERT(m_key != _T(""));
if (RegOpenKeyEx(m_base, m_path, 0, KEY_EXECUTE, &m_hKey)==ERROR_SUCCESS)

{
int size = sizeof(m_value);
DWORD type;
if (RegQueryValueEx(m_hKey, m_key, NULL, &type, (BYTE*) &m_value,(LPDWORD) &size)==ERROR_SUCCESS)

{
ASSERT(type==REG_DWORD);
m_read = TRUE;
RegCloseKey(m_hKey);
return m_value;
}
else

{
RegCloseKey(m_hKey);
return m_defaultvalue;
}
}
return m_defaultvalue;
}

void CRegDWORD::write()


{
ASSERT(m_key != _T(""));
DWORD disp;
if (RegCreateKeyEx(m_base, m_path, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &m_hKey, &disp)!=ERROR_SUCCESS)

{
return;
}
if (RegSetValueEx(m_hKey, m_key, 0, REG_DWORD,(const BYTE*) &m_value, sizeof(m_value))==ERROR_SUCCESS)

{
m_read = TRUE;
}
RegCloseKey(m_hKey);
}


CRegDWORD::operator DWORD()


{
if ((m_read)&&(!m_force))
return m_value;
else

{
return read();
}
}

CRegDWORD& CRegDWORD::operator =(DWORD d)


{
if ((d==m_value)&&(!m_force))

{
//no write to the registry required, its the same value
return *this;
}
m_value = d;
write();
return *this;
}


/**///////////////////////////////////////////////////////////////////////////////////////////////

CRegString::CRegString(void)


{
m_value = _T("");
m_defaultvalue = _T("");
m_key = _T("");
m_base = HKEY_CURRENT_USER;
m_read = FALSE;
m_force = FALSE;
}


/**//**
* Constructor.
* @param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* @param def the default value used when the key does not exist or a read error occured
* @param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* @param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegString::CRegString(CString key, CString def, BOOL force, HKEY base)


{
m_value = "";
m_defaultvalue = def;
m_force = force;
m_base = base;
m_read = FALSE;
key.TrimLeft(_T("\\"));
m_path = key.Left(key.ReverseFind(_T('\\')));
m_path.TrimRight(_T("\\"));
m_key = key.Right(key.GetLength() - key.ReverseFind(_T('\\')));
m_key.Trim(_T("\\"));
read();
}

CRegString::~CRegString(void)


{
//write();
}

CString CRegString::read()


{
ASSERT(m_key != _T(""));
if (RegOpenKeyEx(m_base, m_path, 0, KEY_EXECUTE, &m_hKey)==ERROR_SUCCESS)

{
int size = 0;
DWORD type;
RegQueryValueEx(m_hKey, m_key, NULL, &type, NULL, (LPDWORD) &size);
TCHAR* pStr = new TCHAR[size];
if (RegQueryValueEx(m_hKey, m_key, NULL, &type, (BYTE*) pStr,(LPDWORD) &size)==ERROR_SUCCESS)

{
m_value = CString(pStr);
delete [] pStr;
ASSERT(type==REG_SZ);
m_read = TRUE;
RegCloseKey(m_hKey);
return m_value;
}
else

{
delete [] pStr;
RegCloseKey(m_hKey);
return m_defaultvalue;
}
}
return m_defaultvalue;
}

void CRegString::write()


{
ASSERT(m_key != _T(""));
DWORD disp;
if (RegCreateKeyEx(m_base, m_path, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &m_hKey, &disp)!=ERROR_SUCCESS)

{
return;
}
#ifdef _UNICODE
if (RegSetValueEx(m_hKey, m_key, 0, REG_SZ, (BYTE *)(LPCTSTR)m_value, (m_value.GetLength()+1)*2)==ERROR_SUCCESS)
#else
if (RegSetValueEx(m_hKey, m_key, 0, REG_SZ, (BYTE *)(LPCTSTR)m_value, m_value.GetLength()+1)==ERROR_SUCCESS)
#endif

{
m_read = TRUE;
}
RegCloseKey(m_hKey);
}

CRegString::operator CString()


{
if ((m_read)&&(!m_force))
return m_value;
else

{
return read();
}
}

CRegString& CRegString::operator =(CString s)


{
if ((s==m_value)&&(!m_force))

{
//no write to the registry required, its the same value
return *this;
}
m_value = s;
write();
return *this;
}


/**///////////////////////////////////////////////////////////////////////////////////////////////

CRegRect::CRegRect(void)


{
m_value = CRect(0,0,0,0);
m_defaultvalue = CRect(0,0,0,0);
m_key = _T("");
m_base = HKEY_CURRENT_USER;
m_read = FALSE;
m_force = FALSE;
}


/**//**
* Constructor.
* @param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* @param def the default value used when the key does not exist or a read error occured
* @param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* @param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegRect::CRegRect(CString key, CRect def, BOOL force, HKEY base)


{
m_value = CRect(0,0,0,0);
m_defaultvalue = def;
m_force = force;
m_base = base;
m_read = FALSE;
key.TrimLeft(_T("\\"));
m_path = key.Left(key.ReverseFind(_T('\\')));
m_path.TrimRight(_T("\\"));
m_key = key.Right(key.GetLength() - key.ReverseFind(_T('\\')));
m_key.Trim(_T("\\"));
read();
}

CRegRect::~CRegRect(void)


{
//write();
}

CRect CRegRect::read()


{
ASSERT(m_key != _T(""));
if (RegOpenKeyEx(m_base, m_path, 0, KEY_EXECUTE, &m_hKey)==ERROR_SUCCESS)

{
int size = 0;
DWORD type;
RegQueryValueEx(m_hKey, m_key, NULL, &type, NULL, (LPDWORD) &size);
LPRECT pRect = (LPRECT)new char[size];
if (RegQueryValueEx(m_hKey, m_key, NULL, &type, (BYTE*) pRect,(LPDWORD) &size)==ERROR_SUCCESS)

{
m_value = CRect(pRect);
delete [] pRect;
ASSERT(type==REG_BINARY);
m_read = TRUE;
RegCloseKey(m_hKey);
return m_value;
}
else

{
delete [] pRect;
RegCloseKey(m_hKey);
return m_defaultvalue;
}
}
return m_defaultvalue;
}

void CRegRect::write()


{
ASSERT(m_key != _T(""));
DWORD disp;
if (RegCreateKeyEx(m_base, m_path, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &m_hKey, &disp)!=ERROR_SUCCESS)

{
return;
}
if (RegSetValueEx(m_hKey, m_key, 0, REG_BINARY, (BYTE *)(LPRECT)m_value, sizeof(m_value))==ERROR_SUCCESS)

{
m_read = TRUE;
}
RegCloseKey(m_hKey);
}

CRegRect::operator CRect()


{
if ((m_read)&&(!m_force))
return m_value;
else

{
return read();
}
}

CRegRect& CRegRect::operator =(CRect s)


{
if ((s==m_value)&&(!m_force))

{
//no write to the registry required, its the same value
return *this;
}
m_value = s;
write();
return *this;
}


/**///////////////////////////////////////////////////////////////////////////////////////////////

CRegPoint::CRegPoint(void)


{
m_value = CPoint(0,0);
m_defaultvalue = CPoint(0,0);
m_key = "";
m_base = HKEY_CURRENT_USER;
m_read = FALSE;
m_force = FALSE;
}


/**//**
* Constructor.
* @param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* @param def the default value used when the key does not exist or a read error occured
* @param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* @param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegPoint::CRegPoint(CString key, CPoint def, BOOL force, HKEY base)


{
m_value = CPoint(0,0);
m_defaultvalue = def;
m_force = force;
m_base = base;
m_read = FALSE;
key.TrimLeft(_T("\\"));
m_path = key.Left(key.ReverseFind(_T('\\')));
m_path.TrimRight(_T("\\"));
m_key = key.Right(key.GetLength() - key.ReverseFind(_T('\\')));
m_key.Trim(_T("\\"));
read();
}

CRegPoint::~CRegPoint(void)


{
//write();
}

CPoint CRegPoint::read()


{
ASSERT(m_key != _T(""));
if (RegOpenKeyEx(m_base, m_path, 0, KEY_EXECUTE, &m_hKey)==ERROR_SUCCESS)

{
int size = 0;
DWORD type;
RegQueryValueEx(m_hKey, m_key, NULL, &type, NULL, (LPDWORD) &size);
POINT* pPoint = (POINT *)new char[size];
if (RegQueryValueEx(m_hKey, m_key, NULL, &type, (BYTE*) pPoint,(LPDWORD) &size)==ERROR_SUCCESS)

{
m_value = CPoint(*pPoint);
delete [] pPoint;
ASSERT(type==REG_BINARY);
m_read = TRUE;
RegCloseKey(m_hKey);
return m_value;
}
else

{
delete [] pPoint;
RegCloseKey(m_hKey);
return m_defaultvalue;
}
}
return m_defaultvalue;
}

void CRegPoint::write()


{
ASSERT(m_key != _T(""));
DWORD disp;
if (RegCreateKeyEx(m_base, m_path, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &m_hKey, &disp)!=ERROR_SUCCESS)

{
return;
}
if (RegSetValueEx(m_hKey, m_key, 0, REG_BINARY, (BYTE *)(POINT *)&m_value, sizeof(m_value))==ERROR_SUCCESS)

{
m_read = TRUE;
}
RegCloseKey(m_hKey);
}

CRegPoint::operator CPoint()


{
if ((m_read)&&(!m_force))
return m_value;
else

{
return read();
}
}

CRegPoint& CRegPoint::operator =(CPoint s)


{
if ((s==m_value)&&(!m_force))

{
//no write to the registry required, its the same value
return *this;
}
m_value = s;
write();
return *this;
}

#endif


/**//////////////////////////////////////////////////////////////////////

CRegStdString::CRegStdString(void)


{
m_value = _T("");
m_defaultvalue = _T("");
m_key = _T("");
m_base = HKEY_CURRENT_USER;
m_read = FALSE;
m_force = FALSE;
}


/**//**
* Constructor.
* @param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* @param def the default value used when the key does not exist or a read error occured
* @param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* @param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegStdString::CRegStdString(stdstring key, stdstring def, BOOL force, HKEY base)


{
m_value = _T("");
m_defaultvalue = def;
m_force = force;
m_base = base;
m_read = FALSE;

stdstring::size_type pos = key.find_last_of(_T('\\'));
m_path = key.substr(0, pos);
m_key = key.substr(pos + 1);
read();
}

CRegStdString::~CRegStdString(void)


{
//write();
}

stdstring CRegStdString::read()


{
if (RegOpenKeyEx(m_base, m_path.c_str(), 0, KEY_EXECUTE, &m_hKey)==ERROR_SUCCESS)

{
int size = 0;
DWORD type;
RegQueryValueEx(m_hKey, m_key.c_str(), NULL, &type, NULL, (LPDWORD) &size);
TCHAR* pStr = new TCHAR[size];
if (RegQueryValueEx(m_hKey, m_key.c_str(), NULL, &type, (BYTE*) pStr,(LPDWORD) &size)==ERROR_SUCCESS)

{
m_value.assign(pStr);
delete [] pStr;
m_read = TRUE;
RegCloseKey(m_hKey);
return m_value;
}
else

{
delete [] pStr;
RegCloseKey(m_hKey);
return m_defaultvalue;
}
}
return m_defaultvalue;
}

void CRegStdString::write()


{
DWORD disp;
if (RegCreateKeyEx(m_base, m_path.c_str(), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &m_hKey, &disp)!=ERROR_SUCCESS)

{
return;
}
if (RegSetValueEx(m_hKey, m_key.c_str(), 0, REG_SZ, (BYTE *)m_value.c_str(), (DWORD)m_value.size()+1)==ERROR_SUCCESS)

{
m_read = TRUE;
}
RegCloseKey(m_hKey);
}

CRegStdString::operator LPCTSTR()


{
if ((m_read)&&(!m_force))
return m_value.c_str();
else
return read().c_str();
}

CRegStdString::operator stdstring()


{
if ((m_read)&&(!m_force))
return m_value;
else

{
return read();
}
}

CRegStdString& CRegStdString::operator =(stdstring s)


{
if ((s==m_value)&&(!m_force))

{
//no write to the registry required, its the same value
return *this;
}
m_value = s;
write();
return *this;
}


/**//////////////////////////////////////////////////////////////////////

CRegStdWORD::CRegStdWORD(void)


{
m_value = 0;
m_defaultvalue = 0;
m_key = _T("");
m_base = HKEY_CURRENT_USER;
m_read = FALSE;
m_force = FALSE;
}


/**//**
* Constructor.
* @param key the path to the key, including the key. example: "Software\\Company\\SubKey\\MyValue"
* @param def the default value used when the key does not exist or a read error occured
* @param force set to TRUE if no cache should be used, i.e. always read and write directly from/to registry
* @param base a predefined base key like HKEY_LOCAL_MACHINE. see the SDK documentation for more information.
*/
CRegStdWORD::CRegStdWORD(stdstring key, DWORD def, BOOL force, HKEY base)


{
m_value = 0;
m_defaultvalue = def;
m_force = force;
m_base = base;
m_read = FALSE;

stdstring::size_type pos = key.find_last_of(_T('\\'));
m_path = key.substr(0, pos);
m_key = key.substr(pos + 1);
read();
}

CRegStdWORD::~CRegStdWORD(void)


{
//write();
}

DWORD CRegStdWORD::read()


{
if (RegOpenKeyEx(m_base, m_path.c_str(), 0, KEY_EXECUTE, &m_hKey)==ERROR_SUCCESS)

{
int size = sizeof(m_value);
DWORD type;
if (RegQueryValueEx(m_hKey, m_key.c_str(), NULL, &type, (BYTE*) &m_value,(LPDWORD) &size)==ERROR_SUCCESS)

{
m_read = TRUE;
RegCloseKey(m_hKey);
return m_value;
}
else

{
RegCloseKey(m_hKey);
return m_defaultvalue;
}
}
return m_defaultvalue;
}

void CRegStdWORD::write()


{
DWORD disp;
if (RegCreateKeyEx(m_base, m_path.c_str(), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &m_hKey, &disp)!=ERROR_SUCCESS)

{
return;
}
if (RegSetValueEx(m_hKey, m_key.c_str(), 0, REG_DWORD,(const BYTE*) &m_value, sizeof(m_value))==ERROR_SUCCESS)

{
m_read = TRUE;
}
RegCloseKey(m_hKey);
}

CRegStdWORD::operator DWORD()


{
if ((m_read)&&(!m_force))
return m_value;
else

{
return read();
}
}


【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2007-07-06 SWT Designer 6.0安装小记