レジストリの情報を取得する関数で 前に設定した値が取得される

[戻る]
東海B 2005/07/12(火) 16:50:44
MFC VC++ 6.0 Windows XP sp2
レジストリの種類はREZ_SZの文字列で、
その値を取得する関数GetRegを作成しました。
引数はレジストリの名前になっております。

そこで下記の関数を利用すると、何故か前に設定した違うレジストリの値が
取得されます。
何故このようなことがおこるのでしょうか?


例えばレジストリに

Toolbar 100
Statusbar 200
が設定されているとして以下の関数を実行いたします。
Result2 にToolbarの100が取得されます。
何が原因なのでしょうか?
知っている方教えてください。

void test(){
     SetReg("Toolbar", 100);
     int Result2 = atoi(GetReg("Statusbar"));
}

CString GetReg( CString istrKeyName ){

    // レジストリキーのオープン
    HKEY hkResult;            // キーのハンドル
    DWORD dwDisposition;    // 処理結果を受け取る
    LONG lResult;            // 関数の戻り値を格納する
    lResult = ::RegCreateKeyEx(    HKEY_CURRENT_USER, "Software\\TEST",
                            
    0,"",REG_OPTION_NON_VOLATILE, 
                            
    KEY_ALL_ACCESS, NULL, 
                            
    &hkResult, &dwDisposition);
    if( lResult != ERROR_SUCCESS ){
        AfxMessageBox("It failed in the opening of the registry.");
    }
    
    istrKeyName += '\0';

    // レジストリの値の取得
    //CString ostrValue = "\0";        // 各種キーのデータを受け取る
    CString ostrValue;        // 各種キーのデータを受け取る
    DWORD dwType;            // 値の種類
    DWORD dwSize;            // データのサイズ
    ::RegQueryValueEx(hkResult, istrKeyName, 
         NULL, &dwType, NULL, &dwSize);

    if(dwSize != 0 ){
       ::RegQueryValueEx(hkResult, istrKeyName, NULL, &dwType, 
            (LPBYTE)(LPCTSTR)ostrValue, &dwSize);
    }

    // レジストリキーのクローズ
    ::RegCloseKey(hkResult);

    return ostrValue;
}

void SetReg( CString istrKeyName , CString istrValue ){

    // レジストリキーのオープン
    HKEY hkResult;            // キーのハンドル
    DWORD dwDisposition;    // 処理結果を受け取る
    LONG lResult;            // 関数の戻り値を格納する
    lResult = ::RegCreateKeyEx(    HKEY_CURRENT_USER, "Software\\TEST",
                            
    0,"",REG_OPTION_NON_VOLATILE, 
                            
    KEY_ALL_ACCESS, NULL, 
                            
    &hkResult, &dwDisposition);
    if( lResult != ERROR_SUCCESS ){
        AfxMessageBox("It failed in the opening of the registry.");
    }
    
    // レジストリの値を設定
    ::RegSetValueEx(hkResult, istrKeyName, 
                    0, REG_SZ, 
                    (CONST BYTE*)(LPCTSTR)istrValue, 
                    istrValue.GetLength() + 1);

    // レジストリキーのクローズ
    ::RegCloseKey(hkResult);
}

東海B 2005/07/12(火) 16:52:58
間違えました。修正します。

void test(){
     SetReg("Toolbar", "100");<<-----------------修正
     int Result2 = atoi(GetReg("Statusbar"));
}

KING・王 2005/07/12(火) 17:58:59
本題と関係ないかもしれませんが、少し気になったので。

>   // レジストリの値の取得
>    //CString ostrValue = "\0";        // 各種キーのデータを受け取る
>    CString ostrValue;        // 各種キーのデータを受け取る
>    DWORD dwType;            // 値の種類
>    DWORD dwSize;            // データのサイズ
>    ::RegQueryValueEx(hkResult, istrKeyName, 
>         NULL, &dwType, NULL, &dwSize);
>
>    if(dwSize != 0 ){
>       ::RegQueryValueEx(hkResult, istrKeyName, NULL, &dwType, 
>            (LPBYTE)(LPCTSTR)ostrValue, &dwSize);
>    }

で値を取得するのに、RegQueryValueEx()の引数で、ostrValueを用いていますが、
値を格納してもらうためのバッファにCStingは使用できたのでしょうか?
RegQueryValueEx()の中では、ostrValueはCStringとしては扱われないので、
動的にメモリが確保されることなど無く、正しく動作しないと思うのですが。

あまり詳しくないのですが、CStirngを用いる場合には、CString.GetBuffer()などで、
必要なメモリを確保してから、使用する必要があるかと。
#すいません。このあたり、詳しくないので、識者の方々フォローをお願いします。
#私の場合、迷わず、charの配列を用意して用いますので。

... 2005/07/13(水) 17:19:57
>void test(){
>     SetReg("Toolbar", 100);
>     int Result2 = atoi(GetReg("Statusbar"));
>}                               ^^^^^^^^^
よくやる失敗。

MFCであれば、CWinAppのメンバの
GetProfileInt
WriteProfileInt 
GetProfileString
WriteProfileString
を使ったほうがはるかに簡単。
レジストリでなくINIファイルを使うOSでも同等の動作をしてくれます。

古いスレッドには追加発言できません。