获取外部控件句柄学习日志
前段时间小伊做的程序需要获取外部控件句柄这样的功能,以前虽然有接触过spy++,平时用不上,没有深入过... ...学无止境啊
进入主题...
//====================1
//获取鼠标所处控件的信息
BOOL GetCurrentPosControl()
{
POINT currentMousePos;
GetCursorPos(¤tMousePos);//mouse point
HWND wmControl=WindowFromPoint(currentMousePos);//handle control
//实际情况中如果鼠标下的控件disabled 这里得到的句柄将是该控件的上层容器
//这种方法并不适合获取disabled状态的控件
进入主题...
//====================1
//获取鼠标所处控件的信息
BOOL GetCurrentPosControl()
{
POINT currentMousePos;
GetCursorPos(¤tMousePos);//mouse point
HWND wmControl=WindowFromPoint(currentMousePos);//handle control
//实际情况中如果鼠标下的控件disabled 这里得到的句柄将是该控件的上层容器
//这种方法并不适合获取disabled状态的控件
GetControlInfo(wmControl);
return TRUE;
return TRUE;
}
//======================================
这里最直接的调用 WindowFromPoint 可以简单的获得鼠标下控件的句柄
MSDN对这个函数的解释是The WindowFromPoint function retrieves a handle to the window that contains the specified point
大意是 获的包含鼠标位置点的窗口句柄 两个关键词 包含 和 窗口
包含 我是这样理解的:该窗口上包含这个鼠标点的第一控件 与RealChildWindowFromPoint有些类似了
窗口 这里得到的是最上层窗口的句柄
这个函数不能得到disabled 的控件句柄
//======================================
这里最直接的调用 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 );
//获取鼠标所处的最小控件
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 );
{
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;
}
}
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.
//===============================
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控件句柄能正常获取,但是
遇到重叠的控件,只能得到包含的控件句柄,事实上需要的是被包含的控件句柄
实际使用中disabled控件句柄能正常获取,但是
遇到重叠的控件,只能得到包含的控件句柄,事实上需要的是被包含的控件句柄
稍微作些修改
HWND wmControl=ChildWindowFromPoint(cHwnd,point);//客户区坐标
改为
HWND wmControl=RealChildWindowFromPoint(cHwnd,point);//客户区坐标
HWND wmControl=ChildWindowFromPoint(cHwnd,point);//客户区坐标
改为
HWND wmControl=RealChildWindowFromPoint(cHwnd,point);//客户区坐标
可行
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 转载请保留作者信息,感谢
//===============================