前期工作是要找到TreeView的句柄,这个不在本文讨论范围。
使用SendMessage(TreeViewHwnd, TVM_SELECTITEM, TVGN_CARET, ItemHwnd)可以选定要操作的节点,而TVM_GETITEMRECT消息可以取得节点Rect,再配合WM_LBUTTONDBLCLK消息,就实现双击节点的效果了。
hTree = FindWindowEx(hMain, NULL, "TTreeView", NULL); if (hTree==NULL) { MessageDlg("没运行程序吧!", mtWarning, TMsgDlgButtons() << mbOK, 0); } else { //开工 HTREEITEM hItem = TreeView_GetRoot(hTree); hItem = TreeView_GetNextItem(hTree, hItem, TVGN_CHILD); ::SendMessage(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hItem); TreeView_EnsureVisible(hTree, hItem); DWORD pid = 0; GetWindowThreadProcessId(hTree,&pid); HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,true,pid); RECT *prect=(RECT*)VirtualAllocEx(hProcess, NULL, sizeof(RECT), MEM_COMMIT, PAGE_READWRITE); RECT rect={0}; unsigned long n=0; *(HTREEITEM*)&rect = hItem; WriteProcessMemory(hProcess, prect, &rect, sizeof(RECT), NULL); ::SendMessage(hTree, TVM_GETITEMRECT, (WPARAM)FALSE, (LPARAM)prect); ReadProcessMemory(hProcess,prect,&rect,sizeof(RECT),&n); POINT pt={0}; pt.x = rect.left + (rect.right-rect.left)/2; pt.y = rect.top + (rect.bottom-rect.top)/2; ::SendMessage(hTree, WM_LBUTTONDBLCLK, 0, MAKELPARAM((WORD)pt.x,(WORD)pt.y)); //释放内存 CloseHandle(hProcess); VirtualFreeEx(hProcess, prect, 0, MEM_RELEASE); }
上面是针对TreeView在后台的示例,并且点击了第一个子节点。
如果TreeView在前台,可以使用mouse_event,有种真实鼠标模拟的感觉:
//转换下坐标 ::ClientToScreen(hTree,&pt); //鼠标事件 SetCursorPos(pt.x, pt.y); mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0,0); mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0,0); mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0,0); mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0,0);