首页| 论坛| 消息

标题:Qt指定应用程序窗口采集录屏和推流/自动罗列窗口标题/实时性好延迟极低
作者:liudianwu
日期:2025-06-10 08:31
内容:

## 一、前言说明
之前已经实现了通过ffmpeg桌面采集,也支持指定应用程序的标题来采集,但是需要用户手动输入程序窗口标题,这个就很不友好了,有几个用户知道如何才是完整的正确的标题呢,所以近期特意单独写了个类,专门用来获取当前环境中打开的应用程序标题,以便供用户直接下拉选择,obs推流工具也是这样处理的,通过向著名的软件参考和学习,不断的改进代码。在windows中,通过EnumWindows函数可以枚举所有窗口,然后在回调函数EnumWindowsProc中调用GetWindowText读取标题,发现读取出来的非常多,一大堆,大部分其实是不需要的,所以先要过滤掉不可见窗体的,也就是已经最小化的,这种窗体是无法采集的,obs也是无法采集最小化的窗体,原因未知,可能是系统的特性,不允许采集最小化窗口。后面还发现还有一些系统层的窗口也读取到了,需要用GetWindowLong函数来排除工具窗口和系统窗口,自此基本干净了,那还有没有完善的空间呢,有的,因为还有些应用程序的标题可能重复,那如何区分呢,所以还需要获取程序的完整路径及程序名称,也就是xxx.exe,下拉框中要做出对应的区分,比如obs的格式就是 xxx ,这样就一目了然,知道当前窗口属于哪个程序。

其实Qt6.6版本开始已经提供了类QWindowCapture::capturableWindows(),用来枚举所有窗口,估计后期还需要不断的完善,因为列举出来的窗口没有过滤,一堆都是工具窗口和系统窗口,要么无法采集,要么没有意义,不知道有没有谁去提点建议。好处是这个类跨平台,在其他系统都能完美的枚举窗口,可以学习其中的源码来参考。

下面是从Qt6.6中抠出来的代码

```cpp
static QString windowTitle(HWND hwnd) {
// QTBUG-114890
// TODO: investigate the case when hwnd is inner and belows to another thread.
// It might causes deadlocks in specific cases.
auto titleLength = ::GetWindowTextLengthW(hwnd);
std::wstring buffer(titleLength + 1, L'\0');
titleLength = ::GetWindowTextW(hwnd, buffer.data(), titleLength + 1);
buffer.resize(titleLength);

return QString::fromStdWString(buffer);
}

QList QWinCapturableWin ..

回复 发表
主题 版块