WinUI 3中C++调用FileOpenPicker出现内存错误求助
WinUI3 C++ 打开文件选择器抛出hresult_error的解决方法
问题分析
你当前用GetProcessFirstWindowHandle()获取HWND的方式不可靠,这个方法拿到的不一定是WinUI3应用的主窗口句柄,导致文件选择器无法正确关联父窗口,最终调用PickSingleFileAsync().get()时抛出异常。
正确解决方案
要获取当前WinUI3页面所在窗口的真实HWND,步骤如下:
- 从页面的
XamlRoot获取关联的Window对象 - 通过
WindowId获取对应的HWND - 用正确的HWND初始化文件选择器
修改后的Button_Click代码:
#include <winrt/Microsoft.UI.WindowId.h> #include <winrt/Microsoft.UI.Xaml.h> void winrt::App1::implementation::Tab1Page::Button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e) { OutputTextBlock().Text(OutputTextBlock().Text() + L"Button Clicked\n"); // 获取当前页面所在的Window auto window = this->XamlRoot().Content().as<winrt::Microsoft::UI::Xaml::Window>(); // 获取Window对应的HWND auto windowId = winrt::Microsoft::UI::WindowId::GetForWindow(window); auto hwnd = windowId.TryGetWindowHandle(); if (hwnd) { auto picker = winrt::Windows::Storage::Pickers::FileOpenPicker(); // 初始化文件选择器的父窗口句柄 auto initializeWithWindow = picker.as<::IInitializeWithWindow>(); initializeWithWindow->Initialize(hwnd.value()); picker.SuggestedStartLocation(winrt::Windows::Storage::Pickers::PickerLocationId::Desktop); winrt::Windows::Storage::StorageFile file = picker.PickSingleFileAsync().get(); if (file) { OutputTextBlock().Text(OutputTextBlock().Text() + L"Selected file: " + file.Name() + L"\n"); } } else { OutputTextBlock().Text(OutputTextBlock().Text() + L"Failed to get window handle\n"); } }
额外优化建议
建议使用co_await替代.get()调用异步方法,避免阻塞UI线程,提升应用响应性:
// 修改函数为异步类型 winrt::fire_and_forget winrt::App1::implementation::Tab1Page::Button_Click(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e) { // ... 前面HWND获取代码不变 if (hwnd) { // ... picker初始化代码不变 winrt::Windows::Storage::StorageFile file = co_await picker.PickSingleFileAsync(); if (file) { OutputTextBlock().Text(OutputTextBlock().Text() + L"Selected file: " + file.Name() + L"\n"); } } }
内容的提问来源于stack exchange,提问作者Gaurang Dave
相关产品推荐
相关产品推荐

