CPJRegistry 2.0





0/5 (0 vote)
May 13, 2001
2 min read

106165

531
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:
- CHKLM v1.1 - Registry Access, By PJ Naughter
- Registry Class, By Robert Pittenger
- Stream like operations for the registry, By Martin Holzherr
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 supportHKEY_LOCAL_MACHINE
, via theSetRoot
call.