/********************************************************************/ /* 文件名: 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; } |