Partilhar via


Como personalizar as configurações de impressão (aplicativos de dispositivo UWP)

Important

Os metadados do dispositivo foram preteridos e serão removidos em uma versão futura do Windows. Para obter informações sobre a substituição dessa funcionalidade, consulte Metadados do contêiner do pacote de driver.

No Windows 8.1, os aplicativos de dispositivo UWP permitem que os fabricantes de impressoras personalizem o submenu que exibe configurações de impressão avançadas. Este tópico apresenta o submenu de configurações de impressão avançadas e mostra como a versão em C# do Exemplo de configurações de impressão e notificações de impressão substitui o submenu padrão por um submenu personalizado. Para saber mais sobre os aplicativos de dispositivo UWP em geral, consulte Meet UWP device apps.

A versão em C# do exemplo Configurações de impressão e notificações de impressão usa a página Preferences.xaml para demonstrar a interface do usuário de um submenu personalizado para configurações de impressão avançadas. Uma classe auxiliar de impressão é usada para criar um contexto de dispositivo (IPrinterExtensionContext) e executar as consultas de dispositivo. The PrinterHelperClass.cs file is in the DeviceAppForPrintersLibrary project and uses APIs defined in the PrinterExtensionLibrary project. A biblioteca de extensões de impressora fornece uma maneira conveniente de acessar as interfaces de extensão de impressora do driver de impressão v4. Para mais informações, veja a visão geral da biblioteca de extensões da impressora .

Note

Os exemplos de código mostrados neste tópico são baseados na versão em C# do exemplo de configurações de impressão e notificações de impressão. Este exemplo também está disponível em JavaScript e C++. Observe que, como o C++ pode acessar COM diretamente, a versão C++ do exemplo não inclui projetos de biblioteca de código. Faça o download dos exemplos para ver as versões mais recentes do código.

Configurações avançadas de impressão

A experiência de configurações avançadas de impressão é a funcionalidade que uma impressora oferece quando um usuário deseja selecionar configurações de impressão que não são oferecidas na janela Imprimir. It is accessible through the More settings link in the Print window. Não é uma experiência de ecrã completo, mas é exibida dentro de um flyout, que é um controle para exibir uma interface de utilizador contextual leve e que é fechada quando o utilizador clica ou toca fora dela.

Essa experiência pode ser usada para destacar recursos diferenciados para sua impressora, como a capacidade de aplicar marcas d'água a uma página de documento, oferecer opções de impressão seguras ou opções de aprimoramento de imagem.

Quando um aplicativo de dispositivo UWP não está instalado para uma impressora, o Windows fornece uma experiência de configurações de impressão padrão. Se o Windows detetar que uma aplicação de dispositivo UWP está instalada para a sua impressora e que a aplicação optou pela extensão windows.printTaskSettings, a sua aplicação substituirá a experiência padrão fornecida pelo Windows.

Para invocar o submenu para configurações avançadas de impressão:

  1. Abra um aplicativo UWP que ofereça suporte à impressão

  2. Acesse os botões passando o dedo no lado direito da tela (ou usando a tecla do logotipo do Windows + C)

  3. Tap the Devices charm

  4. Tap Print

  5. Toque numa impressora

  6. The Print window opens

  7. Click the More settings link on the Print window

  8. O submenu de configurações avançadas de impressão é aberto

    • The default flyout appears when no UWP device app for the printer is installed

    • A custom flyout appears when a UWP device app for the printer is installed

Exemplos dos submenus padrão e personalizados para configurações de impressão avançadas.

Prerequisites

Antes de começar:

  1. Verifique se a impressora está instalada usando um driver de impressão v4. Para mais informações, consulte Desenvolvimento de controladores de impressão v4.

  2. Configure o seu PC de desenvolvimento. See Getting started for info about downloading the tools and creating a developer account.

  3. Associe seu aplicativo à loja. Consulte Criar um aplicativo de dispositivo UWP para obter informações sobre isso.

  4. Crie metadados de dispositivo para sua impressora que os associem ao seu aplicativo. Consulte Criar metadados de dispositivo para obter mais informações sobre isso.

  5. Crie a interface do usuário para a página principal do seu aplicativo. Todos os aplicativos de dispositivo UWP podem ser iniciados na tela inicial, onde serão exibidos em tela cheia. Utilize a experiência Iniciar para destacar o seu produto ou serviços de uma forma que corresponda à marca e às funcionalidades específicas dos seus dispositivos. Não há restrições especiais sobre o tipo de controles de interface do usuário que ele pode usar. Para começar com o design da experiência de tela inteira, consulte os princípios de design da Microsoft Store .

  6. If you're writing your app with C# or JavaScript, add the PrinterExtensionLibrary and DeviceAppForPrintersLibrary projects to your UWP device app solution. Você pode encontrar cada um desses projetos no Configurações de impressão e notificações de impressão exemplo.

Note

Como o C++ pode acessar COM diretamente, os aplicativos C++ não exigem uma biblioteca separada para trabalhar com o contexto do dispositivo de impressora baseado em COM.

Passo 1: Registar a extensão

Para que o Windows reconheça que a aplicação pode fornecer um painel personalizado para configurações de impressão avançadas, deve registar a extensão para as configurações de tarefas de impressão. Essa extensão é declarada em um Extension elemento , com um Category atributo definido como um valor de windows.printTaskSettings. Nos exemplos de C# e C++, o Executable atributo é definido como $targetnametoken$.exe e o EntryPoint atributo é definido como DeviceAppForPrinters.App.

You can add the print task settings extension on the Declarations tab of the Manifest Designer in Microsoft Visual Studio. Você também pode editar o XML do manifesto do pacote do aplicativo manualmente, usando o Editor de XML (Texto). Right-click the Package.appxmanifest file in Solution Explorer for editing options.

This example shows the print task settings extension in the Extension element, as it appears in the app package manifest file, Package.appxmanifest.

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
  <Identity Name="Microsoft.SDKSamples.DeviceAppForPrinters.CS" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" Version="1.0.0.0" />
  <Properties>
    <DisplayName>Device App For Printers C# sample</DisplayName>
    <PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
    <Logo>Assets\storeLogo-sdk.png</Logo>
  </Properties>
  <Prerequisites>
    <OSMinVersion>6.3.0</OSMinVersion>
    <OSMaxVersionTested>6.3.0</OSMaxVersionTested>
  </Prerequisites>
  <Resources>
    <Resource Language="x-generate" />
  </Resources>
  <Applications>
    <Application Id="DeviceAppForPrinters" Executable="$targetnametoken$.exe" EntryPoint="DeviceAppForPrinters.App">
      <VisualElements DisplayName="Device App For Printers C# sample" Logo="Assets\squareTile-sdk.png" SmallLogo="Assets\smallTile-sdk.png" Description="DeviceAppForPrinters C# sample" ForegroundText="light" BackgroundColor="#00b2f0" ToastCapable="true">
<DefaultTile ShowName="allLogos" ShortName="App4PrinterCS" WideLogo="Assets\tile-sdk.png" />
<SplashScreen Image="Assets\splash-sdk.png" BackgroundColor="#00b2f0" />
      </VisualElements>
      <Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTask.PrintBackgroundTask">
  <BackgroundTasks>
    <Task Type="systemEvent" />
  </BackgroundTasks>
</Extension>
<Extension Category="windows.printTaskSettings" Executable="$targetnametoken$.exe" EntryPoint="DeviceAppForPrinters.App" />
      </Extensions>
    </Application>
  </Applications>
</Package>

Etapa 2: Criar a interface do usuário

Antes de criar seu aplicativo, você deve trabalhar com seus designers e sua equipe de marketing para projetar a experiência do usuário. A experiência do usuário deve projetar os aspetos de marca da sua empresa e ajudá-lo a construir uma conexão com seus usuários.

Design guidelines

É importante revisar as diretrizes do submenu do aplicativo UWP antes de criar seu submenu personalizado. As diretrizes ajudam a garantir que seu flyout ofereça uma experiência intuitiva consistente com outros aplicativos UWP.

Para a página principal do seu aplicativo, lembre-se de que o Windows 8.1 pode exibir vários aplicativos em vários tamanhos em um único monitor. Consulte as diretrizes a seguir para saber mais sobre como seu aplicativo pode refluir normalmente entre tamanhos de tela, tamanhos de janela e orientações.

Flyout dimensions

O submenu que exibe configurações avançadas de impressão tem 646 pixels de largura e pelo menos 768 pixels de altura (a altura real depende da resolução da tela do usuário). O botão Voltar na área de título do flyout é fornecido pelo Windows. O texto "Título do aplicativo" é o título do aplicativo do manifesto do aplicativo. A área do título tem 80 pixels de altura, deixando 688 pixels para a área visível do submenu personalizado.

Dimensões da caixa de diálogo para configurações avançadas da impressora.

Note

Se o submenu personalizado tiver mais de 688 pixels de altura, o usuário poderá deslizar ou rolar para exibir partes do submenu que estão acima ou abaixo da área visível.

Definindo a cor e o ícone do título do aplicativo

O título, a cor do plano de fundo, a cor do texto e o pequeno logotipo no menu suspenso personalizado são retirados do elemento VisualElements no arquivo de manifesto do pacote do aplicativo.

This example shows the title and icon, as defined in the VisualElements element, in the app package manifest file (Package.appxmanifest).

      <VisualElements DisplayName="Device App For Printers C# sample" Logo="Assets\squareTile-sdk.png" SmallLogo="Assets\smallTile-sdk.png" Description="DeviceAppForPrinters C# sample" ForegroundText="light" BackgroundColor="#00b2f0" ToastCapable="true">
        <DefaultTile ShowName="allLogos" ShortName="App4PrinterCS" WideLogo="Assets\tile-sdk.png" />
        <SplashScreen Image="Assets\splash-sdk.png" BackgroundColor="#00b2f0" />
      </VisualElements>

Best practices

  • Mantenha a mesma aparência e sensação. Alinhe o seu menu personalizado com o design da sua experiência de Início (a página principal da sua aplicação), incluindo elementos como fontes, cores e controlos. O aplicativo deve parecer familiar para as pessoas, independentemente de onde elas o invocam.

  • Mantenha as interações simples. Evite interações demoradas ou complexas. Na maioria dos casos, ações como configurar uma impressora, visualizar o status, solicitar tinta e solucionar problemas são melhor feitas dentro da experiência Iniciar.

  • Mantenha a navegação ao mínimo. Evite fazer com que os utilizadores naveguem repetidamente entre várias páginas no flyout personalizado. Em vez disso, use rolagem vertical ou controles embutidos, como controles de divulgação progressiva, listas suspensas e mensagens de erro embutidas.

  • Não use painéis flutuantes de descarte leve. A experiência de impressão já usa um submenu de descarte leve. Incluir outro elemento de descarte leve no seu flyout personalizado pode confundir os seus utilizadores.

  • Desative links que afastam os usuários da experiência de impressão. Quando um usuário está imprimindo conteúdo, você deve tomar medidas para garantir que eles permaneçam no contexto de impressão. Por exemplo, se o seu aplicativo tiver links que levam a outras áreas do seu aplicativo (como a uma home page ou a uma página para compra de tinta), você deve desativá-los para que o usuário não deixe a experiência de configurações de impressão avançadas acidentalmente.

Etapa 3: Gerir a ativação

Se o seu aplicativo declarou a extensão de configurações da tarefa de impressão, deverá implementar um método OnActivated para manipular o evento de ativação do aplicativo. A ativação da aplicação ocorre quando a sua aplicação pode escolher qual página será aberta no arranque. Para aplicações que declararam a extensão das definições da tarefa de impressão, o Windows passa o contexto da extensão da tarefa de impressão nos argumentos de evento Ativado: Windows.ApplicationModel.Activation.IActivatedEventArgs.

A UWP device app can determine that the activation is intended for advanced print settings (that someone just tapped More options on the print settings dialog) when the event argument's kind property is equal to Windows.ApplicationModel.Activation.ActivationKind.printTaskSettings.

Note

Em alguns casos, se o utilizador fechar a aplicação imediatamente após o seu lançamento, pode ser gerada uma exceção dentro do manipulador de ativação. Para evitar isso, certifique-se de que o manipulador de ativação funcione de forma eficiente e não faça processamento intensivo em recursos.

This example shows the activation event handler in the OnActivated method, as it appears in the Constants.cs file. Os argumentos de evento são então convertidos como Windows.ApplicationModel.Activation.PrintTaskSettingsActivatedEventArgs. Although the sample includes this code in the Constants.cs file, it's actually part of the App class that is also defined in the App.xaml.cs file.

partial class App : Application
{
    protected override void OnActivated(IActivatedEventArgs args)
    {
        if (args.Kind == ActivationKind.PrintTaskSettings)
        {
            Frame rootFrame = new Frame();
            if (null == Window.Current.Content)
            {
                rootFrame.Navigate(typeof(MainPage));
                Window.Current.Content = rootFrame;
            }
            Window.Current.Activate();

            MainPage mainPage = (MainPage)rootFrame.Content;

            // Load advanced printer preferences scenario
            mainPage.LoadAdvancedPrintSettingsContext((PrintTaskSettingsActivatedEventArgs)args);
        }
    }
}

Etapa 4: Exibir configurações

Quando o LoadAdvancedPrintSettingsContext método é chamado, o contexto de configuração da tarefa de impressão é atribuído a variáveis da classe MainPage. Isso permitirá que o painel de opções personalizado aceda às definições de impressão quando for lançado.

Os argumentos de evento que são passados para o LoadAdvancedPrintSettingsContext método, expõem propriedades para acessar e controlar a impressora:

  • The args.configuration property provides an object of type Windows.Devices.Printers.Extensions.PrintTaskConfiguration. Este objeto fornece acesso ao contexto de extensão da tarefa de impressão e também permite que se adicione um gestor de eventos para atualizar o bilhete de impressão.
  • The args.configuration.printerExtensionContext property provides an object of type Windows.Devices.Printers.Extensions.PrinterExtensionContext. Este objeto é um ponteiro para as interfaces PrinterExtensionLibrary para Esquema de Impressão, PrintTicket e informações da fila de impressão. Será nulo se nenhuma interface for exposta. Para obter mais informações, consulte Visão geral da biblioteca de extensões de impressora.

This example shows the LoadAdvancedPrintSettingsContext method, as it appears in the Constants.cs file.

public PrintTaskConfiguration Config;
public Object Context;

public void LoadAdvancedPrintSettingsContext(PrintTaskSettingsActivatedEventArgs args)
{
    Config = args.Configuration;
    Context = Config.PrinterExtensionContext;
    LoadScenario(typeof(DeviceAppForPrinters.Preferences));
}

On the custom flyout page, Preferences.xaml.cs, a class named rootPage acts as a pointer to the MainPage class so that the print task extension context and the printer device context can be accessed from the flyout.

This example shows the pointer in a portion of Preferences class, from the Preferences.xaml.cs file. Transfira o exemplo de definições de impressão e notificações de impressão de e para ver o código completo.

public sealed partial class Preferences : SDKTemplate.Common.LayoutAwarePage
{
    // A pointer back to the main page.  
    MainPage rootPage = MainPage.Current;

    // To listen for save requests.
    PrintTaskConfiguration configuration;

    // To create the printer device context.
    Object printerExtensionContext;
    PrintHelperClass printHelper;

    // The features in this sample were chosen because they're available on a wide range of printer drivers.
    private string[] features = { "PageOrientation", "PageOutputColor", "PageMediaSize", "PageMediaType" };
    private string[] selections = { null, null, null, null };

    // . . .
    // . . .
    // . . .

When the page constructor for Preferences.xaml.cs is called, objects are created for the print task extension context (a PrintTaskConfiguration object named configuration) and the printer device context (a PrintHelperClass object named printHelper).

Depois de criados esses objetos, o contexto de dispositivo da impressora é utilizado no método DisplaySettings para carregar TextBlocks e ComboBoxes. Observe que, ao contrário do JavaScript, as alterações na seleção não são disparadas no mesmo thread que o resto do aplicativo. Você precisa manter um cache local de seleções de usuários para usar mais tarde.

This example shows the custom flyout page constructor, DisplaySettings, and other helper methods in the Preferences.xaml.cs file.

public Preferences()
{
    this.InitializeComponent();

    configuration = rootPage.Config;
    printerExtensionContext = rootPage.Context;
    printHelper = new PrintHelperClass(printerExtensionContext);

    // Disable scenario navigation by hiding the scenario list UI elements
    ((UIElement)rootPage.FindName("Scenarios")).Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    ((UIElement)rootPage.FindName("ScenarioListLabel")).Visibility = Windows.UI.Xaml.Visibility.Collapsed;
    ((UIElement)rootPage.FindName("DescriptionText")).Visibility = Windows.UI.Xaml.Visibility.Collapsed;

    DisplaySettings();
}


private void DisplaySettings(bool constraints=false)
{
    PrintOptions.Visibility = Windows.UI.Xaml.Visibility.Visible;
    WaitPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;

    // Fill in the drop-down select controls for some common printing features.
    TextBlock[] featureLabels = { PageOrientationLabel, PageOutputColorLabel, PageMediaSizeLabel, PageMediaTypeLabel };
    ComboBox[] featureBoxes = { PageOrientationBox, PageOutputColorBox, PageMediaSizeBox, PageMediaTypeBox };

    for (int i = 0; i < features.Length; i++)
    {
        // Only display a feature if it exists
        featureLabels[i].Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        featureBoxes[i].Visibility = Windows.UI.Xaml.Visibility.Collapsed;

        string feature = features[i];

        // Check whether the currently selected printer's capabilities include this feature.
        if (!printHelper.FeatureExists(feature))
        {
            continue;
        }

        // Fill in the labels so that they display the display name of each feature.
        featureLabels[i].Text = printHelper.GetFeatureDisplayName(feature);
        string[] index = printHelper.GetOptionInfo(feature, "Index");
        string[] displayName = printHelper.GetOptionInfo(feature, "DisplayName");
        string selectedOption = printHelper.GetSelectedOptionIndex(feature);

        // Unless specified, do not get constraints
        bool[] constrainedList = constraints ? printHelper.GetOptionConstraints(feature) : new bool[index.Length];

        // Populate the combo box with the options for the current feature.
        PopulateBox(featureBoxes[i], index, displayName, selectedOption, constrainedList);
        selections[i] = selectedOption;

        // Every time the selection for a feature changes, we update our local cached set of selections.
        featureBoxes[i].SelectionChanged += OnFeatureOptionsChanged;

        // Show existing features
        featureLabels[i].Visibility = Windows.UI.Xaml.Visibility.Visible;
        featureBoxes[i].Visibility = Windows.UI.Xaml.Visibility.Visible;
    }
}

void PopulateBox(ComboBox box, string[] index, string[] displayName, string selectedOption, bool[] constrainedList)
{
    // Clear the combobox of any options from previous UI refresh before repopulating it.
    box.SelectionChanged -= OnFeatureOptionsChanged;
    box.Items.Clear();
    // There should be only one displayName for each possible option.
    if (index.Length == displayName.Length)
    {
        for (int i = 0; i < index.Length; i++)
        {
            // Create a new DisplayItem so the user will see the friendly displayName instead of the index.
            ComboBoxItem newItem = new ComboBoxItem();
            newItem.Content = displayName[i];
            newItem.DataContext = index[i];
            newItem.Foreground = constrainedList[i] ? new SolidColorBrush(Colors.Red) : new SolidColorBrush(Colors.Black);
            box.Items.Add(newItem);

            // Display current selected option as selected in the combo box.
            if (selectedOption == index[i])
            {
                box.SelectedIndex = i;
                box.Foreground = newItem.Foreground;
            }
        }
    }
}

private void OnFeatureOptionsChanged(object sender, SelectionChangedEventArgs args)
{
    ComboBox comboBox = sender as ComboBox;

    for (int i = 0; i < features.Length; i++)
    {
        if (features[i] + "Box" == comboBox.Name)
        {
            selections[i] = (comboBox.SelectedItem as ComboBoxItem).DataContext as string;
        }
    }
}

Etapa 5: salvar as configurações

When the user has finished setting advanced print settings, the Microsoft Store device app needs to save the changes before the user goes back to the Print window. To do that, the app needs to listen for when the user taps the Back button (from the custom flyout page). Quando isso acontece, o SaveRequested evento do contexto de extensão da tarefa de impressão (o configuration objeto) é acionado.

This example shows the event listener for SaveRequested, being added in the OnNavigatedTo event handler of the custom flyout, in the Preferences.xaml.cs file. When the SaveRequested event is triggered, the OnSaveRequested method will be invoked (that method is also in the Preferences.xaml.cs file).

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    if (null == configuration)
    {
        rootPage.NotifyUser("Configuration arguments cannot be null", NotifyType.ErrorMessage);
        return;
    }

    // Add an event listener for saverequested (the back button of the flyout is pressed).
    configuration.SaveRequested += OnSaveRequested;
}

OnSaveRequested No método, o aplicativo primeiro usa o printHelper objeto para definir as opções atualmente selecionadas para cada recurso no contexto de extensão da impressora. Em seguida, chama o método Save no objeto request que é passado como argumento para o método OnSaveRequested. O Save método, da classe Windows.Devices.Printers.Extensions.PrintTaskConfigurationSaveRequest, usa o contexto de extensão de impressora para validar o tíquete de impressão e salvar a configuração da tarefa de impressão.

Important

Se o bilhete de impressão for inválido de alguma forma, o método Save lançará uma exceção que a aplicação deve tratar. Se a aplicação não tratar a exceção, o fluxo será interrompido, forçando o utilizador a fechar levemente o flyout e reiniciar o fluxo de impressão.

This example shows the OnSaveRequested method in the Preferences.xaml.cs file. Como o SaveRequested evento não é gerado no thread da interface do usuário, ele precisa usar um Windows.UI.Core.CoreDispatcher para postar mensagens no thread da interface do usuário para exibir as mensagens apropriadas enquanto valida e salva o ticket.

async private void OnSaveRequested(object sender, PrintTaskConfigurationSaveRequestedEventArgs args)
{
    if (null == printHelper || null == printerExtensionContext || null == args)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            rootPage.NotifyUser("onSaveRequested: args, printHelper, and context cannot be null", NotifyType.ErrorMessage);
        });
        return;
    }

    // Get the request object, which has the save method that allows saving updated print settings.
    PrintTaskConfigurationSaveRequest request = args.Request;

    if (null == request)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            rootPage.NotifyUser("onSaveRequested: request cannot be null", NotifyType.ErrorMessage);
        });
        return;
    }

    PrintTaskConfigurationSaveRequestedDeferral deferral = request.GetDeferral();

    // Two separate messages are dispatched to:
    // 1) put up a popup panel,
    // 2) set the each options to the print ticket and attempt to save it,
    // 3) tear down the popup panel if the print ticket could not be saved.
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
    {
        PrintOptions.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        WaitPanel.Visibility = Windows.UI.Xaml.Visibility.Visible;
    });

    // Go through all the feature select elements, look up the selected
    // option name, and update the context
    // for each feature
    for (var i = 0; i < features.Length; i++)
    {
        // Set the feature's selected option in the context's print ticket.
        // The printerExtensionContext object is updated with each iteration of this loop
        printHelper.SetFeatureOption(features[i], selections[i]);
    }

    bool ticketSaved;
    try
    {
        // This save request will throw an exception if ticket validation fails.
        // When the exception is thrown, the app flyout will remain.
        // If you want the flyout to remain regardless of outcome, you can call
        // request.Cancel(). This should be used sparingly, however, as it could
        // disrupt the entire the print flow and will force the user to
        // light dismiss to restart the entire experience.
        request.Save(printerExtensionContext);

        if (configuration != null)
        {
            configuration.SaveRequested -= OnSaveRequested;
        }
        ticketSaved = true;
    }
    catch (Exception exp)
    {
        // Check if the HResult from the exception is from an invalid ticket, otherwise rethrow the exception
        if (exp.HResult.Equals(unchecked((int)0x8007000D))) // E_INVALID_DATA
        {
            ticketSaved = false;
        }
        else
        {
            throw;
        }
    }

    // If ticket isn't saved, refresh UI and notify user
    if (!ticketSaved)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            rootPage.NotifyUser("Failed to save the print ticket", NotifyType.ErrorMessage);
            DisplaySettings(true);
        });
    }
    deferral.Complete();
}

Salvando opções que exigem a entrada do usuário

O Exemplo de configurações de impressão e notificações de impressão demonstra como definir recursos definidos, o que abrange a maioria das opções de impressão. No entanto, algumas opções exigem uma interface do usuário personalizada para obter um valor especificado pelo usuário. Por exemplo, se um aplicativo usasse as configurações avançadas de impressão para especificar um tamanho de página personalizado, ele executaria estas etapas para salvar o valor especificado pelo usuário:

  1. Recupere o ticket de impressão durante a ativação da aplicação. A ativação da aplicação para configurações de impressão é descrita anteriormente em Etapa 3: gerir a ativação.

  2. Verifique se a opção de tamanho da página está especificada. Em um aplicativo C# ou JS, a classe auxiliar de impressão pode verificar essa opção. Em um aplicativo C++, chame QueryInterface em IPrintSchemaOption para recuperar IPrintSchemaPageMediaSizeOption.

    Este exemplo mostra um método em uma classe auxiliar de impressão que verifica se a opção de tamanho da página está especificada.

    public bool ShouldShowCustomUI(string index)
    {
        if (null != index)
        {
            string feature = "PageMediaSize";
            int i = int.Parse(index);
            IPrintSchemaOption selectedOption = GetCachedFeatureOptions(feature)[i];
            if (selectedOption.Name.Equals("CustomMediaSize", StringComparison.CurrentCulture)
                || selectedOption.Name.Equals("PSCustomMediaSize", StringComparison.CurrentCulture))
            {
                return true;
            }
        }
        return false;
    }
    
  3. No flyout personalizado, exiba uma UI personalizada que solicita ao usuário a altura e a largura da página e recupere a altura e a largura especificadas pelo usuário de IPrintSchemaPageMediaSizeOption.

    Este exemplo mostra um método para um painel suspenso personalizado que solicita ao utilizador a altura e a largura da página.

    private void ShowCustomPageMediaSizeUI(string index, bool keepValue)
    {
        //Hide custom media size UI unless needed
        if (IsCustomSizeSelected(index))
        {
           if (keepValue && (!customWidth.Equals("")) && (!customHeight.Equals("")))
           {
                        CustomWidthBox.Text = customWidth;
                        CustomHeightBox.Text = customHeight;
           }
           else
           {
              // Use a helper function from the WinRT helper component
              CustomWidthBox.Text = printHelper.GetCustomWidth(index);
              CustomHeightBox.Text = printHelper.GetCustomHeight(index);
           }
           CustomUIPanel.Visibility = Windows.UI.Xaml.Visibility.Visible;
           CustomWidthBox.KeyDown += OnCustomValueEntered;
           CustomHeightBox.KeyDown += OnCustomValueEntered;
        }
        else
        {
           CustomUIPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
           CustomWidthBox.KeyDown -= OnCustomValueEntered;
           CustomHeightBox.KeyDown -= OnCustomValueEntered;
        }
    }
    
  4. Atualize o IPrintSchemaPageMediaSizeOption objeto com os valores especificados pelo usuário e valide se a altura e a largura correspondem aos valores especificados pelo usuário.

    Este exemplo é um método auxiliar para atualizar o IPrintSchemaPageMediaSizeOption objeto em uma classe auxiliar de impressora. O OnSaveRequested manipulador no flyout personalizado chamaria esta função caso determinasse que uma opção de tamanho de página personalizada foi solicitada.

    public void SetCustomMediaSizeDimensions(string width, string height)
    {
      if ((null == width) && (null == height) && (null == Capabilities))
      {
                    return;
      }
      try
      {
                    CheckSizeValidity(width, height);
      }
      catch (FormatException e)
      {
                    throw new ArgumentException(e.Message);
      }
      catch (OverflowException e)
      {
                    throw new ArgumentException(e.Message);
      }
    
      // The context is retrieved during app activation.
      IPrintSchemaTicket ticket = context.Ticket;
    
      //
      // Input XML as Stream
      //
      XElement ticketRootXElement = null;
      using (Stream ticketReadStream = ticket.GetReadStream())
      {
         ticketRootXElement = XElement.Load(ticketReadStream);
      }
    
      XNamespace psfNs = PrintSchemaConstants.FrameworkNamespaceUri;
      XNamespace pskNs = PrintSchemaConstants.KeywordsNamespaceUri;
      string pskPrefix = ticketRootXElement.GetPrefixOfNamespace(pskNs);
    
      // Modify the MediaSizeHeight and MediaSizeWidth
      IEnumerable<XElement> parameterInitCollection =
        from c in ticketRootXElement.Elements(psfNs + "ParameterInit")
    
      select c;
    
      foreach (XElement parameterInit in parameterInitCollection)
      {
        if (0 == String.Compare((string)parameterInit.Attribute("name"), pskPrefix + ":PageMediaSizePSWidth"))
        {
          IEnumerable<XElement> valueCollection = from c in parameterInit.Elements(psfNs + "Value")
          select c;
          valueCollection.ElementAt(0).Value = width;
        }
    
         else if (0 == String.Compare((string)parameterInit.Attribute("name"), pskPrefix + ":PageMediaSizePSHeight"))
        {
          IEnumerable<XElement> valueCollection = from c in parameterInit.Elements(psfNs + "Value")
          select c;
          valueCollection.ElementAt(0).Value = height;
         }
      }
    
      //
      // Write XLinq changes back to DOM
      //
       using (Stream ticketWriteStream = ticket.GetWriteStream())
       {
         ticketRootXElement.Save(ticketWriteStream);
       }
    }
    

Testing

Antes de testar seu aplicativo de dispositivo UWP, ele deve ser vinculado à impressora usando metadados do dispositivo.

  • Você precisa de uma cópia do pacote de metadados do dispositivo para sua impressora para adicionar as informações do aplicativo do dispositivo a ela. Se você não tiver metadados de dispositivo, poderá criá-los usando o Assistente para Criação de Metadados de Dispositivo conforme descrito no tópico Criar metadados de dispositivo para seu aplicativo de dispositivo UWP.

    Note

    Para usar o Device Metadata Authoring Wizard, você deve instalar o Microsoft Visual Studio Professional, o Microsoft Visual Studio Ultimate ou o SDK autônomo para Windows 8.1antes de concluir as etapas neste tópico. A instalação do Microsoft Visual Studio Express para Windows instala uma versão do SDK que não inclui o assistente.

As etapas a seguir criam seu aplicativo e instalam os metadados do dispositivo.

  1. Ative a assinatura de teste.

    1. Inicie o Assistente para Criação de Metadados de Dispositivo a partir do %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, clicando duas vezes em DeviceMetadataWizard.exe

    2. From the Tools menu, select Enable Test Signing.

  2. Reinicie o computador

  3. Crie a solução abrindo o arquivo de solução (.sln). Pressione F7 ou vá para Build ->Build Solution no menu superior após o carregamento do exemplo.

  4. Desconecte e desinstale a impressora. Esta etapa é necessária para que o Windows leia os metadados atualizados do dispositivo na próxima vez que o dispositivo for detetado.

  5. Edite e salve metadados do dispositivo. Para vincular o aplicativo de dispositivo ao seu dispositivo, você deve associá-lo ao seu dispositivo

    Note

    Se você ainda não criou os metadados do dispositivo, consulte Criar metadados de dispositivo para seu aplicativo de dispositivo UWP.

    1. Se o Assistente para Criação de Metadados de Dispositivo ainda não estiver aberto, inicie-o a partir do %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, clicando duas vezes em DeviceMetadataWizard.exe.

    2. Clique em para Editar Metadados do Dispositivo. Isso permitirá que você edite o pacote de metadados do dispositivo existente.

    3. In the Open dialog box, locate the device metadata package associated with your UWP device app. (It has a devicemetadata-ms file extension.)

    4. Na página Especificar informações do aplicativo de dispositivo UWP, insira as informações do aplicativo da Microsoft Store na caixa do aplicativo de dispositivo UWP. Clique em Importar ficheiro de manifesto da aplicação UWP para inserir automaticamente o Nome do pacote, o Nome do editore o ID da aplicação UWP.

    5. If your app is registering for printer notifications, fill out the Notification handlers box. In Event ID, enter the name of the print event handler. In Event Asset, enter the name of the file where that code resides.

    6. When you're done, click Next until you get to the Finish page.

    7. Na página Revisar o pacote de metadados do dispositivo, verifique que todas as configurações estão corretas e selecione a caixa de seleção Copiar o pacote de metadados do dispositivo para o armazenamento de metadados no computador local. Then click Save.

  6. Reconecte a impressora para que o Windows leia os metadados atualizados do dispositivo quando o dispositivo estiver conectado.

Troubleshooting

Problema: as configurações avançadas de impressão mostram o submenu padrão em vez do submenu personalizado

Se o submenu de configurações avançadas de impressão mostrar o submenu padrão em vez do submenu personalizado que seu aplicativo implementa...

  • Possible cause: Test signing is not turned on. Consulte a seção Depuração neste tópico para obter informações sobre como ativá-la.

  • Possible cause: The app is not querying for the right Package Family Name. Verifique o nome da família do pacote no seu código. Open up package.appxmanifest in Visual Studio and make sure that the package family name you are querying for matches the one in the Packaging tab, in the Package Family Name field.

  • Possible cause: The device metadata is not associated with the Package Family Name. Use o Device Metadata Authoring Wizard para abrir os metadados do dispositivo e verificar o nome da família do pacote. Start the wizard from %ProgramFiles(x86)%\Windows Kits\8.1\bin\x86, by double-clicking DeviceMetadataWizard.exe.

Problema: o aplicativo é iniciado no submenu e, em seguida, é imediatamente descartado

Se o menu deslizante personalizado para configurações avançadas de impressão desaparecer imediatamente após ser iniciado...

  • Possible cause: In Windows 8, there is a known issue that within a flyout, UWP apps will be dismissed under the debugger. Desligue a depuração assim que confirmar que a ativação está a funcionar. Se precisar depurar o salvamento do comprovativo de impressão, anexe o depurador após a ativação.