CTreeCtrl::SelectItem 光标 模拟鼠标点击

CTreeCtrl::SelectItem 光标 模拟鼠标点击

  (2010-12-02 17:37:14)
标签: 

selectitem

 

光标

 

模拟鼠标

分类: C /VC/WM/MFC

我想要实现这么一个过程,新在树中添加一个子项,然后光标自动聚焦在这个子项上。

在使用CTreeCtrl::SelectItem的时候遇到了问题,虽然SelectItem成功了,但是树控件上的该单元并没有被聚焦。

如下,正常鼠标点击后:

1CTreeCtrl::SelectItem 光标 模拟鼠标点击

使用CTreeCtrl::SelectItem:

2

如上所示,虽然确实被选中了,但是被选者的背景没有阴影效果。

怎样才能实现这种效果呢?

答案就是:模拟鼠标点击事件。

示例代码:

//给树m_VNTree的m_hRequest项下插入子项

hItem = this->m_VNTree.InsertItem(“123456”,this->m_hRequest);

//展开m_hRequest项
this->m_VNTree.Expand(this->m_hRequest,TVE_EXPAND);

//模拟鼠标点击,聚焦/选中这个新加的子项。需要#include "winuser.h"

CRect rcItem;

//bRet = this->m_VNTree.SelectItem(hItem);//鼠标点击本身就是select

// 取得该ITEM的坐标。CTreeCtrl::GetItemRect
this->m_VNTree.GetItemRect(hItem,&rcItem,TRUE);
// 转换到屏幕坐标   CTreeCtrl::ClientToScreen
CPoint   pt;
pt.x = rcItem.left+rcItem.Width()/2;
pt.y = rcItem.top+rcItem.Height()/2;
::ClientToScreen(this->m_VNTree.m_hWnd,&pt);
SetCursorPos(pt.x,pt.y);

// mouse_event   发送模拟鼠标消息到该矩形内一点。
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);

 

以上是控制同一进程中的CTreeCtrl控件,要是不同进程该怎么办呢??

 

转自:http://blog.csdn.net/seu07201213/archive/2006/08/19/1097305.aspx

跨进程操作CTreeCtrl

(模拟鼠标发送双击消息给另一进程CTreeCtrl中指定ITEM)

 

进程之间的数据通讯方式有很多种,我们操作另一进程的子窗口一般采用发消息的方式,因为windows窗口之间都是用windows消息机制。如果有时想发消息根据返回的WPARAM wParam,LPARAM lParam参数获取信息,你会发现获取的信息并不是你想要的,例如:
RECT rc;
*(HTREEITEM*)&rc = hTreeItem;
SendMessage(hwndTreeView, TVM_GETITEMRECT, FALSE, (LPARAM)&rc);
因为你将本进程内的内存地址传入其它进程,是不能指望它会正确填充该地址,那怎么解决呢?
查查相关资料:
http://www.codeproject.com/threads/int64_memsteal.asp
和CSDN krh2001(边城浪子)兄的提醒,问题得到了圆满的解决:-)

本人以模拟QQ游戏大厅的树操作(模拟鼠标双击火拼麻将进入游戏)为例,看看实现的效果:

    HWND qqgame = ::FindWindow(NULL,"QQ游戏");
    ::ShowWindow(qqgame,SW_SHOWMAXIMIZED);  //最大化显示qqgame(版本号2006 beta2 patch2)
    HWND q1 = ::FindWindowEx(qqgame,NULL,NULL,"SkinWnd");
    HWND q2 = ::FindWindowEx(qqgame,q1,NULL,"SkinWnd");
    HWND q3 = ::FindWindowEx(q2,NULL,NULL,"SkinTab");
    HWND q4 = ::FindWindowEx(q3,NULL,NULL,"SkinWnd");
    HWND q5 = ::FindWindowEx(q4,NULL,NULL,"SkinTree");
    HWND htree = ::FindWindowEx(q5,NULL,"SysTreeView32",NULL);    
    HTREEITEM Root = TreeView_GetRoot(htree);  //根节点(游戏)
    HTREEITEM Child1 = TreeView_GetChild(htree, Root); //(QQ游戏新手帮助)
    HTREEITEM Child2 = TreeView_GetNextSibling(htree, Child1); //(游戏论坛)
    HTREEITEM Child3 = TreeView_GetNextSibling(htree, Child2); //(新游戏测试)
    HTREEITEM Child4 = TreeView_GetNextSibling(htree, Child3); //(最近玩过的游戏)
    HTREEITEM Child5 = TreeView_GetNextSibling(htree, Child4); //(休闲竞技游戏)
    HTREEITEM Child6 = TreeView_GetNextSibling(htree, Child5); //(麻将类游戏)    
    HTREEITEM Child61 = TreeView_GetChild(htree, Child6); //(火拼麻将)
    BOOL bSel=(BOOL)::SendMessage(htree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)Child61);
    TreeView_EnsureVisible(htree, Child61);
    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 = Child61;
    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;
    ::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);
//释放内存
    CloseHandle(hProcess);
    VirtualFreeEx(hProcess, prect, 0, MEM_RELEASE);

 

上述代码有个几个核心函数:

GetWindowThreadProcessId OpenProcess,  VirtualAllocEx,

WriteProcessMemory,   ReadProcessMemory

 

把以上代码放到一个消息响应函数里,试试吧,前提是要打开qqgame,不然得用CreateProcess之类的函数启动qqgame进程

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值