Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

CPJRegistry 2.0

0.00/5 (No votes)
30 Nov 2001 1  
Registry access to HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER

Details

There are a number of classes for working with the Windows Registry on The Code Project site, including:

All of these are helpful in one way or another, but using the Registry was still more work than it should be. To remedy this, I've come up with CPJRegistry, which makes it much easier to save your MFC application settings.

Examples

Example 1: Load from the Registry

   CPJRegistry  Reg((CWinApp*)this, TRUE);
   Reg.Section("Settings");
   Reg.Profile("StartDate", m_StartDate);
   Reg.Profile("UserName",  m_strUserName);

Example 2: Save to the Registry

   CPJRegistry  Reg((CWinApp*)this, FALSE);
   Reg.Section("Settings");
   Reg.Profile("StartDate", m_StartDate);
   Reg.Profile("UserName",  m_strUserName);

Example 3: Load and save to the Registry

int CMyApp::GetPutRegistryData(BOOL bIsGet) 
{
   CPJRegistry  Reg((CWinApp*)this, bIsGet);
   Reg.Section("Settings");
   Reg.Profile("StartDate", m_StartDate);
   Reg.Profile("UserName",  m_strUserName);
   return 0;
}

Example 4: Load and save to the Registry, using the HKEY_LOCAL_MACHINE base key

int CMyApp::GetPutRegistryData(BOOL bIsGet) 
{
   CPJRegistry  Reg((CWinApp*)this, bIsGet);
   Reg.SetRoot(HKEY_LOCAL_MACHINE);
   Reg.Section("Settings");
   Reg.Profile("StartDate", m_StartDate);
   Reg.Profile("UserName",  m_strUserName);
   return 0;
}

The final two examples show that separate code for loading and saving to the Registry isn't required. The following comments from the class header file describe and demonstrate how this class fits into a typical MFC application:

/*
Class:    CPJRegistry
Author:   Peter M. Jones
Email:    jonespm@home.com
Version:  2.0
Created:  May  7, 2001
Description:
  A class to simplify loading/saving data to the registry.
  Data is written to the registry in human readable form.
  A single call, eg: Reg.Profile("UserName", m_strUserName); 
  handles  both loading and saving of data to the registry.
  The class can use either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER
  as a base key.
  Binary data is supported with the final "Profile" (LPBYTE) call.
  "Profile" is overloaded to handle most data types including:
    bool, WORD, int, long, unsigned long, double,
    CSize, CPoint, CRect, COleDateTime, CString.
Modified: May 15, 2001
Changes: Re-written so class no longer uses CWinApp::WriteProfile...,
   now calls RegSetValueEx, etc.  This allows the class to
   select HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER base keys
   through the new call "RootKey".  Default is the same as
   MFC, HKEY_CURRENT_USER.  ASSERTS are now used.

Example use:
*/

// File MyApp.cpp


CMyApp::CMyApp()
{
  // initialize globals

  m_nUseCount    = 0;
  m_bMadeSummary = FALSE;
  m_strUserName  = "";
  m_StartDate    = GetCurrentTime();
  m_LastUsed     = GetCurrentTime();
  m_rcMainWindow = CRect(50, 50, 650, 450);
  ...
}

#include "PJRegistry.h"


#define GET_REGISTRY TRUE
#define PUT_REGISTRY FALSE

// Get or put our global variables from the registry


int CMyApp::GetPutRegistryData(BOOL  bIsGet) 
{
  CPJRegistry  Reg((CWinApp*)this, bIsGet);

  Reg.RootKey(HKEY_LOCAL_MACHINE);
  Reg.Section("Settings");
  Reg.Profile("UseCount",    m_nUseCount);
  Reg.Profile("MadeSummary", m_bMadeSummary);

  Reg.RootKey(HKEY_CURRENT_USER);
  Reg.Section("Settings");
  Reg.Profile("UserName",    m_strUserName);
  Reg.Profile("StartDate",   m_StartDate);
  Reg.Profile("LastUsed",    m_LastUsed);

  Reg.Section("MainWindow");
  Reg.Profile("Position",     m_rcMainWindow);

  if (bIsGet)
  {
    // Nothing is guaranteed, so correct illegal values

    // and check any relationships between variables, eg:

    if (m_LastUsed < m_StartDate)
      m_StartDate = m_LastUsed;  
  }
  return 0;
}

BOOL CMyApp::InitInstance()
{
  ...
  LoadStdProfileSettings();  // Load standard INI file options 

                             // (including MRU)


  // Load application registry settings

  GetPutRegistryData(GET_REGISTRY);
  ...
}

int CMyApp::ExitInstance() 
{
  GetPutRegistryData(PUT_REGISTRY);
  return CWinApp::ExitInstance();
}

On to the CPJRegistry class definition.

class CPJRegistry  
{
public:
  CPJRegistry(CWinApp*  pApp, BOOL  bIsGet);
  virtual ~CPJRegistry();

  BOOL RootKey(HKEY hRootKey); // select HKEY_CURRENT_USER or 

                              // HKEY_LOCAL_MACHINE

  void Section(CString strSection); // application section, eg: "Settings"


  // note: Visual C++ defines BOOL as an int, unsigned long as DWORD

  // The following reads/writes to registry according to bIsGet

  // Each call returns RegSetValueEx or RegQueryValueEx results.

  // ERROR_SUCCESS means everything worked.

  // ERROR_FILE_NOT_FOUND during a get means the key couldn't be found,

  // this is expected on the initial run of the program.

  long Profile(LPCTSTR lpszEntry, int& nValue);
  long Profile(LPCTSTR lpszEntry, WORD& nValue);
  long Profile(LPCTSTR lpszEntry, DWORD& dwValue);
  long Profile(LPCTSTR lpszEntry, long& lValue);
  long Profile(LPCTSTR lpszEntry, double& dValue);
  long Profile(LPCTSTR lpszEntry, CString& strValue);
  long Profile(LPCTSTR lpszEntry, CPoint& PointValue);
  long Profile(LPCTSTR lpszEntry, CSize& Size);
  long Profile(LPCTSTR lpszEntry, COleDateTime& DateTime);
  long Profile(LPCTSTR lpszEntry, CRect& rcValue);
  long Profile(LPCTSTR lpszEntry, LPBYTE pData, UINT& nBytes);
  
private:
  CWinApp*  m_pApp;      // to retrieve company and application name

  BOOL    m_bGet;      // get or put?

  CString    m_strSection;    // application section name, eg: "Settings"

  HKEY    m_hRootKey;    // HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER

  HKEY    m_hAppKey;    // key for application under RootKey

  HKEY    m_hSectionKey;    // key for section key under application

  BOOL    m_bDirty;    // have changes requiring flush?

  CString    m_strCompanyName;  // company name from m_pApp

  CString    m_strAppName;    // application name from m_pApp


  HKEY GetAppRegistryKey();    // gets key to app based on 

                               // company and app names

};

The overloaded routine Profile accepts most common types, and will read and write to the Registry depending on the bIsGet parameter passed on CPJRegistry creation. If it fails, the passed variable retains it's initialized value. Profile, and settings up your own GetPutRegistryData routine, are the keys to making Registry use simple. Instead of separate Registry reading and writing routines, your GetPutRegistryData routine does the work of both. Once you have written that, you need to call it in your InitInstance to load, call it again in your ExitInstance to save. Just a single line of code in your GetPutRegistryData routine is required for each variable you want in the Registry.

One final note, UINT Profile(LPCTSTR lpszEntry, LPBYTE pData, UINT nBytes); allows you to read/write binary data to the Registry. But, if you try and write a structure that contains pointers or classes you're going to have problems. Save the parts individually instead.

History

  • May 15, 2001 - CPJRegistry 2.0 has been re-written to support HKEY_LOCAL_MACHINE, via the SetRoot call.

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