Impressão de aplicativo da área de trabalho
Esta seção descreve como imprimir de um programa nativo da área de trabalho do Windows.
Visão geral
Para fornecer a melhor experiência do usuário quando você imprime de um programa nativo do Windows, o programa deve ser projetado para imprimir de um thread dedicado. Em um programa nativo do Windows, o programa é responsável por gerenciar eventos e mensagens da interface do usuário. As operações de impressão podem exigir períodos de computação intensa, pois o conteúdo do aplicativo é renderizado para a impressora, o que pode impedir que o programa responda à interação do usuário se esse processamento for executado no mesmo thread que o processamento de eventos da interação do usuário.
Se você já estiver familiarizado com como escrever um programa nativo do Windows com vários threads, vá diretamente para Como imprimir de um aplicativo do Windows e saiba como adicionar funcionalidade de impressão ao seu programa.
Requisitos básicos do Programa Windows
Para obter melhor desempenho e capacidade de resposta do programa, não execute o processamento de trabalho de impressão de um programa no thread que processa a interação do usuário.
Essa separação da impressão da interação do usuário influenciará como o programa gerencia os dados do aplicativo. Você deve entender detalhadamente essas implicações antes de começar a escrever o aplicativo. Os tópicos a seguir descrevem os requisitos básicos de manipulação da impressão em um thread separado de um programa.
Noções básicas do Programa windows
Um programa nativo do Windows deve fornecer o procedimento de janela main para processar as mensagens de janela recebidas do sistema operacional. Cada janela em um programa do Windows tem uma função WndProc correspondente que processa essas mensagens de janela. O thread no qual essa função é executada é chamado de interface do usuário, ou interface do usuário, thread.
Use recursos para cadeias de caracteres.
Use recursos de cadeia de caracteres do arquivo de recurso do programa em vez de constantes de cadeia de caracteres para cadeias de caracteres que talvez precisem ser alteradas quando você der suporte a outro idioma. Antes que um programa possa usar um recurso de cadeia de caracteres como uma cadeia de caracteres, o programa deve recuperar o recurso do arquivo de recurso e copiá-lo para um buffer de memória local. Isso requer alguma programação adicional no início, mas permite uma modificação, tradução e localização mais fáceis do programa no futuro.
Processar dados em etapas.
Processe o trabalho de impressão em etapas que podem ser interrompidas. Esse design possibilita que o usuário cancele uma longa operação de processamento antes de ser concluída e impede que o programa bloqueie outros programas que possam estar em execução ao mesmo tempo.
Usar dados do usuário da janela.
Os aplicativos de impressão geralmente têm várias janelas e threads. Para manter os dados disponíveis entre threads e as etapas de processamento sem usar variáveis globais estáticas, faça referência às estruturas de dados por um ponteiro de dados que faz parte da janela na qual eles são usados.
O exemplo de código a seguir mostra um ponto de entrada main para um aplicativo de impressão. Este exemplo mostra como usar recursos de cadeia de caracteres em vez de constantes de cadeia de caracteres e também mostra o loop de mensagem main que processa as mensagens de janela do programa.
int APIENTRY
wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nCmdShow
)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
MSG msg;
HACCEL hAccelTable;
HRESULT hr = S_OK;
// Register the main window class name
WCHAR szWindowClass[MAXIMUM_RESOURCE_STRING_LENGTH];
LoadString(
hInstance,
IDC_PRINTSAMPLE,
szWindowClass,
MAXIMUM_RESOURCE_STRING_LENGTH);
MyRegisterClass(hInstance, szWindowClass);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
// Unable to initialize this instance of the application
// so display error message and exit
MessageBoxWithResourceString (
hInstance,
GetDesktopWindow(),
IDS_ERROR_INSTINITFAIL,
IDS_CAPTION_ERROR,
(MB_OK | MB_ICONEXCLAMATION));
return FALSE;
}
// Init COM for printing interfaces
if (FAILED(hr = CoInitializeEx(0, COINIT_MULTITHREADED)))
{
// Unable to initialize COM
// so display error message and exit
MessageBoxWithResourceString (
hInstance,
GetDesktopWindow(),
IDS_ERROR_COMINITFAIL,
IDS_CAPTION_ERROR,
(MB_OK | MB_ICONEXCLAMATION));
return FALSE;
}
hAccelTable = LoadAccelerators(
hInstance,
MAKEINTRESOURCE(IDC_PRINTSAMPLE));
// Main message handling loop
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Uninitialize (close) the COM interface
CoUninitialize();
return (int) msg.wParam;
}
Informações do documento
Os programas nativos do Windows que imprimem devem ser projetados para processamento multi-threaded. Um dos requisitos de um design de vários threads é proteger os elementos de dados do programa para que eles sejam seguros para vários threads usarem ao mesmo tempo. Você pode proteger elementos de dados usando objetos de sincronização e organizando os dados para evitar conflitos entre os threads. Ao mesmo tempo, o programa deve impedir alterações nos dados do programa enquanto ele está sendo impresso. O programa de exemplo usa várias técnicas de programação de vários threads diferentes.
Eventos de sincronização
O programa de exemplo usa eventos, identificadores de thread e funções de espera para sincronizar o processamento entre o thread de impressão e o programa main e para indicar que os dados estão em uso.
Mensagens do Windows específicas do aplicativo
O programa de exemplo usa mensagens de janela específicas do aplicativo para tornar o programa mais compatível com outros programas nativos do Windows. Dividir o processamento em etapas menores e enfileirar essas etapas no loop de mensagem de janela facilita o gerenciamento do processamento do Windows sem bloquear outros aplicativos que também podem estar em execução no computador.
Estruturas de dados
O programa de exemplo não é escrito em um estilo orientado a objetos usando objetos e classes, embora agrupe elementos de dados em estruturas de dados. O exemplo não usa uma abordagem orientada a objetos para evitar implicar que uma abordagem é melhor ou pior do que outra.
Você pode usar as funções e estruturas de dados do programa de exemplo como ponto de partida ao projetar seu programa. Se você decidir criar um programa orientado a objetos ou não, a importante consideração de design a ser lembrada é agrupar os elementos de dados relacionados para que você possa usá-los com segurança em threads diferentes, conforme necessário.
Contexto do dispositivo da impressora
Ao imprimir, talvez você queira renderizar o conteúdo a ser impresso em um contexto de dispositivo. Como recuperar um contexto de dispositivo de impressora descreve as diferentes maneiras de obter um contexto de dispositivo de impressora.
Tópicos relacionados
Como imprimir de um aplicativo do Windows