Windows 註冊表是系統配置、硬體資訊、應用程式設定與使用者偏好的中央資料庫。許多進階功能(如自動啟動、檔案關聯、系統策略)都必須透過操作註冊表來實現。雖然 WinAPI 提供了 RegCreateKey()、RegOpenKey()、RegQueryValue() 等函式,但直接呼叫這些 API 程式碼冗長且容易出錯。C++Builder 封裝了 TRegistry 類別,讓開發者能以物件導向方式輕鬆存取註冊表。
首先在專案原始碼最前端引入標頭檔:
#include <registry.hpp>
接著在全域變數區(所有函式之前)以 new 關鍵字建立實例:
TRegistry *MyReg = new TRegistry();
注意: 不能直接宣告 TRegistry MyReg;,這與 VC++ 使用 HKEY 直接操作不同。必須用指標管理物件生命週期。建立後,RootKey 屬性預設指向 HKEY_CURRENT_USER。
HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE、HKEY_CLASSES_ROOT、HKEY_USERS、HKEY_CURRENT_CONFIG、HKEY_DYN_DATA 等常數。Software\Borland),不含根鍵名稱。true,表示寫入操作暫存於記憶體,直到呼叫 CloseKey() 才寫入實體註冊表,提升效能。若需即時生效,設為 false 再執行寫入。bool 表示成功與否。CanCreate=true 時若鍵不存在會自動建立。ReadInteger、WriteBool、ReadBinaryData、WriteDateTime 等。TStringList 實例(TStrings 為抽象類別)。delete MyReg; 釋放物件記憶體。TRegistry 實例(new)。OpenKey() 定位目標鍵。ReadXxx() / WriteXxx() 讀寫資料。CloseKey() 並 delete 物件。此範例示範:首次執行時建立註冊表項、累計執行次數、儲存使用者輸入字串、透過 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run 實現開機自動啟動。
表單元件: Edit1、Label2(顯示次數)、Button1(刪除註冊表項)、CheckBox1(Caption="每次啟動電腦自動運行")。
核心程式碼:
// Unit1.cpp
#include <vcl.h>
#pragma hdrstop
#include <registry.hpp>
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TRegistry *MyReg = new TRegistry(); // 全域實例
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
// --- 讀寫 HKEY_CURRENT_USER\Software\MyReg ---
MyReg->RootKey = HKEY_CURRENT_USER;
if (!MyReg->OpenKey("\\Software\\MyReg", false)) {
MessageBox(NULL, "感謝第一次使用本軟體!", "歡迎!", IDOK);
MyReg->CreateKey("\\Software\\MyReg");
MyReg->OpenKey("\\Software\\MyReg", true);
MyReg->WriteInteger("Number", 0);
MyReg->WriteString("TheString", Edit1->Text);
}
int num = MyReg->ReadInteger("Number") + 1;
MyReg->WriteInteger("Number", num);
Label2->Caption = IntToStr(num);
Edit1->Text = MyReg->ReadString("TheString");
MyReg->CloseKey();
// --- 檢查自動啟動狀態 (HKEY_LOCAL_MACHINE) ---
MyReg->RootKey = HKEY_LOCAL_MACHINE;
MyReg->OpenKey("\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", false);
CheckBox1->Checked = MyReg->ValueExists("AutoShow");
MyReg->CloseKey();
}
void __fastcall TForm1::Edit1Change(TObject *Sender)
{
MyReg->RootKey = HKEY_CURRENT_USER;
MyReg->OpenKey("\\Software\\MyReg", false);
MyReg->WriteString("TheString", Edit1->Text);
MyReg->CloseKey();
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
MyReg->RootKey = HKEY_LOCAL_MACHINE;
MyReg->OpenKey("\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", false);
if (CheckBox1->Checked)
MyReg->WriteString("AutoShow", "C:\\MyReg.exe");
else
MyReg->DeleteValue("AutoShow");
MyReg->CloseKey();
delete MyReg; // 釋放全域實例
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// 刪除自動啟動值
MyReg->RootKey = HKEY_LOCAL_MACHINE;
MyReg->OpenKey("\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", false);
MyReg->DeleteValue("AutoShow");
MyReg->CloseKey();
// 刪除自訂項
MyReg->RootKey = HKEY_CURRENT_USER;
MyReg->DeleteKey("\\Software\\MyReg");
}
原理: Windows 將啟用的輸入法順序儲存在 HKEY_CURRENT_USER\Keyboard Layout\Preload 下,子鍵 1、2、3... 對應順序,其預設值為輸入法識別碼(如 00000409 為英文、E0040804 為智慧 ABC)。輸入法名稱則在 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Keyboard Layouts\{ID} 的 Layout Text 值中。透過交換 Preload 下的識別碼順序即可調整輸入法優先序。
介面佈局: ListBox1(顯示輸入法名稱)、BitBtn1(上移)、BitBtn2(下移)、BitBtn3(確認套用)。
關鍵程式碼片段:
// FormCreate: 列出目前輸入法
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Reg1 = new TRegistry; Reg1->RootKey = HKEY_CURRENT_USER;
Reg2 = new TRegistry; Reg2->RootKey = HKEY_LOCAL_MACHINE;
Reg1->OpenKey("\\Keyboard Layout\\Preload", false);
Reg1->GetKeyInfo(keyInfo);
ListBox1->Items->Clear();
imeStr = new AnsiString[keyInfo.NumSubKeys];
for (int i = 0; i < keyInfo.NumSubKeys; i++) {
Reg1->OpenKey("\\Keyboard Layout\\Preload\\" + IntToStr(i+1), false);
imeStr[i] = Reg1->ReadString(""); // 取得識別碼
Reg2->OpenKey("\\System\\CurrentControlSet\\Control\\Keyboard Layouts\\" + imeStr[i], false);
ListBox1->Items->Add(Reg2->ReadString("Layout Text")); // 顯示名稱
}
Reg1->CloseKey(); Reg2->CloseKey(); delete Reg2;
}
// BitBtn1Click: 上移
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
int i = ListBox1->ItemIndex;
if (i > 0) {
ListBox1->Items->Exchange(i, i-1);
swap(imeStr[i], imeStr[i-1]);
}
}
// BitBtn3Click: 寫回註冊表並重開機
void __fastcall TForm1::BitBtn3Click(TObject *Sender)
{
if (Application->MessageBox("確認更改輸入法順序?", "請確認", MB_OKCANCEL|MB_ICONWARNING) == ID_OK) {
for (int i = 0; i < keyInfo.NumSubKeys; i++) {
Reg1->OpenKey("\\Keyboard Layout\\Preload\\" + IntToStr(i+1), false);
Reg1->WriteString("", imeStr[i]);
}
Reg1->CloseKey(); delete Reg1; delete imeStr;
if (Application->MessageBox("需重新啟動電腦方能生效,立即重啟?", "重啟", MB_OKCANCEL|MB_ICONWARNING) == ID_OK)
ExitWindowsEx(EWX_REBOOT, 0);
}
Close();
}
本程式在 Windows 98 / C++Builder 6.0 環境測試通過。