Compartilhar via


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.

  1. Inicialize a estrutura de dados PRINTDLG .
  2. Chame PrintDlg para exibir a caixa de diálogo Imprimir comum para o usuário.
  3. 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.
  4. Aloque um buffer de memória local grande o suficiente para conter uma cópia da estrutura DEVMODE .
  5. Copie a estrutura DEVMODE retornada para a alocada localmente.
  6. Salve outras informações retornadas na estrutura PRINTDLG e que você precisará processar o trabalho de impressão.
  7. 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.