Mesoscopic Programming

タコさんプログラミング専門

レジストリのクラス

ずっと昔ながらのプロファイルばかり使っていましたが、
意を決してレジストリを使うことにしました。
そこで、レジストリのクラスを作りました。

TRegistry.h
//----------------------------------------------------------------------------
/// @file    TRegistry.h
/// @brief   レジストリクラスヘッダ
/// @details レジストリクラスです。
/// @version 0.1.0
/// @date    2015/05/10
/// @author  Copyright (C) 2015 hidakas1961 All rights reserved.
//----------------------------------------------------------------------------

#pragma once

#include <Common.h>
#include <TLogOut.h>

// 共通ライブラリ名前空間
namespace Common
{
    //------------------------------------------------------------------------
    /// @brief   レジストリクラス
    /// @details レジストリクラスです。
    //------------------------------------------------------------------------
    class TRegistry
    {
        //--------------------------------------------------------------------
        // 動的変数
        //--------------------------------------------------------------------

    private :

        HKEY         m_hopenkey; ///< オープンキーハンドル
        const char * m_headkey;  ///< 先頭キー文字列
        const char * m_subkey;   ///< サブキー文字列

        //--------------------------------------------------------------------
        // 構築子と解体子
        //--------------------------------------------------------------------

    public :

        /// @brief   デフォルト構築子
        /// @param   [in] subkey   サブキー文字列
        /// @param   [in] headkey  先頭キー文字列
        /// @param   [in] hopenkey オープンキーハンドル
        /// @details レジストリクラスを構築します。
        explicit TRegistry( const char * subkey, const char * headkey = "Software", HKEY hopenkey = HKEY_CURRENT_USER );

        /// @brief 解体子
        inline virtual ~TRegistry() {}

        //--------------------------------------------------------------------
        // 動的関数
        //--------------------------------------------------------------------

    private :

        /// @brief   レジストリキーオープン関数
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  レジストリキーハンドル
        /// @details レジストリキーをオープンします。
        HKEY OpenKey( const char * tailkey = 0 ) const;

    public :

        /// @brief   任意型データ保存関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] data    任意データ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @retval  true  成功
        /// @retval  false 失敗
        /// @details 任意の型のデータを保存します。
        template< class T > bool WriteData( const char * entry, const T & data, const char * tailkey = 0 ) const
        {
            bool  result = false;
            DWORD size   = sizeof( data );
            DWORD type   = REG_BINARY;

            Log().Begin( __func__ );
            Log().LineDataText( "entry  ", entry );
            Log().LineDataText( "class T", typeid( data ).name() );
            Log().LineData    ( "data   ", data );
            Log().LineDataText( "tailkey", tailkey );
            Log().LineDataText( "type   ", "REG_BINARY" );
            Log().LineData    ( "size   ", size );

            // レジストリキーをオープンします。
            HKEY hkey = OpenKey( tailkey );

            if ( hkey )
            {
                // エントリデータを保存します。
                result = RegSetValueEx( hkey, entry, 0, type, reinterpret_cast< const BYTE * >( & data ), size ) == ERROR_SUCCESS;

                // レジストリキーをクローズします。
                RegCloseKey( hkey );
            }

            Log().LineData( "result ", result );
            Log().End( __func__ );

            return result;
        }

        /// @brief   任意型データ取得関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] data    デフォルトデータ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  任意型データ
        /// @details 任意の型のデータを取得します。
        template< class T > T ReadData( const char * entry, const T & data, const char * tailkey = 0 ) const
        {
            bool  result = false;
            T     buffer = data;
            DWORD size   = sizeof( T );
            DWORD recv   = 0;
            DWORD type   = REG_BINARY;

            Log().Begin( __func__ );
            Log().LineDataText( "entry  ", entry );
            Log().LineDataText( "class T", typeid( data ).name() );
            Log().LineData    ( "data   ", data );
            Log().LineDataText( "tailkey", tailkey );
            Log().LineDataText( "type   ", "REG_BINARY" );
            Log().LineData    ( "size   ", size );

            // レジストリキーをオープンします。
            HKEY hkey = OpenKey( tailkey );

            if ( hkey )
            {
                // エントリデータを取得します。
                if ( RegQueryValueEx( hkey, entry, 0, & type, reinterpret_cast< BYTE * >( & buffer ), & size ) == ERROR_SUCCESS )
                {
                    result = true;
                    recv   = size;
                }

                // レジストリキーをクローズします。
                RegCloseKey( hkey );
            }

            Log().LineData( "result ", result );
            Log().LineData( "recv   ", recv );
            Log().LineData( "buffer ", buffer );
            Log().End( __func__ );

            return buffer;
        }

        /// @brief   バイナリデータ保存関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] buffer  バッファポインタ
        /// @param   [in] size    バッファサイズ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @retval  true  成功
        /// @retval  false 失敗
        /// @details バイナリデータを保存します。
        bool WriteBinary( const char * entry, const void * buffer, DWORD size, const char * tailkey = 0 ) const;

        /// @brief   文字列保存関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] text    文字列
        /// @param   [in] tailkey 最後尾キー文字列
        /// @retval  true  成功
        /// @retval  false 失敗
        /// @details 文字列を保存します。
        bool WriteText( const char * entry, const char * text, const char * tailkey = 0 ) const;

        /// @brief   整数型データ保存関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] data    整数型データ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @retval  true  成功
        /// @retval  false 失敗
        /// @details 整数型のデータを保存します。
        bool WriteInt( const char * entry, DWORD data, const char * tailkey = 0 ) const;

        /// @brief   バイナリデータ取得関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] buffer  バッファポインタ
        /// @param   [in] size    バッファサイズ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  取得データバイトサイズ
        /// @details バイナリデータを取得します。
        DWORD ReadBinary( const char * entry, void * buffer, DWORD size, const char * tailkey = 0 ) const;

        /// @brief   文字列取得関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] buffer  文字列バッファポインタ
        /// @param   [in] size    バッファサイズ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  取得文字列バイトサイズ
        /// @details 文字列を取得します。
        DWORD ReadText( const char * entry, char * buffer, DWORD size, const char * tailkey = 0 ) const;

        /// @brief   整数型データ取得関数
        /// @param   [in] entry   エントリー文字列
        /// @param   [in] data    デフォルトデータ
        /// @param   [in] tailkey 最後尾キー文字列
        /// @return  整数型データ
        /// @details 整数型のデータを取得します。
        DWORD ReadInt( const char * entry, DWORD data, const char * tailkey = 0 ) const;
    };
}   // Window
TRegistry.cpp
//----------------------------------------------------------------------------
/// @file    TRegistry.cpp
/// @brief   レジストリクラス
/// @details レジストリクラスです。
//----------------------------------------------------------------------------

#include <TRegistry.h>

//----------------------------------------------------------------------------
// 名前空間使用宣言
//----------------------------------------------------------------------------

using namespace Common;

//----------------------------------------------------------------------------
// 構築子と解体子
//----------------------------------------------------------------------------
// デフォルト構築子
TRegistry::TRegistry( const char * subkey, const char * headkey, HKEY hopenkey )
    : m_subkey  ( subkey )
    , m_headkey ( headkey )
    , m_hopenkey( hopenkey )
{
    Log().Begin( __func__ );
    Log().LineDataText( "subkey  ", subkey );
    Log().LineDataText( "headkey ", headkey );
    Log().LineData    ( "hopenkey", hopenkey );
    Log().End( __func__ );
}

//----------------------------------------------------------------------------
// 動的関数
//----------------------------------------------------------------------------

// レジストリキーオープン関数
HKEY TRegistry::OpenKey( const char * tailkey ) const
{
    // サブキー文字列を作成します。
    string subkey;

    if ( m_headkey )
    {
        subkey.append( m_headkey );
        subkey.append( "\\" );
    }

    subkey.append( m_subkey );

    if ( tailkey )
    {
        subkey.append( "\\" );
        subkey.append( tailkey );
    }

    // レジストリキーをオープンします。
    HKEY hkey;

    if ( RegCreateKeyEx( m_hopenkey, subkey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, & hkey, NULL ) == ERROR_SUCCESS )
    {
        return hkey;
    }

    return 0;
}

// バイナリデータ保存関数
bool TRegistry::WriteBinary( const char * entry, const void * buffer, DWORD size, const char * tailkey ) const
{
    bool  result = false;
    DWORD type   = REG_BINARY;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "buffer ", buffer );
    Log().LineData    ( "size   ", size );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_BINARY" );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを保存します。
        result = RegSetValueEx( hkey, entry, 0, type, reinterpret_cast< const BYTE * >( buffer ), size ) == ERROR_SUCCESS;

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().End( __func__ );

    return result;
}

// 文字列保存関数
bool TRegistry::WriteText( const char * entry, const char * text, const char * tailkey ) const
{
    bool  result = false;
    DWORD size   = strlen( text ) + 1;
    DWORD type   = REG_SZ;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineDataText( "text   ", text );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_SZ" );
    Log().LineData    ( "size   ", size );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを保存します。
        result = RegSetValueEx( hkey, entry, 0, type, reinterpret_cast< const BYTE * >( text ), size ) == ERROR_SUCCESS;

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().End( __func__ );

    return result;
}

// 整数型データ保存関数
bool TRegistry::WriteInt( const char * entry, DWORD data, const char * tailkey ) const
{
    bool  result = false;
    DWORD size   = sizeof( DWORD );
    DWORD type   = REG_DWORD;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "data   ", data );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_DWORD" );
    Log().LineData    ( "size   ", size );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを保存します。
        result = RegSetValueEx( hkey, entry, 0, type, reinterpret_cast< const BYTE * >( & data ), size ) == ERROR_SUCCESS;

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().End( __func__ );

    return result;
}

// バイナリデータ取得関数
DWORD TRegistry::ReadBinary( const char * entry, void * buffer, DWORD size, const char * tailkey ) const
{
    bool  result = false;
    DWORD recv   = 0;
    DWORD type   = REG_BINARY;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "buffer ", buffer );
    Log().LineData    ( "size   ", size );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_BINARY" );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを取得します。
        if ( RegQueryValueEx( hkey, entry, 0, & type, reinterpret_cast< BYTE * >( buffer ), & size ) == ERROR_SUCCESS )
        {
            result = true;
            recv   = size;
        }

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().LineData( "recv   ", recv );
    Log().End( __func__ );

    return recv;
}

// 文字列取得関数
DWORD TRegistry::ReadText( const char * entry, char * buffer, DWORD size, const char * tailkey ) const
{
    bool  result = false;
    DWORD recv   = 0;
    DWORD type   = REG_SZ;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "buffer ", buffer );
    Log().LineData    ( "size   ", size );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_SZ" );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを取得します。
        if ( RegQueryValueEx( hkey, entry, 0, & type, reinterpret_cast< BYTE * >( buffer ), & size ) == ERROR_SUCCESS )
        {
            result = true;
            recv   = size;
        }

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().LineData( "recv   ", recv );

    if ( recv )
    {
        Log().LineDataText( "buffer ", buffer );
    }

    Log().End( __func__ );

    return recv;
}

// 整数型データ取得関数
DWORD TRegistry::ReadInt( const char * entry, DWORD data, const char * tailkey ) const
{
    bool  result = false;
    DWORD buffer = data;
    DWORD size   = sizeof( DWORD );
    DWORD recv   = 0;
    DWORD type   = REG_DWORD;

    Log().Begin( __func__ );
    Log().LineDataText( "entry  ", entry );
    Log().LineData    ( "data   ", data );
    Log().LineDataText( "tailkey", tailkey );
    Log().LineDataText( "type   ", "REG_DWORD" );
    Log().LineData    ( "size   ", size );

    // レジストリキーをオープンします。
    HKEY hkey = OpenKey( tailkey );

    if ( hkey )
    {
        // エントリデータを取得します。
        if ( RegQueryValueEx( hkey, entry, 0, & type, reinterpret_cast< BYTE * >( & buffer ), & size ) == ERROR_SUCCESS )
        {
            result = true;
            recv   = size;
        }

        // レジストリキーをクローズします。
        RegCloseKey( hkey );
    }

    Log().LineData( "result ", result );
    Log().LineData( "recv   ", recv );
    Log().LineData( "buffer ", buffer );
    Log().End( __func__ );

    return buffer;
}
解説

整数と文字列以外の任意の型にはテンプレートでバイナリーデータとして対応しているので、
どんなクラスや構造体もそのまま保存と取得ができるようになっています。
またログ出力クラスもだいぶ改良しましたので、
サンプルプログラムは、サイドバーのリンクから倉庫置き場に行って適当に見つけてください。
以上です。