windows C++ -如何捕获屏幕,除了一些窗口

l7wslrjt  于 2023-01-21  发布在  Windows
关注(0)|答案(5)|浏览(434)
    • 情况**:我有一个通过Internet执行屏幕共享的软件,其中一个用户充当演示者,其他用户充当查看者/与会者。

除了演示窗口,演示者还有一组出现在屏幕上的非共享窗口(用于开始共享/停止共享/等的按钮栏,Skype窗口等)。
演示者可以从屏幕共享软件的设置中进行配置,以使这些非共享窗口不可见(即,它们不会出现在发送给与会者的屏幕共享中,但它们后面的窗口内容将出现在屏幕截图中)。
屏幕截图以大约每秒10帧或更快的速度发送。

    • 问题**:除了这些NON-SHARING-WINDOWS窗口之外,我如何以编程方式捕获屏幕?
    • 备注**:
  • 由于每秒帧数较高,我无法最小化/最大化/设置这些窗口的alpha,因为这样窗口会 Flink 。应用程序是用Win32 C++编写的。
  • 我想使用分层窗口,但由于Windows 7桌面合成功能,这不是现成可用的(在Windows 8中,您不能再使用DwmEnableComposition来临时和编程地禁用合成)
  • 我可以对Windows XP/2000/7等使用分层窗口方法,对Windows 8(如果有的话)使用另一种方法,不过我更喜欢在所有系统上运行的单个进程
  • 我也可以尝试通过捕获单个图像(桌面、需要捕获的窗口)并使用它们的z索引创建最终图像来"组合"屏幕截图,但由于所需的每秒帧数值,这个过程会太慢。
2ledvvac

2ledvvac1#

在windows中,即使桌面也被认为是一个窗口,并有自己的HWND。然而,似乎不容易只复制自己的“墙纸”。
所以我基本上看到了两种方法。1.复制整个桌面Eidogg. BitBlt(GetWindowDC(GetDesktopWindow()),...)

1.使用GetWindow并从桌面窗口开始向后遍历窗口列表,您可以使用GetDesktopWindow()确定桌面窗口的HWND,如下所示:
// paint on a black DC hwnd=GetDesktopWindow() while (hwnd = GetWindow(hwnd, GW_HWNDPREV)) { // is this window not shared? continue // else bitblt it into our dc }
希望我给了一些灵感:-)如果有人知道如何只复制桌面而不复制其子窗口,请让我知道。

niknxzdl

niknxzdl2#

您可以使用放大镜API。
放大器API中有一个函数,允许您从目标窗口(放大器渲染的1倍放大的窗口)中排除特定窗口。
您可以将此窗口设置为全屏并使其透明,然后使用PrintWindow功能。
该功能:https://learn.microsoft.com/en-us/windows/desktop/api/magnification/nf-magnification-magsetwindowfilterlist
示例项目:
https://www.codeproject.com/Articles/607288/Screenshot-using-the-Magnification-library
https://code.msdn.microsoft.com/windowsdesktop/Magnification-API-Sample-14269fd2

8xiog9wr

8xiog9wr3#

我知道这个问题是相当古老的,但我遇到了同样的问题,这是非常,非常难找到任何信息,在所有关于这一点。
Windows 10版本2004(内部版本号10.0.19041)起,SetWindowDisplayAffinityAPI已扩展为包含名为WDA_EXCLUDEFROMCAPTURE(0x00000011)的标志。这将从使用BitBlt捕获的图像中删除该窗口
该窗口仅显示在监视器上。在其他任何地方,该窗口根本不显示。此关联的一个用途是用于显示视频录制控件的窗口,以便这些控件不包括在捕获中。
在Windows 10版本2004中引入。请参阅有关Windows早期版本兼容性的备注。

对于2004年之前的版本,它将使用现有的WDA_MONITOR标志。

我已经用桌面的屏幕截图测试过了,我不确定如果你使用windows DC会发生什么。
所以我想一个可能的解决办法是:

// get window handle
hWnd = (...)

BOOL result = SetWindowDisplayAffinity(m_hWnd, WDA_EXCLUDEFROMCAPTURE);

// do bitblt stuff
of1yzvn4

of1yzvn44#

也许你可以使用放大API,甚至微软说The MagImageScalingCallback function is deprecated in Windows 7 and later, and should not be used in new applications. There is no alternate functionality.,但它仍然在Windows 10上工作;
以下是此API的概述:https://learn.microsoft.com/en-us/previous-versions/windows/desktop/magapi/magapi-intro
微软的示例代码如下:https://github.com/microsoft/Windows-classic-samples/tree/main/Samples/Magnification
如果你想得到截图的rgb数据,你可以使用这个API MagSetImageScalingCallback来设置放大镜窗口的回调,每次你使用放大镜窗口的MagSetWindowSource或者InvalidRect,这个回调函数MagImageScalingCallback都会被调用,所以你可以在这里得到截图的rgb数据。

kuarbcqp

kuarbcqp5#

我认为将捕获内容限制在一个大窗口内会更简单。否则你将需要从屏幕捕获中剪切一些窗口。

相关问题