Home Search Contact us About us
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
Page rating   87% for 8 votes Useless Brilliant

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;
}
Comments Date
Home Search Contact us About us