You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下如何判断窗口句柄所属的显示器(多屏截图场景)

多显示器环境下捕获活动窗口图像的解决方案

你的问题核心是无法定位活动窗口所属的显示器,下面提供两种可靠的解决思路,结合Win32 API和Qt的特性来处理:

方法一:用Qt内置函数直接定位屏幕

Qt的QGuiApplication提供了screenAt()方法,只需传入窗口的任意坐标点(比如窗口左上角),就能直接得到该窗口所在的QScreen对象:

if (auto handle = GetForegroundWindow(); handle != nullptr) {
    RECT rect;
    GetWindowRect(handle, &rect);
    
    // 传入窗口左上角坐标,获取对应的屏幕
    QPoint windowPos(rect.left, rect.top);
    QScreen* targetScreen = QGuiApplication::screenAt(windowPos);
    
    // 如果没找到(极端情况), fallback 到主屏幕
    if (!targetScreen) {
        targetScreen = QGuiApplication::primaryScreen();
    }
    
    // 捕获窗口图像
    auto pixmap = targetScreen->grabWindow(0, rect.left, rect.top, 
                                           rect.right - rect.left, 
                                           rect.bottom - rect.top);
}

方法二:结合Win32 API精准匹配显示器

如果需要更底层的控制,可以用Win32的MonitorFromWindow函数获取窗口对应的显示器句柄,再和Qt的屏幕列表匹配:

#include <Windows.h>
#include <QScreen>

if (auto handle = GetForegroundWindow(); handle != nullptr) {
    RECT rect;
    GetWindowRect(handle, &rect);
    
    // 获取窗口所属的显示器句柄
    HMONITOR hMonitor = MonitorFromWindow(handle, MONITOR_DEFAULTTONEAREST);
    MONITORINFO monitorInfo{};
    monitorInfo.cbSize = sizeof(MONITORINFO);
    GetMonitorInfo(hMonitor, &monitorInfo);
    
    // 遍历Qt屏幕列表,找到匹配的屏幕
    QScreen* targetScreen = nullptr;
    for (QScreen* screen : QGuiApplication::screens()) {
        QRect screenRect = screen->geometry();
        // 对比显示器的矩形区域,找到匹配项
        if (screenRect.left() == monitorInfo.rcMonitor.left() &&
            screenRect.top() == monitorInfo.rcMonitor.top() &&
            screenRect.width() == monitorInfo.rcMonitor.right() - monitorInfo.rcMonitor.left() &&
            screenRect.height() == monitorInfo.rcMonitor.bottom() - monitorInfo.rcMonitor.top()) {
            targetScreen = screen;
            break;
        }
    }
    
    // Fallback到主屏幕
    if (!targetScreen) {
        targetScreen = QGuiApplication::primaryScreen();
    }
    
    auto pixmap = targetScreen->grabWindow(0, rect.left, rect.top, 
                                           rect.right - rect.left, 
                                           rect.bottom - rect.top);
}

关键说明

  • screenAt()方法是Qt推荐的简化方式,代码更简洁,适合大多数场景。
  • MonitorFromWindow的MONITOR_DEFAULTTONEAREST参数确保即使窗口跨多个显示器,也能返回最近的那个显示器句柄。
  • 两种方法都加入了fallback逻辑,避免极端情况下找不到屏幕导致崩溃。

内容的提问来源于stack exchange,提问作者StereoMatching

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 07:40:02