下载

0下载券

加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

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

实用电脑技术实例-0587.PDF

实用电脑技术实例-0587

等你来聊
2012-06-20 0人阅读 举报 0 0 0 暂无简介

简介:本文档为《实用电脑技术实例-0587pdf》,可适用于高等教育领域

破解技术实例《遍历和查找外部程序TreeView中的项目》标题:《遍历和查找外部程序TreeView中的项目》作者:Vegeta详细信息:《金山词霸》中的附录收集了很多古诗有时为了寻找一篇古诗得找很久很久(俺文科很差)。观察其附录的结构发现是个TreeView控件如果能查找里面的项目该有多好可这个功能软件本身却并没有提供(不知道现在最新的版本是否已经提供了这个功能如果没有赶快加上吧顺便奖励俺一套该产品的最新版哈哈)……问题出来了:我们要编写一个程序让她在外部程序中的TreeView控件里按用户指定的项目名称顺序查找其中的项目。要查找首先得遍历连范围都确定不好何谈查找?所以本篇分两部分进行讲解:第一部分解决遍历的问题第二部分解决查找指定项目的问题。第一部分:遍历外部程序TreeView中的项目。一:程序说明:下图()为TreeView控件的典型结构图我们将按照图示的顺序来遍历其中的项目。翻阅SDK手册中关于TreeView控件的相关章节发现了几个有用的消息:TVMGETNEXTITEM:得到项目的句柄(参数:TVGNROOT得到根句柄TVGNNEXTVISIBLE得到下一个可见项目的句柄)TVMEXPAND:展开或折叠指定项目(参数:TVEEXPAND展开指定项目)TVMSELECTITEM:选中指定项目。利用这些消息和SendMessage()函数我们可以很容易写出遍历代码。二:具体实践:在本文所提供的DEMO中有一段将十六进制字符串转换成十进制无符号长整型的代码作用是将用户输入的十六进制TV句柄值转换成十进制并存放在变量decsum中。此代码不列入本文讨论的范畴大家不闲弱智的话就将就着用吧。下面是实现遍历功能的关键代码:*TreeViewControlDemoSeqShow版*版权所有(C)天津赵春生**http:timwyeahnet*http:timwcom*本程序能顺序遍历TV控件中的所有项目。*代码在WinPSPVCSP测试通过。*if(error==)如果在数据验证转换的过程中未出现错误(error==时无错误){下面为核心部分:顺序显示(选中)指定TreeView控件中的所有Itemhwnd=HWND(decsum)得到转换后的数据tvitemhItem=(HTREEITEM)::SendMessage(hwnd,TVMGETNEXTITEM,TVGNROOT,x)得到根句柄::SendMessage(hwnd,TVMSELECTITEM,TVGNCARET,(long)tvitemhItem)选中状态while((long)tvitemhItem){while(::SendMessage(hwnd,TVMEXPAND,TVEEXPAND,(long)tvitemhItem))当此项目能展开时{tvitemhItem=(HTREEITEM)::SendMessage(hwnd,TVMGETNEXTITEM,TVGNNEXTVISIBLE,(long)tvitemhItem)选择下一个可见项目::SendMessage(hwnd,TVMSELECTITEM,TVGNCARET,(long)tvitemhItem)选中状态continue}tvitemhItem=(HTREEITEM)::SendMessage(hwnd,TVMGETNEXTITEM,TVGNNEXTVISIBLE,(long)tvitemhItem)当不能再展开的时候选择下一个可见项目::SendMessage(hwnd,TVMSELECTITEM,TVGNCARET,(long)tvitemhItem)选中状态}}释放内存CloseHandle(hwnd)顺序显示(选中)完毕三:TVDemoSeqShow的使用方法(图)::用SPY的FindWindow功能获得目标TV的句柄:将句柄值输入到TVDemoSeqShow中的TreeViewControl'sHandle::点击GO!。如果你把Windows资源管理器中的文件夹作为目标那你可要作好心理准备了……如果实在忍受不了这种刺激干脆把管理器关掉就可以了。第二部分:查找外部程序TreeView中的项目。一:程序说明:我们已经成功得对外部程序TreeView中的项目进行了遍历如果能在遍历的过程中读取每一个项目的名称结合我们给定的项目名进行比较那么查找某个项目的问题将变得易如反掌。由此可见:关键的问题是如何读取项目的名称。读取项目的名称要发送TVMGETITEM消息由于该消息需要为LPARAM参数提供一个TVITEM结构的地址在跨进程发送消息的前提下为了使外部程序正常使用该内存地址所以我们必须将TVITEM结构插入到目标进程的地址空间中去代码如下:ptvitem=(TVITEM*)VirtualAllocEx(hProcess,,sizeof(TVITEM),MEMCOMMIT,PAGEREADWRITE)分配内存WriteProcessMemory(hProcess,ptvitem,tvitem,sizeof(TVITEM),)写入内存在写入内存之前要将TVITEM结构配置好:tvitemmask=TVIFTEXTtvitemcchTextMax=tvitempszText=pItemmask要设置成TVIFTEXT因为我们需要的是pszText的值cchTextMax可以设置得稍微大一些cchTextMax=即可hItem的值用来指定究竟哪个项目来接收TVMGETITEM消息该值在遍历的过程中动态获得重要的是用来存放项目名称的缓冲区地址即pszText参数的设置:和TVITEM结构一样也要把她插入到目标进程的地址空间中去:pItem=(char*)VirtualAllocEx(hProcess,,,MEMCOMMIT,PAGEREADWRITE)二:具体实践:作为演示下面的这段程序将在我们指定的TreeView控件中查找我们需要的项目在发现第一个部分匹配的项目后程序将停止运行不再进行查找操作。作为演示程序程序并没有做速度上的优化大家在具体应用的过程中可自行修改。*TreeViewControlDemoSeqSearch版*版权所有(C)天津赵春生**http:timwyeahnet*http:timwcom*本程序能按用户指定的项目名称顺序查找TV控件中的项目。*代码在WinPSPVCSP测试通过。*if(error==)如果在数据验证转换的过程中未出现错误(error==时无错误){下面为核心部分:按用户指定的项目名称顺序查找TreeView控件中的Itemhwnd=HWND(decsum)得到转换后的数据GetWindowThreadProcessId(hwnd,PID)hProcess=OpenProcess(PROCESSALLACCESS,false,PID)if(!hProcess)MessageBox("获取进程句柄操作失败!","错误!")else{ptvitem=(TVITEM*)VirtualAllocEx(hProcess,,sizeof(TVITEM),MEMCOMMIT,PAGEREADWRITE)pItem=(char*)VirtualAllocEx(hProcess,,,MEMCOMMIT,PAGEREADWRITE)if(!ptvitem)MessageBox("无法分配内存!","错误!")else{MessageBox("本演示程序将按用户指定的项目名称顺序查找。","提示")tvitemmask=TVIFTEXTtvitemcchTextMax=tvitempszText=pItemtvitemhItem=(HTREEITEM)::SendMessage(hwnd,TVMGETNEXTITEM,TVGNROOT,x)得到根句柄::SendMessage(hwnd,TVMSELECTITEM,TVGNCARET,(long)tvitemhItem)选中状态WriteProcessMemory(hProcess,ptvitem,tvitem,sizeof(TVITEM),)将设置好的结构插入目标进程::SendMessage(hwnd,TVMGETITEM,,(LPARAM)ptvitem)发送TVMGETITEM消息ReadProcessMemory(hProcess,pItem,ItemBuf,,)获取pszTextMessageBox(ItemBuf,"ITEMTEXT")if(strnicmp(ItemBuf,stritemtext,strlen(stritemtext))==){MessageBox("已经找到!","恭喜")Bingo=tvitemhItem=(HTREEITEM)x如果根就是我们要找的目标那么程序执行到这里就可以结束了。}while((long)tvitemhItem){while(::SendMessage(hwnd,TVMEXPAND,TVEEXPAND,(long)tvitemhItem))当此项目能展开时{tvitemhItem=(HTREEITEM)::SendMessage(hwnd,TVMGETNEXTITEM,TVGNNEXTVISIBLE,(long)tvitemhItem)选择下一个可见项目::SendMessage(hwnd,TVMSELECTITEM,TVGNCARET,(long)tvitemhItem)选中状态WriteProcessMemory(hProcess,ptvitem,tvitem,sizeof(TVITEM),)将设置好的结构插入目标进程::SendMessage(hwnd,TVMGETITEM,,(LPARAM)ptvitem)发送TVMGETITEM消息ReadProcessMemory(hProcess,pItem,ItemBuf,,)获取pszTextMessageBox(ItemBuf,"ITEMTEXT")if(strnicmp(ItemBuf,stritemtext,strlen(stritemtext))==){MessageBox("已经找到!","恭喜")Bingo=tvitemhItem=(HTREEITEM)x如果发现我们要找的目标那么程序执行到这里就可以结束了。break}continue}if(Bingo!=){tvitemhItem=(HTREEITEM)::SendMessage(hwnd,TVMGETNEXTITEM,TVGNNEXTVISIBLE,(long)tvitemhItem)当不能再展开的时候选择下一个可见项目::SendMessage(hwnd,TVMSELECTITEM,TVGNCARET,(long)tvitemhItem)选中状态WriteProcessMemory(hProcess,ptvitem,tvitem,sizeof(TVITEM),)将设置好的结构插入目标进程::SendMessage(hwnd,TVMGETITEM,,(LPARAM)ptvitem)发送TVMGETITEM消息ReadProcessMemory(hProcess,pItem,ItemBuf,,)获取pszTextMessageBox(ItemBuf,"ITEMTEXT")if(strnicmp(ItemBuf,stritemtext,strlen(stritemtext))==){MessageBox("已经找到!","恭喜")Bingo=tvitemhItem=(HTREEITEM)x如果发现我们要找的目标那么程序执行到这里就可以结束了。break}}}}}}释放内存CloseHandle(hwnd)CloseHandle(hProcess)VirtualFreeEx(hProcess,ptvitem,,MEMRELEASE)顺序查找完毕结束语:今天是难得的七夕愿天下有情人终成眷属。代码写得不够幽雅大家见笑了。在此之前类似的拙文我已经写了四篇希望大家看完后能举一反三。谢谢。《向其他程序的ListView控件发送LVMGETITEMTEXT》《如何选中其他程序ListView控件中的某个Item》《如何更改其他程序ListView控件中某个Item的内容》《如何获取其他程序RichEdit控件中的内容》:

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

评分:

/8

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利