Como: Estender o Esquema de Impressão e Criar Novas Classes de Sistema de Impressão

Quando seu aplicativo deve lidar com dispositivos de impressão especiais que têm características não refletidas pelas classes PrintSystemObject, PrintQueue, PrintCapabilities, e PrintTicket existentes, pode ser que você queira derivar novas classes por herança, criar versões estendidas das classes PrintCapabilities e PrintTicket, e possivelmente também estender o Print Schema. Este artigo descreve as principais partes de um tal projeto; mas ele descreve uma das muitas maneiras de estender as classes gerenciadas relevantes.

É recomendável que você leia este artigo em conjunto com a documentação abrangente do Print Schema. Este artigo pressupõe que você tenha pelo menos uma ideia básica do que é o esquema e o que são documentos PrintTicket e documentos PrintCapabilities.

Este artigo possui as seções a seguir.

  • Derive uma nova classe por herança

  • Determine se os recursos do dispositivo já estão definidos no esquema de impressão

  • Crie tipos para representar recursos de dispositivos

  • Estendendo as classes PrintCapabilities e PrintTicket

    • Estendendo a classe PrintTicket

    • Estendendo a classe PrintCapabilities

  • Lendo e escrevendo fluxos de XML com PrintCapabilities e PrintTicket

  • Sobrecarregando e estendendo propriedades e métodos

  • Expandindo recursos definidos pelo esquema

  • Estendendo o namespace System.Printing.IndexedProperties

Exemplo

O exemplo de projeto apresentado neste artigo não fornece todos os detalhes necessários para compilar e executar um aplicativo. Ele se destina a fornecer uma imagem apenas das principais etapas necessárias para estender a funcionalidade dos namespaces System.Printing e System.Printing.IndexedProperties para dispositivos de impressão que possuem recursos que não são explicitamente suportados nesses namespaces. Exemplos de código são fornecidos apenas onde detalhes concretos são necessários.

Além disso, os exemplos de código não necessariamente incluem técnicas de boas práticas de programação ou de código seguro. Tudo que não for imediatamente relevante para o assunto do artigo é omitido.

Finalmente, este artigo destina-se principalmente a desenvolvedores de aplicativos, e não a desenvolvedores de driver de dispositivo. Por esse motivo, a ênfase está na escrita de objetos PrintTicket, e não em objetos PrintCapabilities.

Derive uma nova classe por herança

Comece derivando uma classe para representar o dispositivo a partir da classe PrintQueue. Na exemplo de código abaixo, uma classe BrailleEmbosser é derivada. Braille é um idioma que é legível pelos cegos porque seus símbolos são compostos de "pontos" em relevo na superfície do papel de modo que eles podem ser sentidos com as pontas dos dedos. Um realçador Braille é simplesmente uma impressora que imprime em Braille. Alguns drivers para realçadores Braille conseguem converter Braille regular em Braille de Grau 3, às vezes chamado Braille 3, que é uma versão menos espaçosa de Braille que usa muitas contrações e abreviações. O exemplo fornece uma propriedade para representar este recurso.

Geralmente você também precisará sobrecarregar alguns propriedades e métodos herdados. Consulte Sobrecarregando e estendendo propriedades e métodos abaixo para mais detalhes.

class BrailleEmbosser : PrintQueue
{
   public BrailleEmbosser(PrintServer ps, String s, PrintSystemDesiredAccess access) : base(ps, s, access)
   {
      // Optionally, include here code to set non-inherited fields.
   }

   // other constructor declarations omitted

   private Boolean isBraille3Enabled;

   public Boolean IsBraile3Enabled
   {
      get { return isBraille3Enabled; }
      set { isBraille3Enabled = value; }
   }

   // remainder of class definition omitted
}

Determine se os recursos do dispositivo já estão definidos no esquema de impressão

As classes PrintTicket e PrintCapabilities têm propriedades que representam os recursos de impressora mais comuns, mas há muitos outros recursos definidos na especificação das Print Schema Public Keywords que não são explicitamente refletidas nessas classes. (Para ver uma lista dos recursos comuns, basta consultar as propriedades da classe PrintCapabilities.) Você deve ler a especificação para determinar se os recursos especiais do dispositivo são definidos ali. Para qualquer recurso é incluídas na especificação, há uma grande vantagem para a especificação modelo: um modelo e a terminologia comum, torna possível para documentos XML de PrintTicket criados para um dispositivo deve ser usado por outro. (O segundo dispositivo pode ter sido feito por um fabricante diferente e, na verdade, ele pode ter sido projetado depois da criação do documento PrintTicket.) Bilhetes de impressão podem ser incorporados nos próprios documentos para que as intenções do autor da impressão, bem como suas inteções de formatação, possam ser transportadas junto ao documento conforme ele é distribuído para pessoas com impressoras diferentes.

Para o restante deste artigo, recursos para os quais há suporte explícito por parte das classes PrintTicket e PrintCapabilities denominar-se-ão "recursos comuns". Aqueles que são definidos na especificação Print Schema Public Keywords, mas não são explicitamente suportados pelas duas classes, denominar-se-ão "recursos definidos". Recursos que não são definidos na especificação das palavras-chave públicas denominar-se-ão "novos recursos."

Também é possível que seu dispositivo tenha um recurso que é quase uma correspondência perfeita para um recurso definido, mas ele tem uma ou mais opções extras não reconhecidas na especificação das Print Schema Public Keywords. O Print Schema pode ser estendido para lidar com esses recursos de uma maneira que aproveita ao máximo a definição existente. Para mais informações sobre como trabalhar com esse um recurso, consulte Expandindo recursos definidos pelo esquema abaixo.

Crie tipos para representar recursos de dispositivos

As propriedades de PrintTicket e PrintCapabilities que correspondem aos recursos da impressora recebem tipos especiais, geralmente enumerações que representam um recurso e seus valores possíveis. A enumeração Collation por exemplo é o tipo para a propriedade PrintTicket.Collation. Ela também é o tipo dos membros da coleção que é a propriedade de tipo PrintCapabilities.CollationCapability.

Crie classes para os recursos definidos e novos do seu dispositivo usando essas classes existentes como modelos. No exemplo de código abaixo, uma enumeração BrailleGrade3 é declarada. Ele foi construído sobre o modelo do Collationenumeração porque a conversão de classificação 3 é semelhante a agrupar: Qualquer impressora teria que oferecem suporte a no mínimo um tipo de saída (uncollated ou agrupado) porque eles são mutuamente completos. Algumas impressoras aceitam os dois. (As impressoras que suportam apenas saída agrupada são raras, mas essa possibilidade tem que ser levada em conta.) Portanto, analogamente, pode haver realçadores que oferecem suporte somente à saída de Braille não traduzido, somente à saída traduzida (pouco provável, mas possível), ou ambos. A enumeração do BrailleGrade3 inclui um valor desconhecido de pelo mesmo Razão que Collationdá: para lidar com situações em que um aplicativo de produção de Documento de PrintTicket definiu o recurso de agrupamento para um valor que não é reconhecido no Print Schema Public Keywordsespecificação. Se seu aplicativo cria um objeto PrintTicket usando um documento assim, então a propriedade PrintTicket.Collation obterá o valor Unknown. (O valor Unknown nunca é usado pelos objetos PrintCapabilities.)

public enum BrailleGrade3 { Translated, Untranslated, Unknown } 

Enumerações nem sempre são a maneira recomendada para representar um recurso. Às vezes, uma classe de tipo de referência é melhor. Isso é especialmente válido quando o recurso possui uma estrutura aninhada de partes subordinadas onde cada uma tem seu próprio valor. Por exemplo, o PageMediaSizeclasse tem Heighte WidthPropriedades. PageMediaSizeé o tipo doPrintTicket.PageMediaSizepropriedade. Ela também é o tipo dos membros da coleção que é o tipo da propriedade PrintCapabilities.PageMediaSizeCapability.

Estendendo as classes PrintCapabilities e PrintTicket

Embora as classes PrintTicket e PrintCapabilities não possam ser herdadas, você pode estender o Print Schema para reconhecer recursos definidos e novos.

Estendendo a classe PrintTicket

Para usar a classe PrintTicket com o seu sistema estendido de recursos, siga as etapas a seguir. Alguns detalhes estão abaixo.

Procedimento de alto nível para estender a classe PrintTicket

  1. Se o dispositivo apresentar recursos novos, crie uma nova classe para encapsulá-los. (Consulte Criar uma classe NewFeaturesPrintTicket para alguns detalhes.)

  2. Se o dispositivo tiver recursos definidos, crie uma classe para encapsulá-los. (Consulte Criar uma classe DefinedFeaturesPrintTicket para alguns detalhes.)

  3. Crie uma classe para representar um bilhete de impressão inteiro. Essa classe desempenhará a função no aplicativo que a classe PrintTicket poderia desempenhar se o dispositivo não tivesser recursos definidos ou novos. (Consulte Criar uma classe WholePrintTicket para alguns detalhes.)

Procedimento para criar uma classe NewFeaturesPrintTicket

  1. Se o dispositivo apresentar recursos novos, crie uma nova classe para encapsulá-los. Vamos chamá-la NewFeaturesPrintTicket.

  2. Forneça novas propriedades à sua classe para representar os novos recursos do dispositivo. Em geral, cada propriedade será de um tipo que você criar, geralmente uma enumeração. Consulte Criar tipos para representar recursos de dispositivos acima.

  3. Forneça uma propriedade adicional à sua classe, vamos chamá-la PrivateNamespace, que armazenará uma referência para o namespace XML provado que define novos recursos do dispositivo. Você precisará dessa string ao escrever marcação XML para documentos PrintTicket e PrintCapabilities. Consulte Lendo e escrevendo fluxos XML de PrintCapabilities e PrintTicket abaixo.

  4. Faça com que a classe tenha dois construtores. Os construtores devem seguir o modelo dos dois construtores de PrintTicket. Um não recebe parâmetros, o outro utiliza um objeto Stream com conteúdo XML. O fluxo XML será um documento PrintTicket que define recursos novos, em vez de recursos comuns. (Consulte Print Schema-Related Technologies e PrintTicket Schema and Document Construction.) Os construtores com o parâmetro devem lançar exceções seguindo o padrão do construtor da classe PrintTicket que tem um parâmetro.

  5. Crie métodos GetXmlStream e SaveTo para a classe. Use a palavra-chave de acesso "internal" para ambos. Estas que servem para coincidir com a funcionalidade dos métodos de PrintTicket que também apresentam esses nomes, exceto pelo fato de que eles processam documentos PrintTicket que definem novos recursos em vez de recursos comuns. These methods must ensure that the streams they produce have an extra namespace declaration (the value of the PrivateNamespace property) in the opening <PrintTicket … > element. Consulte Lendo e escrevendo fluxos XML de PrintCapabilities e PrintTicket abaixo.

Procedimento para criar uma classe DefinedFeaturesPrintTicket

  • Se o dispositivo apresentar recursos definidos, crie uma nova classe para encapsulá-los. Vamos chamá-la DefinedFeaturesPrintTicket. Ela deve ser construída exatamente como é construída NewFeaturesPrintTicket acima, com as seguintes exceções.

    • As propriedades da classe devem ter nomes que correspondam ao nome de recurso correspondente na especificação Print Schema Public Keywords.

    • Não crie uma propriedade PrivateNamespace. O namespace para recursos definidos é o mesmo usado para os recursos comuns. Consulte Lendo e escrevendo fluxos XML de PrintCapabilities e PrintTicket abaixo.

    • Os métodos GetXmlStream e SaveTo não produzem os fluxos com uma declaração extra de namespace.

Procedimento para criar uma classe WholePrintTicket

  1. Declare uma classe que representará um bilhete de impressão inteiro e, portanto, executará a função no seu aplicativo que a classe PrintTicket teria executado se o dispositivo não tivesse recursos definidos ou novos. Vamos chamá-la WholePrintTicket.

  2. Dê uma propriedade a WholePrintTicket, vamos chamá-la CommonFeatures, do tipo PrintTicket.

  3. Dê à classe WholePrintTicket uma ou ambas as propriedades adicionais a seguir, dependendo se ele possui novos recursos, recursos definidos ou ambos.

    • NewFeatures do tipo NewFeaturesPrintTicket.

    • DefinedFeatures do tipo DefinedFeaturesPrintTicket.

  4. Dê dois construtores à classe WholePrintTicket. Um que não recebe parâmetros e um que utiliza um objeto Stream com conteúdo XML. O construtor com um parâmetro fará o seguinte.

    1. Passar o Stream para o construtor do objeto PrintTicket mencionado pela propriedade CommonFeatures. Esse construtor simplesmente irá ignorar qualquer marcação no Stream que não for relevante para recursos comuns.

    2. Passar o Stream para o construtor do objeto NewFeaturesPrintTicket mencionado pela propriedade NewFeatures. Esse construtor simplesmente irá ignorar qualquer marcação no Stream que não for relevante para recursos novos. Se houver qualquer novo recurso marcação, então o Stream começará com <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1" xmlns:namespace-abbreviation=full-namespace-name>, onde full-namespace-name é a URL usada para identificar o esquema que define os novos recursos e namespace-abbreviation é a sua abreviação. (Para obter mais informações, consulte Leitura e gravação de fluxos XML de PrintCapabilities e PrintTicket abaixo.).

    3. Passar o Stream para o construtor do objeto DefinedFeaturesPrintTicket mencionado pela propriedade DefinedFeatures. Esse construtor simplesmente irá ignorar qualquer marcação no Stream que não for relevante para recursos definidos.

  5. Crie métodos GetXmlStream e SaveTo para a classe. Elas destinam-se a coincidir com a funcionalidade dos métodos de PrintTicket com esses mesmos nomes. Eles devem ter as seguintes características.

    • Cada método desses deve chamar o método correspondente de mesmo nome nos objetos referenciados pela propriedade CommonFeatures, pela propriedade DefinedFeatures (se houver) e a propriedade NewFeatures (se houver).

    • Cada método deve concatenar os fluxos produzidos pelas chamadas descritas no item anterior. Of course, all but the last </PrintTicket> end tag, and all but the first <PrintTicket … > start tag, should be deleted. A menos que não haja nenhum novo recurso, a tag de início deve ter a declaração extra de namespace. (Consulte a etapa 4b). For that reason, you should consider always making the new features stream (when there is one) the first one in the concatenated stream since it will already have that declaration in its <PrintTicket … > start tag.

    • Para fazer a concatenação, os métodos GetXmlStream e SaveTo do WholePrintTicket precisarão trabalhar em um fluxo temporário internamente primeiro. Especificamente, eles farão com que as três diferentes classes serializem cada uma seu conteúdo no fluxo temporário, façam o trabalho de concatenação (e trabalho de poda - consulte próximo item) e, em seguida, emitam o resultado da concatenação no fluxo de saída final.

    • Após a concatenação, os métodos GetXmlStream e SaveTo de WholePrintTicket também terão que remover cópias duplicadas e triplicadas de elementos no fluxo antes de retornar o fluxo final. Essas entradas duplicadas e triplicadas estarão no fluxo porque os três objetos, PrintTicket, NewFeaturesPrintTicket e DefinedFeaturesPrintTicket, preservam todo o documento original PrintTicket que foi usado para construi-los, mesmo que cada um deles exponha apenas um subconjunto do documento em suas propriedades.

    • Você pode evitar a etapa de poda descrita no item anterior, se seu construtor WholePrintTicket(Stream) - consulte acima - dividir o fluxo de entrada em três partes criando fluxos separados para os elementos de marcação comuns, novos e definidos. Cada um desses fluxos menores é, em seguida, passado para o construtor apropriado das três propriedades de WholePrintTicket. Essa técnica exige que você adicione uma tag de fechamento </PrintTicket> para cada um dos três fluxos. O fluxo de CommonFeatures e propriedades de DefinedFeatures, você adiciona um Marca de Iniciar desta forma: <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">. A marca Iniciar para o construtor da propriedade NewFeatures adicionaria a isso um namespace particular adicional como este: <psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1" xmlns:abreviação do espaço para nome=nome de namespace Inteiro>, onde o nome de espaço para nome Inteiro de é a URL usada para identificar o esquema define os Nova recursos e a abreviação do espaço para nome de é a abreviação do mesmo.)

O seguinte exemplo de código mostra parte do resultado deste procedimento quando aplicado ao exemplo do realçador Braille. (Por questões de espaço e simplicidade, muitas partes foram omitidas.) Observe que a propriedade BrailleGrade3 é um tipo Nullable<T>. Isso segue o padrão das propriedades de PrintTicket, como Collation. O exemplo supõe que existem recursos novos e definidos, embora ele não especifique quaisquer recursos definidos.

class NewFeaturesPrintTicket
{
    public NewFeaturesPrintTicket()
    {
        // Optionally, initialize fields. For example:
        privateNamespace = "http://www.AjaxEmbossers.com/schemas/deluxemodels/v.1.0";
    }

    public NewFeaturesPrintTicket(Stream printTicketDocument)
    {
    // Parse the stream and initialize fields representing features here.
    // Optionally, initialize other fields. For example:
    privateNamespace = "http://www.AjaxEmbossers.com/schemas/deluxemodels/v.1.0";
    }

    private Nullable<BrailleGrade3> brailleGrade3;
    public Nullable<BrailleGrade3> BrailleGrade3
    {
        get { return brailleGrade3; }
        set { brailleGrade3 = value;}
    }

    private String privateNamespace;
    public String PrivateNamespace
    {
        get { return privateNamespace; }
        set { privateNamespace = value; }
    }
}

class DefinedFeaturesPrintTicket
{
  // Details omitted. Use the NewFeaturesPrintTicket
  // as a model, but leave out the privateNamespace field
  // and property.
}

class WholePrintTicket
{
    public WholePrintTicket()
    {
        commonFeatures = new PrintTicket();
        newFeatures = new NewFeaturesPrintTicket();
        definedFeatures = new DefinedFeaturesPrintTicket();
    }

    public WholePrintTicket(Stream wholePrintTicket)
    {
         // Method 1: Pass the stream to the three constructors.
         // Be sure to reset the read-write position of the stream
         // to the beginning of the stream after each call to a 
         // constructor. 
         // commonFeatures = new PrintTicket(wholePrintTicket);
              // reset read-write head here
        // newFeatures = new NewFeaturesPrintTicket(wholePrintTicket);
              // reset read-write head here
        // definedFeatures = new DefinedFeaturesPrintTicket(wholePrintTicket);
              // reset read-write head here

        // Method 2: Parse the stream and split it into three streams. 
        // Then pass them to the constructors of the three properties. 
        // commonFeatures = new PrintTicket(commonFeaturesPrintTicketDocument);
        // newFeatures = new NewFeaturesPrintTicket(newFeaturesPrintTicketDocument);
        // definedFeatures = new DefinedFeaturesPrintTicket(definedFeaturesPrintTicketDocument);
    }

    private PrintTicket commonFeatures;
    public PrintTicket CommonFeatures
    {
        get { return commonFeatures; }
        set { commonFeatures = value;}
    }

    private PrintTicket newFeatures;
    public PrintTicket NewFeatures
    {   // Details omitted. See CommonFeatures above.}

    private PrintTicket definedFeatures;
    public PrintTicket DefinedFeatures
    {   // Details omitted. See CommonFeatures above.}
}

Estendendo a classe PrintCapabilities

Para usar a classe PrintCapabilities com seu dispositivo, você precisará estendê-la de uma maneira que seja paralela a como você estendeu a classe PrintTicket. Uma vez que você pode utilizar a extensão de PrintTicket como um modelo, somente uma breve visão geral é apresentada aqui.

  • Crie três novas classes, uma para encapsular os novos recursos (NewFeaturesPrintCapabilities), uma para encapsular recursos definidos (DefinedFeaturesPrintCapabilities) e outra para representar um documento inteiro PrintCapabilities (WholePrintCapabilities).

  • Os tipos de propriedades das primeiras duas novas classes serão geralmente ReadOnlyCollection<T>. Use as propriedades existentes do PrintCapabilities (p.ex., CollationCapability) como modelos.

  • Também seguindo o padrão da classe PrintCapabilities existente, os nomes de propriedade devem ter "Capability" no final; por exemplo, BrailleGrade3Capability.

  • A classe NewFeaturesPrintCapabilities possuirá uma propriedade PrivateNamespace idêntica àquela que você criou para NewFeaturesPrintTicket.

  • Nenhuma das classes terá quaisquer métodos além dos que elas herdam da classe Object.

  • Cada uma das classes terá um construtor simples que recebe um parâmetro Stream. O Stream será um documento PrintCapabilities.

  • O construtor DefinedFeaturesPrintCapabilities deve validar que o Stream passado para ele esteja de acordo com o Print Schema Framework antes de usar o Stream para inicializar propriedades. (Uma maneira fácil para fazer isso é passar o Stream primeiro para o construtor PrintCapabilities. Se o último não gerar exceções, o fluxo é válido.)

  • O construtor NewFeaturesPrintCapabilities deve validar que o Stream passado para esteja de acordo com o namespace privado antes de usar o Stream para inicializar propriedades.

  • Ambos os construtores (DefinedFeaturesPrintCapabilities e NewFeaturesPrintCapabilities) lançarão exceções no padrão do construtor PrintCapabilities existente.

  • A classe WholePrintCapabilities terá propriedades CommonFeatures, DefinedFeatures, e NewFeatures. Os tipos dessas propriedades serão PrintCapabilities, DefinedFeaturesPrintCapabilities e NewFeaturesPrintCapabilties, respectivamente. Cada uma será construída sobre o padrão das propriedades de WholePrintTicket.

  • O construtor para a classe WholePrintCapabilities receberá um único parâmetro Stream que representa um documento inteiro PrintCapabilities. O construtor deve passar toda entrada Stream para todos os três construtores para suas propriedades membro. Como a classe WholePrintCapabilities não tem qualquer método que exporte suas configurações no formato XML (como os métodos GetXmlStream e SaveTo de WholePrintTicket ), o fato que haverá marcação duplicada ou triplicada dentro das três propriedades é inofensiva.

Para mais informações, consulte: PrintCapabilities Schema and Document Construction.

Lendo e escrevendo fluxos de XML com PrintCapabilities e PrintTicket

O trabalho principal dos construtores e métodos das classes PrintTicket e PrintCapabilities existentes e as novas classes criadas acima em Estendendo as classes PrintCapabilities e PrintTicket é ler, analisar, gravar e às vezes validar objetos Stream cujo conteúdo é um documento PrintTicket ou um documento PrintCapabilities. Você deve estar familiarizado com Arquivo básico de E/S e os métodos dessas classes. Uma vez que o conteúdo desses fluxos de for XML, você deve também familiarizar com o XML de leitura e gravação de suporte, descrito em XML Processing Options in the .NET Framework. Se seu aplicativo funcionará com XML Paper Specification (XPS)documentos, há APIno System.Windows.Xps, de System.Windows.Xps.Packaging, e System.Windows.Xps.Serializationespaços para nome criados para leitura e gravação em XPSdocumentos, incluindo a leitura e gravação de PrintTickets. Consulte também PackageRelationshippara obter Informação sobre como Adicionando uma relação com uma PrintTicketem um pacote.

Exemplos completos de um documento PrintTicket e um documento PrintCapabilities podem ser encontrados em PrintTicket Example e PrintCapabilities Document Example.

Veja a seguir um exemplo simples de um documento PrintCapabilities no qual todos os recursos do dispositivo -- exceto um deles -- foram omitidos. O recurso mostrado é DocumentCollate que é o recurso representado pelas propriedades PrintCapabilities.CollationCapability e PrintTicket.Collation.

<psf:PrintCapabilities xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">

   <!-- other features omitted --> 
   
   <psf:Feature name="psk:DocumentCollate">
        <psf:Property name="psf:SelectionType">
            <psf:Value xsi:type="xsd:QName">psk:PickOne</psf:Value>
        </psf:Property>
        <psf:Property name="psk:DisplayName">
            <psf:Value xsi:type="xsd:string">Collate Copies</psf:Value>
        </psf:Property>
        <psf:Option name="psk:Collated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">Yes</psf:Value>
            </psf:Property>
        </psf:Option>
        <psf:Option name="psk:Uncollated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">No</psf:Value>
            </psf:Property>
        </psf:Option>
    </psf:Feature>
                   
   <!-- other features omitted --> 
   
</PrintCapabilities>

Observe que cada opção possível do recurso está listada (agrupadas e não agrupadas) e o estado de cada uma (ou seja, se ela é restrita ou não) é identificado. Em um documento PrintCapabilities completo, o estado de cada opção de cada recurso é identificado, portanto, o documento é um tipo de retrato da configuração do dispositivo naquele momento.

Veja a seguir um exemplo simples de um documento PrintTicket que possui apenas um único recurso.

<psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1">
  
  <!-- other features omitted -->
  
  <psf:Feature name="psk:DocumentCollate">
    <psf:Option name="psk:Collated" />
  </psf:Feature>  
    
  <!-- other features omitted -->
  
</PrintTicket>

Observe que a estrutura pode ser um pouco mais simples porque não é necessário que um documento PrintTicket especifique explicitamente o estado de cada opção. Ele precisa apenas identificar a opção solicitada.

A sintaxe e a estrutura do recurso é definida em DocumentCollate pelo Print Schema Framework e as Print Schema Public Keywords. Quando você estiver trabalhando com os novos recursos, você estará trabalhando com recursos definidos um namespace XML privado definido em um esquema suplementar. Geralmente isso é fornecido pelo fabricante do dispositivo, por uma associação comercial, ou por uma organização de padrões sem fins lucrativos; mas pode ser você quem o cria. Use o Print Schema Framework existente e as Print Schema Public Keywords para aprender a sintaxe necessária e para localizar modelos sobre os quais você pode basear suas definições. A própria Microsoft criou um novo namespace para estender o sistema PrintCapabilities e PrintTicket para o novo driver Microsoft XPS Document Writer (MXDW). Para detalhes, consulte Configurações MXDW.

Se supormos que uma empresa fictícia AJAX Embosser tenha definido o recurso de tradução BrailleGrade3 de tal maneira que ele seja paralelo ao recurso de agrupamento de documentos da Microsoft, então podemos ver como ficariam as entradas de documento PrintTicket e PrintCapabilities do recurso. Observe que o namespace onde o recurso está definido deve ser declarado nas tags iniciais <PrintCapabilities …> e <PrintTicket …>.

A marcação do documento PrintCapabilities

<psf:PrintCapabilities xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           xmlns:ajax="http://www.AjaxEmbossers.com/schemas/deluxemodels" version="1">

   <!-- other features omitted --> 
   
   <psf:Feature name="ajax:BrailleGrade3Translation">
        <psf:Property name="psf:SelectionType">
            <psf:Value xsi:type="xsd:QName">psk:PickOne</psf:Value>
        </psf:Property>
        <psf:Property name="psk:DisplayName">
            <psf:Value xsi:type="xsd:string">Braille3 translation</psf:Value>
        </psf:Property>
        <psf:Option name="ajax:Translated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">Yes</psf:Value>
            </psf:Property>
        </psf:Option>
        <psf:Option name="ajax:Untranslated" constrained="psk:None">
            <psf:Property name="psk:DisplayName">
                <psf:Value xsi:type="xsd:string">No</psf:Value>
            </psf:Property>
        </psf:Option>
    </psf:Feature>
                   
   <!-- other features omitted --> 
   
</PrintCapabilities>

A marcação do documento PrintTicket

<psf:PrintTicket xmlns:psf="https://schemas.microsoft.com/windows/2003/08/printing/printschemaframework" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
           xmlns:ajax="http://www.AjaxEmbossers.com/schemas/deluxemodels" version="1">
  
  <!-- other features omitted -->
  
  <psf:Feature name="ajax:BrailleGrade3Translation">
    <psf:Option name="ajax:Translated" />
  </psf:Feature>  
    
  <!-- other features omitted -->
  
</PrintTicket>

Para mais informações sobre como escrever documentos PrintTicket que lidam com os recursos novos consulte Creating a Device-Specific PrintTicket. Para documentação abrangente sobre a criação de documentos PrintTicket e PrintCapabilities, consulte as seções PrintCapabilities Schema and Document Construction e PrintTicket Schema and Document Construction da documentação do Esquema de Impressão.

Sobrecarregando e estendendo propriedades e métodos

Qualquer método de qualquer classe que receber um parâmetro PrintTicket ou retorna um PrintTicket, e que você desejar usar com o seu sistema de recursos estendidos, terá que ser substituído por um método que usa WholePrintTicket no lugar de PrintTicket. Da mesma forma, as propriedades do tipo PrintTicket que você desejar usar precisarão ser substituídas por propriedades do tipo WholePrintTicket. Os mesmos pontos aplicam-se, mutatis mutandis, para PrintCapabilities e WholePrintCapabilities.

Quando a classe que hospeda o método ou propriedade for herdável, você pode derivar uma classe e sobrecarregar o método ou propriedade para usar WholePrintTicket no lugar de PrintTicket.

Se a classe de hospedagem não é hereditária, será necessário para estendê-lo de maneira PrintTickete PrintCapabilitiesforam Estendido acima: Crie uma classe que contém a classe de hospedagem sistema autônomo um membro. Em seguida, adicione métodos e propriedades à classe externa com os mesmos nomes que os métodos correspondentes que tenham (ou retornem) parâmetros PrintTicket ou PrintCapabilities. Normalmente, a funcionalidade da classe externa deve corresponder àquela da classe interna do mesmo nome, mas ela usará parâmetros WholePrintTicket ou WholePrintCapabilities em vez de parâmetros PrintTicket ou PrintCapabilities. Além disso, para propriedades da classe interna que são do tipo PrintTicket PrintCapabilities, crie uma propriedade correspondente de mesmo nome na classe externa que usa WholePrintTicket ou WholePrintCapabilities .

Provavelmente, os métodos mais importantes que você precisará sobrecarregar são as duas versões de MergeAndValidatePrintTicket. A classe BrailleEmbosser (consulte Derive uma nova classe por herança acima) precisará de substituições que usam parâmetros WholePrintTicket e que adicionam lógica para validar tickets com novos recursos contra o esquema do namespace privado. Você pode sobrecarregar os métodos existentes ou criar novos métodos chamados MergeAndValidateWholePrintTicket.

Dois métodos que retornam um PrintTicket são ConvertDevModeToPrintTicket e Clone. Em .NET Framework há 15 outros métodos, sem contar sobrecargas, que recebem um parâmetro PrintTicket e 19 propriedades do tipo PrintTicket. Mas é pouco provável que um aplicativo qualquer usará mais do que um pequeno número desses, portanto, sua carga de trabalho não será tão alta como esses números podem sugerir. Felizmente, o único método que retorna um objeto PrintCapabilities é GetPrintCapabilities e existem há propriedades com o tipo PrintCapabilities.

Expandindo recursos definidos pelo esquema

Recursos totalmente novos são não a única situação onde uma extensão do Print Schema pode ser necessária. Também é possível que um dispositivo irá oferecer opções novas e indefinidas para um recurso familiar e definido. Uma vez que um namespace particular deve ser usado para sistema autônomo novas opções indefinidas exatamente sistema autônomo deve ser usado para um recurso totalmente Nova, é provavelmente mais fácil tratar esses recursos Estendido sistema autônomo tratar inteiramente Nova recursos (mas usam sistema autônomo nomes definidos pelo esquema para o recurso e sistema autônomo de suas opções já definidas): colocá-los na sua NewFeaturesPrintTicket de e de NewFeaturesPrintCapabilities . Abordar todos os detalhes necessários para implementar esse tipo de extensão do esquema vai além do escopo deste artigo, mas observe que o trabalho de concatenação que deve ser feito pelos métodos WholePrintTicket.GetXmlStream e WholePrintTicket.SaveAs tornar-se-ia um pouco mais complicado.

Estendendo o namespace System.Printing.IndexedProperties

Se você desejar aproveitar as APIs no namespace System.Printing.IndexedProperties, você talvez precise derivar uma nova classe a partir de PrintProperty. Você precisaria fazer isso se a propriedade que você criou para a classe derivada de PrintQueue tiver um tipo que não seja representado por qualquer um das classes existentes em System.Printing.IndexedProperties. Para ver mais exemplos do que pode ser feito com o namespace System.Printing.IndexedProperties, consulte Como: Clonar uma impressora e Como: Get Print System Object Properties Without Reflection.

Isso não é necessário para o nosso exemplo acima, pois a única propriedade que adicionamos à nossa classe BrailleEmbosser é IsBraile3Enabled, que é um Boolean. Já existe uma classe System.Printing.IndexedProperties.PrintBooleanProperty.

Consulte também

Tarefas

Como: Clonar uma impressora

Como: Get Print System Object Properties Without Reflection

Referência

System.Printing

System.Printing.IndexedProperties

System.Printing.Interop

System.Windows.Xps

System.Windows.Xps.Packaging

System.Windows.Xps.Serialization

GetPrintCapabilities

PackageRelationship

PrintCapabilities

PrintQueue

PrintSystemObject

PrintTicket

Definição de Configuração MXDW

Conceitos

XML Processing Options in the .NET Framework

Documentos no WPF

Visão Geral de Impressão

Outros recursos

Esquema de Impressão

Estrutura de Esquema de Imprimir

Criando um PrintTicket específicas do dispositivo

As tecnologias relacionadas ao esquema de Imprimir

Esquema de PrintTicket e construção de documento

Exemplo de PrintTicket

Exemplo de documento PrintCapabilities

Esquema de PrintCapabilities e construção de documento

Palavras-chave Público do esquema de Imprimir

Microsoft XPS Document Writer