⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 registry.cpp

📁 一个操作注册表的类的应用
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*// --- 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 + -