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

WinUI3+C++20下如何打印NavigationView中的指定XAML元素

WinUI3 C++ 打印NavigationView选中页面的解决方案

一、确认CLSID与依赖配置

首先确保你使用的CLSID_PrintManager是正确的,其值为{1B8E2F1F-6D97-441B-802B-699F000A6CE2}。同时检查项目配置:

  • 必须包含头文件:<winrt/Windows.Graphics.Printing.h> 和 <printmanagerinterop.h>
  • 链接器输入中添加windowsapp.lib(Windows App SDK核心库)
  • 目标平台版本设置为10.0.19041.0或更高

二、正确初始化IPrintManagerInterop

WinUI3中不能直接实例化PrintManager,必须通过IPrintManagerInterop绑定到窗口HWND。以下是可行的初始化代码:

#include <winrt/Windows.UI.WindowManagement.h>
#include <printmanagerinterop.h>

// 获取当前WinUI窗口的HWND
auto currentAppWindow = winrt::Windows::UI::WindowManagement::AppWindow::GetCurrent();
HWND hwnd = winrt::Windows::UI::WindowManagement::GetWindowFromWindowId(currentAppWindow.Id());

// 创建IPrintManagerInterop实例
winrt::com_ptr<IPrintManagerInterop> printManagerInterop;
HRESULT hr = CoCreateInstance(CLSID_PrintManager, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&printManagerInterop));

if (SUCCEEDED(hr))
{
    winrt::Windows::Graphics::Printing::PrintManager printManager;
    hr = printManagerInterop->GetForWindow(hwnd, IID_PPV_ARGS(&printManager));
    
    if (SUCCEEDED(hr))
    {
        // 注册打印请求事件
        printManager.PrintRequested([this](const auto&, const winrt::Windows::Graphics::Printing::PrintRequestedEventArgs& args)
        {
            auto printTask = args.Request().CreatePrintTask(L"选中页面打印", [this](const auto& taskArgs)
            {
                // 这里传入选中页面的打印数据源
                taskArgs.SetSource(GetSelectedPagePrintSource());
            });
        });
    }
}

注意:这段代码必须在UI线程执行,WinUI3的主线程默认已初始化COM,无需额外调用CoInitializeEx。

三、实现仅打印选中页面

不要直接打印整个窗口,需单独处理选中页面的内容:

  1. 捕获页面内容:将选中的NavigationView页面渲染到RenderTargetBitmap
    winrt::Windows::UI::Xaml::Controls::Page selectedPage = /* 获取选中的页面实例 */;
    winrt::Windows::UI::Xaml::Media::RenderTargetBitmap renderBitmap;
    co_await renderBitmap.RenderAsync(selectedPage);
    
  2. 转换为打印源:将渲染后的位图转换为PrintDocument可使用的数据源,或直接使用页面的可视化元素作为打印预览源:
    winrt::Windows::UI::Xaml::Printing::PrintDocument printDoc;
    printDoc.SetPreviewPage(1, selectedPage);
    // 返回printDoc.DocumentSource()作为打印源
    

四、错误排查

  • 接口未注册:更新Windows App SDK到最新稳定版,确认项目的“Windows App SDK版本”配置正确
  • IPrintManagerInterop创建失败:检查CoCreateInstance的CLSCTX参数,使用CLSCTX_ALL而非其他受限值
  • 打印无响应:确保打印事件处理逻辑在UI线程执行,避免阻塞或跨线程调用UI元素

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 11:20:58