vc簡單操作註冊表


本文只是對註冊表實現簡單的打開、創建、讀、寫、關閉操作,故只是基本知識的介紹,適合不能熟練使用註冊表操作的初級讀者。

       (我把本文放在這裏,其實最主要的目的是怕自己以後忘了,畢竟我也不常用這方面的知識,好不容易弄懂了點點,就趕快存起來,呵呵^_^)

       一、說明:
       註冊表是Windows重要組成部分,註冊表記錄了大量有關電腦軟硬件的信息。註冊表中的值通過其名稱標識。值名稱由與鍵名相同的字符組成。值本身可以是字符串、二進制數據或者是32位無符號值。在這裏我們主要運用以下技巧:

       (一)、預定義的註冊表鍵。註冊表包含了幾個預定義鍵:
       1. HKEY_LOCAL_MACHINE  包含描述計算機及其配置的條目。其中包括關於處理器、系統主板、內存和已安裝的軟件和硬件的信息。  
       2. HKEY_CLASSES_ROOT   是與文檔類型和 OLE/COM 相關的信息的支持鍵。這個鍵是 HKEY_LOCAL_MACHINE的從屬鍵。  
       3. HKEY_USERS          用作默認用戶首選設置,也作爲單個用戶的首選設置。  
       4. HKEY_CLASSES_USER   是用於當前(登錄)用戶的相關信息。  
       5. HKEY_CURRENT_CONFIG 包含了當前系統配置的信息。  
       6. 還有一個,一般不會出現,只有配置的局域網後纔會有。  

       (二)、VC中兩種註冊表操作方法

       在VC中,主要有兩種方法可以實現註冊表的操作,一是使用MFC封裝的類CRegKey,該類包含了14個成員函數,它們可以實現註冊表的簡單操作(基本的如本文提到的“打開、創建、讀、寫、關閉”等);二是使用Windows API函數。當然,對我來說,能使用底層的,那爲什麼不用呢,畢竟我現在是程序員,使用底層函數,可以移植到更多的開發平臺中嘛。
       1.
       所需要頭文件:atlbase.h  
       該種方法可以使用類CRegKey中的成員函數來完成。先包含頭文件,再申明一個類對象CRegKey RKey;然後就可以調用成員函數來操作了。
       基本功能的成員函數:
       LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName,REGSAM samDesired = KEY_ALL_ACCESS);
       LONG Close();
       LONG Create(HKEY hKeyParent, LPCTSTR lpszKeyName,
       LPTSTR lpszClass = REG_NONE, DWORD dwOptions = REG_OPTION_NON_VOLATILE,
       REGSAM samDesired = KEY_ALL_ACCESS,
       LPSECURITY_ATTRIBUTES lpSecAttr = NULL,
       LPDWORD lpdwDisposition = NULL);
       LONG SetValue(DWORD dwValue, LPCTSTR lpszValueName);
       LONG SetValue(LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
       LONG QueryValue(DWORD& dwValue, LPCTSTR lpszValueName);
       LONG QueryValue(LPTSTR szValue, LPCTSTR lpszValueName, DWORD* pdwCount);

       其他幾個:
       LONG SetKeyValue(LPCTSTR lpszKeyName, LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
       static LONG WINAPI SetValue(HKEY hKeyParent, LPCTSTR lpszKeyName,LPCTSTR lpszValue, LPCTSTR lpszValueName = NULL);
       HKEY Detach();
       void Attach(HKEY hKey);
       LONG DeleteSubKey(LPCTSTR lpszSubKey);
       LONG RecurseDeleteKey(LPCTSTR lpszKey);
       LONG DeleteValue(LPCTSTR lpszValue);

       但是本文主要介紹使用Windows API函數來操作註冊表,所以這裏不詳細的介紹這些成員函數的用法了。

       2. Windows API函數個數比較多,一共有三、四十個,這裏主要介紹幾個常用的函數,來實現本文所說的基本功能即可。

       常用API函數

       ☆ 打開一個鍵的函數:RegOpenKeyEx
       函數定義:LONG RegOpenKeyEx(HKEY hKey,//已經打開的鍵的句柄,或者直接是上述幾個根鍵
                                    LPCTSTR lpSubKey,//要打開的子鍵名字的地址
                                    DWORD ulOptions,//保留值,必須爲0
                                    REGSAM samDesired,//打開方式,如讀還是寫
                                    PHKEY phkResult//返回的打開的子鍵的句柄
                                   );
       說明:如果指定的要打開的子鍵不存在,則返回失敗;反之返回成功ERROR_SUCCESS;

       ☆ 創建一個鍵的函數:RegCreateKeyEx
       函數定義:LONG RegCreateKeyEx(HKEY hKey,//已經打開的鍵的句柄,或者直接是上述幾個根鍵
                                    LPCTSTR lpSubKey,//要創建的子鍵名字的地址
                                    DWORD ulOptions,//保留值,必須爲0
                                    REGSAM samDesired,//打開方式,如讀還是寫
                                    PHKEY phkResult//返回的創建的子鍵的句柄
                                   );
       說明:如果指定的要創建的子鍵已經存在,則打開該子鍵;反之創建該子鍵。函數成功則返回ERROR_SUCCESS;
       該子鍵可以一次創建多層子鍵,格式爲“子鍵1層//子鍵2層//子鍵3層。。。”

       ☆ 查詢某一個鍵值:RegQueryValueEx
       函數定義:LONG RegQueryValueEx(HKEY hKey,//要查詢的鍵的句柄
                                       LPCTSTR lpValueName,//要查詢的鍵值的名稱
                                       LPDWORD lpReserved,//保留值,必須爲0
                                       LPDWORD lpType,//要查詢的數據的類型,如果不關心,可以爲NULL
                                       LPBYTE lpData,//要返回的查詢的數據
                                       LPDWORD lpcbData//預置的數據的長度,理論上可以爲NULL,但實際我發現不行,最好設一個值
                                      );

       ☆ 設置一個鍵值RegSetValueEx
       函數定義:LONG RegSetValueEx(HKEY hKey,//要設置的鍵的句柄
                                     LPCTSTR lpValueName,//要訪問的鍵值的名稱
                                     LPDWORD lpReserved,//保留值
                                     DWORD dwType,//要設置的數據的類型
                                     const BYTE *lpData,//要設置的健值
                                     DWORD cbData//數據的長度
                                    );
       說明:如果要寫入的數據已經存在,只是改變值而已;如果不存在,則新建子鍵並存值。

       二、例子

       我做了一些註冊表的簡單操作,主要是打開,如果打開失敗,則創建;然後存值;

       HKEY key;
       CString strName = "hello";
       CString strCompany = "world";
       CString strSeries = "1111-1111";
       bool G_bIsLicesed = true;

       if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software//my Application//Settings"), 0, KEY_ALL_ACCESS, &hkey)!= ERROR_SUCCESS)
       {
               VERIFY(!RegCreateKey(HKEY_CURRENT_USER, _T("Software//my Application//Settings"), &hkey));
       }

       VERIFY(!RegSetValueEx(hkey, _T("LicesedBool"), 0, REG_DWORD, (BYTE *)&G_bIsLicesed, 4));
       VERIFY(!RegSetValueEx(hkey, _T("User Name"), 0, REG_SZ, (BYTE *)strName.GetBuffer(strName.GetLength()), 50));
       VERIFY(!RegSetValueEx(hkey, _T("Company Name"), 0, REG_SZ, (BYTE *)strCompany.GetBuffer(strCompany.GetLength()),25));
       VERIFY(!RegSetValueEx(hkey, _T("License Code"), 0, REG_SZ, (BYTE *)strSeries.GetBuffer(strSeries.GetLength()), 20));
       RegCloseKey(hkey);

       另外,我還做了註冊表的讀取操作    
       unsigned char  chbuf[50];
       CString strCompany = "";
       CString strSeries = "";
       HKEY  hkey;
       DWORD type(0);
       DWORD len(50);
       memset(chbuf, 0, sizeof(chbuf));

       if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software//my Application//Settings"), 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS)
       {        
               if (RegQueryValueEx(hkey, _T("User Name"), 0, &type, chbuf, &len) == ERROR_SUCCESS)
               {
                       ;
               }
               if (!RegQueryValueEx(hkey, _T("Company Name"), 0, &type, chbuf, &len))
               {
                       strCompany.Format("%s", chbuf);
               }
               if (!RegQueryValueEx(hkey, _T("License Code"), 0, &type, chbuf, &len))
               {
                       strSeries.Format("%s", chbuf);
               }
               if (!RegQueryValueEx(hkey, _T("LicesedBool"), 0, &type, chbuf, &len))
               {
                       G_bIsLicesed = chbuf[0];
               }

               RegCloseKey(hkey);
       }  

         先就到這裏吧,如果要求不是很高的話,就“依葫蘆畫瓢”,基本可是實現本文所說的功能了。

         如果有朋友來看了本文,而你又有更詳盡更使用的東東,請貼上來,不盡感謝!

還特別說明一點,就是從註冊表中取值的時候,一定記得
RegQueryValueEx(hkey, _T("LicesedBool"), 0, &type, chbuf, &len)
函數中的參數len,它的大小必須能夠容納要取的值的內存大小。

也就是說,比如要取一個字符串,長爲100,那麼,你在調用該函數前必須爲len定義一個值,該值大於等於100,否則,它取值會失敗!
len返回值是實際取值的長度,但是傳入之前必須定義一個大於該長度的值,否則它雖然仍會返回實際長度的值,可是數據確取不 出來。


我上面的代碼,實際就有點失誤。用同一個len連續用在三個取值函數中,雖然開始是設定了值的,可是一旦在前面或中間某個取值函數中返回的len值小於後面一個取值函數中的len實際值,那麼後面那個取痔函數就取不 出來值而且,這種失誤也是很難檢測出來的,因爲它的語法沒有任何錯誤。必須時刻注意!!!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章