|
|
Title |
Reading and writing to the Registery
|
Summary |
Notes on reading and writing to the Registery using the simple "HKEY_CURRENT_USER\Software" key and also working with any key using a more difficult method. |
Contributor |
John McTainsh
|
Published |
10-Oct-2000 |
Last updated |
10-Oct-2000 |
|
|
Description.
The registry is a good place to save configuration information about
you application. Functions to retrieve this information are presented in this section.
Remember avoid writing large amount of data to register.
Simple "HKEY_CURRENT_USER\Software" key.
When you create a simple MFC application the wizard the following line to
the CZzzzz::InitInstance() function.
// Change the registry key under which our settings are stored.
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization.
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
By changing the string you will be able to read and write data
about your application. It will appear in the registery in a key such
as "HKEY_CURRENT_USER\Software\MyCompany\MyAppName".
To write a string or integer to the registry use the following
AfxGetApp()->WriteProfileString(
_T("UserInfo"), _T("Name"), _T("Bill") );
AfxGetApp()->WriteProfileInt(
_T("UserInfo"), _T("DefaultFontSize"), 12 );
This information will be stored in the registry and persistent for this user.
However if another user logs on the "HKEY_CURRENT_USER" will be different,
ie the data in this section is user specific.
To read the data in the registry for this user / application use;
CString sUserName = AfxGetApp()->GetProfileString(
_T("UserInfo"), _T("Name"),
_T("Unknown") );
UINT nFont = AfxGetApp()->ReadProfileInt(
_T("UserInfo"), _T("DefaultFontSize"),
8 );
In both cases id the registry key does not exist the default value is returned.
Note:
- Strings are limited to _MAX_PATH in length.
- This member function is not case sensitive, so the strings in the
lpszSection and lpszEntry parameters may differ in case.
- These commands are limited to the "HKEY_CURRENT_USER\Software\MyCompany\MyAppName" key only and
are not persistent across different profiles.
- These function should not be called too often within an application as
they do take significant time to complete.
- Try to discourage support engineers from modifying the registery using Regedit (by hand) by
creating all missing keys when the application starts and populating them with
default values.
Advanced Registry access routines. (Read and Write)
It is often advantageous to be able to read and write to other keys in the registery
some common reasons are.
- To make data persistant between user profiles.
- Read regietry settings of other programs.
This first example works in a simular way to the above functions
but stores data that is persistant across user profiles.
Header file.
//////////////////////////////////////////////////////////////////////
//
// EASYREG.h: interface for the CEasyReg class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_EASYREG_H__4CEB51C3_8190_42b0_9D91_5C__INCLUDED_)
#define AFX_EASYREG_H__4CEB51C3_8190_42b0_9D91_5C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <atlbase.h> //ATL support for CRegKey
//////////////////////////////////////////////////////////////////////
//CLASS DEFINITION:
// CEasyReg
class CEasyReg : public CRegKey
{
//Operators
public:
CEasyReg::CEasyReg( CString sSupplier = _T("") );
virtual ~CEasyReg();
DWORD GetDW( LPCSTR lpszField, DWORD dwDefault = 0 );
CString GetStr( LPCSTR lpszField, LPCSTR lpszDefault = NULL );
bool SetDW( LPCSTR lpszField, DWORD dwVal );
bool SetStr( LPCSTR lpszField, LPCSTR lpszValue );
//Attributes
public:
//Operators
private:
//Attributes
private:
};
#endif // !defined(AFX_EASYREG_H__4CEB51C3_8190_42b0_9D91_5C__INCLUDED_)
Implementation file
//////////////////////////////////////////////////////////////////////
//
// EasyReg.cpp: implementation of the CEasyReg class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "EasyReg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
///////////////////////////////////////////////////////////////////////////////
//DESCRIPTION:
// Open the MyCompany directory on entry
//CREATED:
// 10-7-1999 9:34:08
//PARAMS:
// sSupplier Suppliers name OR "MyCompany" for Empty()
// bErrorDisp True is Errors are to be displayed.
//RETURN:
//
CEasyReg::CEasyReg( CString sSupplier )
{
//
//Open the Registery key
//
CString sKeyName = sSupplier.IsEmpty() ?
_T("SOFTWARE\\MyCompany") :
sSupplier;
Create( HKEY_LOCAL_MACHINE, sKeyName );
Close();
if( sSupplier.IsEmpty() )
{
sKeyName += _T("\\");
sKeyName += AfxGetAppName();
}
//Now open the actual key
if( Create( HKEY_LOCAL_MACHINE, sKeyName ) )
{
CString sError =_T("Unable to access Registery\n")\
_T("HKEY_LOCAL_MACHINE\\") +
sKeyName + _T("\n")\
_T("Will not be able to setup system.");
AfxMessageBox( sError, MB_ICONSTOP | MB_SYSTEMMODAL );
return;
}
}
///////////////////////////////////////////////////////////////////////////////
//DESCRIPTION:
// Clean up the House on the way home
//CREATED:
// 10-7-1999 9:33:52
//PARAMS:
//
//RETURN:
//
CEasyReg::~CEasyReg()
{
Close();
}
///////////////////////////////////////////////////////////////////////////////
//DESCRIPTION:
// Extract data from the System. Also add the Key if it is not their
//CREATED:
// 11-7-1999 11:31:00
//PARAMS:
// lpszField Key field name
// dwDefault Default value
// lpszDefault ..
//RETURN:
// read value.
DWORD CEasyReg::GetDW( LPCSTR lpszField, DWORD dwDefault )
{
DWORD dwRet; //Returned value
if( QueryValue(dwRet , lpszField ) != ERROR_SUCCESS )
dwRet = dwDefault;
//Optionally set the read value to create the key for next time
SetValue( dwRet, lpszField );
return dwRet;
}
CString CEasyReg::GetStr( LPCSTR lpszField, LPCSTR lpszDefault )
{
CString sRet; //Returned value
TCHAR szBuff[1025]; //Read buffer
DWORD dwSize = 1024;
if( QueryValue( szBuff, lpszField, &dwSize ) == ERROR_SUCCESS )
{
szBuff[dwSize] = NULL;
sRet = szBuff;
}
else
{
sRet = lpszDefault ? lpszDefault : _T("");
}
//Optionally set the read value to create the key for next time
SetValue( sRet, lpszField );
return sRet;
}
///////////////////////////////////////////////////////////////////////////////
//DESCRIPTION:
// Save the Data to the Registery
//CREATED:
// 11-7-1999 11:31:00
//PARAMS:
// lpszField Key field name
// dwVal Default value
// lpszData ..
//RETURN:
// read value.
bool CEasyReg::SetDW( LPCSTR lpszField, DWORD dwVal )
{
if( SetValue( dwVal, lpszField ) == ERROR_SUCCESS )
return true;
CString sError = _T("Unable to access Registery\n");
sError +=lpszField;
sError +=_T("\n");
sError +=_T("To save value.");
AfxMessageBox( sError, MB_ICONSTOP | MB_SYSTEMMODAL );
return false;
}
bool CEasyReg::SetStr( LPCSTR lpszField, LPCSTR lpszValue )
{
if( SetValue( lpszValue, lpszField ) == ERROR_SUCCESS )
return true;
CString sError = _T("Unable to access Registery\n");
sError +=lpszField;
sError +=_T("\n");
sError +=_T("To save value.\n");
sError +=lpszValue;
AfxMessageBox( sError, MB_ICONSTOP | MB_SYSTEMMODAL );
return false;
}
Advanced Registry access routines. (Read only)
Alternatively to read a single entry use the following function.
///////////////////////////////////////////////////////////////////////////////
//DESCRIPTION:
// Extracts the Data from the provided registery key
//CREATED:
// 13-10-1998 11:05:05
//PARAMS:
// KeyRoot HKEY_LOCAL_MACHINE, ...
// szSubKey ie, _T("Software\\Microsoft\\Internet Explorer")
// lpValueName _T("") to read "(Default)"
// pData Data to recieve
// pdwSize Size of data read (0 for errors)
// dwExpectType Type of Data expected, ie REG_SZ.
//RETURN:
// true if all goes well.
bool GetRegData( HKEY KeyRoot, LPCTSTR szSubKey, LPCTSTR lpValueName,
void *const pData, DWORD *const pdwSize, DWORD dwExpectType )
{
TRACE( _T("GetRegData( %x, %s, %s, %p, %x, %x )\n"), KeyRoot, szSubKey,
lpValueName, pData, *pdwSize, dwExpectType );
DWORD dwType; //Returned data type
DWORD rc; //Responce from the Registery calls
HKEY hKeySubKey = NULL; //Opend Key
//
//Open the Key
//
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
szSubKey,
0,
KEY_QUERY_VALUE,
&hKeySubKey );
//Display the Error and Return
if (rc != ERROR_SUCCESS)
{
*pdwSize = 0;
const DWORD dwMessSize = 1024;
TCHAR szBuff[dwMessSize];
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, rc, NULL,
szBuff, dwMessSize, NULL );
OpFailTrace( _T("OPENING : %s"), szBuff );
return false;
}
//
//Open the Sub Key to Get the Data
//
rc = RegQueryValueEx( hKeySubKey,
lpValueName, 0, &dwType,
(LPBYTE)pData, pdwSize );
RegCloseKey( hKeySubKey ); //Close up shop.
//Display the Error and Return
if (rc != ERROR_SUCCESS)
{
*pdwSize = 0;
const DWORD dwMessSize = 1024;
TCHAR szBuff[dwMessSize];
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, rc, NULL, szBuff,
dwMessSize, NULL );
TRACE( _T("ERROR READING : %n"), szBuff );
return false;
}
//Display error for Data type
if( dwType != dwExpectType )
{
TRACE( _T("ERROR Wrong data type : Recieved %d, Expected %d\n"),
dwType, dwExpectType );
return false;
}
//All is well so return
return true;
}
|