8

私は C++ と WinCe 開発の初心者です。

レジストリから文字列を読み取り、MessageBox(). 私は以下を試しました。

HKEY key;
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\GPS Intermediate Driver\\Drivers\\SiRFStar3HW"), 0, KEY_READ, &key) != ERROR_SUCCESS)
{
    MessageBox(NULL,L"Can't open the registry!",L"Error",MB_OK);
}
char value[5];
DWORD value_length=5;
DWORD type=REG_SZ;
RegQueryValueEx(key,(LPCTSTR)"Baud", NULL, &type, (LPBYTE)&value, &value_length);
wchar_t buffer[5];
_stprintf(buffer, _T("%i"), value);

::MessageBox(NULL,buffer,L"Value:",MB_OK);

::RegCloseKey(key);

ここで何か問題があることはわかっていますが、どうすれば解決できますか?

4

5 に答える 5

22

Win32 APIの操作は、難しい作業になる可能性があります。レジストリAPIは、より複雑なもののいくつかです。これは、レジストリ文字列を読み取る方法を示す短いプログラムです。

#include <Windows.h>
#include <iostream>
#include <string>

using namespace std;

wstring ReadRegValue(HKEY root, wstring key, wstring name)
{
    HKEY hKey;
    if (RegOpenKeyEx(root, key.c_str(), 0, KEY_READ, &hKey) != ERROR_SUCCESS)
        throw "Could not open registry key";

    DWORD type;
    DWORD cbData;
    if (RegQueryValueEx(hKey, name.c_str(), NULL, &type, NULL, &cbData) != ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        throw "Could not read registry value";
    }

    if (type != REG_SZ)
    {
        RegCloseKey(hKey);
        throw "Incorrect registry value type";
    }

    wstring value(cbData/sizeof(wchar_t), L'\0');
    if (RegQueryValueEx(hKey, name.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(&value[0]), &cbData) != ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
        throw "Could not read registry value";
    }

    RegCloseKey(hKey);

    size_t firstNull = value.find_first_of(L'\0');
    if (firstNull != string::npos)
        value.resize(firstNull);

    return value;
}

int wmain(int argc, wchar_t* argv[])
{
    wcout << ReadRegValue(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", L"CommonFilesDir");
    return 0;
}

ノート:

  1. 私はCEを持っていないので、これはUnicode用にコンパイルされたプレーンなWin32アプリです。CEはANSI文字を使用しないため、私はそのルートを採用しました。
  2. 私は多くのC++機能を利用しました。最も重要なのはstd::wstring。これにより、文字列の処理が簡単になります。
  3. エラー処理に例外を使用しました。これを他のメカニズムに置き換えることもできますが、エラー処理の問題をバックグラウンドで維持するという私の目的を果たしました。
  4. 例外を使用すると、レジストリキーを閉じるのが少し面倒になります。より良い解決策は、RAIIクラスを使用してレジストリキーの有効期間をまとめることです。簡単にするためにそれを省略しましたが、本番コードでは、その余分な手順を実行する必要があります。
  5. 通常、nullで終了するデータをRegQueryValueEx返します。REG_SZこのコードは、最初のヌル文字を超えて切り捨てることによってそれを処理します。返される値がnullで終了していない場合、その切り捨ては発生しませんが、値は引き続き問題ありません。
  6. コンソールに印刷したばかりですが、電話をかけるのは簡単ですMessageBox。このような:MessageBox(0, value.c_str(), L"Caption", MB_OK)
于 2012-05-20T19:42:43.277 に答える
1

これはテストされていません (私のデバイスにはあなたのキー/値がありません) が、CE 用にコンパイルされ、目的を達成する方法の要点が得られます: #include

int _tmain(int argc, _TCHAR* argv[])
{
    HKEY key;

    if(!RegOpenKeyEx(
        HKEY_LOCAL_MACHINE, 
        _T("System\\CurrentControlSet\\GPS Intermediate Driver\\Drivers\\SiRFStar3HW"), 
        0, 
        NULL, 
        &key))
    {
        MessageBox(NULL, _T("Failed to open key"), _T("Error"), 0);
        return -1;
    }

    DWORD length;

    // get the size - it's going to be 4 for a DWORD, but this shows how to deal with REG_SZ, etc
    if(!RegQueryValueEx(
        key, 
        _T("Baud"), 
        NULL, 
        NULL, 
        NULL, 
        &length))
    {
        MessageBox(NULL, _T("Failed to get buffer size"), _T("Error"), 0);
        goto exit;
    }

    // allocate - again, if we know it's a DWORD, this could be simplified
    BYTE *buffer = (BYTE*)LocalAlloc(LPTR, length);

    // query
    if(!RegQueryValueEx(
        key, 
        _T("Baud"), 
        NULL, NULL, 
        buffer, 
        &length))
    {
        MessageBox(NULL, _T("Failed to get value data"), _T("Error"), 0);
        goto exit;
    }

    // assuming "baud" is a DWORD, not a string
    DWORD baud = *(DWORD*)buffer;

    // build an output
    TCHAR message[MAX_PATH];
    _stprintf(message, _T("The baud value is %i"), baud);
    MessageBox(NULL, message, _T("Success"), 0);

    exit:
    RegCloseKey(key);

    return 0;
}
于 2012-05-20T22:55:44.513 に答える
-1

RegQueryValueEx を使用して buf に入れるだけです

于 2013-07-18T12:34:08.927 に答える
-1

char 配列を使用する場合は、次のように、バッファーではなくバッファーへのポインターを設定する必要があります。

MessageBox(0,&buffer,"Value:",MB_OK);
于 2012-05-20T19:08:42.560 に答える