日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 跨进程实现在Tree中快速定位节点 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

跨進程實現在Tree中快速定位節點

--------------------------------------------------------------------------------
?
????? 前些日子寫軟件時,需要實現一個功能,就是在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

總結

以上是生活随笔為你收集整理的跨进程实现在Tree中快速定位节点的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。