左边树型CregLeftView类的设计:
1.和文档类进行通信的代码:
在类定义前加入class CRegExplorerDoc;并在类中实现public型的成员函数
CRegExplorerDoc* CRegLeftView::GetDocument() { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CRegExplorerDoc))); return (CRegExplorerDoc*)m_pDocument; } |
2.用树来显示注册表信息。
注意:注册表信息内容比较多,不可能全部显示,则可一开始,先显示最接近于树根,再根据操作来逐步显示子树的方案来实现,
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; } |
|