Click here to Skip to main content
Click here to Skip to main content

Stream like operations for the registry

, 24 Jan 2001
Rate this:
Please Sign up or sign in to vote.
Use the operators >> and to extract/insert registry entries.
<!-- Download Links -->
  • Download source files - 8 Kb
  • Download demo project - 11 Kb
  • Introduction

    cout <<  "Birthday: " << dt << "; Height: " <<  d; 
    

    is better than the equivalent printf statement. It is easier to remember than the printf format specifiers, less error prone and the operators << and >> can be used for different streams ( cout,files,CArchive). This article presents stream operations for the registry. The above example would be written to the registry by:

    regStream << RegVal("Birthday",dt) << RegVal("Height",d);
    

    All arithmetic data types and the MFC value types CPoint, CSize, CRect, CSize, COleDateTime and CFont are supported. This article merely presents a new interface to an already existing CRegistry class by Robert Pittenger, which can be found on this site.

    Two stream variants are supported. CRegStream<CRegBaseHumanReadable> stores all registry entries as human readable strings. The second stream variant supported is CRegStream<CRegBaseGeneral>. It uses all the registry datatypes that are also used by Robert Pittenger's class. The first interface is mainly intended for the application settings in which users of your software prefer readable registry entries over encoded ones.

    Interface

    Registry entries are Name/Value pairs. Each operand of an inserter or extractor >> must be a Name/Value pair. The function RegVar(LPCTSTR lpszEntry,T& t,const T& defaultVal= T()) returns a Name/Value pair as an operand of >>, whereas RegVal(LPCTSTR lpszEntry,const T& t) returns a Name/Value pair which is suitable for the operand . The macros RVAR and RVAL allow you to leave out the lpszEntry parameter. This is because the Name is constructed from the C++ variable name supplied to the macro.

    /* functions which construct Name/Value pairs for the  and >> operators */
    template<class T>
    RegVariable<T> RegVar(LPCTSTR lpszEntry,T& t,const T& defaultVal= T())
    {   return RegVariable<T>(lpszEntry,t,defaultVal);}
    
    template<class T>
    RegValue<T> RegVal(LPCTSTR lpszEntry,const T& t)
    {   return RegValue<T>(lpszEntry,t); }
    
    /* Macros, which construct an lpszEntry from the C++ variable name */
    #define RVAL(v)         RegVal(RegTrim(#v),v)
    #define RVAR(v)         RegVar(RegTrim(#v),v)
    #define RVAR1(v)        RegVar(RegTrim(#v),v,defaultVal)
    
    template<class CRegBase>
    class CRegStream   : public CRegBase
    {
    public:
    	CRegStream(HKEY hKey=0):m_bSuccess(true)
    	{ if( hKey!=0 ){ SetRootKey(hKey);}}
    
    	bool    Success() //indicates whether last operation was successful
    	{   return m_bSuccess;}
    
    	//  and >> operator functions 
    	//....
    };
    class CRegBaseGeneral : public CRegistry
    {	
    	// directly interfacing to Robert Pittenger's <code>CRegistry</code> class.
    	// ...
    };
    class CRegBaseHumanReadable : public CRegistry
    {
    	// this class writes human readable strings into the registry. e.g. "{3,5}" for a point.
    	// ....
    };
    

    Example Usage

    In the following example, human readable register entries are written to the HKEY_CURRENT_USER registry part and encoded register entries are written to the HKEY_LOCAL_MACHINE registry part. Afterwards the entries are read from both parts and checked for equality.

    int main(int argc,TCHAR* argv[])
    {
        float           fFloatEps= FLT_EPSILON;             CString strTitle=  "Sir";
        COleDateTime    dtBirthday(1970,10,10,10,15,30);    CPoint pt;
        BOOL bOk;
        CRegStream<CRegBaseHumanReadable> reg_user(HKEY_CURRENT_USER);
        if( bOk=reg_user.SetKey("Software\\RegStreamDemo\\Settings",TRUE) ){
            reg_user    << RVAL(fFloatEps)  <<  RVAL(strTitle)  <<  RVAL(dtBirthday) 
                        << RegVal(_T("$-Point"),CPoint(3,5));
        }
        CRegStream<CRegBaseGeneral> reg_machine(HKEY_LOCAL_MACHINE);
        if( bOk&& (bOk=reg_machine.SetKey("Software\\RegStreamDemo\\Settings",TRUE)) ){
            reg_machine <<  RVAL(fFloatEps) <<  RVAL(strTitle)  <<  RVAL(dtBirthday)
                        <<  RegVal(_T("$-Point"),CPoint(3,5));
        }
        if( bOk ){
            reg_user    >>  RVAR(fFloatEps) >>  RVAR(strTitle)  >> RVAR(dtBirthday)
                        >>  RegVar(_T("$-Point"),pt);
            float floatEps1; CString strTitle1; CPoint pt1;
            reg_machine >>  RegVar(_T("FloatEps"),floatEps1)    >>  RegVar(_T("Title"),strTitle1)
                        >>  RegVar(_T("$-Point"),pt1);
            ASSERT(fFloatEps==floatEps1 && strTitle==strTitle1 && pt==pt1);
        }
    }
    

    Implementation Details

    The implementation resides entirely in the header file "RegStream.h". It consists of template types and functions. It's the first time that I used member template functions. They helped a lot in reducing the coding task. The resulting code is remarkably uniform, easy to understand and read.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    Share

    About the Author

    Martin Holzherr

    Switzerland Switzerland
    No Biography provided

    Comments and Discussions

     
    -- There are no messages in this forum --
    | Advertise | Privacy | Mobile
    Web03 | 2.8.141015.1 | Last Updated 25 Jan 2001
    Article Copyright 2001 by Martin Holzherr
    Everything else Copyright © CodeProject, 1999-2014
    Terms of Service
    Layout: fixed | fluid