QtC++截图支持窗口获取

介绍

在截图工具中你会发现,接触到窗口后会自动圈出目标窗口,个别强大一点的还能进行元素识别可以自动圈出元素,那么今天简单分析一下QTc++如何获取窗口并圈出当前鼠标下的窗口。

1.如何获取所有窗口

1.我们需要调用windows接口EnumWindowsProc回调函数来获取所有顶级窗口,需要包含windows.h,以及pro文件链接win库。

win32 {
    LIBS+= -luser32 -ldwmapi    # 使用WindowsAPI需要链接库
}
// 窗口信息结构体
struct WindowInfo
{
    HWND hwnd; // 窗口句柄
    int zOrder; // 窗口的Z序,值越小越在顶层
    RECT rect; // 窗口区域
    POINT pos; //窗口坐标
};

std::vector<WindowInfo> windows; //窗口信息列表排序的
// 获取所有顶级窗口的回调函数
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
    std::vector<WindowInfo>* windows = reinterpret_cast<std::vector<WindowInfo>*>(lParam);
    if (IsWindowVisible(hwnd)) // 如果窗口可见
    {
        char title[256];
        GetWindowTextA(hwnd, title, sizeof(title));

        // 过滤掉一些不需要的窗口
        QString str = QString::fromLocal8Bit(title);
        if (str.isEmpty() || str == "ZOrder" || str == "YMagnifier")
        {
            return TRUE; // 继续下一个窗口
        }

        // 获取窗口区域
        RECT rect;
        GetWindowRect(hwnd, &rect);


        int zOrder = GetWindowZOrder(hwnd);
        windows->push_back({hwnd, zOrder, rect});
    }
    return TRUE;
}

2.比较函数

1.那么我们获取窗口后,我们需要知道窗口的层级,自然要获取鼠标下最顶层的窗口句柄。

// 比较函数,用于排序窗口信息
bool CompareWindowInfo(const WindowInfo& a, const WindowInfo& b)
{
    return a.zOrder < b.zOrder;
}

3.实现窗口判断

1.第一步我们先调用接口
// 枚举所有顶级窗口
EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&windows));

// 按照Z序排序窗口信息
std::sort(windows.begin(), windows.end(), CompareWindowInfo);


// 获取鼠标当前位置
POINT cursorPos;
GetCursorPos(&cursorPos);

2.然后比遍历调用PtInRect判断列表的窗口位置是否匹配当前鼠标位置
匹配的话就可以拿坐标宽高来绘制了
// 寻找处于鼠标位置下的最顶层窗口
for (const auto& window : windows)
{
    if (PtInRect(&window.rect, cursorPos))
    {
        // 窗口左上角坐标
        int x = window.rect.left;
        int y = window.rect.top;

        // 窗口宽度和高度
        int width = window.rect.right - window.rect.left;
        int height = window.rect.bottom - window.rect.top;

        // 判断窗口是否位于主显示器上
        if (!IsWindowOnPrimaryMonitor(window.hwnd)) {
            x = (image.width() + x);
        }

        expectArea.setX(qAbs(x));
        expectArea.setY(qAbs(y));
        expectArea.setWidth(width);
        expectArea.setHeight(height);
        refreshScreenShotArea();
        isSelectWin = true;
        break;
    }
}

结尾

1.通过以上代码就可以实现获取鼠标当下的窗口,如想获取元素,后面会更新新的文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值