获取外部控件句柄学习日志

 

获取外部控件句柄学习日志
前段时间小伊做的程序需要获取外部控件句柄这样的功能,以前虽然有接触过spy++,平时用不上,没有深入过... ...学无止境啊
进入主题...
//====================1
//获取鼠标所处控件的信息
BOOL GetCurrentPosControl()
{
 POINT currentMousePos;
 GetCursorPos(&currentMousePos);//mouse point
 HWND wmControl=WindowFromPoint(currentMousePos);//handle control
 //实际情况中如果鼠标下的控件disabled 这里得到的句柄将是该控件的上层容器
 //这种方法并不适合获取disabled状态的控件
 GetControlInfo(wmControl);
 return TRUE;
}
//======================================
这里最直接的调用 WindowFromPoint  可以简单的获得鼠标下控件的句柄
MSDN对这个函数的解释是The WindowFromPoint function retrieves a handle to the window that contains the specified point
大意是 获的包含鼠标位置点的窗口句柄  两个关键词  包含 和 窗口
包含 我是这样理解的:该窗口上包含这个鼠标点的第一控件 与RealChildWindowFromPoint有些类似了
窗口 这里得到的是最上层窗口的句柄
这个函数不能得到disabled 的控件句柄
//================================2
//获取鼠标所处的最小控件
BOOL SmallestWindowFromPoint()

 RECT rect, rcTemp;
 HWND hParent, hWnd, hTemp;
 POINT point;
 GetCursorPos(&point);
 hWnd = WindowFromPoint( point );
 if( hWnd != NULL )
 {
  GetWindowRect( hWnd, &rect );
  hParent = GetParent( hWnd );
  if( hParent != NULL )
  {
   hTemp = hWnd;
   do{
    //已获得鼠标位置控件的下层控件
    hTemp = GetWindow( hTemp, GW_HWNDNEXT );
    //该控件屏幕坐标
    GetWindowRect( hTemp, &rcTemp );
    //排除同容器但不在在当前鼠标位置的其他控件
    if(PtInRect(&rcTemp, point) && GetParent(hTemp) == hParent && IsWindowVisible(hTemp))
    {
     // 面积最小
     if(((rcTemp.right - rcTemp.left) * (rcTemp.bottom - rcTemp.top)) < ((rect.right - rect.left) * (rect.bottom - rect.top)))
     {
      // 循环下去!
      hWnd = hTemp;
      GetWindowRect(hWnd, &rect);
     }
    }
   }while( hTemp != NULL );
  }
 }
 GetControlInfo(hWnd);
 return TRUE;
}
//============================
看起来复杂些,简单分解的步骤就是
1.WindowFromPoint 定位一下窗口控件
2.GetParent 得到父窗口句柄
3.从父窗口开始循环 GetWindow GW_HWNDNEXT 递进下层窗口
4.判断面积是否最小
这里功能已经比较完善了,唯一的缺陷是依然不能得到 disabled 控件,原因在windowfrompoint getwindow 上
//===============================
Xisat@ 2008-03-06 转载请保留作者信息,感谢
//==================================3
//获取鼠标位置的最底层控件,包括disabled control
BOOL GetRealWindowFromPoint(HWND cHwnd)
{
 POINT point,WindowPos={0};
 GetCursorPos(&point);
 ClientToScreen(cHwnd,&WindowPos);//转换成屏幕坐标,表示客户区窗口左上角的坐标
 point.x-=WindowPos.x;
 point.y-=WindowPos.y;
 HWND wmControl=ChildWindowFromPoint(cHwnd,point);//客户区坐标
 
 //getlasterr(GetLastError());
 if (wmControl!=NULL)
 {
  if(wmControl!=cHwnd)//wmControl==cHwnd时表示已经到达RealChildWindowFromPoint所能取到的最底层
   GetRealWindowFromPoint(wmControl);//递归
   
  else
  {
   GetControlInfo(wmControl);
   return TRUE;
  }
 }
}
//===============================
Xisat@ 2008-03-06 转载请保留作者信息,感谢
//===============================
主要的API ChildWindowFromPoint MSDN的说明是
The ChildWindowFromPoint function determines which, if any, of the child windows belonging to a parent window contains the specified point. The search is restricted to immediate child windows. Grandchildren, and deeper descendant windows are not searched.
大意是 获取父窗口直接从属的子窗口中包含鼠标位置的控件句柄,限制在直属子窗口,不包括更深层窗口 --这没关系,我们可以递归枚举下去
实际使用中disabled控件句柄能正常获取,但是
1
遇到重叠的控件,只能得到包含的控件句柄,事实上需要的是被包含的控件句柄
稍微作些修改
HWND wmControl=ChildWindowFromPoint(cHwnd,point);//客户区坐标
改为
HWND wmControl=RealChildWindowFromPoint(cHwnd,point);//客户区坐标
2
可行
MSDN 对这个api的解释是
The RealChildWindowFromPoint function retrieves a handle to the child window at the specified point. The search is restricted to immediate child windows; grandchildren and deeper descendant windows are not searched.
咋一看还真没区别
关键词是 at 而上面是 contains
at 在鼠标位置下的最直接控件 contains是包含鼠标位置的第一控件(老外学起来是不是没这样费力 BS^_^)
MS为什么不把这两个api统一一下???
//============================
还有这方面几个常用的API
WindowFromPhysicalPoint Vista下用的???
ChildWindowFromPointEx 和ChildWindowFromPoint类似 多了一个扩展参数
EnumChildWindows 枚举子窗口内的所有控件,包括一个回调函数,实在找不到就枚举吧
更多说明请参考MSDN,该做饭去咯^_^.
//===============================
Xisat@ 2008-03-06 转载请保留作者信息,感谢
//===============================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值