首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++Builder 註冊表程式設計完整指南與實戰範例

     編輯:關於C++

一、註冊表程式設計核心概念

Windows 註冊表是系統配置、硬體資訊、應用程式設定與使用者偏好的中央資料庫。許多進階功能(如自動啟動、檔案關聯、系統策略)都必須透過操作註冊表來實現。雖然 WinAPI 提供了 RegCreateKey()、RegOpenKey()、RegQueryValue() 等函式,但直接呼叫這些 API 程式碼冗長且容易出錯。C++Builder 封裝了 TRegistry 類別,讓開發者能以物件導向方式輕鬆存取註冊表。

1. 使用前的準備工作

首先在專案原始碼最前端引入標頭檔:

#include <registry.hpp>

接著在全域變數區(所有函式之前)以 new 關鍵字建立實例:

TRegistry *MyReg = new TRegistry();

注意: 不能直接宣告 TRegistry MyReg;,這與 VC++ 使用 HKEY 直接操作不同。必須用指標管理物件生命週期。建立後,RootKey 屬性預設指向 HKEY_CURRENT_USER。

2. 核心屬性與方法詳解

  • RootKey (int):目前操作的根鍵。可指派 HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE、HKEY_CLASSES_ROOT、HKEY_USERS、HKEY_CURRENT_CONFIG、HKEY_DYN_DATA 等常數。
  • CurrentPath (AnsiString):目前鍵值的相對路徑文字描述(如 Software\Borland),不含根鍵名稱。
  • LazyWrite (bool):預設 true,表示寫入操作暫存於記憶體,直到呼叫 CloseKey() 才寫入實體註冊表,提升效能。若需即時生效,設為 false 再執行寫入。
  • CreateKey(const AnsiString& Key):建立子鍵,若已存在則覆蓋。回傳 bool 表示成功與否。
  • DeleteKey(const AnsiString& Key):刪除指定子鍵;參數為空字串時刪除目前鍵。
  • OpenKey(const AnsiString& Key, bool CanCreate):定位至指定鍵,後續讀寫以此為基準。CanCreate=true 時若鍵不存在會自動建立。
  • ReadString / WriteString:讀寫字串型值。同類函式尚有 ReadInteger、WriteBool、ReadBinaryData、WriteDateTime 等。
  • ValueExists / KeyExists:檢查值或子鍵是否存在。
  • GetKeyNames(TStrings* Strings):取得目前鍵下所有子鍵名稱。參數需傳入 TStringList 實例(TStrings 為抽象類別)。
  • CloseKey():關閉目前開啟的鍵,釋放系統資源。使用完畢後務必呼叫 delete MyReg; 釋放物件記憶體。

3. 標準操作四步驟

  1. 建立 TRegistry 實例(new)。
  2. 呼叫 OpenKey() 定位目標鍵。
  3. 使用 ReadXxx() / WriteXxx() 讀寫資料。
  4. 呼叫 CloseKey() 並 delete 物件。

二、實戰範例 1:應用程式執行計數與自動啟動管理

此範例示範:首次執行時建立註冊表項、累計執行次數、儲存使用者輸入字串、透過 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");
}

三、實戰範例 2:輸入法順序調整器

原理: 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 環境測試通過。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved