Click here to Skip to main content
Licence 
First Posted 12 May 2001
Views 82,387
Bookmarked 14 times

CPJRegistry 2.0

By | 30 Nov 2001 | Article
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

About the Author

Peter M. Jones



Canada Canada

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionRestricted User Pinmemberdipali_be200321:18 14 Apr '06  
AnswerRe: Restricted User PinmemberPeter M. Jones3:26 15 Apr '06  
GeneralNo matter what I do... PinmemberDarren Schroeder11:14 16 Oct '01  
GeneralRe: No matter what I do... PinmemberPeter Jones11:58 16 Oct '01  
GeneralRe: No matter what I do... PinmemberDarren Schroeder15:13 16 Oct '01  
GeneralRe: No matter what I do... PinmemberPeter Jones16:25 16 Oct '01  
GeneralSuggestion Pinmemberpeterchen23:03 8 Jul '01  
GeneralRe: Suggestion PinmemberPeter Jones7:15 9 Jul '01  
GeneralMicrosoft specification PinmemberAnonymous4:26 15 May '01  
GeneralRe: Microsoft specification PinmemberRobR6:41 15 May '01  
GeneralRe: Microsoft specification PinmemberPeter Jones7:14 15 May '01  
GeneralRe: Microsoft specification PinmemberAnonymous6:57 15 May '01  
GeneralRe: Microsoft specification PinmemberTomasz Sowinski7:47 15 May '01  
GeneralRe: Microsoft specification PinmemberJim A. Johnson8:16 15 May '01  
GeneralRe: Microsoft specification PinmemberJohn Simmons / outlaw programmer0:31 16 May '01  
GeneralRe: Microsoft specification PinmemberTomasz Sowinski0:36 16 May '01  
GeneralRe: Microsoft specification PinmemberJohn Simmons / outlaw programmer4:51 13 Oct '01  
GeneralRe: Microsoft specification PinmemberHenry Jacobs6:03 16 May '01  
GeneralRe: Microsoft specification PinmemberCathy6:25 21 May '01  
Questionall in the same root key? PinmemberDarren Schroeder15:12 14 May '01  
AnswerRe: all in the same root key? Yes. PinmemberPeter Jones16:17 14 May '01  
GeneralRe: all in the same root key? Not in 2.0 PinmemberPeter Jones10:56 15 May '01  

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

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120517.1 | Last Updated 1 Dec 2001
Article Copyright 2001 by Peter M. Jones
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid