Partilhar via


Documentos multipágina

Este artigo descreve o protocolo de impressão do Windows e explica como imprimir documentos que contêm mais de uma página. O artigo aborda os seguintes tópicos:

O protocolo de impressão

Para imprimir um documento multipágina, a estrutura e a exibição interagem da maneira a seguir. Primeiro, a estrutura exibe a caixa de diálogo Imprimir, cria um contexto de dispositivo para a impressora e chama a função membro StartDoc do objeto CDC. Em seguida, para cada página do documento, a estrutura chama a função membro StartPage do objeto CDC, instrui o objeto de exibição a imprimir a página e chama a função membro EndPage. Se o modo de impressora precisar ser alterado antes de iniciar uma página específica, a exibição chamará ResetDC, que atualiza a estrutura DEVMODE que contém as novas informações do modo de impressora. Quando todo o documento tiver sido impresso, a estrutura chamará a função membro EndDoc.

Substituição de funções de classe de exibição

A classe CView define várias funções de membro que são chamadas pela estrutura durante a impressão. Ao substituir essas funções na classe de exibição, você fornece as conexões entre a lógica de impressão da estrutura e a lógica de impressão da classe de exibição. A tabela a seguir lista essas funções de membro.

Funções substituíveis do CView para impressão

Nome Motivo para substituição
OnPreparePrinting Para inserir valores na caixa de diálogo Imprimir, especialmente o tamanho do documento
OnBeginPrinting Para alocar fontes ou outros recursos de GDI
OnPrepareDC Para ajustar atributos do contexto de dispositivo para uma determinada página ou para fazer paginação em tempo de impressão
OnPrint Para imprimir uma determinada página
OnEndPrinting Para desalocar recursos de GDI

Você também pode fazer processamento relacionado à impressão em outras funções, mas essas funções são as que controlam o processo de impressão.

A figura a seguir ilustra as etapas envolvidas no processo de impressão e mostra onde cada uma das funções de membro de impressão da CView são chamadas. O restante deste artigo explica a maioria dessas etapas com mais detalhes. Partes adicionais do processo de impressão são descritas no artigo Alocar recursos de GDI.

Printing loop process.
O loop de impressão

Paginação

A estrutura armazena grande parte das informações sobre um trabalho de impressão em uma estrutura CPrintInfo. Vários dos valores em CPrintInfo pertencem à paginação e esses valores são acessíveis conforme mostrado na tabela a seguir.

Informações de número de página armazenadas na CPrintInfo

Variável de membro ou

nome(s) de função
Número da página referenciada
GetMinPage/SetMinPage Primeira página do documento
GetMaxPage/SetMaxPage Última página do documento
GetFromPage Primeira página a ser impressa
GetToPage Última página a ser impressa
m_nCurPage Página sendo impressa no momento

Os números de página começam em 1, ou seja, a primeira página é numerada com 1, e não com 0. Para obter mais informações sobre esses e outros membros da CPrintInfo, consulte a Referência do MFC.

No início do processo de impressão, a estrutura chama a função membro OnPreparePrinting do modo de exibição, passando um ponteiro para uma estrutura CPrintInfo. O Assistente de Aplicativo fornece uma implementação da OnPreparePrinting que chama DoPreparePrinting, outra função membro da CView. DoPreparePrinting é a função que exibe a caixa de diálogo Imprimir e cria um contexto de dispositivo de impressora.

Neste ponto, o aplicativo não sabe quantas páginas estão no documento. Ele usa os valores padrão 1 e 0xFFFF para os números da primeira e da última página do documento. Se você souber quantas páginas o documento tem, substitua OnPreparePrinting e chame [SetMaxPage]--brokenlink--(reference/cprintinfo-class.md#setmaxpage) para a estrutura CPrintInfo antes de enviá-la para DoPreparePrinting. Isso permite que você especifique o tamanho do documento.

DoPreparePrinting exibe a caixa de diálogo Imprimir. Quando retorna, a estrutura CPrintInfo contém os valores especificados pelo usuário. Se o usuário quiser imprimir apenas um intervalo selecionado de páginas, ele ou ela poderá especificar os números de página inicial e final na caixa de diálogo Imprimir. A estrutura recupera esses valores usando as funções GetFromPage e GetToPage daCPrintInfo. Se o usuário não especificar um intervalo de páginas, a estrutura chamará GetMinPage e GetMaxPage, e usará os valores retornados para imprimir o documento inteiro.

Para cada página de um documento a ser impresso, a estrutura chama duas funções de membro na classe de exibição, OnPrepareDC e OnPrint, e passa a cada função dois parâmetros: um ponteiro para um objeto CDC e um ponteiro para uma estrutura CPrintInfo. Cada vez que a estrutura chama OnPrepareDC e OnPrint, ela passa um valor diferente no membro m_nCurPage da estrutura CPrintInfo. Dessa forma, a estrutura informa ao modo de exibição qual página deve ser impressa.

A função membro OnPrepareDC também é usada para exibição em tela. Ela faz ajustes no contexto de dispositivo antes que o desenho seja feito. OnPrepareDC serve uma função semelhante na impressão, mas há algumas diferenças: primeiro, o objeto CDC representa um contexto de dispositivo de impressora em vez de um contexto de dispositivo de tela e, em segundo lugar, um objeto CPrintInfo é passado como um segundo parâmetro. (Esse parâmetro é NULL quando OnPrepareDC é chamada para exibição em tela.) Substitua OnPrepareDC para fazer ajustes no contexto de dispositivo com base em qual página está sendo impressa. Por exemplo, você pode mover a origem do visor e a área de recorte para garantir que a parte apropriada do documento seja impressa.

A função membro OnPrint executa a impressão real da página. O artigo Como a impressão padrão é feita mostra como a estrutura chama OnDraw com um contexto de dispositivo de impressora para realizar a impressão. Mais precisamente, a estrutura chama OnPrint com uma estrutura CPrintInfo e um contexto de dispositivo, e OnPrint passa o contexto do dispositivo para OnDraw. Substitua OnPrint para executar qualquer renderização que deve ser feita somente durante a impressão e não para exibição em tela. Por exemplo, para imprimir cabeçalhos ou rodapés (consulte o artigo Cabeçalhos e Rodapés para obter mais informações). Em seguida, chame OnDraw da substituição de OnPrint para fazer a renderização comum para exibição em tela e impressão.

O fato de OnDraw fazer a renderização para exibição em tela e impressão de significa que o aplicativo é WYSIWYG: "O que você vê é o que você obtém". No entanto, suponha que você não esteja gravando um aplicativo WYSIWYG. Por exemplo, considere um editor de texto que usa uma fonte em negrito para impressão, mas exibe códigos de controle para indicar texto em negrito na tela. Nessa situação, você usa OnDraw estritamente para exibição em tela. Ao substituir OnPrint, substitua a chamada para OnDraw por uma chamada para uma função de desenho separada. Essa função desenha o documento da maneira como ele aparece no papel, usando os atributos que não são exibidos na tela.

Páginas da impressora vs. páginas do documento

Quando você se refere a números de página, às vezes é necessário distinguir entre o conceito da impressora de uma página e o conceito do documento de uma página. Do ponto de vista da impressora, uma página é uma folha de papel. No entanto, uma folha de papel não é necessariamente igual a uma página do documento. Por exemplo, se você estiver imprimindo um boletim informativo, em que as folhas devem ser dobradas, uma folha de papel poderá conter a primeira e a última páginas do documento, lado a lado. Da mesma forma, se você estiver imprimindo uma planilha, o documento não consistirá em páginas. Em vez disso, uma folha de papel talvez contenha linhas de 1 a 20 e colunas de 6 a 10.

Todos os números de página na estrutura CPrintInfo se referem às páginas da impressora. A estrutura chama OnPrepareDC e OnPrint uma vez para cada folha de papel que passará pela impressora. Ao substituir a função OnPreparePrinting para especificar o tamanho do documento, você deve usar as páginas da impressora. Se houver uma correspondência um-para-um (ou seja, uma página da impressora é igual a uma página do documento), isso será fácil. Se, por outro lado, as páginas do documento e as páginas da impressora não corresponderem diretamente, você deverá mover entre elas. Por exemplo, considere imprimir uma planilha. Ao substituir OnPreparePrinting, você deve calcular quantas folhas de papel serão necessárias para imprimir a planilha inteira e, em seguida, usar esse valor ao chamar a função membro SetMaxPage da CPrintInfo. Da mesma forma, ao substituir OnPrepareDC, você deve mover m_nCurPage para o intervalo de linhas e colunas que aparecerão nessa planilha específica e, em seguida, ajustar a origem do visor adequadamente.

Paginação em tempo de impressão

Em algumas situações, a classe de exibição pode não saber com antecedência quanto tempo o documento permanece até que ele seja realmente impresso. Por exemplo, suponha que o aplicativo não seja WYSIWYG e, portanto, o tamanho de um documento na tela não corresponde ao seu tamanho quando impresso.

Isso causa um problema quando você substitui o OnPreparePrinting para a classe de exibição: não é possível passar um valor para a função SetMaxPage da estrutura CPrintInfo porque você não sabe o tamanho de um documento. Se o usuário não especificar um número de página no qual parar usando a caixa de diálogo Imprimir, a estrutura não saberá quando interromper o loop de impressão. A única maneira de determinar quando interromper o loop de impressão é imprimir o documento e ver quando ele termina. A classe de exibição deve verificar o fim do documento enquanto ele está sendo impresso e informar a estrutura quando o fim for alcançado.

A estrutura depende da função OnPrepareDC da classe de exibição para dizer quando parar a impressão. Após cada chamada para OnPrepareDC, a estrutura verifica um membro da estrutura CPrintInfo chamada m_bContinuePrinting. Seu valor padrão é TRUE. Enquanto permanecer assim, a estrutura continuará o loop de impressão. Se estiver definido como FALSE, a estrutura interromperá o loop. Para executar a paginação em tempo de impressão, substitua OnPrepareDC para verificar se o fim do documento foi alcançado e defina m_bContinuePrinting como FALSE quando ele tiver alcançado o fim.

A implementação padrão de OnPrepareDC define m_bContinuePrinting como FALSE se a página atual for maior que 1. Isso significa que, se o tamanho do documento não foi especificado, a estrutura pressupõe que o documento tem uma página. Uma consequência disso é que você deve ter cuidado se chamar a versão da classe base da OnPrepareDC. Não presuma que m_bContinuePrinting será TRUE depois de chamar a versão da classe base.

O que mais você deseja saber?

Confira também

Imprimindo
Classe CView
Classe CDC