六大根鍵:HKEY_CLASSES_ROOT (HKCR)、HKEY_CURRENT_USER (HKCU)、HKEY_LOCAL_MACHINE (HKLM)、HKEY_USERS (HKU)、HKEY_CURRENT_CONFIG (HKCC)、HKEY_PERFORMANCE_DATA。樹狀結構:鍵 → 子鍵 → 值 (名稱/資料/類型)。
TRegistry* reg = new TRegistry; // 預設 RootKey = HKCU
// 切換根鍵
reg->RootKey = HKEY_LOCAL_MACHINE; // 需管理員權限寫入
// 開啟現有鍵 (唯讀)
if (reg->OpenKeyReadOnly("\\Software\\MyApp")) { ... }
// 開啟或建立鍵 (可寫)
if (reg->OpenKey("\\Software\\MyApp", true)) { // true = 不存在則建立
// 讀寫值...
reg->CloseKey();
}
路徑格式:\\Software\\MyApp (絕對、相對根鍵)、SubKey (相對當前鍵)。
// 寫入
reg->WriteString("Version", "1.0.0");
reg->WriteInteger("MaxConnections", 100);
reg->WriteBool("AutoStart", true);
reg->WriteBinaryData("Key", buffer, size);
// 讀取 (不存在會拋出異常,建議先檢查)
if (reg->ValueExists("Version"))
AnsiString ver = reg->ReadString("Version");
int maxConn = reg->ReadInteger("MaxConnections"); // 不存在返回 0
bool autoStart = reg->ReadBool("AutoStart");
TStringList* keys = new TStringList;
reg->GetKeyNames(keys); // 當前鍵下所有子鍵名稱
for (int i = 0; i < keys->Count; ++i)
ListBox1->Items->Add(keys->Strings[i]);
delete keys;
TStringList* vals = new TStringList;
reg->GetValueNames(vals); // 當前鍵下所有值名稱
// ...
delete vals;
注意:GetKeyNames/ValueNames 參數為 TStrings*,必須用衍生類 TStringList 實例化(TStrings 為抽象類)。
LazyWrite = true (預設):寫入操作暫存記憶體,CloseKey() 時一次寫入磁碟 → 效能佳。LazyWrite = false:每次寫入立即同步磁碟 → 關鍵設定即時生效、跨進程可見。
reg->CloseKey();
delete reg; // 釋放 new 配置的記憶體
void __fastcall TForm1::BtnReadClick(TObject* Sender) {
TRegistry* reg = new TRegistry;
reg->RootKey = HKEY_LOCAL_MACHINE;
if (reg->OpenKeyReadOnly("\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")) {
TStringList* keys = new TStringList;
reg->GetKeyNames(keys);
for (int i = 0; i < keys->Count; ++i) {
TRegistry* sub = new TRegistry;
sub->RootKey = HKEY_LOCAL_MACHINE;
if (sub->OpenKeyReadOnly("\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + keys->Strings[i])) {
if (sub->ValueExists("DisplayName")) {
ComboBox1->Items->Add(sub->ReadString("DisplayName"));
}
sub->CloseKey();
delete sub;
}
}
reg->CloseKey();
delete keys;
}
delete reg;
}
| 錯誤 | 後果 | 修正 |
|---|---|---|
忘記 CloseKey() / delete | 鍵控制代碼洩漏、記憶體洩漏 | 用 RAII 包裝或 try__finally 確保釋放 |
直接用 TStrings* 宣告變數傳給 GetKeyNames | 編譯錯誤(抽象類無法實例化) | 用 TStringList* |
| 寫入 HKLM 無管理員權限 | 存取被拒絕、靜默失敗 | 清單檔要求 requireAdministrator 或寫 HKCU |
路徑分隔符用單反斜線 \ | C++ 字串逸出錯誤 | 用雙反斜線 \\ 或原始字串 R"(\Software\MyApp)" |
| 假設值存在直接 ReadString | 拋出 ERegistryException | 先 ValueExists() 或 try-catch |