⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regview.cpp

📁 ce系统下面的一个浏览注册表的应用程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		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 + -