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
相关产品推荐
相关产品推荐

