Como recuperar um contexto de dispositivo de impressora
Este tópico descreve como recuperar um contexto de dispositivo de impressora. Você pode recuperar um contexto de dispositivo de impressora chamando a função CreateDC diretamente ou pode ser retornada por uma caixa de diálogo Imprimir comum.
Ao exibir uma caixa de diálogo Imprimir comum, um usuário poderá selecionar a impressora, as páginas do documento e o número de cópias de documento que deseja imprimir. A caixa de diálogo Imprimir comum retorna essas seleções em uma estrutura de dados.
Este tópico descreve como obter um contexto de dispositivo de impressora usando os métodos a seguir.
Chamar CreateDC
Se você souber o dispositivo para o qual deseja imprimir, poderá chamar CreateDC e passar essas informações diretamente para a função. CreateDC retorna um contexto de dispositivo no qual você pode renderizar o conteúdo a ser impresso.
A chamada mais simples para recuperar um contexto de dispositivo é mostrada no exemplo de código a seguir. O código neste exemplo recupera um contexto de dispositivo para o dispositivo de exibição padrão.
hDC = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
Para renderizar em uma impressora específica, você deve especificar "WINSPOOL" como o dispositivo e passar o nome correto da impressora para CreateDC. Você também pode passar uma estrutura DEVMODE na chamada para CreateDC se quiser fornecer dados de inicialização específicos do dispositivo para o driver de dispositivo ao criar o contexto do dispositivo.
O exemplo a seguir mostra uma chamada para CreateDC na qual o driver "WINSPOOL" está selecionado e o nome da impressora é especificado pelo nome.
printerDC = CreateDC( L"WINSPOOL", printerName, NULL, NULL);
Você pode obter a cadeia de caracteres de nome da impressora exata para passar para CreateDC chamando a função EnumPrinters . O exemplo de código a seguir mostra como chamar EnumPrinters e obter os nomes das impressoras locais e conectadas localmente. Como o tamanho do buffer necessário não pode ser conhecido com antecedência, os EnumPrinters são chamados duas vezes. A primeira chamada retorna o tamanho do buffer necessário. Essas informações são usadas para alocar um buffer do tamanho necessário e a segunda chamada para EnumPrinters retorna os dados desejados.
fnReturn = EnumPrinters(
PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
NULL,
1L, // printer info level
(LPBYTE)NULL,
0L,
&dwNeeded,
&dwReturned);
if (dwNeeded > 0)
{
pInfo = (PRINTER_INFO_1 *)HeapAlloc(
GetProcessHeap(), 0L, dwNeeded);
}
if (NULL != pInfo)
{
dwReturned = 0;
fnReturn = EnumPrinters(
PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
NULL,
1L, // printer info level
(LPBYTE)pInfo,
dwNeeded,
&dwNeeded,
&dwReturned);
}
if (fnReturn)
{
// Review the information from all the printers
// returned by EnumPrinters.
for (i=0; i < dwReturned; i++)
{
// pThisInfo[i]->pName contains the printer
// name to use in the CreateDC function call.
//
// When this desired printer is found in the list of
// returned printer, set the printerName value to
// use in the call to CreateDC.
// printerName = pThisInfo[i]->pName
}
}
Exibir uma caixa de diálogo Imprimir Comum
Você pode escolher entre duas caixas de diálogo Imprimir comum para exibir a um usuário; a caixa de diálogo mais recente, que você pode exibir chamando a função PrintDlgEx e a caixa de diálogo estilo mais antigo, que você pode exibir chamando a função PrintDlg . As seções a seguir descrevem como chamar cada caixa de diálogo de um aplicativo.
Usando a função PrintDlgEx
Chame a função PrintDlgEx para exibir a folha de propriedades Imprimir . Usando a folha de propriedades, o usuário pode especificar informações sobre o trabalho de impressão. Por exemplo, o usuário pode selecionar um intervalo de páginas para imprimir, o número de cópias e assim por diante. O PrintDlgEx também pode recuperar um identificador para um contexto de dispositivo para a impressora selecionada. Você pode usar o identificador para renderizar a saída na impressora.
Para obter um código de exemplo que ilustra o uso de PrintDlgEx para recuperar um contexto de dispositivo de impressora, consulte "Usando a folha de propriedades de impressão" em Usando caixas de diálogo comuns.
Usando a função PrintDlg
Se o aplicativo precisar ser executado em um sistema que não dê suporte à função PrintDlgEx , como em um sistema que esteja executando uma versão do Windows anterior ao Windows 2000 ou que não precise da funcionalidade extra que a função PrintDlgEx fornece, use a função PrintDlg . As etapas a seguir descrevem como exibir o estilo mais antigo Caixa de diálogo Imprimir comum.
- Inicialize a estrutura de dados PRINTDLG .
- Chame PrintDlg para exibir a caixa de diálogo Imprimir comum para o usuário.
- Se a chamada PrintDlg retornar TRUE, bloqueie a memória da estrutura DEVMODE retornada. Se a chamada PrintDlg retornar FALSE, o usuário pressionará o botão Cancelar na caixa de diálogo Imprimir comum para que não haja mais nada a processar.
- Aloque um buffer de memória local grande o suficiente para conter uma cópia da estrutura DEVMODE .
- Copie a estrutura DEVMODE retornada para a alocada localmente.
- Salve outras informações retornadas na estrutura PRINTDLG e que você precisará processar o trabalho de impressão.
- Libere o PRINTDLG e os buffers de memória que ele referencia.
O código de exemplo a seguir ilustra como usar a função PrintDlg para obter o contexto do dispositivo e o nome da impressora selecionada.
// Display the printer dialog box so the user can select the
// printer and the number of copies to print.
BOOL printDlgReturn = FALSE;
HDC printerDC = NULL;
PRINTDLG printDlgInfo = {0};
LPWSTR localPrinterName = NULL;
PDEVMODE returnedDevmode = NULL;
PDEVMODE localDevmode = NULL;
int localNumberOfCopies = 0;
// Initialize the print dialog box's data structure.
printDlgInfo.lStructSize = sizeof( printDlgInfo );
printDlgInfo.Flags =
// Return a printer device context.
PD_RETURNDC
// Don't allow separate print to file.
// Remove these flags if you want to support this feature.
| PD_HIDEPRINTTOFILE
| PD_DISABLEPRINTTOFILE
// Don't allow selecting individual document pages to print.
// Remove this flag if you want to support this feature.
| PD_NOSELECTION;
// Display the printer dialog and retrieve the printer DC.
printDlgReturn = PrintDlg(&printDlgInfo);
// Check the return value.
if (TRUE == printDlgReturn)
{
// The user clicked OK so the printer dialog box data
// structure was returned with the user's selections.
// Copy the relevant data from the data structure and
// save them to a local data structure.
//
// Get the HDC of the selected printer
printerDC = printDlgInfo.hDC;
// In this example, the DEVMODE structure returned by
// the printer dialog box is copied to a local memory
// block and a pointer to the printer name that is
// stored in the copied DEVMODE structure is saved.
//
// Lock the handle to get a pointer to the DEVMODE structure.
returnedDevmode = (PDEVMODE)GlobalLock(printDlgInfo.hDevMode);
localDevmode = (LPDEVMODE)HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
returnedDevmode->dmSize);
if (NULL != localDevmode)
{
memcpy(
(LPVOID)localDevmode,
(LPVOID)returnedDevmode,
returnedDevmode->dmSize);
// Save the printer name from the DEVMODE structure.
// This is done here just to illustrate how to access
// the name field. The printer name can also be accessed
// by referring to the dmDeviceName in the local
// copy of the DEVMODE structure.
localPrinterName = localDevmode->dmDeviceName;
// Save the number of copies as entered by the user
localNumberOfCopies = printDlgInfo.nCopies;
}
else
{
// Unable to allocate a new structure so leave
// the pointer as NULL to indicate that it's empty.
}
// Free the DEVMODE structure returned by the print
// dialog box.
if (NULL != printDlgInfo.hDevMode)
{
GlobalFree(printDlgInfo.hDevMode);
}
}
else
{
// The user cancelled out of the print dialog box.
}
Para obter mais informações sobre a função PrintDlg , consulte "Exibindo a caixa de diálogo Imprimir" em Usando caixas de diálogo comuns.