首页 > 开发 > 综合 > 正文

跨进程实现在Tree中快速定位节点

2024-07-21 02:15:57
字体:
来源:转载
供稿:网友

    前些日子写软件时,需要实现一个功能,就是在tree中快速定位节点,比如注册表编辑器左边的tree,只要给出tree中的节点路径(以“/”分隔),就可以快速将树展开,并将当前节点定位到指定的节点。功能的实现并不难,但稍有些麻烦。原因在于,如果是本进程中的tree,只要发消息就可以了,但如果是另外一个进程中的tree,就要在那个进程中申请内存,将tree节点的文字复制到这块内存,然后再把这块内存的数据复制到本进程的一块内存中,才能与指定的节点路径相比较。由于这个功能还有一些可一般化的东西,所以就写了一个dll,只要给出tree的句柄和节点路径,就可以展开这颗树并定位节点。



     dll源代码如下:



/********************************************************************/



/* 文件名: tree.cpp                                                 */



/*                                                                  */



/* 功能: 标准 dll ---- 跨进程展开 systreeview32 中指定的节点        */



/*                                                                  */



/* 作者: 卢培培 (goodname008)           时间: 2005.02.18            */



/*                                                                  */



/* blog: http://blog.csdn.net/goodname008                           */



/********************************************************************/




 


#include "stdafx.h"



#include "tree.h"



#include "commctrl.h"



#include <string>




 


using namespace std;




 


bool apientry dllmain( handle hmodule, dword ul_reason_for_call, lpvoid lpreserved)



{



     switch (ul_reason_for_call)



     {



         case dll_process_attach:



         case dll_thread_attach:



         case dll_thread_detach:



         case dll_process_detach:



              break;



     }



    return true;



}




 


/********************************************************************/



/* 功  能: 跨进程展开 systreeview32 中指定的节点



/*



/* 参  数: htreewnd         systreeview32 的句柄



/*          lpszpath        systreeview32 中的节点路径(忽略大小写)



/*



/* 返回值: true             成功



/*         false            失败(节点路径不存在时会返回失败, 但仍然展开)



/*



/* 说  明: 在节点路径不存在的情况下, 本函数会尽可能展开存在的节点



/********************************************************************/



tree_api bool apientry expandtreenode(hwnd htreewnd, lpcstr lpszpath)



{



     string szpath = lpszpath;




 


     if (szpath.empty())



         return false;




 


     dword dwprocessid = null;



     getwindowthreadprocessid(htreewnd, &dwprocessid);



     if (!dwprocessid)



         return false;




 


     handle hprocess = null;



     hprocess = openprocess(process_vm_operation | process_vm_read | process_vm_write | process_query_information, false, dwprocessid);



     if (!hprocess)



         return false;




 


     tvitem tvitem, *pitem = null;



     zeromemory(&tvitem, sizeof(tvitem));



     pitem = (tvitem *)virtualallocex(hprocess, null, sizeof(tvitem), mem_commit, page_readwrite);




 


     tvitem.mask = tvif_text;



     tvitem.cchtextmax = 512;



     tvitem.psztext = (lpstr)virtualallocex(hprocess, null, 512, mem_commit, page_readwrite);



     tvitem.hitem = treeview_getroot(htreewnd);



     if (!tvitem.hitem)



         return false;




 


     string szpathnode;



     string::size_type nbackslashpos = -1;



     char szitemtext[512] = {'/0'};




 


     do



     {



         szpathnode = szpath.substr(nbackslashpos + 1, szpath.find('//', nbackslashpos + 1) - nbackslashpos - 1);



         do



         {



              if (!writeprocessmemory(hprocess, pitem, &tvitem, sizeof(tvitem), null))



                   return false;




 


              if (!treeview_getitem(htreewnd, pitem))



                   return false;




 


              if (!readprocessmemory(hprocess, tvitem.psztext, szitemtext, 512, null))



                   return false;




 


              if (lstrcmpi(szpathnode.c_str(), szitemtext) == 0)



              {



                   treeview_selectitem(htreewnd, tvitem.hitem);




 


                   if (treeview_expand(htreewnd, tvitem.hitem, tve_expand))



                   {



                       tvitem.hitem = treeview_getchild(htreewnd, tvitem.hitem);



                       if (!tvitem.hitem)



                            return false;



                   }



              }



              else



              {



                   tvitem.hitem = treeview_getnextsibling(htreewnd, tvitem.hitem);



                   if (!tvitem.hitem)



                       return false;



              }




 


         } while(lstrcmpi(szpathnode.c_str(), szitemtext) != 0);




 


         nbackslashpos = szpath.find('//', nbackslashpos + 1);




 


     } while(nbackslashpos != -1);




 


     virtualfreeex(hprocess, tvitem.psztext, null, mem_release);



     virtualfreeex(hprocess, pitem, null, mem_release);




 


     closehandle(hprocess);




 


     return true;



}




 


    头文件源代码:



#ifdef tree_exports



#define tree_api __declspec(dllexport)



#else



#define tree_api __declspec(dllimport)



#endif





tree_api bool apientry expandtreenode(hwnd htreewnd, lpcstr lpszpath);




 


    def文件如下:



library  tree




 


exports

expandtreenode     @1




    



   
调用例程就不再这里给出了,dll和vc的调用例程都是用.net环境写的。



    源代码及调用例程的下载地址: http://csdngoodname008.51.net/tree.zip

*-------------------------------------------*



*  转载请通知作者并注明出处,csdn欢迎您!   *



*  作者:卢培培(goodname008)              *



*  邮箱:[email protected]                *



*  专栏:http://blog.csdn.net/goodname008   *



*-------------------------------------------*

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表