Click here to Skip to main content
15,921,793 members
Articles / Desktop Programming / MFC
Article

CPJRegistry 2.0

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
30 Nov 20012 min read 105.7K   531   14   22
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


Written By
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionRestricted User Pin
dipali_be200314-Apr-06 21:18
dipali_be200314-Apr-06 21:18 
AnswerRe: Restricted User Pin
Peter M. Jones15-Apr-06 3:26
Peter M. Jones15-Apr-06 3:26 
GeneralNo matter what I do... Pin
Darren Schroeder16-Oct-01 11:14
Darren Schroeder16-Oct-01 11:14 
GeneralRe: No matter what I do... Pin
Peter Jones16-Oct-01 11:58
Peter Jones16-Oct-01 11:58 
GeneralRe: No matter what I do... Pin
Darren Schroeder16-Oct-01 15:13
Darren Schroeder16-Oct-01 15:13 
GeneralRe: No matter what I do... Pin
Peter Jones16-Oct-01 16:25
Peter Jones16-Oct-01 16:25 
GeneralSuggestion Pin
peterchen8-Jul-01 23:03
peterchen8-Jul-01 23:03 
GeneralRe: Suggestion Pin
Peter Jones9-Jul-01 7:15
Peter Jones9-Jul-01 7:15 
GeneralMicrosoft specification Pin
15-May-01 4:26
suss15-May-01 4:26 
GeneralRe: Microsoft specification Pin
15-May-01 6:41
suss15-May-01 6:41 
GeneralRe: Microsoft specification Pin
Peter Jones15-May-01 7:14
Peter Jones15-May-01 7:14 
GeneralRe: Microsoft specification Pin
15-May-01 6:57
suss15-May-01 6:57 
GeneralRe: Microsoft specification Pin
Tomasz Sowinski15-May-01 7:47
Tomasz Sowinski15-May-01 7:47 
GeneralRe: Microsoft specification Pin
Jim A. Johnson15-May-01 8:16
Jim A. Johnson15-May-01 8:16 
GeneralRe: Microsoft specification Pin
#realJSOP16-May-01 0:31
professional#realJSOP16-May-01 0:31 
GeneralRe: Microsoft specification Pin
Tomasz Sowinski16-May-01 0:36
Tomasz Sowinski16-May-01 0:36 
GeneralRe: Microsoft specification Pin
#realJSOP13-Oct-01 4:51
professional#realJSOP13-Oct-01 4:51 
GeneralRe: Microsoft specification Pin
Henry Jacobs16-May-01 6:03
Henry Jacobs16-May-01 6:03 
GeneralRe: Microsoft specification Pin
Cathy21-May-01 6:25
Cathy21-May-01 6:25 
Questionall in the same root key? Pin
Darren Schroeder14-May-01 15:12
Darren Schroeder14-May-01 15:12 
AnswerRe: all in the same root key? Yes. Pin
Peter Jones14-May-01 16:17
Peter Jones14-May-01 16:17 
GeneralRe: all in the same root key? Not in 2.0 Pin
Peter Jones15-May-01 10:56
Peter Jones15-May-01 10:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.