獲取外部控件句柄學習日誌
進入主題...
//====================1
//獲取鼠標所處控件的信息
BOOL GetCurrentPosControl()
{
POINT currentMousePos;
GetCursorPos(¤tMousePos);//mouse point
HWND wmControl=WindowFromPoint(currentMousePos);//handle control
//實際情況中如果鼠標下的控件disabled 這裏得到的句柄將是該控件的上層容器
//這種方法並不適合獲取disabled狀態的控件
return TRUE;
//======================================
這裏最直接的調用 WindowFromPoint 可以簡單的獲得鼠標下控件的句柄
MSDN對這個函數的解釋是The WindowFromPoint function retrieves a handle to the window that contains the specified point
大意是 獲的包含鼠標位置點的窗口句柄 兩個關鍵詞 包含 和 窗口
包含 我是這樣理解的:該窗口上包含這個鼠標點的第一控件 與RealChildWindowFromPoint有些類似了
窗口 這裏得到的是最上層窗口的句柄
這個函數不能得到disabled 的控件句柄
//獲取鼠標所處的最小控件
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 );
{
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控件句柄能正常獲取,但是
遇到重疊的控件,只能得到包含的控件句柄,事實上需要的是被包含的控件句柄
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 轉載請保留作者信息,感謝
//===============================