You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinRT C++下打开GraphicsCapturePicker的示例需求及问题咨询

解决方案:WinRT图形捕获实用示例(C++)

一、解决co_await编译错误

先完成项目配置修正编译问题:

  • 项目属性 -> 常规 -> C++语言标准:设置为C++20或更高版本
  • C/C++ -> 预处理器 -> 预处理器定义:添加_WINRT_DLL
  • 链接器 -> 输入 -> 附加依赖项:添加windowsapp.lib

代码中必须包含基础WinRT头文件:

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Graphics.Capture.h>
#include <winrt/Windows.Devices.Display.h>
#include <iostream>

二、控制台应用打开GraphicsCapturePicker

控制台默认是MTA线程,需手动创建STA线程运行Picker,避免阻塞死锁:

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Graphics.Capture.h>
#include <windows.h>
#include <iostream>

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Capture;

DWORD WINAPI CaptureThread(LPVOID lpParam)
{
    init_apartment(apartment_type::single_threaded);

    try
    {
        GraphicsCapturePicker picker;
        auto item = picker.PickSingleItemAsync().get();

        if (item)
        {
            std::wcout << L"捕获项名称: " << item.DisplayName().c_str() << std::endl;
        }
        else
        {
            std::wcout << L"未选择任何捕获项" << std::endl;
        }
    }
    catch (const winrt::hresult_error& ex)
    {
        std::wcout << L"错误: " << ex.message().c_str() << std::endl;
    }

    return 0;
}

int main()
{
    HANDLE hThread = CreateThread(nullptr, 0, CaptureThread, nullptr, 0, nullptr);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);

    return 0;
}

三、Win32桌面应用打开GraphicsCapturePicker

Win32窗口线程默认是STA,直接在消息循环中用异步操作处理:

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Graphics.Capture.h>
#include <windows.h>
#include <iostream>

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Capture;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CREATE:
        winrt::fire_and_forget([hwnd]() -> IAsyncAction
        {
            try
            {
                GraphicsCapturePicker picker;
                picker.SetWindow(hwnd);
                auto item = co_await picker.PickSingleItemAsync();

                if (item)
                {
                    std::wcout << L"捕获项名称: " << item.DisplayName().c_str() << std::endl;
                }
                else
                {
                    std::wcout << L"未选择任何捕获项" << std::endl;
                }
            }
            catch (const winrt::hresult_error& ex)
            {
                std::wcout << L"错误: " << ex.message().c_str() << std::endl;
            }
        });
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    init_apartment(apartment_type::single_threaded);

    const wchar_t CLASS_NAME[] = L"CaptureWindowClass";
    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    RegisterClass(&wc);

    HWND hwnd = CreateWindowEx(0, CLASS_NAME, L"Win32 Capture Demo", WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, nullptr, nullptr, hInstance, nullptr);

    if (!hwnd) return 0;
    ShowWindow(hwnd, nCmdShow);

    MSG msg;
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return (int)msg.wParam;
}

四、UWP C++应用打开GraphicsCapturePicker

必须在UI线程用co_await处理异步,避免阻塞:

#include "pch.h"
#include "MainPage.xaml.h"

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Capture;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;

namespace winrt::CaptureApp::implementation
{
    IAsyncAction MainPage::Button_Click(IInspectable const& sender, RoutedEventArgs const& e)
    {
        try
        {
            GraphicsCapturePicker picker;
            auto item = co_await picker.PickSingleItemAsync();

            if (item)
            {
                auto btn = sender.as<Button>();
                btn.Content(box_value(item.DisplayName()));
            }
        }
        catch (const winrt::hresult_error& ex)
        {
            auto dialog = Windows::UI::Popups::MessageDialog(ex.message());
            co_await dialog.ShowAsync();
        }
    }
}

对应XAML按钮绑定事件:

<Button Content="选择捕获项" Click="Button_Click"/>

五、无需Picker直接获取Monitor 0的GraphicsCaptureItem

通过DisplayMonitor枚举显示器直接创建捕获项:

#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Graphics.Capture.h>
#include <winrt/Windows.Devices.Display.h>
#include <iostream>

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Graphics::Capture;
using namespace Windows::Devices::Display;

int main()
{
    init_apartment(apartment_type::single_threaded);

    try
    {
        auto monitors = co_await DisplayMonitor::GetAllAsync();
        if (monitors.Size() > 0)
        {
            auto monitor = monitors.GetAt(0);
            auto item = GraphicsCaptureItem::CreateFromDisplayMonitor(monitor);

            if (item)
            {
                std::wcout << L"捕获显示器: " << item.DisplayName().c_str() << std::endl;
            }
        }
    }
    catch (const winrt::hresult_error& ex)
    {
        std::wcout << L"错误: " << ex.message().c_str() << std::endl;
    }

    return 0;
}

内容的提问来源于stack exchange,提问作者user19250735

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:34:59