用VC6編寫登錄檔管理程式(二) (轉)

amyz發表於2007-11-28
用VC6編寫登錄檔管理程式(二) (轉)[@more@]

用VC6編寫登錄檔管理(二):namespace prefix = o ns = "urn:schemas--com::office" />

  顧劍輝(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_[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;

  D 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="(未設定型別)",strTe="(未設定鍵值)";

 

  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;

}

到此資料的顯示已經基本完成,餘下為資料操作的程式碼

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

相關文章