用VC6编写注册表管理程序(二)

类别:VC语言 点击:0 评论:0 推荐:

用VC6编写注册表管理程序(二)

               顾剑辉(Solarsoft)

1.  用树来显示注册表信息。

注意:注册表信息内容比较多,不可能全部显示,则可一开始,先显示最接近于树根,再根据操作来逐步显示子树的方案来实现,

1)  初始化树

void CRegLeftView::OnInitialUpdate()

{

       CTreeView::OnInitialUpdate();

    /*定义TreeCtrl的图标*/

       m_pImageList = new CImageList();

       CWinApp* pApp = AfxGetApp();

       ASSERT(m_pImageList != NULL);

       m_pImageList->Create(16, 16, ILC_COLOR8 | ILC_MASK,  9, 9);

       m_pImageList->Add(pApp->LoadIcon(ICO_MYCOMPUTER));

       m_pImageList->Add(pApp->LoadIcon(ICO_OPENFLD));

       m_pImageList->Add(pApp->LoadIcon(ICO_CLSDFLD));

       GetTreeCtrl().SetImageList(m_pImageList , TVSIL_NORMAL);

       HTREEITEM hParent = GetTreeCtrl().InsertItem(MYCOMPUTER, ILI_MYCOMP, ILI_MYCOMP);

   //显示树根,MYCOMPUTER宏定义为“我的电脑”

       InitTreeView(hParent);

   //初始化主键

       GetTreeCtrl().Expand(hParent, TVE_EXPAND);

       }

void CRegLeftView::InitTreeView(HTREEITEM hParent)

{    

    HTREEITEM hItem;

       for(int i=0;i<6;i++)

       {

       hItem = GetTreeCtrl().InsertItem(HKey_Root[i], ILI_CLSDFLD, ILI_OPENFLD, hParent);

       AddDummyNode(hItem);//加入空子树

}

}

2)  发送树型视图消息TVN_ITEMEXPANDING和TVN_SELCHANGING的编写,前者为列表项被扩展(或收缩),后者为当前的选择项发生变化。

函数体如下:

void CRegLeftView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)

{

       NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

       HKEY hKey;

       HTREEITEM hItem = pNMTreeView->itemNew.hItem;

    if(!IsSubTree(hItem))

       {

              CString strDataName = GetDataFromItem (hItem);

//返回除去“我的电脑”的项目名,实为键路径

            hKey=GetHkey(strDataName);

//返回当前项目名的主键

            CString  strSubKey;

              int i=strDataName.Find("\\");

              if(i==-1)

              {      

                     strSubKey="";

              }else

              strSubKey=strDataName.Mid(i+1);

              CWaitCursor wait;

              if (pNMTreeView->action == TVE_EXPAND)

              {

                if(strDataName != MYCOMPUTER)

                {

                     DeleteChildren (hItem);

           //删除当前项目的所有子树

               if (!EnumerateKey(hKey,strSubKey,hItem))

           //枚举当前项目的所有子树

                      *pResult = TRUE;

                }

              }

       }

       *pResult = 0;

}

void CRegLeftView::OnSelchanging(NMHDR* pNMHDR, LRESULT* pResult)

{

       NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

       if(i!=0)

       {

       HKEY hKey;

       HTREEITEM hItem = pNMTreeView->itemNew.hItem;

       CString strDataName = GetDataFromItem (hItem);

    hKey=GetHkey(strDataName);

    CString  strSubKey;

       int i=strDataName.Find("\\");

       if(i==-1)

       {    

          strSubKey="";

       }else

       strSubKey=strDataName.Mid(i+1);

       CWaitCursor wait;

       CRegExplorerDoc* pDoc = GetDocument();

       pDoc->m_RegExplorerView->DeleteAllItems();

//与文档类通信的代码,并可以操作RegExplorerView

       if(strDataName == MYCOMPUTER)

              return;

       pDoc->m_RegExplorerView->DoListView(hKey,strSubKey);

       }

       i++;

       *pResult = 0;

}

其他函数的实现:

CString CRegLeftView::GetDataFromItem(HTREEITEM hItem)

{

   CString str;

    while (hItem != NULL)

       {

              CString string = GetTreeCtrl().GetItemText (hItem);

        if ((string.Right (1) != "\\") && !str.IsEmpty ())

               string += "\\";

              str = string + str;

        hItem = GetTreeCtrl().GetParentItem (hItem);

    }

      

//8为我的电脑的长度,为的是去除我的电脑4个字

       if(str.Left(8) == MYCOMPUTER && str.GetLength() > 8)

              str = str.Mid(9);

    return str;

}

HKEY CRegLeftView::GetHkey(LPCTSTR strKey)

{

       HKEY hKeyRootName;

    CString cstrKeyRootName=strKey;

       int i=cstrKeyRootName.Find("\\");

       if(i!=-1)

           cstrKeyRootName=cstrKeyRootName.Left(i);

       if(cstrKeyRootName == _T("HKEY_CLASSES_ROOT"))

              hKeyRootName = HKEY_CLASSES_ROOT;

       else if(cstrKeyRootName == _T("HKEY_CURRENT_USER"))

              hKeyRootName = HKEY_CURRENT_USER;

       else if(cstrKeyRootName == _T("HKEY_LOCAL_MACHINE"))

              hKeyRootName = HKEY_LOCAL_MACHINE;

       else if(cstrKeyRootName == _T("HKEY_USERS"))

              hKeyRootName = HKEY_USERS;

       else if(cstrKeyRootName == _T("HKEY_PERFORMANCE_DATA"))

              hKeyRootName = HKEY_PERFORMANCE_DATA;

       else if(cstrKeyRootName == _T("HKEY_CURRENT_CONFIG"))

              hKeyRootName = HKEY_CURRENT_CONFIG;

       else if(cstrKeyRootName == _T("HKEY_DYN_DATA"))

              hKeyRootName = HKEY_DYN_DATA;

   

       return hKeyRootName;

}

/*一层树算法:对注册表树的当前一层进行枚举*/

UINT CRegLeftView::EnumerateKey(HKEY hKey, LPCTSTR strKey, HTREEITEM hItem)

{

    HTREEITEM hSubItem;

       TCHAR strCurString[100];

       long lResult;

       DWORD dwCurIndex=0;

       HKEY hCurKey;

       CString strCurKey;

    CString strSubKey=strKey;

       CString str=strKey;

    if(strKey=="")

       {

              AddDummyNode(hItem);

              return 0;

       }

    CWaitCursor wait;

       //CRegExplorerDoc* pDoc = GetDocument();

       //pDoc->m_ExplorerView->DeleteAllItems();

       //第二部分工作,加入对ListView的支持

       lResult = RegOpenKeyEx(hKey, strKey, 0, KEY_ENUMERATE_SUB_KEYS, &hCurKey);

       if( lResult != ERROR_SUCCESS )

              return 0;

 

       do

       {

              lResult = RegEnumKey(hCurKey, dwCurIndex, strCurString , sizeof(strCurString));

 

              if((lResult == ERROR_NO_MORE_ITEMS) || (lResult == ERROR_INVALID_HANDLE))

              {

                     break;

              }

              else

              {

                     strCurKey.Format("%s",strCurString);

            hSubItem=GetTreeCtrl().InsertItem (strCurKey, 2, 1, hItem,TVI_SORT);

                     if(!strCurKey.IsEmpty()&&!str.IsEmpty())

                    {

                        strSubKey  = str + "\\" + strCurString;

                     }

                 else

                    {

                           strSubKey = strCurString;   

                    }

                    if(HasSubKey(hKey , strSubKey))

                     {

                            AddDummyNode(hSubItem);

                     }

                     dwCurIndex++;

              }

 

       }while(TRUE);

       RegCloseKey(hCurKey);

       return dwCurIndex;

}

void CRegLeftView::AddDummyNode(HTREEITEM hItem)

{

 

  GetTreeCtrl().InsertItem ("", 2, 1, hItem);

}

UINT CRegLeftView::DeleteChildren(HTREEITEM hItem)

{

       UINT nCount = 0;

    HTREEITEM hChild = GetTreeCtrl().GetChildItem (hItem);

    while (hChild != NULL) {

        HTREEITEM hNextItem = GetTreeCtrl().GetNextSiblingItem (hChild);

        GetTreeCtrl().DeleteItem (hChild);

        hChild = hNextItem;

        nCount++;

    }

    return nCount;

 

}

右边列表CregExplorerView类的实现:

在类里定义private型的变量       HKEY m_hKey;//通信函数传来主键

CString m_strSubKey;//子键名

1.  和文档类进行通信的代码同上。

2.  显示当前树的数据

在CRegLeftView::OnSelchanging中有一通信函数pDoc->m_RegExplorerView->

DoListView(hKey,strSubKey);

void CRegExplorerView::DoListView(HKEY hKey, LPCTSTR strSubKey)

{

       LV_ITEM  lvitem;

       int iActualItem;

       CString strTemp1="(默认)",strTemp2="(未设置类型)",strTemp3="(未设置键值)";

 

    m_hKey=hKey;

    m_strSubKey=strSubKey;

    lvitem.mask = LVIF_TEXT | LVIF_IMAGE;

       lvitem.iItem = 0;

       lvitem.iSubItem = 0;

       lvitem.pszText = strTemp1.GetBuffer(strTemp1.GetLength());

       lvitem.iImage =ICI_STR;

       iActualItem = GetListCtrl().InsertItem(&lvitem);

 

    GetListCtrl().SetItemText(iActualItem,1,strTemp2.GetBuffer(0));

          GetListCtrl().SetItemText(iActualItem,2,strTemp3.GetBuffer(0));

    EnumerateValues(hKey,strSubKey);//枚举该子键的所有数据项并显示在ListView上

}

void CRegExplorerView::EnumerateValues(HKEY hKey, LPCTSTR cstrKey)

{

       static HKEY hLastKey = hKey;

       LONG lResult;

       DWORD dwIndex = 0;

       HKEY hCurKey = hKey;

       DWORD dwKeyType;

       DWORD dwKeyDataLength, dwKeyNameLen;

       LPBYTE pbbinKeyData = NULL;

       TCHAR *tcKeyName = NULL;

       TCHAR tcDataType[1024] = _T("");

       lResult = RegOpenKeyEx(hCurKey, cstrKey, 0, KEY_QUERY_VALUE , &hKey);

       if(lResult != ERROR_SUCCESS)

              return;

 

       DWORD lNoOfValues = 0;

       DWORD lLongestKeyNameLen = 1;

       DWORD lLongestDataLen = 1;

 

       lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &lNoOfValues, &lLongestKeyNameLen, &lLongestDataLen,

                                                 NULL, NULL);

      

       if(lResult != ERROR_SUCCESS)

              return;

 

 

       hLastKey = hKey;

 

       lLongestKeyNameLen++;

       lLongestDataLen++;

 

       tcKeyName =       new TCHAR[lLongestKeyNameLen];

       pbbinKeyData = new BYTE[lLongestDataLen];

 

       CString cstrFinalData, cstrTemp;

 

       while(TRUE)

       {

              memset(pbbinKeyData, 0, lLongestDataLen);

              memset(tcKeyName, 0, lLongestKeyNameLen);

              dwKeyType = dwKeyDataLength = dwKeyNameLen = 0;

 

              dwKeyNameLen = lLongestKeyNameLen;

              dwKeyDataLength = lLongestDataLen;

 

              lResult = RegEnumValue(hKey, dwIndex, tcKeyName, &dwKeyNameLen, NULL, &dwKeyType, pbbinKeyData, &dwKeyDataLength);

              if(lResult == ERROR_NO_MORE_ITEMS)

                     break;

        AddRegistryItem(tcKeyName, dwKeyType, pbbinKeyData, dwKeyDataLength, dwIndex);//显示数据于ListView

 

              dwIndex++;

       }

       RegCloseKey(hKey);

       delete tcKeyName;

       delete pbbinKeyData;

}

int CRegExplorerView::AddRegistryItem(CString Name, DWORD Type, void *Data, DWORD DataSize, int Row)

{

       if (Name.IsEmpty())

       {

           DeleteAllItems();

              Name="(默认)";

       }

       LVITEM Item={0};

       Item.mask=LVIF_TEXT | LVIF_IMAGE;

       Item.cchTextMax=Name.GetLength();

       Item.iItem=Row;

       Item.pszText=Name.GetBuffer(0);

       int iPosition;

 

       CString FormatData;

      

       switch (Type)

       {

              case REG_DWORD_BIG_ENDIAN:

              case REG_DWORD: 

              {

                     Item.iImage=1;

                     iPosition=GetListCtrl().InsertItem(&Item);

                     GetListCtrl().SetItemText(iPosition,1,"REG_DWORD");

                     DWORD* dwData=(DWORD*) Data;

                    

                     if (Data!=NULL)

                     {

                            FormatData.Format("0x%x (%d)",*dwData,*dwData);

                            GetListCtrl().SetItemText(iPosition,2,FormatData.GetBuffer(0));

                     }

                     break;

              }

 

              case REG_BINARY:

              {

                     Item.iImage=1;

                     iPosition=GetListCtrl().InsertItem(&Item);

                     GetListCtrl().SetItemText(iPosition,1,"REG_BINARY");

                     if (Data!=NULL)

                     {

                            FormatData=FormatBinary((BYTE*) Data,DataSize);

                            GetListCtrl().SetItemText(iPosition,2,FormatData.GetBuffer(0));

                     }

                     break;

              }

             

              case REG_EXPAND_SZ:

              case REG_SZ:

              case REG_LINK:

              case REG_MULTI_SZ:

              {

                     Item.iImage=0;

                     iPosition=GetListCtrl().InsertItem(&Item);

                     GetListCtrl().SetItemText(iPosition,1,"REG_SZ");

                            if (Data!=NULL)

                     {

                            FormatData.Format("\"%s\"",(char*) Data);

                            GetListCtrl().SetItemText(iPosition,2,FormatData.GetBuffer(0));

                     }

                     break;

              }

 

              default:

              {

                     Item.mask=LVIF_TEXT;

                     iPosition=GetListCtrl().InsertItem(&Item);

                     GetListCtrl().SetItemText(iPosition,1,"REG_NONE");

                     break;

              }

       }

 

       return iPosition;

}

到此数据的显示已经基本完成,余下为数据操作的代码

本文地址:http://com.8s8s.com/it/it1353.htm