采集桌面、窗口,必然需要获取其列表以及缩略图。获取桌面显示器列表在《【音视频】获取视频设备-MMDeviceAPI&MONITORINFOEX(2-3)》已经讲过。本篇主要记录一下如何获取窗口列表,以及显示器、窗口的缩略图。
1、获取窗口列表以及缩略图
使用EnumWindows枚举所有窗口,需要实现enumWindowProc方法
int VideoDevice::getApplicationDevices(std::list<VIDEO_DEVICE>& devices)
{
int err = ERROR_CODE_OK;
devices.clear();
BOOL ret = EnumWindows(enumWindowProc, reinterpret_cast<LPARAM>(&devices));
if (!ret || devices.empty()) {
err = ERROR_CODE_DEVICE_GET_MONITOR_FAILED;
}
if (err != ERROR_CODE_OK) {
LOGGER::Logger::log(LOGGER::LOG_TYPE_ERROR, "[%s] get video devices error: %s", __FUNCTION__,
HCMDR_GET_ERROR_DESC(err));
}
return err;
}
其中enumWindowProc方法的实现如下:
BOOL CALLBACK VideoDevice::enumWindowProc(HWND hwnd, LPARAM dwData)
{
std::list<VIDEO_DEVICE>* devices = reinterpret_cast<std::list<VIDEO_DEVICE>*>(dwData);
if (devices == nullptr) {
return FALSE;
}
// 忽略看不见的窗口和子窗口
if (!IsWindowVisible(hwnd) || GetParent(hwnd) != nullptr) {
return TRUE;
}
VIDEO_DEVICE device = {
};
long handle = reinterpret_cast<long>(hwnd);
#ifdef UNICODE
device.id = HELPER::StringConverter::convertUnicodeToUtf8(std::to_wstring(handle));
#else
device.id = HELPER::StringConverter::convertAsciiToUtf8(std::to_string(handle));
#endif // UNICODE
TCHAR title[MAX_PATH] = {
0 };
::GetWindowText(hwnd, title, MAX_PATH);
#ifdef UNICODE
device.name = HELPER::StringConverter::convertUnicodeToUtf8(title);
#else
device.name = HELPER::StringConverter::convertAsciiToUtf8(title);
#endif
device.isDefault = devices->empty() ? 1 : 0;
if (!device.id.empty() && !device.name.empty()) {
int err = allocWindowThumbnail(hwnd, device.thumbnail);
if (err != ERROR_CODE_OK) {
LOGGER::Logger::log(LOGGER::LOG_TYPE_ERROR, "[%s] alloc window thumbnail error: %s", __FUNCTION__,
HCMDR_GET_ERROR_DESC(err));
}
devices->push_back(device);
}
return TRUE;
}
其中VIDEO_DEVICE结构体如下:
typedef struct _VIDEO_DEVICE {
std::string id; // device id
std::string name; // device name
uint8_t isDefault; // is default device or not
VIDEO_THUMBNAIL thumbnail; // Desktop or application thumbnail
} VIDEO_DEVICE;
typedef struct _VIDEO_THUMBNAIL {
std::string type = ""; // Image type
int width = 0; // Thumbnail width
int height = 0; // Thumbnail height
uint8_t* buffer = nullptr;