前言
Windows 登錄檔儲存系統與應用程式設定。C++Builder 封裝 TRegistry 類別,提供直覺的物件導向介面,避免繁瑣的 Win32 API (RegCreateKeyEx、RegQueryValueEx 等)。本文詳細說明用法、屬性、方法與最佳實踐。
一、前置準備
// 1. 引入標頭檔
#include <registry.hpp>
// 2. 建立實例 (必須用 new,不可堆疊宣告)
TRegistry* reg = new TRegistry();
// 預設 RootKey = HKEY_CURRENT_USER
// 3. 使用完畢釋放
delete reg;
二、核心屬性
| 屬性 | 型別 | 說明 |
| RootKey | HKEY | 根鍵:HKEY_CURRENT_USER (預設)、HKEY_LOCAL_MACHINE、HKEY_CLASSES_ROOT、HKEY_USERS、HKEY_CURRENT_CONFIG、HKEY_DYN_DATA |
| CurrentPath | String | 目前開啟鍵的完整路徑 (唯讀) |
| LazyWrite | bool | true 時延遲寫入磁碟 (效能較好),false 立即同步 |
三、鍵值操作方法
| 方法 | 用途 | 範例 |
OpenKey(const String& Key, bool CanCreate) | 開啟/建立子鍵,回傳成功與否 | reg->OpenKey("\\Software\\MyApp", true) |
CloseKey() | 關閉目前鍵 | |
KeyExists(const String& Key) | 檢查子鍵是否存在 | |
DeleteKey(const String& Key) | 刪除子鍵 (含所有值) | |
GetKeyNames(TStrings* List) | 列舉所有子鍵名稱 | |
GetValueNames(TStrings* List) | 列舉目前鍵下所有值名稱 | |
ValueExists(const String& Name) | 檢查值是否存在 | |
DeleteValue(const String& Name) | 刪除指定值 | |
四、資料讀寫方法 (型別安全)
| 資料型別 | 寫入 | 讀取 |
| String | WriteString(Name, Value) | ReadString(Name) |
| Integer | WriteInteger(Name, Value) | ReadInteger(Name) |
| Boolean | WriteBool(Name, Value) | ReadBool(Name) |
| Float/Double | WriteFloat(Name, Value) | ReadFloat(Name) |
| DateTime | WriteDateTime(Name, Value) | ReadDateTime(Name) |
| Binary (Byte 陣列) | WriteBinaryData(Name, Buffer, BufSize) | ReadBinaryData(Name, Buffer, BufSize) |
| TStrings | WriteStringList(Name, List) | ReadStringList(Name, List) |
五、完整實戰範例
1. 應用程式設定儲存/載入
class AppSettings {
String regPath = "\\Software\\MyCompany\\MyApp";
TRegistry* reg;
public:
AppSettings() : reg(new TRegistry()) {}
~AppSettings() { delete reg; }
void Save(const String& windowTitle, int left, int top, int width, int height, bool maximize) {
if (reg->OpenKey(regPath, true)) {
reg->WriteString("WindowTitle", windowTitle);
reg->WriteInteger("Left", left);
reg->WriteInteger("Top", top);
reg->WriteInteger("Width", width);
reg->WriteInteger("Height", height);
reg->WriteBool("Maximized", maximize);
reg->CloseKey();
}
}
void Load(String& windowTitle, int& left, int& top, int& width, int& height, bool& maximize) {
if (reg->OpenKey(regPath, false)) {
windowTitle = reg->ReadString("WindowTitle");
left = reg->ReadInteger("Left");
top = reg->ReadInteger("Top");
width = reg->ReadInteger("Width");
height = reg->ReadInteger("Height");
maximize = reg->ReadBool("Maximized");
reg->CloseKey();
}
}
};
2. 檔案關聯註冊 (需管理員權限)
void RegisterFileAssociation(const String& ext, const String& progId, const String& desc, const String& exePath, const String& iconPath) {
TRegistry* reg = new TRegistry();
reg->RootKey = HKEY_CLASSES_ROOT;
// 1. 副檔名 → ProgID
if (reg->OpenKey(ext, true))
reg->WriteString("", progId);
// 2. ProgID 定義
String progPath = progId + "\\shell\\open\\command";
if (reg->OpenKey(progPath, true))
reg->WriteString("", "\"" + exePath + "\" \"%1\"");
// 3. 圖示
if (reg->OpenKey(progId + "\\DefaultIcon", true))
reg->WriteString("", iconPath + ",0");
// 4. 描述
if (reg->OpenKey(progId, true))
reg->WriteString("", desc);
delete reg;
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL); // 通知殼層重整
}
3. 列舉已安裝軟體 (HKEY_LOCAL_MACHINE)
void ListInstalledSoftware(TStrings* list) {
TRegistry* reg = new TRegistry();
reg->RootKey = HKEY_LOCAL_MACHINE;
if (reg->OpenKey("\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall", false)) {
reg->GetKeyNames(list);
reg->CloseKey();
}
delete reg;
}
六、權限與安全性注意事項
⚠ 關鍵提醒
- HKEY_LOCAL_MACHINE 寫入需**管理員權限** (UAC 昇權)
- Vista+ 虛擬化:32 位應用寫入
HKLM\Software 會被重導向至 HKCU\Software\Classes\VirtualStore
- 敏感資料 (密碼、金鑰) **勿明文存入登錄檔**,使用 DPAPI (
CryptProtectData) 加密
- 大量讀寫設
LazyWrite = true,關鍵資料設 false 確保同步
- 64 位系統:32 位應用預設存取
Wow6432Node 視圖,需 KEY_WOW64_64KEY 旗標 (TRegistry 不直接支援,需呼叫 API)
七、現代替代方案
- 應用程式設定:
System.IniFiles.TMemIniFile (INI 檔)、System.JSON + 檔案、WinRT Windows.Storage.ApplicationData (UWP/WinUI)
- 跨平台:FireMonkey 專案用
System.IniFiles 或 SQLite
- 高效能/大量資料:SQLite / LevelDB / Redis
結語
TRegistry 為 VCL 應用提供便利的登錄檔存取,掌握根鍵選擇、鍵值操作、型別安全讀寫、權限模型與虛擬化機制,能正確實作設定持久化、檔案關聯、軟體清查等功能。新架構專案建議評估 INI/JSON/雲端同步等現代替代方案。