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

註冊表讀寫實戰:MFC 應用中修改用戶/公司名稱完整範例

     編輯:關於VC++

註冊表基礎知識速覽

  • 根鍵:HKEY_LOCAL_MACHINE (機器配置)、HKEY_CURRENT_USER (當前用戶)、HKEY_CLASSES_ROOT (文件關聯/COM)、HKEY_USERS、HKEY_CURRENT_CONFIG。
  • 數據類型:REG_SZ (字串)、REG_DWORD (32位整數)、REG_BINARY (二進位)、REG_MULTI_SZ (多字串)、REG_EXPAND_SZ (含環境變數字串)。
  • 核心 API:RegOpenKeyEx、RegQueryValueEx、RegSetValueEx、RegCloseKey。

路徑差異:9x vs NT 系列

系統路徑
Windows 9x/MeHKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion
Windows NT/2000/XP/後續HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion

目標值:RegisteredOwner (用戶名)、RegisteredOrganization (公司名)。

MFC 對話框專案實作

介面佈局

  • 兩個編輯框:綁定 CString m_strOwner、m_strCompany。
  • 兩個按鈕:「查詢」(ID_QUERY)、「修改」(ID_MODIFY)。

「查詢」按鈕完整代碼


void CRegeditDlg::OnQuery()
{
    UpdateData(TRUE); // 讀取介面輸入(此處僅為習慣)

    HKEY hKey = NULL;
    LPCTSTR lpSubKey = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\"); // 注意雙反斜線

    // 1. 開啟鍵 (唯讀)
    LONG lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey);
    if (lRet != ERROR_SUCCESS) {
        AfxMessageBox(_T("錯誤:無法開啟註冊表鍵值"));
        return;
    }

    // 2. 查詢用戶名
    BYTE bufOwner[256] = {0};
    DWORD dwType = REG_SZ, dwSize = sizeof(bufOwner);
    lRet = ::RegQueryValueEx(hKey, _T("RegisteredOwner"), NULL, &dwType, bufOwner, &dwSize);
    if (lRet != ERROR_SUCCESS) {
        ::RegCloseKey(hKey);
        AfxMessageBox(_T("錯誤:無法讀取用戶名"));
        return;
    }
    m_strOwner = (LPCTSTR)bufOwner;

    // 3. 查詢公司名
    BYTE bufCompany[256] = {0};
    dwSize = sizeof(bufCompany);
    lRet = ::RegQueryValueEx(hKey, _T("RegisteredOrganization"), NULL, &dwType, bufCompany, &dwSize);
    if (lRet != ERROR_SUCCESS) {
        ::RegCloseKey(hKey);
        AfxMessageBox(_T("錯誤:無法讀取公司名"));
        return;
    }
    m_strCompany = (LPCTSTR)bufCompany;

    // 4. 關閉鍵並更新介面
    ::RegCloseKey(hKey);
    UpdateData(FALSE);
}

「修改」按鈕完整代碼


void CRegeditDlg::OnModify()
{
    UpdateData(TRUE); // 取得編輯框新值

    HKEY hKey = NULL;
    LPCTSTR lpSubKey = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\");

    // 1. 開啟鍵 (寫入權限 KEY_WRITE)
    LONG lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_WRITE, &hKey);
    if (lRet != ERROR_SUCCESS) {
        AfxMessageBox(_T("錯誤:無法開啟註冊表鍵值 (需管理員權限)"));
        return;
    }

    // 2. 寫入用戶名
    // CString 直接轉 BYTE* (含結束符 \0)
    int nLen = m_strOwner.GetLength() + 1;
    lRet = ::RegSetValueEx(hKey, _T("RegisteredOwner"), 0, REG_SZ,
                           (const BYTE*)(LPCTSTR)m_strOwner, nLen * sizeof(TCHAR));
    if (lRet != ERROR_SUCCESS) {
        ::RegCloseKey(hKey);
        AfxMessageBox(_T("錯誤:用戶名寫入失敗"));
        return;
    }

    // 3. 寫入公司名
    nLen = m_strCompany.GetLength() + 1;
    lRet = ::RegSetValueEx(hKey, _T("RegisteredOrganization"), 0, REG_SZ,
                           (const BYTE*)(LPCTSTR)m_strCompany, nLen * sizeof(TCHAR));
    if (lRet != ERROR_SUCCESS) {
        ::RegCloseKey(hKey);
        AfxMessageBox(_T("錯誤:公司名寫入失敗"));
        return;
    }

    ::RegCloseKey(hKey);
    AfxMessageBox(_T("註冊表修改完成!"));
    UpdateData(FALSE);
}

關鍵技術細節與避坑指南

1. 字串轉 LPBYTE 的正確姿勢

原文自寫 CString_To_LPBYTE 分配記憶體極易洩漏。MFC CString 可直接轉型:


// Unicode 建構下 (預設)
(const BYTE*)(LPCTSTR)strVar  // 直接指向內部緩衝區,包含結束符
// 長度計算
(strVar.GetLength() + 1) * sizeof(TCHAR)

無需手動 new/delete,安全高效。

2. 權限陷阱:Vista+ 需管理員權限

寫入 HKLM 需提升權限。專案屬性 → Linker → Manifest File → UAC Execution Level 設為 requireAdministrator,或在 Manifest 中宣告。

3. 9x/NT 相容性處理


CString strPath;
OSVERSIONINFO osvi = { sizeof(OSVERSIONINFO) };
GetVersionEx(&osvi);
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) // 9x/Me
    strPath = _T("Software\\Microsoft\\Windows\\CurrentVersion\\");
else
    strPath = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\");

4. 64 位系統重定向

32 位程式訪問 HKLM\Software 會被重定向至 HKLM\Software\WOW6432Node。若需訪問真 64 位視圖,RegOpenKeyEx 加入 KEY_WOW64_64KEY 標誌。

總結

註冊表操作核心在於:**正確路徑、正確權限、正確數據類型、嚴謹錯誤檢查、及時關閉鍵句柄**。本文範例展示了標準的「查詢-修改」閉環流程,配合 MFC DDX 機制,代碼清晰易維護,可直接移植至實際專案中管理應用程式設定。

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