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

Gid*_*idi 2 c++ winapi

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

我的窗口创建如下:

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);
Run Code Online (Sandbox Code Playgroud)

我捕获屏幕如下:

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);
Run Code Online (Sandbox Code Playgroud)

我找到了以下链接从屏幕捕获中排除某些窗口,但它没有提供适用于 IE 8 及更高版本的解决方案。我没有找到针对此问题发布的任何其他解决方案。

AsP*_*Pas 6

我知道这个问题已经很老了,但我遇到了同样的问题,而且很难找到与此相关的任何信息。

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

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

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

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

我已经用桌面的屏幕截图对此进行了测试,我不确定如果您使用窗口 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

Run Code Online (Sandbox Code Playgroud)