win32 api 注册表类

来源:互联网 发布:用网络看电视需要什么 编辑:程序博客网 时间:2024/05/22 14:21

一、问题的提出    
     
  Windows  
已由原来的 16 位   windows   3.x   升级为现今我们使用的 32 windows   95/97/98    
 
以其   Windows   NT ,用户不仅在使用上应逐步适应,对于程序开发人员来说在编程技术    
 
上也应紧跟操作系统的技术发展,就如同   在   Linux   操作系统下,   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   hKeyRoot,LPCTSTR   pszPath);  
 
  void   RegRegClose();  
 
   
 
  //  
利用函数重载实现对注册表键值(串值,二进制值, 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 类:    
   
 
 
创建一个新文件   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;  
 
   
 
  }  
 
 
Top

   
  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   /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  
 
   
 
   
 
  file://###########################################  
 
   
 
  //  
打开注册表路径   .    
   
 
  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"));  
 
   
 
   
 
  //  
读取键值并分别传递到编辑控件参数中去:    
  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("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  
 
   
 
  }  
 
   
 
 
注册表类在实际应用程序编制中使用频率极高,比如程序员自定义的文件的图标选择等    
 
的很多地方都要用到,所以一个成熟优秀的应用程序应尽可能的适应环境及发挥操作系    
 
统的各种优势,在此,使用 win32   API Windows 灵魂 -- 注册表存取技术的操作已完    
 
,你就可以利用它来完善自己的应用程序了。