首页 实用电脑技术实例-0587

实用电脑技术实例-0587

举报
开通vip

实用电脑技术实例-0587 破解技术实例0587-《遍历和查找外部程序Tree-View中的项目》 标 题: 《遍历和查找外部程序Tree-View中的项目》 作 者: Vegeta 详细信息: 《金山词霸2002》中的附录收集了很多古诗,有时为了寻找一篇古诗,得 找很久很久(俺文科很差)。观察其附录的结构,发现是个Tree-View控件 ,如果能查找里面的项目该有多好,可这个功能软件本身却并没有提供(不知 道现在最新的版本是否已经提供了这个功能,如果没有,赶快加上吧,顺便奖 励俺一套该产品的最新版,哈哈)……问...

实用电脑技术实例-0587
破解技术实例0587-《遍历和查找外部程序Tree-View中的项目》 标 题: 《遍历和查找外部程序Tree-View中的项目》 作 者: Vegeta 详细信息: 《金山词霸2002》中的附录收集了很多古诗,有时为了寻找一篇古诗,得 找很久很久(俺文科很差)。观察其附录的结构,发现是个Tree-View控件 ,如果能查找里面的项目该有多好,可这个功能软件本身却并没有提供(不知 道现在最新的版本是否已经提供了这个功能,如果没有,赶快加上吧,顺便奖 励俺一套该产品的最新版,哈哈)……问题出来了:我们要编写一个程序,让 她在外部程序中的Tree-View控件里,按用户指定的项目名称顺序查找其中的 项目。 要查找首先得遍历,连范围都确定不好何谈查找?所以本篇分两部分进行 讲解:第一部分解决遍历的问题;第二部分解决查找指定项目的问题。 第一部分:遍历外部程序Tree-View中的项目。 一:程序说明: 下图(1)为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(hProcess,ptvitem,&tvitem,sizeof(TVITEM),NULL);/ /写入内存 在写入内存之前,要将TV_ITEM结构配置好: tvitem.mask=TVIF_TEXT; tvitem.cchTextMax=512; tvitem.pszText=pItem; mask要设置成TVIF_TEXT,因为我们需要的是pszText的值 ;cchTextMax可以设置得稍微大一些,cchTextMax=512即可;hItem的值 用来指定究竟哪个项目来接收TVM_GETITEM消息,该值在遍历的过程中动态 获得;重要的是用来存放项目名称的缓冲区地址,即pszText参数的设置:和 TV_ITEM结构一样,也要把她插入到目标进程的地址空间中去: pItem=(char*)VirtualAllocEx(hProcess,NULL,16,MEM_COMMIT,PAGE_RE ADWRITE); 二:具体实践: 作为演示,下面的这段程序将在我们指定的Tree-View控件中查找我们需 要的项目,在发现第一个部分匹配的项目后,程序将停止运行,不再进行查找 操作。作为演示程序,程序并没有做速度上的优化,大家在具体应用的过程中 可自行修改。 ////////////////////////////////////////////////////////////////////// /* Tree-View Control_Demo_SeqSearch 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);//得到转换后的数据 GetWindowThreadProcessId(hwnd, &PID); hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID); if (!hProcess) MessageBox("获取进程句柄操作失败!","错误!"); else { ptvitem=(TVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(TVITEM), MEM_COMMIT, PAGE_READWRITE); pItem=(char*)VirtualAllocEx(hProcess, NULL, 16, MEM_COMMIT, PAGE_READWRITE); if (!ptvitem) MessageBox("无法分配内存!","错误!"); else { MessageBox("本演示程序将按用户指定的项目名称顺序查找。","提示"); tvitem.mask=TVIF_TEXT; tvitem.cchTextMax=512; tvitem.pszText=pItem; tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, TVM_GETNEXTITEM,TVGN_ROOT, 0x0);//得到根句柄 ::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, (long)tvitem.hItem);//选中状态 WriteProcessMemory(hProcess, ptvitem, &tvitem, sizeof(TVITEM), NULL);//将设置好的结构插入目标进程 ::SendMessage(hwnd, TVM_GETITEM,0, (LPARAM)ptvitem);//发送TVM_GETITEM消息 ReadProcessMemory(hProcess, pItem, ItemBuf, 512, NULL);//获取 pszText //MessageBox(ItemBuf,"ITEM TEXT"); if( strnicmp( ItemBuf,str_item_text,strlen(str_item_text) ) == 0) { MessageBox("已经找到!","恭喜"); Bingo=1; tvitem.hItem=(HTREEITEM)0x0;//如果根就是我们要找的目标,那么程 序执行到这里就可以结束了。 } 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);//选中状态 WriteProcessMemory(hProcess, ptvitem, &tvitem, sizeof(TVITEM), NULL);//将设置好的结构插入目标进程 ::SendMessage(hwnd, TVM_GETITEM,0, (LPARAM)ptvitem);//发送TVM_GETITEM消息 ReadProcessMemory(hProcess, pItem, ItemBuf, 512, NULL);//获取 pszText //MessageBox(ItemBuf,"ITEM TEXT"); if( strnicmp( ItemBuf,str_item_text,strlen(str_item_text) ) == 0) { MessageBox("已经找到!","恭喜"); Bingo=1; tvitem.hItem=(HTREEITEM)0x0;//如果发现我们要找的目标,那么程序 执行到这里就可以结束了。 break; } continue; } if(Bingo!=1) { tvitem.hItem=(HTREEITEM)::SendMessage(hwnd, TVM_GETNEXTITEM,TVGN_NEXTVISIBLE, (long)tvitem.hItem);//当不能再展开的时候,选择下一个可见项目 ::SendMessage(hwnd, TVM_SELECTITEM,TVGN_CARET, (long)tvitem.hItem);//选中状态 WriteProcessMemory(hProcess, ptvitem, &tvitem, sizeof(TVITEM), NULL);//将设置好的结构插入目标进程 ::SendMessage(hwnd, TVM_GETITEM,0, (LPARAM)ptvitem);//发送TVM_GETITEM消息 ReadProcessMemory(hProcess, pItem, ItemBuf, 512, NULL);//获取 pszText //MessageBox(ItemBuf,"ITEM TEXT"); if( strnicmp( ItemBuf,str_item_text,strlen(str_item_text) ) == 0) { MessageBox("已经找到!","恭喜"); Bingo=1; tvitem.hItem=(HTREEITEM)0x0;//如果发现我们要找的目标,那么程序 执行到这里就可以结束了。 break; } } } } } } //释放内存 CloseHandle(hwnd); CloseHandle(hProcess); VirtualFreeEx(hProcess, ptvitem, 0, MEM_RELEASE); //顺序查找完毕 ////////////////////////////////////////////////////////////////////// 结束语: 今天是难得的七夕,愿天下有情人终成眷属。 代码写得不够幽雅,大家见笑了。在此之前,类似的拙文我已经写了四篇 ,希望大家看完后能举一反三。谢谢。 《向其他程序的ListView控件发送LVM_GETITEMTEXT》 《如何选中其他程序ListView控件中的某个Item》 《如何更改其他程序ListView控件中某个Item的内容》 《如何获取其他程序RichEdit控件中的内容》 17:02 2006-08-30 ---------------------------------------------------------------------
本文档为【实用电脑技术实例-0587】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_554469
暂无简介~
格式:pdf
大小:162KB
软件:PDF阅读器
页数:0
分类:文学
上传时间:2012-06-20
浏览量:16