Win32 API 登錄檔類的編制以及使用 (轉)

worldblog發表於2007-12-04
Win32 API 登錄檔類的編制以及使用 (轉)[@more@]
登錄檔類的編制以及使用 一、問題的提出 已由原來的16位 windows 3.x 升級為現今我們使用的32位windows 95/97/98 以其 ,不僅在使用上應逐步適應,對於開發人員來說在技術 上也應緊跟操作的技術發展,就如同 在 下, X-Window 程式設計就顯 得很重要一樣。作為一個完整成熟的 Windows 程式,需要儲存程式所有的環境變數和 私有資訊。諸如使用者的偏好,裝入的列表、退出時使用者使用的視窗位置 .存檔歷史 紀錄等。過去在 windows 3.x時代 ,常用 Win16 Get/RegWrite ProfileString 將有關程式的資訊寫入 *.ini 檔案,但現在該項技術由 Win32登錄檔所替代。 可以這樣說,登錄檔是當今32位 Windows 作業系統的靈魂,一切資訊都在其中,也就 是為什麼Windows98在Windows95的基礎上升級可以不重灌等等 的如此方便的應用,其原理就是根據了原登錄檔中的資訊來完成各種方便的處理,所以 Windows登錄檔對應用程式的重要性就顯而易見了。 原來的 Win16程式私有資訊是在一個平面檔案INI中,這樣做有很多弊端,例如該 INI檔案沒有任何機制,使用者可以直接在INI檔案中修改各種引數和程式入口,這樣 就可能造成不可估計的嚴重後果,還有該檔案只能支援和文字資料不能存入二進位制資料 等各種不利因素,所以的工程師也認識到這一點,於是註冊就誕生了,註冊 資料庫就是為了解決在 Windows 3.x 的一些關於 OLE 的此類問題而建立的,現在 Win32 應用程式的註冊資料庫透過微軟帶給我們的新的 Win32 API 得到了顯著的改 善。使用訪問登錄檔的 Win32 函式比起使用管理 INI 檔案的 Win16函式要靈活的多, 這意味著在功能上將大大增強,但是,另一方面,如果你還未用過,就會對處理登錄檔 的Win32 API 的新規則感到困惑或不知所措。本文就是本著這一目的,逐步讓你懂得並 掌握怎樣用 Win32API 函式來處理32位 Windows 程式登錄檔的方法。 二 . 技術的實現原理 為了在以後自己編寫的程式中更多的體現模組化思想以及使程式設計變得更加簡單,應儘可 能的建立自己實現各種功能的類,以類作為實現應用程式各種功能的單位。 在此,可 以建立一個包括登錄檔許多常用功能而介面簡單的類庫,下面將建立 CMyRegKey類,對 應用程式處理登錄檔的具體細節進行封裝,從而在外部透過這個功能類方便地實現進行 訪問登錄檔資訊的各種操作,在外部其成員函式即可。以後,你就可以在每一個應 用程式中包含此類並用其外部介面進行程式設計了。 三 . 實現程式碼與步驟 1. 建立功能類的標頭檔案: 建立一個新的標頭檔案 MyRegKey.h ,在其中加入以下的程式碼。 #include "winreg.h" // 包含標頭檔案 winreg.h , 因登錄檔Win32 API 函式在其內定義 // 建立 CMyRegKey 類: class CMyRegKey { // Construction public: CMyRegKey(); virtual ~CMyRegKey (); // Attributes public: // 定義開啟和關閉登錄檔的成員函式: LONG RegRegOpen(HKEY hKey,LPCTSTR pszPath); void RegRegClose(); // 利用函式過載實現對登錄檔鍵值(串值,二進位制值,D值 ) 的讀和寫: LONG RegRead (LPCTSTR pszKey,DWORD& dwVal); LONG RegRead (LPCTSTR pszKey,CString& sVal); LONG RegRead (LPCTSTR pszKey,BYTE *pData,DWORD& dwLength); LONG RegWrite (LPCTSTR pszKey,DWORD dwVal); LONG RegWrite (LPCTSTR pszKey,LPCTSTR pszVal); LONG RegWrite (LPCTSTR pszKey,const BYTE *pData,DWORD dwLength); protected: HKEY m_hKey; CString m_sPath; }; 2. 建立功能類的Cpp檔案定義 CMyRegKey類: 建立一個新檔案 MyRegKey.cpp ,程式碼如下: #include "MyRegKey.h" //////////////////////////////////////////////////////////////////////////// / // CMyRegKey //////////////////////////////////////////////////////////////////////////// / CMyRegKey:: CMyRegKey() { m_hKey = NULL; } CMyRegKey:: ~CMyRegKey() { RegClose(); } // 定義開啟登錄檔的函式,RegOpen 函式帶有兩個引數:指定要訪問登錄檔根結點的 HKEY, 以及注 // 冊表中資訊的全路徑。如果給入的路徑不存在,則需建立一個新路徑。從 RegCreateKeyEx API函式返// 回的 HKEY 作為 m_hKey 儲存。 LONG CMyRegKey::RegOpen(HKEY hKeyRoot,LPCTSTR pszPath) { DWORD dw; m_sPath = pszPath; return RegCreateKeyEx(hKeyRoot,pszPath,0L,NULL,REG_OPTION_VOLATILE,KEY_ALL_ACCESS,N ULL, &m_hKey,&dw); } void CMyRegKey::RegClose() { if(m_hKey) { RegCloseKey (m_hKey); m_hKey = NULL; } } LONG CMyRegKey::RegWrite(LPCTSTR pszKey,DWORD dwVal) { ASSERT(m_hKey); ASSERT(pszKey); ASSERT(pData&&dwLength>0); ASSERT(AfxIsValidAddress(pData,dwLength,FALSE)); return RegSetValueEx(m_hKey,pszKey,0L,REG_DWORD,(CONST BYTE *)&dwVal,sizeof(DWORD)); } LONG CMyRegKey::RegWrite(LPCTSTR pszKey,LPCTSTR pszData) { ASSERT(m_hKey); ASSERT(pszKey); ASSERT(pszData); ASSERT(pData&&dwLength>0); ASSERT(AfxIsValidAddress(pszData,strlen(pszData),FALSE)); return RegSetValueEx(m_hKey,pszKey,0L,REG_SZ,(CONST BYTE *)pszData,strlen (pszData)+1); } LONG CMyRegKey::RegWrite(LPCTSTR pszKey,const BYTE *pData,DWORD dwLength) { ASSERT(m_hKey); ASSERT(pszKey); ASSERT(AfxIsValidAddress (pData,dwLength,FALSE)); ASSERT(pData&&dwLength>0); ASSERT(AfxIsValidAddress(pData,dwLength,FALSE)); return RegSetValueEx(m_hKey,pszKey,0L,REG_BINARY,pData,dwLength); } LONG CMyRegKey::RegRead (LPCTSTR pszKey,DWORD& dwVal) { ASSERT(m_hKey); ASSERT(pszKey); DWORD dwType; DWORD dwSize = sizeof (DWORD); DWORD dwDest; LONG LRet = RegQueryValueEx(m_hKey,(LPSTR)pszKey,NULL,&dwType,(BYTE *) &dwDest,&dwSize); if(LRet==ERROR_SUCCESS) dwVal = dwDest; return LRet; } LONG CMyRegKey::RegRead (LPCTSTR pszKey,CString& sVal) { ASSERT(m_hKey); ASSERT(pszKey); DWORD dwType; DWORD dwSize = 200; char string[200]; LONG IReturn = RegQueryValueEx(m_hKey,(LPSTR)pszKey,NULL,&dwType,(BYTE *) string,&dwSize); if(IReturn==ERROR_SUCCESS) sVal = string; return IReturn; } LONG CMyRegKey::RegRead (LPCTSTR pszKey,BYTE * pData,DWORD& dwLen) { ASSERT(m_hKey); ASSERT(pszKey); DWORD dwType; return RegQueryValueEx(m_hKey,(LPSTR)pszKey,NULL,&dwType,pData,&dwLen); } 在使用者需要使用時只需在你的 Project 中的 SorceFile 和 HeadFile 中分別加入 MyRegKey.cpp 以及 MyRegKey.h 程式檔案。 四 . 使用外部介面示例 在VC中建立一個基於對話方塊(Dialog Base) 的應用程式,在對話方塊上放上幾個Edit control 的,如同示例小程式 RegTech 框(見圖一), 程式時,首先讀出注 冊表資訊分別顯示在三個編輯欄中,為了演示寫入操作,你可以在註冊使用者欄中重新輸 入使用者名稱,按更改完成寫入,重新執行程式,檢視寫入是否成功。在RegTech 框中安置 了三個編輯欄,ID 為 IDC_INSTALL,IDC_USERID,IDC_VERSION, 用ClassWizard 的Member Variable 分別加上引數:m_Install, m_UserID 和 m_Version. 用引數來傳遞登錄檔鍵值。 在初始化對話方塊時就應開啟登錄檔並讀取所需的資訊,這三項存放路徑為 HKEY_LOCAL_MACHINE SOFTWARE Windows CurrentVersion下, 分別讀出windows 版本號(放置於Version鍵值中),註冊使用者名稱(放置於 RegisteredOwner鍵值中),Windows 目錄(放置於SystemRoot 鍵值中 ),更多 的資訊請使用Windows 目錄下的 RegEdit.exe程式. 需用到登錄檔類的原程式檔案中加上 #inxlude " MyRegKey.h"  即可。 在檔案 RegTechDlg.cpp 中初始化對話方塊的地方加上以下程式碼開啟路徑並讀取鍵值: BOOL CRegtechDlg::OnInitDialog() { CDialog::OnInitDialog(); ...................... ...................... // TODO: Add extra initialization here file://########################################### // 開啟登錄檔路徑 . CMyRegKey regKey1,regKey2,regKey3; regKey1.RegOpen(HKEY_LOCAL_MACHINE, _T("SoftwareMicrosoftWindowsCurrentVersion")); regKey2.RegOpen(HKEY_LOCAL_MACHINE, _T("SoftwareMicrosoftWindowsCurrentVersion")); regKey3.RegOpen(HKEY_LOCAL_MACHINE, _T("SoftwareMicrosoftWindowsCurrentVersion")); // 讀取鍵值並分別傳遞到編輯控制元件引數中去: regKey1.RegRead(_T("Version"),m_Version); regKey2.RegRead(_T("RegisteredOwner"),m_UserID); regKey3.RegRead(_T("SystemRoot"),m_Install); UpdateData(FALSE); file://############################################ return TRUE; // return TRUE unless you set the focus to a control } 在重新輸入了註冊使用者名稱後,按下更改按鈕(按鈕控制元件ID_ChangeID),將完成登錄檔 的寫入操作: void CRegtechDlg::OnChangeID() { file://######################## CMyRegKey regKey; regKey.RegOpen(HKEY_LOCAL_MACHINE, _T("SOFTWAREMicrosoftWindowsCurrentVersion")); // 傳遞從編輯攔輸入的值並寫入開啟路徑的指定鍵值名中: UpdateData(TRUE); regKey.RegWrite(_T("RegisteredOwner"),m_UserID); MessageBox("更改註冊使用者名稱完畢!","Message",MB_ICONINFORMATION|MB_OK); ///######################### // TODO: Add your control notification handler code here } 登錄檔類在實際應用程式編制中使用頻率極高,比如程式設計師自定義的檔案的圖示選擇等 的很多地方都要用到,所以一個成熟優秀的應用程式應儘可能的適應環境及發揮操作系 統的各種優勢,在此,使用win32 API對Windows靈魂--登錄檔存取技術的操作已完 ,你就可以利用它來完善自己的應用程式了。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-987891/,如需轉載,請註明出處,否則將追究法律責任。

相關文章