用VC6編寫登錄檔管理程式(二) (轉)
用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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 用VC6編寫登錄檔管理程式(三) (轉)
- 應用 WSH 讀寫登錄檔和建立快捷方式 (轉)
- Windows 98 登錄檔的應用(轉)Windows
- 用Delphi編寫DelTree程式 (轉)
- 用Delphi編寫點對點傳檔案程式(1) (轉)
- 用Delphi編寫點對點傳檔案程式(2) (轉)
- 用VC++編寫CGI程式 (轉)C++
- 用VB編寫抽獎程式 (轉)
- 用PHP編寫登陸介面PHP
- 在DOS下使用登錄檔掃描程式 (轉)
- VC6 UTF-8檔案讀寫
- 用Delphi編寫安裝程式(1) (轉)
- 用VB編寫標準CGI程式 (轉)
- 用 C++Builder 編寫 Tray 程式 (轉)C++UI
- 利用Java編寫HTML檔案分析程式(轉)JavaHTML
- Windows 98 登錄檔妙用(轉)Windows
- Win32 API 登錄檔類的編制以及使用 (轉)Win32API
- Python技法:實用運維指令碼編寫(程式/檔案/目錄操作)Python運維指令碼
- Linux網路驅動程式編寫(二)(轉)Linux
- 用VC++6.0編寫撥號程式 (轉)C++
- 為Linux 應用程式編寫 DLL(轉)Linux
- 用 Delphi 編寫 VxD 裝置驅動程式(轉) (轉)
- 隱藏任意程式,目錄檔案,登錄檔,埠
- 用登錄檔儲存資料 (VB函式篇) (轉)函式
- Windows 98 登錄檔應用的30個例項(轉)Windows
- 遠端登錄檔訪問 (轉)
- 登錄檔資料庫Registry (轉)資料庫
- Windows XP 登錄檔修改精粹(轉)Windows
- Windows XP登錄檔詳解(轉)Windows
- 檔案、目錄防寫(轉)
- 登錄檔
- 編寫Linux實用程式的藝術(轉)Linux
- 用BCB編寫身份證號識別程式 (轉)
- 用Delphi編寫塗鴉桌面的小程式 (轉)
- 通過登錄檔完成檔名字尾與運用程式相關聯
- VB中使用系統登錄檔 (轉)
- 利用Windows登錄檔儲存資訊 (轉)Windows
- Windows 98 登錄檔大修改(轉)Windows