- 情况**:我有一个通过Internet执行屏幕共享的软件,其中一个用户充当演示者,其他用户充当查看者/与会者。
除了演示窗口,演示者还有一组出现在屏幕上的非共享窗口(用于开始共享/停止共享/等的按钮栏,Skype窗口等)。
演示者可以从屏幕共享软件的设置中进行配置,以使这些非共享窗口不可见(即,它们不会出现在发送给与会者的屏幕共享中,但它们后面的窗口内容将出现在屏幕截图中)。
屏幕截图以大约每秒10帧或更快的速度发送。
- 问题**:除了这些NON-SHARING-WINDOWS窗口之外,我如何以编程方式捕获屏幕?
- 备注**:
- 由于每秒帧数较高,我无法最小化/最大化/设置这些窗口的alpha,因为这样窗口会 Flink 。应用程序是用Win32 C++编写的。
- 我想使用分层窗口,但由于Windows 7桌面合成功能,这不是现成可用的(在Windows 8中,您不能再使用DwmEnableComposition来临时和编程地禁用合成)
- 我可以对Windows XP/2000/7等使用分层窗口方法,对Windows 8(如果有的话)使用另一种方法,不过我更喜欢在所有系统上运行的单个进程
- 我也可以尝试通过捕获单个图像(桌面、需要捕获的窗口)并使用它们的z索引创建最终图像来"组合"屏幕截图,但由于所需的每秒帧数值,这个过程会太慢。
5条答案
按热度按时间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 }
希望我给了一些灵感:-)如果有人知道如何只复制桌面而不复制其子窗口,请让我知道。
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
8xiog9wr3#
我知道这个问题是相当古老的,但我遇到了同样的问题,这是非常,非常难找到任何信息,在所有关于这一点。
自Windows 10版本2004(内部版本号10.0.19041)起,
SetWindowDisplayAffinity
API已扩展为包含名为WDA_EXCLUDEFROMCAPTURE
(0x00000011)的标志。这将从使用BitBlt
捕获的图像中删除该窗口该窗口仅显示在监视器上。在其他任何地方,该窗口根本不显示。此关联的一个用途是用于显示视频录制控件的窗口,以便这些控件不包括在捕获中。
在Windows 10版本2004中引入。请参阅有关Windows早期版本兼容性的备注。
对于2004年之前的版本,它将使用现有的
WDA_MONITOR
标志。我已经用桌面的屏幕截图测试过了,我不确定如果你使用windows DC会发生什么。
所以我想一个可能的解决办法是:
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数据。kuarbcqp5#
我认为将捕获内容限制在一个大窗口内会更简单。否则你将需要从屏幕捕获中剪切一些窗口。