📄 regview.cpp
字号:
lvi.iImage = 2;
else if(_tcscmp(pszType,_T("REG_BINARY")) == 0)
lvi.iImage = 3;
else // Unknown type
lvi.iImage = 4;
rc = SendMessage(hwndLV,LVM_INSERTITEM,(WPARAM)0,(LPARAM)(const LVITEM FAR *)&lvi);
// 设置该行其余数据项再
lvi.mask = LVIF_TEXT;
lvi.iItem = nItem;
lvi.iSubItem = 1;
lvi.pszText = pszData;
rc = SendMessage(hwndLV,LVM_SETITEM,0,(LPARAM)&lvi);
lvi.mask = LVIF_TEXT;
lvi.iItem = nItem;
lvi.iSubItem = 2;
lvi.pszText = pszType;
rc = SendMessage(hwndLV,LVM_SETITEM,0,(LPARAM)&lvi);
return 0;
}
/************************************************************************
** 函数:HTREEITEM InsertTV(HWND hWnd,HTREEITEM hParent,TCHAR *pszName,
LPARAM lParam,DWORD nChildren)
** 功能:树形视图注册表中插入子项。成功:返回新插入项的句柄;失败:
** 输入:
hWnd[in]: 父窗口句柄
hParent[in]: 父结点句柄
pszName[in]: 要插入结点的名称
lParam[in]:
nChildren[in]:要插入结点的子结点个数;
** 输出:
HTREEITEM[out]:新插入结点的句柄
** 作者:XZP
** 日期:07.9.4
** 备注:主要用到Treeview_InsertItem函数和TV_INSERTSTRUCT结构向树形视图插入结点
************************************************************************/
HTREEITEM InsertTV(HWND hWnd,HTREEITEM hParent,TCHAR *pszName,
LPARAM lParam,DWORD nChildren)
{
TV_INSERTSTRUCT tvis;
HWND hwndTV = GetDlgItem(hWnd,ID_TREEV);
memset(&tvis,0,sizeof(tvis));
tvis.hParent = hParent; // 父项目句柄
tvis.hInsertAfter = TVI_SORT; // 按字母排列
tvis.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_CHILDREN | TVIF_IMAGE;
tvis.item.pszText = pszName;
tvis.item.cchTextMax = _tcsclen(pszName);
tvis.item.iImage = 1; // 该结点没被选中时显示图象链表中的第n张图
tvis.item.iSelectedImage = 2; // 该结点被选中时显示图象链表中的第n张图
tvis.item.lParam = lParam;
if(nChildren)
tvis.item.cChildren = 1; // 该结点有子结点
else
tvis.item.cChildren = 0; // 该结点没有子结点
return TreeView_InsertItem(hwndTV,&tvis);
}
/************************************************************************
** 函数:int GetTree(HWND hWnd,HTREEITEM hItem,HKEY *pRoot,TCHAR *pszKey,int nMax)
** 输入:
hWnd[in]: 父窗口句柄
hItem[in]: 要操作的结点句柄
nMax[in]: pszKey缓冲区大小
** 输出:
pRoot[out]: 根结点句柄
pszKey[out]:树型视图结点完整路径(不包含根结点)
return int: 0 - 成功; other - 失败
** 功能:获取一树型视图某一结点的完整路径(不包含根结点)及其根结点句柄。
** 作者:XZP
** 日期:07.9.6
** 备注:主要是用API函数TreeView_GetParent()获得某一结点的父结点句柄,再
利用嵌套调用该函数直到得到其所在的根结点,从而获取结点的完整路径(不包含根结点)。
************************************************************************/
int GetTree(HWND hWnd,HTREEITEM hItem,HKEY *pRoot,TCHAR *pszKey,int nMax)
{
TV_ITEM tvi; // 树型视图结点结构体
TCHAR szName[256];
HTREEITEM hParent; // 父结点句柄
HWND hwndTV; // 树型视图控件句柄
int rc = 0;
hwndTV = GetDlgItem(hWnd,ID_TREEV);
memset(&tvi,0,sizeof(tvi));
hParent = TreeView_GetParent(hwndTV,hItem);
if(hParent)
{
// 嵌套调用,直到获得根结点
GetTree(hWnd,hParent,pRoot,pszKey,nMax);
// 获取该结点的名称
tvi.mask = TVIF_TEXT;
tvi.hItem = hItem;
tvi.pszText = szName;
tvi.cchTextMax = sizeof(szName)/sizeof(TCHAR);
TreeView_GetItem(hwndTV,&tvi);
_tcscat(pszKey,_T("\\"));
_tcscat(pszKey,szName);
}
else
{
// 根结点
*pszKey = _T('\0');
szName[0] = _T('\0');
// 获取根结点的名称
tvi.mask = TVIF_TEXT | TVIF_PARAM;
tvi.hItem = hItem;
tvi.pszText = szName;
tvi.cchTextMax = sizeof(szName)/sizeof(TCHAR);
if(TreeView_GetItem(hwndTV,&tvi))
* pRoot = (HKEY)(HTREEITEM)tvi.lParam;
else
{
rc =GetLastError();
return rc;
}
}
return rc;
}
/************************************************************************
** 函数:int EnumValues(HWND hWnd,HKEY hRoot,LPTSTR pszKey)
** 输入:
hWnd[in]: 父窗口
hRoot[in]: 指定结点的根结点句柄
pszKey[in]: 指定结点的完整路径(不包括根结点)
** 输出:
** 功能:枚举指定结点(子键)的键值名称、键值大小和类型,并显示到右边的列表框视图中。
** 作者:XZP
** 日期:07.9.6
** 备注:
1). API函数RegEnumValue()可根据第二个参数值dwIndex来枚举出指定健的所有
键值名称、键值大小和数据类型。
2). RegEnumValue枚举时,数据大小,举个例子,如果某键的键值为字符串,如
Name Data Type
Grou NDIS REG_SZ
则枚举是数据大小(in bytes),即NDIS的大小为10,包括结束符,而且为宽字符
3). 每枚举一次都调用了两次RegEnumValue函数,第一次得到数据大小,便于分
配内存,第二次才是真正的枚举。
************************************************************************/
int EnumValues(HWND hWnd,HKEY hRoot,LPTSTR pszKey)
{
int nCnt = 0,rc;
DWORD dwNSize,dwDSize,dwType;
TCHAR szName[256]; // 注册表健和键值的名称不能超过255个字符
BYTE *pbData = NULL;
HKEY hKey;
if(_tcslen(pszKey))
{
if(RegOpenKeyEx(hRoot,pszKey,0,0,&hKey) != ERROR_SUCCESS)
return 0;
}
else
hKey = hRoot;
// 清除列表视图控件
ListView_DeleteAllItems(GetDlgItem(hWnd,ID_LISTV));
// 查看第nCnt个键值数据大小
dwNSize = sizeof(szName)/sizeof(TCHAR);
rc = RegEnumValue(hKey,nCnt,szName,&dwNSize,
NULL,NULL,NULL,&dwDSize);
if(rc != ERROR_SUCCESS)
{
RETAILMSG(TRUE,(_T("rc != ERROR_SUCCESS 1\n")));
return 0;
}
RETAILMSG(TRUE,(_T("dwDSize = %d\n"),dwDSize));
// 为第nCnt个键值存储数据分配内存
pbData = (LPBYTE)malloc(dwDSize);
if(!pbData)
{
RETAILMSG(TRUE,(_T("no enough memory\n")));
return 0;
}
// 枚举第nCnt个键值的相关数据
dwNSize = sizeof(szName)/sizeof(TCHAR);
rc = RegEnumValue(hKey,nCnt,szName,&dwNSize,
NULL,&dwType,pbData,&dwDSize);
if(rc != ERROR_SUCCESS)
{
RETAILMSG(TRUE,(_T("rc != ERROR_SUCCESS 2\n")));
return 0;
}
RETAILMSG(TRUE,(_T("szName = %s; pbData = %s\n"),szName,pbData));
while(rc == ERROR_SUCCESS)
{
// 将数据显示到列表视图控件中
DisplayValue(hWnd,nCnt,szName,pbData,dwDSize,dwType);
if(pbData)
{
free(pbData);
pbData = NULL;
}
nCnt++;
// 查看第nCnt个键值数据大小
dwNSize = sizeof(szName)/sizeof(TCHAR);
dwDSize = 0;
rc = RegEnumValue(hKey,nCnt,szName,&dwNSize,
NULL,NULL,NULL,&dwDSize);
if(rc != ERROR_SUCCESS)
{
RETAILMSG(TRUE,(_T("rc != ERROR_SUCCESS 3\n")));
return 0;
}
//RETAILMSG(TRUE,(_T("dwDSize = %d\n"),dwDSize));
// 为第nCnt个键值存储数据分配内存
pbData = (LPBYTE)malloc(dwDSize);
if(!pbData)
{
RETAILMSG(TRUE,(_T("no enough memory 2\n")));
return 0;
}
// 枚举第nCnt个键值的相关数据
dwNSize = sizeof(szName)/sizeof(TCHAR);
rc = RegEnumValue(hKey,nCnt,szName,&dwNSize,
NULL,&dwType,pbData,&dwDSize);
if(rc != ERROR_SUCCESS)
{
RETAILMSG(TRUE,(_T("rc != ERROR_SUCCESS 4\n")));
return 0;
}
//RETAILMSG(TRUE,(_T("szName = %s; pbData = %x\n"),szName,*(DWORD *)pbData));
}
ListView_SortItems(GetDlgItem(hWnd,ID_LISTV),(PFNLVCOMPARE)CompareFunc,0);
if(hKey != hRoot)
RegCloseKey(hKey);
if(pbData)
{
free(pbData);
pbData = NULL;
}
return 1;
}
/************************************************************************
** 函数:DWORD EnumChildren(HWND hWnd,
HTREEITEM hParent,
HKEY hRoot,
LPTSTR pszKey)
** 输入:
hWnd[in]: 父窗口句柄
hParent[in]:要枚举的结点句柄
hRoot[in]: 该结点的根结点句柄
pszKey[in]: 该结点的完整路径(不包括根结点)
** 输出:
** 功能:枚举出某一结点的所有子结点。并添加到树型视图中。
** 作者:XZP
** 日期:07.9.6
** 备注:API函数RegEnumKeyEx()可根据第二个参数值dwIndex来枚举出指定健的所有
子健。枚举出某一子键,在要将数据加入树型视图控件之前,还要得知该子键是否包含
有子键。以便设定TV_ITEM结构体中的参数cChildren。
************************************************************************/
DWORD EnumChildren(HWND hWnd,HTREEITEM hParent,HKEY hRoot,LPTSTR pszKey)
{
int i = 0,rc;
DWORD dwNSize,dwCSize,nChild;
TCHAR szName[MAX_PATH],szClass[256];
FILETIME ft;
HKEY hKey;
TV_ITEM tvi;
HTREEITEM hChild,hNext;
//
// 在枚举出子结点之前,先清空该结点的所有子结点,以免出现重复显示子结点的想象。
//
// 先获得第一个子结点句柄(两种方法)
/*
hChild = TreeView_GetChild(
hwndCtl, // 树型控件句柄
pNotifyTV->itemNew.hItem); // 结点句柄
*/
hChild = (HTREEITEM)SendMessage(GetDlgItem(hWnd,ID_TREEV),
TVM_GETNEXTITEM,
TVGN_CHILD,
(LPARAM)hParent);
while(hChild)
{
// 获得下一兄弟结点(两种方法)
/*
hNext = TreeView_GetNextItem(
hwndCtl, // 树型控件句柄
hChild, // 结点句柄
TVGN_NEXT); // 指明结点的下一兄弟结点
*/
hNext =(HTREEITEM)SendMessage(GetDlgItem(hWnd,ID_TREEV),
TVM_GETNEXTITEM,
TVGN_NEXT,
(LPARAM)hChild);
// 删除子结点
TreeView_DeleteItem(GetDlgItem(hWnd,ID_TREEV),hChild);
hChild = hNext;
}
if(_tcslen(pszKey))
{
if(RegOpenKeyEx(hRoot,pszKey,0,0,&hKey) != ERROR_SUCCESS)
{
rc = GetLastError();
return 0;
}
}
else
hKey = hRoot;
dwNSize = sizeof(szName)/sizeof(TCHAR);
dwCSize = sizeof(szClass)/sizeof(TCHAR);
// 开始枚举子健,并添加到树型控件中
rc = RegEnumKeyEx(hKey,i,szName,&dwNSize,NULL,szClass,&dwCSize,&ft);
while(rc == ERROR_SUCCESS)
{
// 获得结点pszKey的子结点szName的子结点的个数先。
// 在要向树型视图插入某一结点时,必须设定该结点结构体TV_ITEM中的
// cChildren参数,该参数表示该结点是否有子结点。
nChild = CountChildren(hRoot,pszKey,szName);
// 把相应健添加到树型视图中
InsertTV(hWnd,hParent,szName,0,nChild);
dwNSize = sizeof(szName)/sizeof(TCHAR);
rc = RegEnumKeyEx(hKey,++i,szName,&dwNSize,NULL,NULL,NULL,&ft);
}
// if this wasn't a root key,close it
if(hKey != hRoot)
RegCloseKey(hKey);
if(i == 0)
{ // 如果没有子结点,删除展开按钮
tvi.hItem = hParent;
tvi.mask = TVIF_CHILDREN;
tvi.cChildren = 0; // 指定子结点个数为0,便不会显示"+","-"号
TreeView_SetItem(GetDlgItem(hWnd,ID_TREEV),&tvi);
}
else
{ // 如果一个结点从无结点变成有结点,如新建项,则添加展开按钮
tvi.hItem = hParent;
tvi.mask = TVIF_CHILDREN;
tvi.cChildren = 1; // 指定子结点个数为1,便会显示"+","-"号
TreeView_SetItem(GetDlgItem(hWnd,ID_TREEV),&tvi);
}
return 1;
}
/************************************************************************
** 函数:DWORD CountChildren(HKEY hRoot,
LPTSTR pszKeyPath,
LPTSTR pszKey)
** 输入:
hRoot[in]: 根结点句柄
pszKeyPath[in]: 某一结点的完整路径(不包括根结点)
pszKey[in]: 某一结点pszKeyPath的某一子结点名称
** 输出:
return: 子结点个数
** 功能:计算出树型视图某一结点pszKeyPath的子结点pszKey的子结点的个数。
** 作者:XZP
** 日期:07.9.6
** 备注:API函数RegQueryInfoKey()可以得到注册表中某一健的子健个数
************************************************************************/
DWORD CountChildren(HKEY hRoot,LPTSTR pszKeyPath,LPTSTR pszKey)
{
TCHAR *pEnd;
DWORD dwCnt;
HKEY hKey;
pEnd = pszKeyPath + _tcslen(pszKeyPath);
_tcscpy(pEnd,_T("\\"));
_tcscat(pEnd,pszKey);
if(RegOpenKeyEx(hRoot,pszKeyPath,0,0,&hKey) == ERROR_SUCCESS)
{
RegQueryInfoKey(hKey,NULL,NULL,0,&dwCnt,NULL,NULL,NULL,
NULL,NULL,NULL,NULL);
RegCloseKey(hKey);
}
*pEnd = _T('\0');
return dwCnt;
}
/************************************************************************
** 函数:int DisplayValue(HWND hWnd,
int nCnt,
LPTSTR pszName,
PBYTE pbData,
DWORD dwDSize,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -