ここでは、RALを用いた設定保存・取得機能の利用方法等に触れます。

従来のアプリケーションは、INIファイルに設定情報を出力して利用していました。Win32ではINIファイルの代わりにレジストリを使用するようになっています。ただし互換性のためにINIファイルのサポートはまだ行われています。RALの設定保存・取得機能は、従来INIファイルを使用していたのをレジストリでのそれに置き換えたモノです。設計にあたってINIファイルを使用していたユーザが移行しやすいように設計したつもりです。まずはアプリケーションの設定情報がレジストリのどこに保存されるかという話から始めます。

●設定情報の保存場所

レジストリではアプリケーションが設定を保存する場所を規定しています。アプリケーションの設定保存場所には2通りがあります。

HKEY_CURRENT_USER\Software
HKEY_LOCAL_MACHINE\Software

上記の何れか、或いは場合によっては両方に保存することになっています。具体例を挙げて説明します。レジストリエディタでHKEY_CURRENT_USER\Softwareの傘下を見てみると様々なキーがあることと思います。このHKEY_CURRENT_USER\Software傘下にあるキー階層にはある程度規則があります。

HKEY_CURRENT_USER\Software\会社名\プロダクト名

普通は上記の構造になっています。Softwareキーの下にアプリケーションの会社名のキーがあり、さらにその会社名のキーの下にアプリケーションの名称を表すキーがあります。例えば...

HKEY_CURRENT_USER\Software\Microsoft\Visual Basic

といった具合です。これは「Microsoft」社の「Visual Basic」という製品に関する設定情報の在処ということになります。

プロダクト名のキー傘下の階層構造はどうなっているかというと、実はこれに関しては全くの自由ということになっています。プロダクト名キーの下に直接設定情報を格納しても構いませんし、或いは必要に応じて更に深くキーを用意しても構いません。プロダクト名以下のキー階層をどのようにするかはアプリケーションを設計・開発する人の自由です。

●キー階層の捉え方

では何故プロダクト名傘下に更なるキー階層が必要なのかを考えてみます。

小規模のアプリケーションの場合にはおそらく保存が必要な設定情報の種類や数も少ないことでしょう。しかし大規模なアプリケーションになってくると次第にレジストリに保存すべき設定情報の種類や数が増えてきます。これらをキー階層を作らずにプロダクト名のキーの下に直接保存しても、それはそれで構いません。キー階層を作る目的は、レジストリに保存する設定情報を分類・整理することです。

例としてワードプロセッサの場合を考えてみます。今時のワードプロセッサであればウィンドウの状態、フォント、段落等、様々な設定が出来ることと思います。これらをレジストリに保存するとします。ウィンドウの状態とはウィンドウの表示位置、サイズ、表示状態(通常表示、最大表示、アイコン表示)のことを意味します。フォントとしてはワードプロセッサを使い始めた時にデフォルトで使用するフォントの種類やサイズがあります。段落には左寄せ、右寄せ、センタリング、行間、段落間、インデント設定等があるでしょう。これらをレジストリに保存する際に

HKEY_CURRENT_USER
 +---Software
    +---なんとかソフト
       +---なんとかワープロ
          +---Window
          +---Font
          +---Paragraph

上記のようにプロダクト名のキー傘下にそれぞれ"Window"、"Font"、"Paragraph"といったキーを作り、それぞれをウィンドウ、フォント、段落の設定情報を保存する場所として使います。キー名には英数字以外に全角文字を使用しても構いません。この方がおそらく目的の設定情報を探しやすくなるでしょう。また通常は、設定を保存する際には設定に名前を付けます。これを項目名と呼んでいます。設定情報の数が増えてくると、この項目名が既に存在する項目名とかち合いやすくなってきます。

●レジストリへの置き換え

これらのことをふまえた上でINIファイルに格納されている設定情報をレジストリに移行されることにします。

INIファイルに設定情報を保存する場合は通常以下のような形式になっています。

[Window]
Left=123
Top=456
Width=321
Height=654

ここで[]でくくられた部分をセクションと呼びます。セクションの後に続いている各行はエントリと呼びます。エントリ行は最初にエントリ名があり、その直後に=で設定情報の内容を記述します。上記の例では[Window]セクションにウィンドウのX座標、Y座標、ウィンドウの幅、高さがそれぞれLeft、Top、Width、Heightというエントリ名で格納されていることになります。これをレジストリで保存する際には以下のようにするのが良いでしょう。

HKEY_CURRENT_USER
 +---Software
    +---会社名
       +---プロダクト名
          +---Window
             Left  123
             Top   456
             Width  321
             Height 654

WindowキーがINIファイルでの[Window]セクションにあたります。Windowキー傘下にあるLeft、Top、Width、Heightは項目名で、123、456、321、654を保存します。

●レジストリへのアクセス

では実際にこのような構造でレジストリに情報を格納する方法を説明します。

RALを使用してレジストリに設定情報を保存するには手順があります。RALで設定情報を保存するには、まず最初にRalInitiateをコールしておく必要があります。このAPIの仕事は会社名とプロダクト名を覚えることです。このAPIには会社名とプロダクト名を指定する引数があります。今後RALの各APIでレジストリに設定情報を保存する際には、このAPIで指定した会社名及びプロダクト名の傘下に保存することをRALに指示するのが目的です。設定を保存する度に逐一会社名とプロダクト名を指定する必要がなくなるよう、このAPIは用意されています。このAPIは設定保存を行う前に1度だけコールしておけば充分です。

先に挙げたワードプロセッサの例で言うと、「なんとかソフト」と「なんとかワープロ」をそれぞれ会社名、プロダクト名としてRalInitiateに引数として渡しておきます。逆に"Window"、"Font"、"Paragraph"の各キーは実際にレジストリに設定情報を保存する際に指定します。

RalInitiateをコールしたら、いつでも設定情報をレジストリに保存できる状態になっています。実際にレジストリに設定情報を保存するには以下のAPIを使用します。

RalSaveBinary ユーザバイナリ保存
RalSaveCheckBox チェックボックス設定保存
RalSaveRadioButton ラジオボタン設定保存
RalSaveScrollBar スクロールバー設定保存
RalSaveString ユーザ文字列保存
RalSaveSystemBinary  マシンバイナリ保存
RalSaveSystemString マシン文字列保存
RalSaveSystemValue マシン値保存
RalSaveValue ユーザ値保存
RalSaveWindow ウィンドウ設定保存

多くの種類がありますが必ずしも全てを使用する必要はなく、上記の何れかを選んで使用します。設定保存を行うAPIは全てRalSave〜という識別子になっています。RalSave〜の後はどのような情報を格納するかを表しています。これらのAPIには保存したいキー名、保存したい情報に付ける項目名、保存したい情報そのもの等を引数として指定するようになっています。1回のAPIコールで1つの設定情報を保存できます。APIからリターンしてきた時には既にレジストリに情報が保存されています。後は必要なだけこれらのAPIを呼び出して順次設定情報をレジストリに保存していきます。

●設定情報の種類

ここでRALを使用してレジストリに保存できる設定情報の種類について触れておきます。

レジストリに保存できるデータ型には多くの種類がありますが、RALがサポートしているのは整数、文字列、バイナリ(任意形式)の3種類です。整数は32bitです。文字列はC言語で言うところの文字列で、0で終端している必要があります。バイナリは任意形式のデータで、バイナリの場合のみ先頭アドレスとバイト数により保存したいデータを指定します。

またレジストリに保存する設定情報の性質により、更に2つの保存方法があります。これらはユーザ固有情報とマシン固有情報で区別します。Windows 95やWindows NTではそのマシンを複数の人が使用できるように作られています。Windowsでは使う人のことをユーザと呼んで区別しています。複数のユーザがあり得るということは、ユーザ毎に設定を別々で保存する必要があります。これはユーザによってアプリケーションの設定が違ってくるためです。あるユーザはウィンドウを最大表示で使うかもしれませんが、別のあるユーザは通常表示で使うかもしれません。従って、ユーザ毎に別々にアプリケーションが設定情報を保存・管理出来なければなりません。しかしアプリケーションがユーザ管理を行うには荷が重いですし、またそもそもユーザ管理はアプリケーションの仕事ではなくWindowsの仕事です。

そこでレジストリはユーザ毎に設定情報を保存・管理するためのメカニズムを最初から持っています。このメカニズムを使用して情報を保存すれば自動的にユーザ毎に情報を保存することが出来ます。アプリケーションがユーザについて関知する必要はありません。このメカニズムを利用して保存された情報をユーザ固有情報と呼ぶことにします。ユーザ固有情報は以下のAPIで保存できます。

RalSaveBinary  ユーザバイナリ保存
RalSaveString ユーザ文字列保存
RalSaveValue ユーザ値保存

識別子から想像できると思いますが、RalSaveValueが整数、RalSaveStringが文字列、RalSaveBinaryがバイナリを保存するAPIです。これらのAPIは保存するデータ型が異なる以外は全て同じ引数になっています。これらのAPIには共通の引数として以下のモノがあります。

char *pszKey; /* キー名 */
char *pszName;  /* 項目名 */
BOOL fCreate; /* フラグ */

pszKeyには分類・整理の目的で用意するキー名、pszNameには保存する設定情報に付ける項目名を指定します。最後のfCreatepszKeyで指定したキーが無い場合に作成するかどうかを指定するフラグです。通常はTRUEを指定しておきます。

再度先に挙げたワードプロセッサの例を当てはめると、pszKeyには"Window"、"Font"、"Paragraph"といったキー名を指定します。pszKeyに"Window"を指定すれば実際の設定情報の格納場所はHKEY_CURRENT_USER\Software\会社名\プロダクト名\Windowとなります。キーを用意する必要がなければpszKeyにNULLを指定します。その場合はHKEY_CURRENT_USER\Software\会社名\プロダクト名になります。pszNameには"Left"、"Top"、"Width"、"Height"といった項目名を指定します。

●マシン固有情報

レジストリがユーザを区別して情報を管理・保存するメカニズムを持っていることは説明しました。先に説明したAPIで設定情報を保存するとそれはユーザ固有情報としてレジストリに格納されます。逆にユーザを区別しない情報としてレジストリに保存しなければならない場合もあるでしょう。そのような情報をマシン固有情報と呼ぶことにします。マシン固有情報としてレジストリに設定情報を保存するには以下のAPIを使用します。

RalSaveSystemBinary  マシンバイナリ保存
RalSaveSystemString マシン文字列保存
RalSaveSystemValue マシン値保存

これらのAPIを使用してマシン固有情報としてレジストリに保存された情報は、全てのユーザに共通の情報となります。マシン固有情報のAPIはユーザ固有情報のAPIと全く同じ引数を指定します。マシン固有情報としてレジストリに保存する以外に違いは全くありません。

ユーザ固有情報とマシン固有情報はレジストリ中の保存場所が異なっています。ユーザ固有情報はHKEY_CURRENT_USER\Software\会社名\プロダクト名の傘下に保存されますが、マシン固有情報はHKEY_LOCAL_MACHINE\Software\会社名\プロダクト名の傘下に保存されます。

●設定の取得

RALのAPIを使用してレジストリに保存された設定情報は同じくRALのAPIでレジストリから取得することが出来ます。設定情報の取得を行うAPIは全て保存を行うAPIと対をなしています。設定情報の取得を行う場合にもあらかじめRalInitiateをコールしておく必要があります。RalInitiateは設定情報の保存と取得の両方に共通で、1度RalInitiateをコールすれば保存、取得のどちらでも行うことが出来ます。設定情報の取得を行うAPIには以下のモノがあります。

RalLoadBinary ユーザバイナリ取得
RalLoadCheckBox チェックボックス設定取得
RalLoadRadioButton ラジオボタン設定取得
RalLoadScrollBar スクロールバー設定取得
RalLoadString ユーザ文字列取得
RalLoadSystemBinary  マシンバイナリ取得
RalLoadSystemString マシン文字列取得
RalLoadSystemValue マシン値取得
RalLoadValue ユーザ値取得
RalLoadWindow ウィンドウ設定取得

設定取得を行うAPIは全てRalLoad〜という識別子になっています。RalLoad〜の後はどのような情報を取得するかを表しています。これらのAPIには取得先のキー名、取得したい情報に付けられている項目名、取得した情報を返すアドレス等を引数として指定するようになっています。1回のAPIコールで1つの設定情報を取得できます。APIからリターンしてきた時には既にレジストリから情報が取得され、指定されたアドレスに格納されています。後は必要なだけこれらのAPIを呼び出して順次設定情報をレジストリから取得していきます。

レジストリから設定情報を取得する際には保存されている設定情報の型に合わせて使用するAPIを選択します。設定情報の保存時に用いた型とは異なる型で取得を行うことは出来ません。

また、ユーザ固有情報として保存された設定情報はユーザ固有情報としてしか取得できません。マシン固有情報として保存された設定情報はマシン固有情報としてしか取得できません。

●サンプル

ここではCでの使用例を挙げます。

DWORD dwValue; // 数値
unsigned char pszString[ 256 ]; // 文字列
struct tagBinaryData
{
  ・
  ・
  ・
};
struct tagBinaryData DefaultData; // デフォルト構造体
struct tagBinaryData BinaryData; // 構造体

//
// はじめにRalInitiateをコールしておきます。
// 設定情報の格納場所を
//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊
// または
// HKEY_LOCAL_MACHINE\Software\雲表ソフト\C坊
//
// とします。
//
// BOOL RalInitiate( char *pszCompany, char *pszProduct, BOOL fCommit );
//
if( !RalInitiate( "雲表ソフト", "C坊", TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊
// の傘下に整数変数dwValueの値をValue1という名前で保存します。
//
// RalSaveValueのかわりにRalSaveSystemValueを使用すると
// ユーザ固有情報ではなくマシン固有情報として保存できます。
// RalSaveValueとRalSaveSystemValueは全て同じ引数です。
//
// BOOL RalSaveValue( char *pszKey, char *pszName, DWORD dwValue, BOOL fCreate );
//
if( !RalSaveValue( NULL, "Value1", dwValue, TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊\IntegerData
// の傘下に整数変数dwValueの値をValue2という名前で保存します。
//
// RalSaveValueのかわりにRalSaveSystemValueを使用すると
// ユーザ固有情報ではなくマシン固有情報として保存できます。
// RalSaveValueとRalSaveSystemValueは全て同じ引数です。
//
// BOOL RalSaveValue( char *pszKey, char *pszName, DWORD dwValue, BOOL fCreate );
//
if( !RalSaveValue( "IntegerData", "Value2", dwValue, TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊
// の傘下に文字配列(文字列)pszStringの値をString1という名前で保存します。
//
// RalSaveStringのかわりにRalSaveSystemStringを使用すると
// ユーザ固有情報ではなくマシン固有情報として保存できます。
// RalSaveStringとRalSaveSystemStringは全て同じ引数です。
//
// BOOL RalSaveString( char *pszKey, char *pszName, char *pszString, BOOL fCreate );
//
if( !RalSaveString( NULL, "String1", pszString, TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊\StringData
// の傘下に文字配列(文字列)pszStringの値をString2という名前で保存します。
//
// RalSaveStringのかわりにRalSaveSystemStringを使用すると
// ユーザ固有情報ではなくマシン固有情報として保存できます。
// RalSaveStringとRalSaveSystemStringは全て同じ引数です。
//
// BOOL RalSaveString( char *pszKey, char *pszName, char *pszString, BOOL fCreate );
//
if( !RalSaveString( "StringData", "String2", pszString, TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊
// の傘下に構造体BinaryをBinary1という名前で保存します。
//
// RalSaveBinaryのかわりにRalSaveSystemBinaryを使用すると
// ユーザ固有情報ではなくマシン固有情報として保存できます。
// RalSaveBinaryとRalSaveSystemBinaryは全て同じ引数です。
//
// BOOL RalSaveBinary( char *pszKey, char *pszName, void *pvBinary, DWORD cbBinary, BOOL fCreate );
//
if( !RalSaveBinary( NULL, "Binary1", &BinaryData, sizeof( BinaryData ), TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊\BinaryData
// の傘下に構造体BinaryをBinary2という名前で保存します。
//
// RalSaveBinaryのかわりにRalSaveSystemBinaryを使用すると
// ユーザ固有情報ではなくマシン固有情報として保存できます。
// RalSaveBinaryとRalSaveSystemBinaryは全て同じ引数です。
//
// BOOL RalSaveBinary( char *pszKey, char *pszName, void *pvBinary, DWORD cbBinary, BOOL fCreate );
//
if( !RalSaveBinary( "BinaryData", "Binary2", &BinaryData, sizeof( BinaryData ), TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊
// の傘下からValue1という名前の情報を整数変数dwValueに取得します。
// 該当個所に情報が無ければデフォルトとして0x12345678がdwValueに格納されます。
//
// BOOL RalLoadValue( char *pszKey, char *pszName, DWORD *pdwValue, DWORD dwDefault, BOOL fCreate );
//
if( !RalLoadValue( NULL, "Value1", &dwValue, 0x12345678, TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊\IntegerData
// の傘下からValue2という名前の情報を整数変数dwValueに取得します。
// 該当個所に情報が無ければデフォルトとして0x12345678がdwValueに格納されます。
//
// BOOL RalLoadValue( char *pszKey, char *pszName, DWORD *pdwValue, DWORD dwDefault, BOOL fCreate );
//
if( !RalLoadValue( "IntegerData", "Value2", &dwValue, 0x12345678, TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊
// の傘下からString1という名前の情報を文字配列pszStringに取得します。
// 該当個所に情報が無ければデフォルトとして"abcdef"がpszStringに格納されます。
//
// BOOL RalLoadString( char *pszKey, char *pszName, char *pszString, DWORD cbString, char *pszDefault, BOOL fCreate );
//
if( !RalLoadString( NULL, "String1", pszString, sizeof( pszString ), "abcdef", TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊\StringData
// の傘下からString2という名前の情報を文字配列pszStringに取得します。
// 該当個所に情報が無ければデフォルトとして"abcdef"がpszStringに格納されます。
//
// BOOL RalLoadString( char *pszKey, char *pszName, char *pszString, DWORD cbString, char *pszDefault, BOOL fCreate );
//
if( !RalLoadString( "StringData", "String2", pszString, sizeof( pszString ), "abcdef", TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊
// の傘下からBinary1という名前の情報を構造体BinaryDataに取得します。
// 該当個所に情報が無ければデフォルトとして構造体DefaultDataの内容がBinaryDataに格納されます。
//
// BOOL RalLoadBinary( char *pszKey, char *pszName, void *pvBinary, DWORD cbBinary, void *pvDefault, BOOL fCreate );
//
if( !RalLoadBinary( NULL, "Binary1", &BinaryData, sizeof( BinaryData ), &DefaultData, TRUE ) )
{
  // エラー処理
}

//
// HKEY_CURRENT_USER\Software\雲表ソフト\C坊\BinaryData
// の傘下からBinary2という名前の情報を構造体BinaryDataに取得します。
// 該当個所に情報が無ければデフォルトとして構造体DefaultDataの内容がBinaryDataに格納されます。
//
// BOOL RalLoadBinary( char *pszKey, char *pszName, void *pvBinary, DWORD cbBinary, void *pvDefault, BOOL fCreate );
//
if( !RalLoadBinary( "BinaryData", "Binary2", &BinaryData, sizeof( BinaryData ), &DefaultData, TRUE ) )
{
  // エラー処理
}


戻る