11

Situation: I have a software that performs screen sharing over the Internet, where one user acts as a presenter, and other users act as viewers/attendees.

Besides the presentation windows, the presenter also has a set of NON-SHARING-WINDOWS that appear on the screen (a button bar for start sharing/stop sharing/etc., a Skype window etc.).

The presenter can configure from the setup of the screen sharing software to make these NON-SHARING-WINDOWS invisible (i.e. they will not appear in the screen sharing that is being sent to the attendees, but the window content behind them will appear in the screenshot).

The screenshots are sent at approximately 10 frames-per-second, or faster.

Question: how can I programmatically capture the screen, except for these NON-SHARING-WINDOWS windows?

Notes:

  • Because of the higher frames-per-second value, I cannot minimize/maximize/set alpha for these windows, because then the windows will flicker. The application is written in Win32 C++.
  • I would use layered windows, but because of the Windows 7 Desktop Composition feature, this is not usable out-of-the-box (and in Windows 8, you cannot use DwmEnableComposition anymore to temporarily and programmatically disable composition)
  • I could use the layered window approach for Windows XP/2000/7 etc., and a different approach for Windows 8 (if there is one), though I would prefer a single process that works on all systems
  • I could also try to "compose" the screenshots by capturing individual images (of the desktop, the windows that need to be captured) and using their z-index to create the final image, but because of the required frames-per-second value, this process would be too slow.
4

3 回答 3

1

在 Windows 中,甚至桌面也被认为是一个窗口,并且有自己的 HWND。然而,仅靠自己复制“壁纸”似乎并不容易。

所以我基本上看到了两种方法来做到这一点。1. 复制整个桌面 例如 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 }

希望我能给我一些启发:-) 如果有人知道如何只复制没有子窗口的桌面,请告诉我。

于 2016-02-19T08:31:41.950 回答
0

您可以使用放大镜 API。

放大镜 API 中有一个函数允许您从目标窗口中排除特定窗口(放大镜呈现 1 倍放大率的窗口)。

您可以将此窗口设置为全屏并使其透明,然后使用 PrintWindow 功能。

功能:https ://docs.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

于 2018-12-26T10:26:04.180 回答
-1

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

于 2012-05-04T19:40:14.420 回答