自学内容网 自学内容网

FFMPEG录屏(17)--- 使用 DwmRegisterThumbnail 捕获指定窗口图像数据

使用 DwmRegisterThumbnail 捕获指定窗口图像数据

在 Windows 平台上,捕获指定窗口的图像数据可以通过多种方法实现,其中一种高效的方法是使用 [DwmRegisterThumbnail] 本文将介绍如何使用 [DwmRegisterThumbnail] 捕获窗口图像数据,并提供一个完整的示例代码。

前提条件

在开始之前,请确保您的开发环境满足以下条件:

  1. Windows Vista 或更高版本(因为 DWM API 在 Windows Vista 中引入)。
  2. 安装了 Visual Studio 或其他支持 Windows API 开发的编译器。

步骤

1. 包含必要的头文件

首先,包含必要的头文件:

#include <dwmapi.h>
#include <windows.h>
#include <iostream>
2. 检查 DWM 是否支持

在使用 DWM API 之前,检查当前系统是否支持 DWM:

bool is_dwm_supported() {
    HINSTANCE dwmapi = ::LoadLibraryW(L"dwmapi.dll");
    if (dwmapi != nullptr) {
        ::FreeLibrary(dwmapi);
        return true;
    }
    return false;
}
3. 注册缩略图

使用 DwmRegisterThumbnail 注册窗口的缩略图:

HTHUMBNAIL register_thumbnail(HWND dest_window, HWND src_window) {
    HTHUMBNAIL thumbnail_id = nullptr;
    if (FAILED(::DwmRegisterThumbnail(dest_window, src_window, &thumbnail_id))) {
        std::cerr << "Register thumbnail failed: " << GetLastError() << std::endl;
        return nullptr;
    }
    return thumbnail_id;
}
4. 更新缩略图属性

设置缩略图的属性,例如可见性、透明度等:

bool update_thumbnail_properties(HTHUMBNAIL thumbnail_id, int width, int height) {
    DWM_THUMBNAIL_PROPERTIES properties = {};
    properties.fVisible = TRUE;
    properties.fSourceClientAreaOnly = FALSE;
    properties.opacity = 180; // 255 * 0.7
    properties.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION | DWM_TNP_SOURCECLIENTAREAONLY;
    properties.rcDestination = {0, 0, width, height};

    if (FAILED(::DwmUpdateThumbnailProperties(thumbnail_id, &properties))) {
        std::cerr << "Update thumbnail properties failed: " << GetLastError() << std::endl;
        return false;
    }
    return true;
}
5. 捕获窗口图像数据

使用 GDI 或其他方法捕获窗口图像数据:

bool capture_window_image(HWND window, int width, int height, uint8_t** data) {
    // 使用 GDI 或其他方法捕获图像数据
    // 这里省略具体实现
    return true;
}
6. 完整示例

以下是一个完整的示例代码,展示了如何使用 DwmRegisterThumbnail 捕获指定窗口的图像数据:

#include <dwmapi.h>
#include <windows.h>
#include <iostream>

bool is_dwm_supported() {
    HINSTANCE dwmapi = ::LoadLibraryW(L"dwmapi.dll");
    if (dwmapi != nullptr) {
        ::FreeLibrary(dwmapi);
        return true;
    }
    return false;
}

HTHUMBNAIL register_thumbnail(HWND dest_window, HWND src_window) {
    HTHUMBNAIL thumbnail_id = nullptr;
    if (FAILED(::DwmRegisterThumbnail(dest_window, src_window, &thumbnail_id))) {
        std::cerr << "Register thumbnail failed: " << GetLastError() << std::endl;
        return nullptr;
    }
    return thumbnail_id;
}

bool update_thumbnail_properties(HTHUMBNAIL thumbnail_id, int width, int height) {
    DWM_THUMBNAIL_PROPERTIES properties = {};
    properties.fVisible = TRUE;
    properties.fSourceClientAreaOnly = FALSE;
    properties.opacity = 180; // 255 * 0.7
    properties.dwFlags = DWM_TNP_VISIBLE | DWM_TNP_RECTDESTINATION | DWM_TNP_SOURCECLIENTAREAONLY;
    properties.rcDestination = {0, 0, width, height};

    if (FAILED(::DwmUpdateThumbnailProperties(thumbnail_id, &properties))) {
        std::cerr << "Update thumbnail properties failed: " << GetLastError() << std::endl;
        return false;
    }
    return true;
}

bool capture_window_image(HWND window, int width, int height, uint8_t** data) {
    // 使用 GDI 或其他方法捕获图像数据
    // 这里省略具体实现
    return true;
}

int main() {
    if (!is_dwm_supported()) {
        std::cerr << "DWM is not supported on this system." << std::endl;
        return -1;
    }

    HWND src_window = ::FindWindow(nullptr, L"Source Window Title");
    HWND dest_window = ::CreateWindowEx(WS_EX_LAYERED, L"STATIC", L"Destination Window",
                                        WS_POPUP | WS_VISIBLE, 0, 0, 800, 600, nullptr, nullptr,
                                        nullptr, nullptr);

    if (!src_window || !dest_window) {
        std::cerr << "Failed to find or create window." << std::endl;
        return -1;
    }

    HTHUMBNAIL thumbnail_id = register_thumbnail(dest_window, src_window);
    if (!thumbnail_id) {
        return -1;
    }

    if (!update_thumbnail_properties(thumbnail_id, 800, 600)) {
        ::DwmUnregisterThumbnail(thumbnail_id);
        return -1;
    }

    uint8_t* data = nullptr;
    if (!capture_window_image(dest_window, 800, 600, &data)) {
        ::DwmUnregisterThumbnail(thumbnail_id);
        return -1;
    }

    // 处理捕获的图像数据
    // ...

    ::DwmUnregisterThumbnail(thumbnail_id);
    return 0;
}

总结

通过 [DwmRegisterThumbnail] API,我们可以高效地捕获指定窗口的图像数据。本文介绍了如何检查 DWM 支持、注册缩略图、更新缩略图属性以及捕获窗口图像数据的完整过程。希望这篇文章对您有所帮助。

代码地址

traa

ps
我偷懒了,这个文章是根据代码用copilot自动生成的,看起来还行啊,步骤什么都有了


原文地址:https://blog.csdn.net/peilinok/article/details/142979856

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!