通过移动鼠标获取最前端控件信息

---恢复内容开始---

 1 void GetCtrlWndFromPoint(const POINT& point)
 2 {
 3     ClientToScreen(this->GetHWND(),&pt); // 转换到屏幕坐标
 4 
 5     //找到当前位置的最小窗口
 6     HWND current_window = SpyFindSmallestWindow(pt); 
 7     if (current_window != NULL)
 8     {
 9         // 确保找到的窗口不是自己的窗口,窗口进程不同
10         if (GetWindowThreadProcessId(/*GetSafeHwnd()*/*this, NULL) != GetWindowThreadProcessId(current_window, NULL))
11         {
12             // 若是新窗口,就把旧窗口的边界去掉,画新窗口的边界
13             if (current_window != prev_window)
14             {
15                 SpyInvertBorder(prev_window);
16                 prev_window = current_window;
17                 SpyInvertBorder(prev_window);
18             }
19         }
20         else
21         {
22             // 窗口是自己的
23             SpyInvertBorder(prev_window);
24             prev_window = NULL;
25         }

      GetWindowRect() //获取控件矩阵
      GetWindowLong(hwnd, GWL_STYLE);// 窗口风格 
      GetWindowLong(hwnd, GWL_EXSTYLE);// 窗口扩展风格 

      ::GetClassName(hwnd, szClassName, MAX_BUFFER_LENGTH);
26     }
27 }        
HWND SpyFindSmallestWindow(const POINT &pt)
{
    HWND hWnd = WindowFromPoint(pt);// 鼠标所在窗口
    if (hWnd != NULL)
    {
        // 得到本窗口大小和父窗口句柄,以便比较
        RECT rect;
        ::GetWindowRect(hWnd, &rect);
        HWND parent = ::GetParent(hWnd); // 父窗口
        // 只有该窗口有父窗口才继续比较
        if (parent != NULL)
        {
            // 按Z方向搜索
            HWND find = hWnd; // 递归调用句柄
            RECT rect_find;

            while (TRUE) // 循环
            {
                CHAR szWindowText[MAX_BUFFER_LENGTH]; // 窗口标题
                ZeroMemory(szWindowText, sizeof(szWindowText));
                DWORD dwResult = 0;
                ::SendMessageTimeoutA(hWnd, WM_GETTEXT, MAX_BUFFER_LENGTH, (LPARAM)szWindowText, SMTO_ABORTIFHUNG, 5 * 1000, &dwResult);
                find = ::GetWindow(find, GW_HWNDNEXT); // 得到下一个窗口的句柄
                ::GetWindowRect(find, &rect_find); // 得到下一个窗口的大小

                if (::PtInRect(&rect_find, pt) // 鼠标所在位置是否在新窗口里
                    && ::GetParent(find) == parent // 新窗口的父窗口是否是鼠标所在主窗口
                    && ::IsWindowVisible(find)) // 窗口是否可视
                {
                    // 比较窗口,看哪个更小
                    if ( ((rect_find.right - rect_find.left) * (rect_find.bottom - rect_find.top) < (rect.right - rect.left) * (rect.bottom - rect.top)))
                    {
                        // 找到更小窗口
                        hWnd = find;
                        // 计算新窗口的大小
                        ::GetWindowRect(hWnd, &rect);
                    }
                }

                // hWnd的子窗口find为NULL,则hWnd为最小窗口
                if (find == NULL)
                {
                    break; // 退出循环
                }
            }
        }
    }
   return NULL;
}

void SpyInvertBorder(const HWND &hWnd)
{
    // 若非窗口则返回
    if (!IsWindow(hWnd))
        return;
    RECT rect; // 窗口矩形
    // 得到窗口矩形
    ::GetWindowRect(hWnd, &rect);
   
    HDC dc = ::GetDC(hWnd);
    // 设置窗口当前前景色的混合模式为R2_NOT
    // R2_NOT - 当前的像素值为屏幕像素值的取反,这样可以覆盖掉上次的绘图
    SetROP2(dc,R2_NOT);
    
    // 创建画笔
    //CPen pen;
    // PS_INSIDEFRAME - 产生封闭形状的框架内直线,指定一个限定矩形
    // 3 * GetSystemMetrics(SM_CXBORDER) - 三倍边界粗细
    // RGB(0,0,0) - 黑色
    HPEN pen = CreatePen(PS_INSIDEFRAME, 3 * GetSystemMetrics(SM_CXBORDER), RGB(0, 0, 0));
    // 选择画笔
    HGDIOBJ old_pen = SelectObject(dc,pen);
    // 设定画刷
    HGDIOBJ old_brush = SelectObject(dc,GetStockObject(NULL_BRUSH));
    // 画矩形
    Rectangle(dc,0, 0, rect.right-rect.left, rect.bottom-rect.top);
    // 恢复原来的设备环境
    SelectObject(dc,old_pen);
    SelectObject(dc,old_brush);

    DeleteObject(pen);
}
 
  

 

 

 

 

---恢复内容结束---

转载于:https://www.cnblogs.com/fenglangxiaotian/p/9705888.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值