レジストリ――正体はWindowsフォルダにあるUser.datとSystem.datのことです。これらのファイルはあらゆるアプリケーション、そしてOSと常にアクセスし、ありとあらゆる情報を格納しています。
レジストリは非常に便利な存在です。ユーザーひとりひとりの情報を格納することにプログラマ側は気を使わずに済み、同じメーカーのアプリケーション同士の情報を交換しあい、ときには他メーカーのアプリケーションの情報を取得し、むちゃくちゃな方法として一種のグローバル変数として使う方法もあります。
レジストリを操作する方法は、3つあります。ひとつはWin32APIを使う方法。ふたつめは、CWinAppクラスのメンバ関数を使う方法、みっつめはCRecentFileListクラスを使う方法です。これらを使ってレジストリにアクセスする方法を見ていきましょう。 |
Win32APIを使ってみる
まずはじめに、winreg.hヘッダーファイルを読み込んでおかないと、このレジストリ関連のAPIは使えません。簡単な方法は、「ビルド」−「設定」−「C/C++」−「プリコンパイル済みヘッダー」で、「プリコンパイル済みヘッダーを使用しない」を選択すればそれでOKです。
さて、実際のレジストリ操作ですが、まずRegSetValueEx関数で新しくキーを作るか、RegOpenKeyEx関数で既存のキーを開きます。このとき、成功すればそのキーへのハンドルを取得できます。レジストリへの操作は、このハンドルを使います。ファイルに似てますね。
Win32APIを使う以外の2つの方法は、HKEY_CURRENT_USERにしかアクセスできません。そのため、他のキーにアクセスするためにはWin32APIを使う必要があります。また、MFCに頼らないインストーラなどを作る場合にも必要でしょう。
HKEY_CLASSES_ROOTでは、まず拡張子を設定できます。フォルダの「オプション」−「ファイルタイプ」で表示されるデータは、このレジストリが元になっています。自分のアプリケーションが独自のファイルタイプを持つ場合には、この部分に自分の拡張子を書き加えます。また、ShellNewというキーを加えると、フォルダ上の右クリック−新規作成で表示されます。
HKEY_CURRENT_USERには、現在ログインしているユーザーの各設定情報が書き込まれています。「ログイン」というのはウィンドウズNTでは普通のもので、1台の機械を何人もの人が使う場合、最初にユーザー名とパスワードを入力します。インターネットへのログインとほぼ同じです。そうやってログインした場合、各ユーザーごとにカスタマイズの内容は異なることになるので、ユーザーごとの情報は個別に取って置かれます。このHKEY_CURRENT_USERには、現在しているユーザーの情報が書かれているので、ソフトウェアはこの部分にアクセスするだけで済みます。現在ログインしているユーザーを調べる必要がなければ、他のユーザーの設定を変更する恐れもありません。
HKEY_LOCAL_MACHINEには、そのコンピューターの設定が書き込まれています。ユーザーごとに変わることのないハードウェアの設定やアプリケーションのインストール場所、ウィンドウズのフォルダの位置などが書き込まれています。
HKEY_USERSには、各ユーザーの情報が書き込まれています。ウィンドウズ95をひとりで使っている場合には、ここには.Defaultしかありません。これは、基本的にHKEY_CURRENT_USERの内容と同じです。複数人数で使っている場合には、各ユーザーの情報があります。ウィンドウズNTでは、基本的に他のユーザーがこのレジストリにアクセスすることはできません。
HKEY_CURRENT_CONFIGには、HKEY_LOCAL_MACHINE_Configの中身と同じ内容が書き込まれていると思います。ちょっとよくわかんないかも。ごめん。
HKEY_DYN_DATAには、ハードウェアやドライバの設定が書き込まれています。ほとんどがバイナリー形式なので、下手に書き加えない方がいいでしょう。
と、以上のようにWin32APIを使ってアクセスする部分は、HKEY_CLASSES_ROOTとHKEY_LOCAL_MACHINEがほとんどです。簡単なライブラリを作っておくと便利でしょう。 |
CWinAppクラスのメンバ関数を使う
CWinAppクラスには、レジストリを扱う便利なメンバ関数が揃っています。これを使わない手はありません。実際にどう使うか、見てみましょう。
アプリケーションの各情報は、ウィンドウズ3.1までイニシャライゼーションファイル(拡張子がiniのファイル)を使っていました。ですが、Win32では、それらはレジストリのHKEY_CURRENT_USER\SOFTWAREに蓄えられています。CWinAppクラスは、デフォルトとしてなぜかイニシャライゼーションファイルへの書き込みを行うようにしています。それをまずはレジストリに書き込むようにします。そのために、SetRegistryKeyメンバ関数を使います。 |
SetRegistryKey( _T( "KAB-Software Develop-studio" ) );
こうすることで、各データはイニシャライゼーションファイルではなく、HKEY_CURRENT_USER\SOFTWARE\KAB-Software Develop-studio\MadoKAB(アプリケーションの名前です)へと書き込まれるようになりました(逆に言えば、HKEY_CURRENT_USER\SOFTWARE以外には書き込めないということです。それ以外はWin32APIを用います)。
さて、実際の読み書きはWriteProfileStringメンバ関数やGetProfileStringメンバ関数を用いて、値の書き込み&読み込みを行います。Win32APIを使うよりもずっと簡単です。ただ、操作できるのは整数と文字列だけです。バイナリーデータ等はWin32APIでないとムリです。
これらのメンバ関数を使うときの注意として、CWinAppクラスのオブジェクトへのポインタを取得する方法というのがあります。ドキュメントやビューからこれらのメンバ関数を使うときには、グローバル変数のを使うか、AfxGetApp関数を使ってCWinAppクラスへのポインタを取得しておきましょう。例としてはこんな感じでしょうか。 |
CWinApp* pApp = AfxGetApp();
i = pApp->GetProfileInt( _T( "Settings\\Global" ), _T( "Open" ), 0 );
SetRegistryKeyメンバ関数は一度使ってしまえばいいので、InitInstanceメンバ関数の中で行ってしまいましょう。
あと、他のアプリケーションの情報を書き換えないよう注意しましょう。無断で他のデベロッパーのアプリケーション情報を利用していると、そのアプリケーションの仕様が変わったときに困ったことになるので、とりあえず「使いますよ」くらいのことは言っておいた方がいいでしょう(相手がMSとかだとちょっとムリかも……)。 |
CRecentFileListクラスを使う
さて最後に、CRecentFileListクラスという便利なクラスを使ってみましょう。あ、afxadv.hヘッダーファイルを読み込んでおきましょうね。 このクラスは、ほとんどのアプリケーションに見られる「最近使ったファイル」の情報を扱うためのクラスです。「ファイル」の下の方につらつらとありますね。元々はファイルの情報を扱うためのものですが、いろいろなことに使えるんで便利に利用しましょう。
まず最初に、前述のSetRegistryKeyメンバ関数を使ってあることが前提です。これも一回使っていればいいので、InitInstanceメンバ関数の中ですでに使っていればそれで問題ないでしょう。 |
CRecentFileList MList( 0, _T( "Settings\\MRU" ), _T( "%d" ), 20 );
詳しいことはオンラインヘルプを見てください。こうすることで、HKEY_CURRENT_USER\SOFTWARE\KAB-Software Develop-studio\MadoKAB(アプリケーションの名前です)\Settings\MRUキーにデータが書き込まれるようになりました。データの名前は各数字が使われます。
そのあと、実際に操作をする前にReadListメンバ関数を使って、実際のレジストリからデータを読み込んでおきます。これをしておかないと、オブジェクトの中身が空のままです。 読み込んだあとは、各操作ができます。実際には配列を操作するのに似ています。 操作したあとは、WriteListメンバ関数を使ってレジストリに書き込みます。これも忘れるとなんの意味もありません。
このクラスはなかなか便利で、色々なリストをレジストリに書き込むときに重宝します。もしこれを手動でするとなると、forを使ってループを作り、各数字をitoaを使って文字に変換してWriteProfileStringメンバ関数を使わなければならないでしょう。それに比べれば、非常に便利なクラスといえます。
しかし、いくつか問題点もあるので注意しておきましょう。その多くは、これが「最近使ったファイル」を操作するために作られたことに起因します。
あと、他に注意すべき点がいくつかあります。このクラスで扱ったキーは、完全に作り変えられます。そのキーの中に他の値があった場合でも、それらはすべて削除されて、このクラスの値だけが残るようになります。このクラスを使う場合には、別にキーを用意する必要があるということです。
こう見ると使いにくそうですが、うまく使えば非常に便利なものです。ぜひ使いましょう。
|
まとめ
さて、以上をまとめると……
・OS全体に関わるデータはWin32APIを使う。主にインストール時にお世話になる。 ・アプリケーションの各設定はCWinAppクラスのメンバ関数を使う。 ・リスト形式の設定をレジストリに書き込むときはCRecentFileListクラスが便利。 というところになるでしょうか。レジストリは慣れるとひじょーに便利なので、がんがん使っていきましょう。
|
HKEY_CLASSES_ROOTに簡単に書き込む
MFCの中にはHKEY_CLASSES_ROOTに簡単に書き込むこめる関数があります。その名はSetRegKey()。ですが、これstatic関数なので他のファイルから使用することができません。 関数の定義はDocmgr.cppの76行目くらいにあると思うので、コピーして自分のアプリケーションで使ってしまいましょう(笑)。 |
アプリケーション名以外のキーを使いたい!!
CWinAppのメンバを使ってレジストリに書き込むと、必ずアプリケーション名のキーを使用することになります。ですが、実際には変えたい場合もあるでしょう(実行ファイルの名前が同じでバージョンの違うものとか)。 実は、このキーの部分はCWinApp::m_pszProfileNameという部分に格納されています。デフォルトではアプリケーション名ですが、ちゃんと変えることができます。実際にはCWinApp::SetRegistryKey()のあとくらいに、次のコードを書き込めばOKです。 |
free( (void *)m_pszProfileName );
m_pszProfileName = _tcsdup( cKeyStr );
// cKeyStrには指定したいキーの名前が入っています。
こうすることで、書き込むキーは「Software\(SetRegistryKey())\(m_pszProfileName)」となります。この文字列は動的に作製しなければならないので、その辺を注意してください。
|
(C)KAB-studio 1997, 1998 ALL RIGHTS RESERVED. |