📄 registry.cpp
字号:
/*// --- FILE INFORMATION -----------------------------
CRegistry.cpp
Classes: CRegEntry and CRegistry
Author: Stuart Konen
Email: skonen@gmail.com
Date: 12/1/2004 (MM/DD/YYYY)
Version: 1.00
(-!-) If you're going to use these classes please do not
remove these comments... To use these classes, simply #include
Registry.h . In MFC you should also turn off precompiled headers
for this file, in VC++ this can be done by navigating to:
Project->Settings->Project Name->CRegistry.cpp->C/C++->Precompiled Headers
*///----------------------------------------------------
#include "Registry.h"
#pragma warning (disable : 4706)
/* ===================================================
* CONSTRUCTOR
* =================================================*/
CRegEntry::CRegEntry(CRegistry *Owner) {
assert(Owner);
InitData(Owner);
}
/* ===================================================
* CRegEntry::InitData(CRegistry *Owner)
*
* Initializes the entries default values and sets the entries
* owner (CRegistry). This is only called during construction.
*/
void CRegEntry::InitData(CRegistry *Owner) {
dwDWORD = iType = 0;
lpszName = lpszStr = NULL;
__bStored = false;
__bConvertable = true;
__cregOwner = Owner;
}
/* ===================================================
* CRegEntry::ForceStr()
*
* Forces the memory allocation for the entry's string value, if it
* has not already been allocated.
*/
void CRegEntry::ForceStr() {
if (lpszStr == NULL) { lpszStr = new _TCHAR[_MAX_REG_VALUE]; lpszStr[0] = 0; }
}
/* ===================================================
* CRegEntry::operator=(LPCTSTR lpszValue)
*
* OPERATOR: Assigns a const character array to the open
* registry value. The registry value type will be REG_SZ.
*/
CRegEntry& CRegEntry::operator=(LPCTSTR lpszValue) {
size_t nValueLen = (_tcslen(lpszValue) + 1)*sizeof(TCHAR);
assert(nValueLen <= _MAX_REG_VALUE);
ForceStr(); iType = REG_SZ;
_tcsncpy(lpszStr, lpszValue, nValueLen > _MAX_REG_VALUE ? _MAX_REG_VALUE : nValueLen);
REGENTRY_ALLOWCONV(true)
if (REGENTRY_NOTLOADING && REGENTRY_KEYVALID( KEY_SET_VALUE ))
RegSetValueEx(__cregOwner->hKey, lpszName, NULL, REG_SZ, (LPBYTE)lpszValue, nValueLen);
REGENTRY_TRYCLOSE;
__bStored = true;
return *this;
}
/* ===================================================
* CRegEntry::operator=(LPDWORD lpdwValue)
*
* OPERATOR: Assigns a DWORD to the open registry value.
* The registry value type will be REG_DWORD.
*/
CRegEntry& CRegEntry::operator=(LPDWORD lpdwValue) {
iType = REG_DWORD;
memcpy(&dwDWORD, lpdwValue, sizeof( DWORD ));
REGENTRY_ALLOWCONV(true)
if (REGENTRY_NOTLOADING && REGENTRY_KEYVALID( KEY_SET_VALUE ))
RegSetValueEx(__cregOwner->hKey, lpszName, NULL, REG_DWORD, (LPBYTE)&dwDWORD, sizeof( DWORD ));
REGENTRY_TRYCLOSE;
__bStored = true;
return *this;
}
/* ===================================================
* CRegEntry::operator=(CRegEntry& cregValue)
*
* OPERATOR: Copys value information from the specified
* registry entry (CRegEntry) into this entry.
*/
CRegEntry& CRegEntry::operator=(CRegEntry& cregValue) {
if (this == &cregValue)
return *this;
if (lpszName == NULL) {
size_t nNameLen = _tcslen(cregValue.lpszName) + 1;
lpszName = new _TCHAR[nNameLen]; _tcsncpy(lpszName, cregValue.lpszName, nNameLen);
}
switch ((iType = cregValue.iType)) {
case REG_SZ:
return (*this = (ForceStr(), cregValue.lpszStr));
break;
case REG_MULTI_SZ: {
LPTSTR lpszBuf = new _TCHAR[_MAX_REG_VALUE];
SetMulti(cregValue.GetMulti(lpszBuf), cregValue.MultiLength());
delete [] lpszBuf; return *this;
}
break;
case REG_BINARY: {
size_t n = cregValue.vBytes.size(); LPBYTE buf = new BYTE[n];
cregValue.GetBinary(buf, n); SetBinary(buf, n);
delete [] buf; return *this;
}
break;
default:
return (*this = cregValue.dwDWORD);
}
}
/* ===================================================
* CRegEntry::operator LPTSTR()
*
* OPERATOR: Converts (if required) and returns the open registry
* value as a null terminated string.
*/
CRegEntry::operator LPTSTR() {
/* If caching is disabled, refresh the entries */
REGENTRY_REFRESH_IF_NOCACHE
assert(__bConvertable); // Check for conversion implementation
ForceStr();
switch (iType) {
case REG_DWORD:
_stprintf(lpszStr, _T("%lu"), dwDWORD);
break;
case REG_MULTI_SZ:
GetMulti(lpszStr);
break;
case REG_BINARY: {
_tcsncpy(lpszStr, (const _TCHAR*)&vBytes[0], vBytes.size());
lpszStr[vBytes.size()] = 0;
}
break;
}
return lpszStr;
}
/* ===================================================
* CRegEntry::operator DWORD()
*
* OPERATOR: Converts (if required) and returns the open registry
* value as an unsigned 32-bit integer (unsigned long).
*/
CRegEntry::operator DWORD() {
/* If caching is disabled, refresh the entries */
REGENTRY_REFRESH_IF_NOCACHE
assert(__bConvertable); // Check for conversion implementation
REGENTRY_BINARYTOSTRING
return (REGENTRY_SZ_SAFE ? _tcstoul(lpszStr, NULL, NULL) : dwDWORD);
}
/* ===================================================
* CRegEntry::GetBinary(LPBYTE lpbValue, size_t nLen)
*
* Sets the registry value to a binary value (REG_BINARY)
*
* Important Params:
*
* LPBYTE lpbDest: Pointer to the byte array to store *
* size_t nLen: Elements contained within the byte array.
*/
void CRegEntry::SetBinary(LPBYTE lpbValue, size_t nLen) {
if (!nLen) { assert(nLen); return; }
iType = REG_BINARY;
if (REGENTRY_NOTLOADING && REGENTRY_KEYVALID ( KEY_SET_VALUE ) )
RegSetValueEx(__cregOwner->hKey, lpszName, NULL, REG_BINARY, lpbValue, nLen);
REGENTRY_TRYCLOSE;
__bStored = true;
if (vBytes.size() < nLen) vBytes.reserve(nLen);
vBytes.clear();
do { vBytes.push_back(lpbValue[vBytes.size()]); }
while (vBytes.size() < nLen);
}
/* ===================================================
* CRegEntry::GetBinary(LPBYTE lpbDest, size_t nMaxLen)
*
* Gets the binary value of a value stored as REG_BINARY
*
* Important Params:
*
* LPBYTE lpbDest: Pointer to the byte array to fill
* size_t nMaxLen: The maximum bytes to copy to lpbDest
*
* Notes: This will only work for values that were saved
* using the binary registry type specification (REG_BINARY)
*/
void CRegEntry::GetBinary(LPBYTE lpbDest, size_t nMaxLen) {
assert(IsBinary()); // Must be stored as Binary
REGENTRY_REFRESH_IF_NOCACHE
if ((size_t)(&vBytes.back() - &vBytes.at(0)+1) == vBytes.size()*sizeof(BYTE))
memcpy(lpbDest, (LPBYTE)&vBytes.at(0), vBytes.size() > nMaxLen ? nMaxLen : vBytes.size());
else
for (size_t n=0; n < vBytes.size() && n < nMaxLen; n++)
lpbDest[n] = vBytes[n];
}
/* ===================================================
* CRegEntry::GetBinaryLength()
*
* Returns the size of the binary value in bytes.
*/
size_t CRegEntry::GetBinaryLength() {
assert(IsBinary());
REGENTRY_REFRESH_IF_NOCACHE
return vBytes.size();
}
/* ===================================================
* CRegEntry::SetMulti(LPCTSTR lpszValue, size_t nLen, bool bInternal)
*
* Stores an array of null-terminated string, terminated by two null characters.
* For Example: First String\0Second\Third\0\0
*
* Important Params:
*
* LPCTSTR lpszValue: The string consisting of the null-terminated string array
* size_t nLen: The number of characters in the string, including null characters
*
* Note: For inserting individual null-terminated strings into the array,
* use MultiAdd or MultiSetAt.
*/
void CRegEntry::SetMulti(LPCTSTR lpszValue, size_t nLen, bool bInternal) {
size_t nCur = 0, nPrev = 0, nShortLen = nLen;
/* When this is internal, there is no need to repopulate the vector. */
if (bInternal) goto SkipNoInternal;
iType = REG_MULTI_SZ; vMultiString.clear();
if (nLen <= 2) goto SkipNoInternal; // The string is empty : \0\0
if (*(lpszValue + nShortLen-1) == '\0')
nShortLen--;
/* Populate a vector with each string part for easy and quick access */
while ((nCur = (int)(_tcschr(lpszValue+nPrev, '\0')-lpszValue)) < nShortLen) {
vMultiString.push_back(lpszValue+nPrev);
nPrev = nCur+1;
}
SkipNoInternal:
if (REGENTRY_NOTLOADING && REGENTRY_KEYVALID ( KEY_SET_VALUE ) )
RegSetValueEx(__cregOwner->hKey, lpszName, NULL, REG_MULTI_SZ, (LPBYTE)lpszValue, nLen*sizeof(TCHAR));
REGENTRY_TRYCLOSE;
__bStored = true;
}
/* ===================================================
* CRegEntry::MultiLength(bool bInternal = false)
*
* Returns the number of characters (including null) stored
* in the full string. Don't confuse this with MultiCount()
* which returns the number of strings stored in the array.
*/
size_t CRegEntry::MultiLength(bool bInternal /*false*/) {
//Ensure correct values with no cache
if (!bInternal) REGENTRY_REFRESH_IF_NOCACHE
for (size_t nLen = 0, nIndex = 0; nIndex < vMultiString.size(); nIndex++)
nLen += vMultiString[nIndex].length() + 1;
return nLen ? nLen+1 : 0;
}
/* ===================================================
* CRegEntry::MultiCount()
*
* Returns the number of strings located within the array.
*/
size_t CRegEntry::MultiCount() {
// Ensure correct values with no cache
REGENTRY_REFRESH_IF_NOCACHE
return vMultiString.size();
}
/* ===================================================
* CRegEntry::MultiRemoveAt(size_t nIndex)
*
* Simply removes the string stored at the zero-based index of nIndex
*/
void CRegEntry::MultiRemoveAt(size_t nIndex) {
// Ensure correct values with no cache
REGENTRY_REFRESH_IF_NOCACHE
assert(nIndex < vMultiString.size());
vMultiString.erase(vMultiString.begin()+nIndex);
// Update the registry
REGENTRY_UPDATE_MULTISTRING
}
/* ===================================================
* CRegEntry::MultiSetAt(size_t nIndex, LPCTSTR lpszVal)
*
* Alters the value of a string in the array located at
* the 0 based index of nIndex. The new value is lpszVal.
* The index must be within the bounds of the array, with
* the exception of being == the number of elements in
* which case calling this function is equal to calling
* MultiAdd.
*/
void CRegEntry::MultiSetAt(size_t nIndex, LPCTSTR lpszVal) {
// Ensure correct values with no cache
REGENTRY_REFRESH_IF_NOCACHE
assert(nIndex <= vMultiString.size());
iType = REG_MULTI_SZ;
// Add a new string element if == elements+1
if (nIndex == vMultiString.size())
vMultiString.push_back(lpszVal);
else
vMultiString[nIndex] = lpszVal;
// Update the registry
REGENTRY_UPDATE_MULTISTRING
}
/* ===================================================
* CRegEntry::MultiGetAt(size_t nIndex)
*
* Returns a constant pointer to the string located in
* the array at the zero-based index of nIndex. Note that
* the return value is not an STL string.
*/
LPCTSTR CRegEntry::MultiGetAt(size_t nIndex) {
// Ensure correct values with no cache
REGENTRY_REFRESH_IF_NOCACHE
assert(nIndex < vMultiString.size() && IsMultiString());
return vMultiString[nIndex].c_str();
}
/* ===================================================
* CRegEntry::GetMulti(LPCTSTR lpszDest, size_t nMax)
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -