XAML 将Win32位图转换为WinUI 3 C++/WinRT图像源

ma8fv8wu  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(171)

我想在自定义列表视图中显示文件,除了在列表视图中显示每个文件扩展名的图标外,我做了所有需要的事情。
我发现了如何采取HICON/位图的文件扩展名,但我需要显示在自定义列表视图像图像或类似的东西。
我怎么才能做到呢?
我正在使用WinUI3 C ++/WinRT,最新的软件包。

uurity8g

uurity8g1#

IInspectable的评论的帮助下,我能够找到我自己问题的答案,非常感谢他。
您将需要这些标头:

#include <winrt/Windows.Storage.h>
#include <winrt/Microsoft.Ui.Xaml.Media.Imaging.h>

这是异步方法:

::winrt::Windows::Foundation::IAsyncOperation<::winrt::Microsoft::UI::Xaml::Media::ImageSource>
GetIconFromFile(
    const ::winrt::hstring& file,
    ::winrt::Windows::Storage::FileProperties::ThumbnailMode thumbnailMode = ::winrt::Windows::Storage::FileProperties::ThumbnailMode::DocumentsView
) {
    const auto& fileStorage = co_await ::winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(file);
    const auto& fileThumbnail = co_await fileStorage.GetThumbnailAsync(thumbnailMode);

    ::winrt::Microsoft::UI::Xaml::Media::Imaging::BitmapImage bitmapImage;
    bitmapImage.SetSource(fileThumbnail);

    co_return bitmapImage;
}

您可以通过使用它们来摆脱名称空间,但我决定不这样做,因为如果包含Windows名称空间中的内容,可能会出现不明确的错误。
您可以这样使用它:

// xaml
<Image x:Name="image" Width="40" Height="40"/>

//cpp
::winrt::Windows::Foundation::IAsyncAction LoadImageIcon() {
        const auto& filePath = TEXT("<your file path>");
        image().Source(co_await GetIconFromFile(filePath));
    }
mpgws1up

mpgws1up2#

下面是一个通用函数,它可以完成HBITMAP =〉WinUI3 Image.Source转换:

#pragma comment(lib, "gdi32")
#pragma comment(lib, "oleaut32")

using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams; // for InMemoryRandomAccessStream
using namespace Windows::Graphics::Imaging; // for BitmapDecoder
using namespace Microsoft::UI::Xaml;
using namespace Microsoft::UI::Xaml::Controls;  // for Image
using namespace Microsoft::UI::Xaml::Media::Imaging;  // for SoftwareBitmapSource

IAsyncAction SetImageSourceFromHBITMAPAsync(HBITMAP hBitmap, Image image)
{
  PICTDESC pd = {};
  pd.cbSizeofstruct = sizeof(PICTDESC);
  pd.picType = PICTYPE_BITMAP;
  pd.bmp.hbitmap = hBitmap;

  com_ptr<IPicture> picture;
  if (FAILED(OleCreatePictureIndirect(&pd, IID_IPicture, FALSE, (LPVOID*)picture.put()))) // #include <olectl.h> in pch.h
    return;

  InMemoryRandomAccessStream memStream; // #include <winrt/Windows.Storage.Streams.h> in pch.h
  com_ptr<IStream> stream;
  if (FAILED(CreateStreamOverRandomAccessStream(winrt::get_unknown(memStream), IID_PPV_ARGS(&stream)))) // #include <shcore.h> in pch.h
    return;

  if (FAILED(picture->SaveAsFile(stream.get(), TRUE, nullptr)))
    return;

  auto decoder = co_await BitmapDecoder::CreateAsync(memStream); // #include <winrt/Windows.Graphics.Imaging.h> in pch.h
  auto bitmap = co_await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat::Bgra8, BitmapAlphaMode::Premultiplied);

  SoftwareBitmapSource bitmapSource; // #include <winrt/Microsoft.UI.Xaml.Media.Imaging.h> in pch.h
  co_await bitmapSource.SetBitmapAsync(bitmap);
  image.Source(bitmapSource);
}

以及如何使用它的示例:

namespace winrt::WinUIApp1CPP::implementation
{
    MainWindow::MainWindow()
    {
        InitializeComponent();
    }

    void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
    {
        auto hBitmap = (HBITMAP)LoadImage(nullptr, L"D:\\Downloads\\dog.bmp", IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
        if (!hBitmap)
            return;

        auto op{ SetImageSourceFromHBITMAPAsync(hBitmap, myImage()) }; // add this XAML somewhere <Image x:Name="myImage" />
        DeleteObject(hBitmap);
    }
}

相关问题