如何在Win32 API中从屏幕捕获中排除某些窗口

How to exclude certain window from screen capture in Win32 API?

本文关键字:排除 窗口 Win32 API 屏幕      更新时间:2023-10-16

我想捕获桌面并排除正在捕获的应用程序的窗口。

我的窗口创建如下:

m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_LAYERED,
                        g_lpszClassName, NULL, WS_THICKFRAME,
                        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
                        _WPModule.GetHInstance(), NULL);

我捕获的屏幕如下:

HWND    hWndCapture     = ::GetDesktopWindow();
HDC     hdcScreen       = ::GetDC(hWndCapture);
HDC     hdcMem          = ::CreateCompatibleDC(hdcScreen);
::BitBlt(
    hdcMem,
    0,
    0,
    Width, //width of region of interest
    Height, //height of region of interest
    hdcScreen,
    X, //left staring point for capture
    Y, //top staring point for capture
    SRCCOPY);

我发现了以下链接将某些窗口从屏幕捕获中排除,但它没有为IE 8及更高版本提供解决方案。我没有发现任何其他解决方案发布了这个问题。

我知道这个问题很老了,但我遇到了同样的问题,很难找到任何关于这个问题的信息。

Windows 10 2004版(内部版本10.0.19041)以来,SetWindowDisplayAffinity API已扩展为包含一个名为WDA_EXCLUDEFROMCAPTURE(0x00000011)的标志。这将从BitBlt 捕获的图像中删除窗口

该窗口仅显示在监视器上。在其他地方,该窗口根本不会出现。这种相关性的一个用途是用于显示视频录制控件的窗口,这样控件就不会包含在捕获中。

在Windows 10 2004版中引入。请参阅有关Windows早期版本兼容性的备注。

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

我已经用桌面的屏幕截图进行了测试,我不确定如果你使用Windows DC会发生什么。

所以我想一个可能的解决方案是:

// get window handle
m_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_LAYERED,
                        g_lpszClassName, NULL, WS_THICKFRAME,
                        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
                        _WPModule.GetHInstance(), NULL);
BOOL result = SetWindowDisplayAffinity(m_hWnd, WDA_EXCLUDEFROMCAPTURE);
// do bitblt stuff