方式一:
BOOL SetWindowDisplayAffinity(
HWND hWnd,
DWORD dwAffinity
);
hWnd:窗口句柄
dwAffinity:
#define WDA_NONE 0x00000000
#define WDA_MONITOR 0x00000001
#define WDA_EXCLUDEFROMCAPTURE 0x00000011
在beta版本下,才有WDA_EXCLUDEFROMCAPTURE
包含在:C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\WinUser.h
然鹅,经过测试,并没有用,被排除的窗口,只是显示成了黑框。失败!
方式二(从webrtc M81抠的):
Windows放大镜Magnification API
MagSetWindowFilterList
Sets the list of windows to be magnified or the list of windows to be excluded from magnification.
BOOL MagSetWindowFilterList(
HWND hwnd,
DWORD dwFilterMode,
int count,
HWND *pHWND
);
接口MagSetWindowFilterList具有排除指定窗口的功能。
测试可行,只是稍显复杂:
//excludewindow.h
#pragma once
#include
#include
#include
// kMagnifierWindowClass has to be "Magnifier" according to the Magnification
// API. The other strings can be anything.
static wchar_t kMagnifierHostClass[] = L"ScreenCapturerWinMagnifierHost";
static wchar_t kHostWindowName[] = L"MagnifierHost";
static wchar_t kMagnifierWindowClass[] = L"Magnifier";
static wchar_t kMagnifierWindowName[] = L"MagnifierWindow";
class CExcludeWindow
{
public:
CExcludeWindow();
virtual ~CExcludeWindow();
int SetExcludeWnd(HWND hWnd);
bool Init();
bool CaptureFrame();
private:
typedef BOOL(WINAPI* MagImageScalingCallback)(HWND hwnd,
void* srcdata,
MAGIMAGEHEADER srcheader,
void* destdata,
MAGIMAGEHEADER destheader,
RECT unclipped,
RECT clipped,
HRGN dirty);
typedef BOOL(WINAPI* MagInitializeFunc)(void);
typedef BOOL(WINAPI* MagUninitializeFunc)(void);
typedef BOOL(WINAPI* MagSetWindowSourceFunc)(HWND hwnd, RECT rect);
typedef BOOL(WINAPI* MagSetWindowFilterListFunc)(HWND hwnd,
DWORD dwFilterMode,
int count,
HWND* pHWND);
typedef BOOL(WINAPI* MagSetImageScalingCallbackFunc)(
HWND hwnd,
MagImageScalingCallback callback);
static BOOL WINAPI OnMagImageScalingCallback(HWND hwnd,
void* srcdata,
MAGIMAGEHEADER srcheader,
void* destdata,
MAGIMAGEHEADER destheader,
RECT unclipped,
RECT clipped,
HRGN dirty);
void OnCaptured(void* data, const MAGIMAGEHEADER& header);
HMODULE mag_lib_handle_ = NULL;
MagInitializeFunc mag_initialize_func_ = nullptr;
MagUninitializeFunc mag_uninitialize_func_ = nullptr;
MagSetWindowSourceFunc set_window_source_func_ = nullptr;
MagSetWindowFilterListFunc set_window_filter_list_func_ = nullptr;
MagSetImageScalingCallbackFunc set_image_scaling_callback_func_ = nullptr;
// The hidden window hosting the magnifier control.
HWND host_window_ = NULL;
// The magnifier control that captures the screen.
HWND magnifier_window_ = NULL;
// True if the magnifier control has been successfully initialized.
bool magnifier_initialized_ = false;
// True if the last OnMagImageScalingCallback was called and handled
// successfully. Reset at the beginning of each CaptureImage call.
bool magnifier_capture_succeeded_ = true;
};
//excludewindow.cpp
#include "excludewindow.h"
#include
DWORD GetTlsIndex() {
static const DWORD tls_index = TlsAlloc();
return tls_index;
}
CExcludeWindow::CExcludeWindow()
{
}
bool CExcludeWindow::Init()
{
mag_lib_handle_ = LoadLibraryW(L"Magnification.dll");
if (!mag_lib_handle_)
return false;
// Initialize Magnification API function pointers.
mag_initialize_func_ = reinterpret_cast(
GetProcAddress(mag_lib_handle_, "MagInitialize"));
mag_uninitialize_func_ = reinterpret_cast(
GetProcAddress(mag_lib_handle_, "MagUninitialize"));
set_window_source_func_ = reinterpret_cast(
GetProcAddress(mag_lib_handle_, "MagSetWindowSource"));
set_window_filter_list_func_ = reinterpret_cast(
GetProcAddress(mag_lib_handle_, "MagSetWindowFilterList"));
set_image_scaling_callback_func_ =
reinterpret_cast(
GetProcAddress(mag_lib_handle_, "MagSetImageScalingCallback"));
if (!mag_initialize_func_ || !mag_uninitialize_func_ ||
!set_window_source_func_ || !set_window_filter_list_func_ ||
!set_image_scaling_callback_func_) {
std::cout << "Failed to initialize ScreenCapturerWinMagnifier: "
<< "library functions missing.";
return false;
}
BOOL result = mag_initialize_func_();
if (!result) {
std::cout << "Failed to initialize ScreenCapturerWinMagnifier: "
<< "error from MagInitialize " << GetLastError();
return false;
}
HMODULE hInstance = nullptr;
result =
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
reinterpret_cast(&DefWindowProc), &hInstance);
if (!result) {
mag_uninitialize_func_();
std::cout << "Failed to initialize ScreenCapturerWinMagnifier: "
<< "error from GetModulehandleExA " << GetLastError();
return false;
}
// Register the host window class. See the MSDN documentation of the
// Magnification API for more infomation.
WNDCLASSEXW wcex = {};
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpfnWndProc = &DefWindowProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.lpszClassName = kMagnifierHostClass;
// Ignore the error which may happen when the class is already registered.
RegisterClassExW(&wcex);
// Create the host window.
host_window_ =
CreateWindowExW(WS_EX_LAYERED, kMagnifierHostClass, kHostWindowName, 0, 0,
0, 0, 0, nullptr, nullptr, hInstance, nullptr);
if (!host_window_) {
mag_uninitialize_func_();
std::cout << "Failed to initialize ScreenCapturerWinMagnifier: "
<< "error from creating host window "
<< GetLastError();
return false;
}
// Create the magnifier control.
magnifier_window_ = CreateWindowW(kMagnifierWindowClass, kMagnifierWindowName,
WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
host_window_, nullptr, hInstance, nullptr);
if (!magnifier_window_) {
mag_uninitialize_func_();
std::cout << "Failed to initialize ScreenCapturerWinMagnifier: "
<< "error from creating magnifier window "
<< GetLastError();
return false;
}
// Hide the host window.
ShowWindow(host_window_, SW_HIDE);
// Set the scaling callback to receive captured image.
result = set_image_scaling_callback_func_(
magnifier_window_,
&CExcludeWindow::OnMagImageScalingCallback);
if (!result) {
mag_uninitialize_func_();
std::cout << "Failed to initialize ScreenCapturerWinMagnifier: "
<< "error from MagSetImageScalingCallback "
<< GetLastError();
return false;
}
return true;
}
CExcludeWindow::~CExcludeWindow()
{
}
BOOL CExcludeWindow::OnMagImageScalingCallback(
HWND hwnd,
void* srcdata,
MAGIMAGEHEADER srcheader,
void* destdata,
MAGIMAGEHEADER destheader,
RECT unclipped,
RECT clipped,
HRGN dirty) {
CExcludeWindow* owner =
reinterpret_cast(TlsGetValue(GetTlsIndex()));
TlsSetValue(GetTlsIndex(), nullptr);
owner->OnCaptured(srcdata, srcheader);
return TRUE;
}
void CExcludeWindow::OnCaptured(void* data, const MAGIMAGEHEADER& header) {
// Verify the format.
// TODO(jiayl): support capturing sources with pixel formats other than RGBA.
int captured_bytes_per_pixel = header.cbSize / header.width / header.height;
if (header.format != GUID_WICPixelFormat32bppRGBA ) {
std::cout
<< "Output format does not match the captured format: "
<< "width = " << header.width << ", "
<< "height = " << header.height << ", "
<< "stride = " << header.stride << ", "
<< "bpp = " << captured_bytes_per_pixel << ", "
<< "pixel format RGBA ? "
<< (header.format == GUID_WICPixelFormat32bppRGBA) << ".";
return;
}
static FILE* fp = fopen(".\\rgba.rgba","wb");
if (fp)
{
//fwrite(data, header.width * header.height * 4, 1, fp);
fwrite(data, header.cbSize, 1, fp);
fflush(fp);
fclose(fp);
fp = NULL;
}
// Copy the data into the frame.
/* current_frame->CopyPixelsFrom(
reinterpret_cast(data), header.stride,
DesktopRect::MakeXYWH(0, 0, header.width, header.height));*/
magnifier_capture_succeeded_ = true;
}
int CExcludeWindow::SetExcludeWnd(HWND hWnd)
{
if (hWnd) {
BOOL result = set_window_filter_list_func_(
magnifier_window_, MW_FILTERMODE_EXCLUDE, 1, &hWnd);
if (!result) {
mag_uninitialize_func_();
std::cout
<< "Failed to initialize ScreenCapturerWinMagnifier: "
<< "error from MagSetWindowFilterList " << GetLastError();
return -1;
}
}
return 0;
}
bool CExcludeWindow::CaptureFrame()
{
int nX = GetSystemMetrics(SM_XVIRTUALSCREEN);
int nY = GetSystemMetrics(SM_YVIRTUALSCREEN);
int nScreenW = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int nScreenH = GetSystemMetrics(SM_CYVIRTUALSCREEN);
BOOL result = SetWindowPos(magnifier_window_, NULL, nX, nY,
nScreenW, nScreenH, 0);
if (!result) {
std::cout << "Failed to call SetWindowPos: " << GetLastError()
<< ". Rect = {" << nX
<< ", " << nY << ", " << nX + nScreenW << ", "
<< nY + nScreenH << "}";
return false;
}
magnifier_capture_succeeded_ = false;
RECT native_rect = { nX, nY, nX+nScreenW, nY+ nScreenH };
TlsSetValue(GetTlsIndex(), this);
// OnCaptured will be called via OnMagImageScalingCallback and fill in the
// frame before set_window_source_func_ returns.
result = set_window_source_func_(magnifier_window_, native_rect);
if (!result) {
std::cout << "Failed to call MagSetWindowSource: "
<< GetLastError() << ". Rect = {" << nX
<< ", " << nY << ", " << nX + nScreenW << ", "
<< nY + nScreenH << "}";
return false;
}
return magnifier_capture_succeeded_;
}
测试:
CExcludeWindow ex;
ex.Init();
ex.SetExcludeWnd(hWnd);
ex.CaptureFrame();
//回调函数会写下一个rgba的文件