当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 遍历和查找外部程序 Tree-View 中的项目

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 遍历和查找外部程序 Tree-View 中的项目


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 188 ::
收藏到网摘: n/a

遍历和查找外部程序 Tree-View 中的项目

天津 赵春生

下载源代码

  《金山词霸2002》中的附录收集了很多古诗,有时为了寻找一篇古诗,得找很久很久(俺文科很差)。观察其附录的结构,发现是个Tree-View控件,如果能查找里面的项目该有多好,可这个功能软件本身却并没有提供(不知道现在最新的版本是否已经提供了这个功能,如果没有,赶快加上吧,顺便奖励俺一套该产品的最新版,哈哈)……问题出来了:我们要编写一个程序,让她在外部程序中的Tree-View控件里,按用户指定的项目名称顺序查找其中的项目。
  要查找首先得遍历,连范围都确定不好何谈查找?所以本篇分两部分进行讲解:第一部分解决遍历的问题;第二部分解决查找指定项目的问题。

第一部分:遍历外部程序Tree-View中的项目

一:程序说明:

如图一所示Tree-View控件的典型结构图,我们将按照图示的顺序来遍历其中的项目。


图一

翻阅SDK手册中关于Tree-View控件的相关章节,发现了几个有用的消息:

  • TVM_GETNEXTITEM:得到项目的句柄(参数:TVGN_ROOT得到根句柄,TVGN_NEXTVISIBLE得到下一个可见项目的句柄);
  • TVM_EXPAND:展开或折叠指定项目(参数:TVE_EXPAND展开指定项目);
  • TVM_SELECTITEM:选中指定项目。

利用这些消息和SendMessage()函数,我们可以很容易写出遍历代码。

二:具体实践

  在本文所提供的DEMO中,有一段将十六进制字符串转换成十进制无符号长整型的代码,作用是将用户输入的十六进制TV句柄值转换成十进制并存放在变量dec_sum中。此代码不列入本文讨论的范畴,大家不闲弱智的话就将就着用吧。下面是实现遍历功能的关键代码:

	/*	Tree-View Control_Demo_SeqShow 1.0 版	*	版权所有 (C) 2006 天津 赵春生	*	2006.08.28	*	http://timw.yeah.net	*	http://timw.126.com	*	本程序能顺序遍历TV控件中的所有项目。	*	代码在Win2000P+SP4 + VC6+SP6测试通过。	*/	if(error==0)//如果在数据验证转换的过程中未出现错误(error==0时无错误)	{	//下面为核心部分:顺序显示(选中)指定Tree-View控件中的所有Item.	hwnd=HWND(dec_sum);//得到转换后的数据	//得到根句柄	tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, TVM_GETNEXTITEM,TVGN_ROOT, 0x0);	::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, (long)tvitem.hItem);//选中状态	while((long)tvitem.hItem)	{	//当此项目能展开时	while(::SendMessage(hwnd, TVM_EXPAND,TVE_EXPAND, (long)tvitem.hItem))	{	//选择下一个可见项目	tvitem.hItem=(HTREEITEM)::SendMessage(hwnd,	TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,	(long)tvitem.hItem);	//选中状态	::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, (long)tvitem.hItem);	continue;	}	//当不能再展开的时候,选择下一个可见项目	tvitem.hItem=(HTREEITEM)::SendMessage(hwnd,	TVM_GETNEXTITEM,TVGN_NEXTVISIBLE,	(long)tvitem.hItem);	//选中状态	::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET,	(long)tvitem.hItem);	}	}	//释放内存	CloseHandle(hwnd);	//顺序显示(选中)完毕
三:TV_Demo_SeqShow的使用方法(图2):


图二

  1. 用SPY++的[Find Window]功能获得目标TV的句柄;
  2. 将句柄值输入到TV_Demo_SeqShow中的[Tree-View Control''s Handle:];
  3. 点击[GO!];

  如果你把[Windows 资源管理器]中的[文件夹]作为目标,那你可要作好心理准备了……如果实在忍受不了这种刺激,干脆把管理器关掉就可以了。

第二部分:查找外部程序Tree-View中的项目

一:程序说明:

  我们已经成功得对外部程序Tree-View中的项目进行了遍历,如果能在遍历的过程中读取每一个项目的名称,结合我们给定的项目名进行比较,那么查找某个项目的问题将变得易如反掌。由此可见:关键的问题是如何读取项目的名称。
  读取项目的名称要发送TVM_GETITEM消息,由于该消息需要为LPARAM参数提供一个TV_ITEM结构的地址,在跨进程发送消息的前提下,为了使外部程序正常使用该内存地址,所以我们必须将TV_ITEM结构插入到目标进程的地址空间中去,代码如下:

ptvitem=(TVITEM*)VirtualAllocEx(hProcess,NULL,sizeof(TVITEM),MEM_COMMIT,PAGE_READWRITE);//分配内存WriteProcessMemory(hPr