📄 registryserialize.cpp
字号:
// RegistrySerialize.cpp : implementation file
//
/* This file was written by Amir Israeli , July 2000 Email: israelaq@walla.co.il
No warranty of any kind . Dont remove this header . Thanks.
*/
// RegistrySerialize.cpp : implementation file
//
/* Hello programmer ,
How to use :
First you need a slight understanding how it works : in general it
builds a small 'database' of keys and values where your settings are .
you can use commands to install , uninstall , set the values , load them ...
you can :
1) go directly to the dialog file "PersistDlg.cpp" :
watch 'OnInitDialog' how programmaticly you build a database
watch 'PersistObject(BOOL)' function does the persistence
of information in+out registry.
The whole CRegistrySerialize object is working very similar
to CDocument::Serialize : an internal function gets an archive
with load/store operations , you call operation with
'PersistObject(BOOL)' (TRUE=load)
the persistence : in the main object 'CRegistrySerialize' , the 'keys' array
is scaned in each entry : using the pointer to call the object :
'CSerializedKeyPath' that represents a path of keys . each
of these objects contain an array that holds data about its'
value names and type ... this array ('values') is scanned and
operation is called whether its' Persist (to load/save) or install(un) ...
2) I reccommend to read the object and try all buttons
This class has some extras :
a) it has a function to format a string to
its' components (the oposite of all printf functions :wprintf ,sprintf fprintf ...)
b) An extended memory mapped manager (very simple => 1 function)
(descendant of CMemFile) to load a custom resource (and automaticly release)
and use it . I thought of adding such functions
LoadAniResource(LPCTSTR lpszRes); for any defined type of resource (+- 20 functions)
so you want need to use 'LPCTSTR lpszType' and remember resources
types or aliases such as RT_ANICURSOR , RT_GROUP_CURSOR ...
(When using FindResouce (...LPCTSTR lpszType).
C) an extra object wrapper of API registry function (already presented)
made especially for those who dont want to use the HKEY
registry handle .
All objects use MFC.
(Amir July 2000)
*/
/* UPDATED August 2000
1) in InsertValue you insert the name of the class or type
instead of non standard names (or non consistent)
2) CRegistry now uses references : to those who dont like pointers ...
3) Standard name for all functions of :
SetValue CreateValue
GetValue
All these fuctions are overloaded (9 options),
Theres a direct support for 8 common types
(int , DWORD , CSize = save size of window , CRect = save placement ...)
and another generic : you need to specify size of item.
(for example : to persist double :
double d = 10.99;
Persist( (LPBYTE)&d,sizeof(double))
to insert it into map
InsertValue( _T(" insert here path ...."), _T(" name of value here")
_T("LPBYTE"),TRUE/FALSE)
non standard types are always saved as REG_BINARY ,
standard -> sometimes (string REG_SZ dwords REG_DWORD)
3) Some sent me mail , asking why didn't I use templates ?
well , I could but I prefered to set 9 functions of each
overloaded instead of 30+ , that a user can inject into the code.
(These 9 overloads will do the job of 90% of data persisted ,
and as you see most of the job is done by 1 function (in every set))
Amir Israeli (August 2000)
*/
#include "stdafx.h"
#include "RegistrySerialize.h"
#include "Message.h"
#include "MemFileEx.h" //for usage with loading maps from resources
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CRegistrySerialize
CRegistrySerialize::CRegistrySerialize()
{
keys.SetSize(0,1);
}
CRegistrySerialize::~CRegistrySerialize()
{
Destroy();
}
//whenever a new map is built and should replace the current map in this object
//this function is called and frees the structures
void CRegistrySerialize::Destroy()
{
for (int nCount = keys.GetSize() , i = nCount-1 ; i>=0 ; i--) {
delete keys.GetAt(i);
}
keys.RemoveAll();
}
IMPLEMENT_SERIAL(CRegistrySerialize , CObject , 1)
#ifdef _DEBUG
void CRegistrySerialize::Info(BOOL bShowValuesInfo )
{
int nCount = keys.GetSize();
CString strMessage;
for (int i=0 ; i<nCount ; i++) {
CSerializedKeyPath *pPath = keys.GetAt(i);
if (pPath) {
CString str = pPath->GetPath();
strMessage += str;
strMessage += _T("\n");
}
}
reg.msg( strMessage , _T("Paths ..."));
if (bShowValuesInfo) {
for (i=0 ; i<nCount ; i++) {
CSerializedKeyPath *pPath = keys.GetAt(i);
if (pPath) pPath->Info();
}//end for
}
}
#endif
//function to format a string buffer to its basic elements :
//int's DWORD'S strings etc
BOOL CRegistrySerialize::FormatElement(LPCTSTR lpszBuffer,int iPosition , LPCTSTR lpszFormatSpecifier , LPVOID lpData)
{
return CMessage::FormatElement( lpszBuffer, iPosition, lpszFormatSpecifier, lpData);
}
BOOL CRegistrySerialize::FormatElements( LPCTSTR lpszBuffer, LPCTSTR lpszFormatSpecifier,
LPVOID lpData1, LPVOID lpData2, LPVOID lpData3, LPVOID lpData4, LPVOID lpData5,
LPVOID lpData6, LPVOID lpData7, LPVOID lpData8, LPVOID lpData9, LPVOID lpData10)
{
return CMessage::FormatElements( lpszBuffer, lpszFormatSpecifier,
lpData1, lpData2, lpData3, lpData4, lpData5,
lpData6, lpData7, lpData8, lpData9, lpData10);
}
////////// Function to get object in index
CSerializedValue* CRegistrySerialize::GetValueObject(LPCTSTR lpszValueName) {
int nIndex = SearchPath(strLastInsertedPath);
if (nIndex == -1) return NULL;
CSerializedKeyPath *pPath = keys.GetAt(nIndex);
nIndex = pPath->Search4Value(lpszValueName);
if (nIndex == -1)
return FALSE;
return pPath->GetValueObject(nIndex);
}
//during loading or saving
BOOL CRegistrySerialize::Path( LPCTSTR lpszRegistryPath) {
strLastInsertedPath = lpszRegistryPath;
return TRUE;
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, CString *pstrDest, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( pstrDest,bLoading);
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, DWORD *dwDest, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( dwDest, bLoading);
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, int *iDest, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( iDest, bLoading);
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, float *pfDest, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( pfDest, bLoading);
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, CRect *pRect, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( pRect, bLoading);
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, CPoint *pPoint, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( pPoint,bLoading);
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, CSize *pSize, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( pSize,bLoading);
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, CTime *ptDest, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( ptDest, bLoading);
}
BOOL CRegistrySerialize::Value( LPCTSTR lpszValueName, LPBYTE *lpByte,DWORD cbBuffLen, BOOL bLoading ) {
CSerializedValue *pValue = GetValueObject(lpszValueName);
if (!pValue) return FALSE;
return pValue->Persist( lpByte, cbBuffLen ,bLoading);
}
//////////////////
BOOL CRegistrySerialize::InsertCSerializedKeyPath(CSerializedKeyPath *pNewPath)
{
CString path = pNewPath->GetPath();
int nIndex = SearchPath( path);
if (nIndex == -1) {
keys.Add(pNewPath);
return TRUE;
}
return FALSE;
}
//Loading maps from resources
BOOL CRegistrySerialize::LoadFromResource(UINT uResourceID, LPCTSTR lpszResourceType)
{
return LoadFromResource(MAKEINTRESOURCE(uResourceID) , lpszResourceType);
}
BOOL CRegistrySerialize::LoadFromResource(LPCTSTR lpszResourceName, LPCTSTR lpszResourceType)
{
CMemFileEx f;
if (!f.LoadResource(lpszResourceName, lpszResourceType))
return FALSE;
CFileException e;
try {
CArchive ar( &f, CArchive::load);
InternalSerialize(ar);
return TRUE;
}
catch (CArchiveException *ae) {
ae->ReportError();
ae->Delete();
}
return FALSE;
}
void CRegistrySerialize::Serialize(LPCTSTR lpszFileName , BOOL bLoading )
{
ASSERT(lpszFileName!=NULL);//must be a valid file name
CFile f;
CFileException e;
UINT uFlags = (bLoading) ? (CFile::modeRead) : (CFile::modeCreate|CFile::modeWrite) ;
if (f.Open( lpszFileName , uFlags , &e)) {
UINT uArFlags = (bLoading) ? (CArchive::load) : (CArchive::store) ;
try {
CArchive ar( &f, uArFlags);
InternalSerialize(ar);
}
catch (CArchiveException *ae) {
ae->ReportError();
ae->Delete();
}
}
}
void CRegistrySerialize::Serialize(CArchive &ar)
{
InternalSerialize(ar);
}
void CRegistrySerialize::InternalSerialize(CArchive &ar)
{
int nCount;
if (ar.IsLoading()) { //loading
Destroy();//if already contains a map delete it
ar>>nCount;
for (int i=0 ; i<nCount ; i++) {
CSerializedKeyPath *pPath = new CSerializedKeyPath (®);
if (pPath) {
pPath->Serialize(ar);
if (!InsertCSerializedKeyPath(pPath))
delete pPath;
}
} // end for
}
else { //storing
nCount = keys.GetSize();
ar<<nCount;
for (int i=0 ; i<nCount ; i++) {
CSerializedKeyPath *pPath = keys.GetAt(i);
if (pPath) pPath->Serialize(ar);
}
}
}
//// function to build the map
BOOL CRegistrySerialize::InsertPath( LPCTSTR lpszRegistryPath , BOOL bDelete)
{
CString path = lpszRegistryPath;
reg.GetPathObj().Trim(path);
if (SearchPath( path) != -1) //already got key
return TRUE;
strLastInsertedPath = path; //saving the last path
CSerializedKeyPath *pPath = new CSerializedKeyPath;
if (!pPath) return FALSE;
pPath->SetPath( path);
pPath->SetDelete(bDelete);
pPath->SetRegistryObject(®);
keys.Add( pPath);
return TRUE;
}
BOOL CRegistrySerialize::InsertValue( LPCTSTR lpszRegistryPath,
LPCTSTR lpszValueName ,REGDATA iDataType, BOOL bDeleteOnUnInstall)
{
CString path = (!lpszRegistryPath) ?
(strLastInsertedPath) : lpszRegistryPath;
if (path.IsEmpty())
return FALSE; //empty
if (!InsertPath( path)) return FALSE;
int nIndex = SearchPath( path);
if (nIndex == -1) //still not exist (serious failure)
return FALSE;
CSerializedKeyPath *pPath = keys.GetAt(nIndex);
if (pPath) {
return pPath->InsertValue( lpszValueName,
iDataType , bDeleteOnUnInstall);
}
return FALSE;
}
BOOL CRegistrySerialize::InsertValue( LPCTSTR lpszRegistryPath, LPCTSTR lpszValueName,
LPCTSTR lpszDataType ,BOOL bDeleteOnUnInstall)
{
REGDATA iDataType = REGEMPTY;
if (!::lstrcmp(lpszDataType,_T("CString"))) iDataType = REGSTRING;
if (!::lstrcmp(lpszDataType,_T("DWORD"))) iDataType = REGDWORD;
if (!::lstrcmp(lpszDataType,_T("int"))) iDataType = REGINT;
if (!::lstrcmp(lpszDataType,_T("float"))) iDataType = REGFLOAT;
if (!::lstrcmp(lpszDataType,_T("CPoint"))) iDataType = REGPOINT;
if (!::lstrcmp(lpszDataType,_T("CRect"))) iDataType = REGRECT;
if (!::lstrcmp(lpszDataType,_T("CSize"))) iDataType = REGSIZE;
if (!::lstrcmp(lpszDataType,_T("CTime"))) iDataType = REGTIME;
if (!::lstrcmp(lpszDataType,_T("LPBYTE"))) iDataType = REGPBYTE;
if (iDataType==REGEMPTY) {
CString strErr;
strErr.Format("Empty Value line=%u",__LINE__);
reg.msg( strErr);
}
return InsertValue( lpszRegistryPath, lpszValueName, iDataType,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -