明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

Win32 API 注冊表類的編制以及使用

[摘要]一、問題的提出Windows 已由原來的16位 windows 3.x 升級為現(xiàn)今我們使用的32位windows 95/97/98 以其 Windows NT,用戶不僅在使用上應(yīng)逐步適應(yīng),對于程序開發(fā)人員來說在編程技術(shù)上也應(yīng)緊跟操作系統(tǒng)的技術(shù)發(fā)展,就如同 在 Linux 操作系統(tǒng)下, X-Wind...
一、問題的提出
Windows 已由原來的16位 windows 3.x 升級為現(xiàn)今我們使用的32位windows 95/97/98 以其 Windows NT,用戶不僅在使用上應(yīng)逐步適應(yīng),對于程序開發(fā)人員來說在編程技術(shù)上也應(yīng)緊跟操作系統(tǒng)的技術(shù)發(fā)展,就如同 在 Linux 操作系統(tǒng)下, X-Window 編程就顯得很重要一樣。作為一個(gè)完整成熟的 Windows 程序,需要保存程序所有的環(huán)境變量和私有信息。諸如用戶的偏好,文件裝入的列表、退出時(shí)用戶使用的窗口位置 .存盤歷史紀(jì)錄等。過去在 windows 3.x時(shí)代 ,常用 Win16函數(shù) Get/RegWrite ProfileString 將有關(guān)程序的信息寫入 *.ini 文件,但現(xiàn)在該項(xiàng)技術(shù)由 Win32注冊表所替代。
可以這樣說,注冊表是當(dāng)今32位 Windows 操作系統(tǒng)的靈魂,一切信息都在其中,也就是為什么Windows98在Windows95的基礎(chǔ)上升級可以不重裝軟件等等的如此方便的應(yīng)用,其原理就是根據(jù)了原注冊表中的信息來完成各種方便的處理,所以Windows注冊表對應(yīng)用程序的重要性就顯而易見了。
原來的 Win16程序存儲私有信息是在一個(gè)平面文件INI中,這樣做有很多弊端,例如該INI文件沒有任何安全機(jī)制,用戶可以直接在INI文件中修改各種參數(shù)和程序入口,這樣就可能造成不可估計(jì)的嚴(yán)重后果,還有該文件只能支持和文本數(shù)據(jù)不能存入二進(jìn)制數(shù)據(jù)等各種不利因素,所以微軟的工程師也認(rèn)識到這一點(diǎn),于是注冊數(shù)據(jù)庫就誕生了,注冊數(shù)據(jù)庫就是為了解決在 Windows 3.x 的一些關(guān)于 OLE 的此類問題而創(chuàng)建的,現(xiàn)在 Win32 應(yīng)用程序的注冊數(shù)據(jù)庫通過微軟帶給我們的新的 Win32 API 得到了顯著的改善。使用訪問注冊表的 Win32 函數(shù)比起使用管理 INI 文件的 Win16函數(shù)要靈活的多,這意味著在功能上將大大增強(qiáng),但是,另一方面,如果你還未用過,就會對處理注冊表的Win32 API 的新規(guī)則感到困惑或不知所措。本文就是本著這一目的,逐步讓你懂得并掌握怎樣用 Win32API 函數(shù)來處理32位 Windows 程序注冊表的方法。



二 . 技術(shù)的實(shí)現(xiàn)原理

為了在以后自己編寫的程序中更多的體現(xiàn)模塊化思想以及使編程變得更加簡單,應(yīng)盡可能的建立自己實(shí)現(xiàn)各種功能的類,以類作為實(shí)現(xiàn)應(yīng)用程序各種功能的單位。 在此,可以創(chuàng)建一個(gè)包括注冊表許多常用功能而接口簡單的類庫,下面將建立 CMyRegKey類,對應(yīng)用程序處理注冊表的具體細(xì)節(jié)進(jìn)行封裝,從而在外部通過這個(gè)功能類方便地實(shí)現(xiàn)進(jìn)行訪問注冊表信息的各種操作,在外部調(diào)用其成員函數(shù)即可。以后,你就可以在每一個(gè)應(yīng)用程序中包含此類并用其外部接口進(jìn)行編程了。

三 . 實(shí)現(xiàn)代碼與步驟



1. 建立功能類的頭文件:

創(chuàng)建一個(gè)新的頭文件 MyRegKey.h ,在其中加入以下的代碼。



#include "winreg.h"

// 包含頭文件 winreg.h , 因注冊表Win32 API 函數(shù)在其內(nèi)定義

// 建立 CMyRegKey 類:
class CMyRegKey
{


// Construction
public:
CMyRegKey();
virtual ~CMyRegKey ();

// Attributes
public:

// 定義打開和關(guān)閉注冊表的成員函數(shù):

LONG RegRegOpen(HKEY hKeyRoot,LPCTSTR pszPath);
void RegRegClose();

// 利用函數(shù)重載實(shí)現(xiàn)對注冊表鍵值(串值,二進(jìn)制值,DWORD值 ) 的讀和寫:

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類:

創(chuàng)建一個(gè)新文件 MyRegKey.cpp ,代碼如下:


#include "MyRegKey.h"

/////////////////////////////////////////////////////////////////////////////
// CMyRegKey
/////////////////////////////////////////////////////////////////////////////

CMyRegKey:: CMyRegKey()
{
m_hKey = NULL;
}

CMyRegKey:: ~CMyRegKey()
{
RegClose();
}

// 定義打開注冊表的函數(shù),RegOpen 函數(shù)帶有兩個(gè)參數(shù):指定要訪問注冊表根結(jié)點(diǎn)的 HKEY, 以及注

// 冊表中信息的全路徑。如果給入的路徑不存在,則需創(chuàng)建一個(gè)新路徑。從 RegCreateKeyEx API函數(shù)返// 回的 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,NULL,
&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);

}

在用戶需要使用時(shí)只需在你的 Project 中的 SorceFile 和 HeadFile 中分別加入 MyRegKey.cpp 以及 MyRegKey.h 程序文件。

四 . 使用外部接口示例


在VC中建立一個(gè)基于對話框(Dialog Base) 的應(yīng)用程序,在對話框上放上幾個(gè)Edit control 的控件,如同示例小程序 RegTech 框(見圖一), 程序執(zhí)行時(shí),首先讀出注冊表信息分別顯示在三個(gè)編輯欄中,為了演示寫入操作,你可以在注冊用戶欄中重新輸入用戶名,按更改完成寫入,重新運(yùn)行程序,查看寫入是否成功。在RegTech 框中安置了三個(gè)編輯欄,ID 為 IDC_INSTALL,IDC_USERID,IDC_VERSION,
用ClassWizard 的Member Variable 分別加上對象參數(shù):m_Install, m_UserID 和 m_Version.
用參數(shù)來傳遞注冊表鍵值。

在初始化對話框時(shí)就應(yīng)打開注冊表并讀取所需的信息,這三項(xiàng)存放路徑為HKEY_LOCAL_MACHINE \SOFTWARE \Microsoft \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


//###########################################

// 打開注冊表路徑 .

CMyRegKey regKey1,regKey2,regKey3;

regKey1.RegOpen(HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\Windows\\CurrentVersion"));
regKey2.RegOpen(HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\Windows\\CurrentVersion"));
regKey3.RegOpen(HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\Windows\\CurrentVersion"));


// 讀取鍵值并分別傳遞到編輯控件參數(shù)中去:
regKey1.RegRead(_T("Version"),m_Version);
regKey2.RegRead(_T("RegisteredOwner"),m_UserID);
regKey3.RegRead(_T("SystemRoot"),m_Install);
UpdateData(FALSE);

//############################################

return TRUE; // return TRUE unless you set the focus to a control
}

在重新輸入了注冊用戶名后,按下更改按鈕(按鈕控件ID_ChangeID),將完成注冊表的寫入操作:

void CRegtechDlg::OnChangeID()
{


//########################

CMyRegKey regKey;


regKey.RegOpen(HKEY_LOCAL_MACHINE,
_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"));

// 傳遞從編輯攔輸入的值并寫入打開路徑的指定鍵值名中:

UpdateData(TRUE);
regKey.RegWrite(_T("RegisteredOwner"),m_UserID);
MessageBox("更改注冊用戶名完畢!","Message",MB_ICONINFORMATION MB_OK);


///#########################


// TODO: Add your control notification handler code here

}

注冊表類在實(shí)際應(yīng)用程序編制中使用頻率極高,比如程序員自定義的文件的圖標(biāo)選擇等的很多地方都要用到,所以一個(gè)成熟優(yōu)秀的應(yīng)用程序應(yīng)盡可能的適應(yīng)環(huán)境及發(fā)揮操作系統(tǒng)的各種優(yōu)勢,在此,使用win32 API對Windows靈魂--注冊表存取技術(shù)的操作已完成 ,你就可以利用它來完善自己的應(yīng)用程序了。