在做录制时,有时需要指定窗口进行录制,就像视频会议软件,钉钉、腾讯会议都有这个功能,那么是如何让做到的呢,我们在obs的代码里面可以找到,windows里面的枚举窗口用到的API是EnumWindows:
BOOL
WINAPI
EnumWindows(
_In_ WNDENUMPROC lpEnumFunc,
_In_ LPARAM lParam);
根据该方法,我们去查找obs代码, EnumWindows调用的地方:
HWND find_window_top_level(enum window_search_mode mode,
enum window_priority priority, const char *class,
const char *title, const char *exe)
{
if (!class)
return NULL;
struct top_level_enum_data data;
data.mode = mode;
data.priority = priority;
data.class = class;
data.title = title;
data.exe = exe;
data.generic_class = is_generic_class(class);
data.best_window = NULL;
data.best_rating = 0x7FFFFFFF;
EnumWindows(enum_windows_proc, (LPARAM)&data);
return data.best_window;
}
根据EnumWindows的回调函数enum_windows_proc可知,最终把枚举到的窗口类信息,窗口标题等等都给了*data, 代码如下:
BOOL CALLBACK enum_windows_proc(HWND window, LPARAM lParam)
{
struct top_level_enum_data *data = (struct top_level_enum_data *)lParam;
if (!check_window_valid(window, data->mode))
return TRUE;
int cloaked;
if (SUCCEEDED(DwmGetWindowAttribute(window, DWMWA_CLOAKED, &cloaked,
sizeof(cloaked))) &&
cloaked)
return TRUE;
const int rating = window_rating(window, data->priority, data->class,
data->title, data->exe,
data->generic_class);
if (rating best_rating) {
data->best_rating = rating;
data->best_window = window;
}
return rating > 0;
}
find_window_top_level是在wc_tick中调用,就是在调用BitBlt之前,先获取到需要录制的窗口句柄。