Cómo: Recuperar un contexto de dispositivo de impresora

En este tema se describe cómo recuperar un contexto de dispositivo de impresora. Puede recuperar un contexto de dispositivo de impresora llamando directamente a la función CreateDC , o bien puede devolverlo un cuadro de diálogo común Imprimir .

Al mostrar un cuadro de diálogo común Imprimir , un usuario podrá seleccionar la impresora, las páginas del documento y el número de copias de documento que desea imprimir. El cuadro de diálogo Imprimir común devuelve estas selecciones en una estructura de datos.

En este tema se describe cómo obtener un contexto de dispositivo de impresora mediante los métodos siguientes.

Llamar a CreateDC

Si conoce el dispositivo al que desea imprimir, puede llamar a CreateDC y pasar esa información directamente a la función. CreateDC devuelve un contexto de dispositivo en el que puede representar el contenido que se va a imprimir.

La llamada más sencilla para recuperar un contexto de dispositivo se muestra en el ejemplo de código siguiente. El código de este ejemplo recupera un contexto de dispositivo en el dispositivo de visualización predeterminado.

    hDC = CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);

Para representar en una impresora específica, debe especificar "WINSPOOL" como dispositivo y pasar el nombre correcto de la impresora a CreateDC. También puede pasar una estructura DEVMODE en la llamada a CreateDC si desea proporcionar datos de inicialización específicos del dispositivo para el controlador de dispositivo al crear el contexto del dispositivo.

En el ejemplo siguiente se muestra una llamada a CreateDC en la que se selecciona el controlador "WINSPOOL" y el nombre de la impresora se especifica por nombre.

    printerDC = CreateDC( L"WINSPOOL", printerName, NULL, NULL);

Puede obtener la cadena exacta de nombre de impresora que se va a pasar a CreateDC llamando a la función EnumPrinters . En el ejemplo de código siguiente se muestra cómo llamar a EnumPrinters y obtener los nombres de las impresoras locales y conectadas localmente. Dado que el tamaño del búfer necesario no se puede conocer de antemano, se llama a EnumPrinters dos veces. La primera llamada devuelve el tamaño del búfer necesario. Esa información se usa para asignar un búfer del tamaño necesario y la segunda llamada a EnumPrinters devuelve los datos que desea.

    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
        }
    }

Mostrar un cuadro de diálogo común de impresión

Puede elegir entre dos cuadros de diálogo comunes Imprimir para mostrar a un usuario; el cuadro de diálogo más reciente, que puede mostrar llamando a la función PrintDlgEx y al cuadro de diálogo estilo anterior, que puede mostrar llamando a la función PrintDlg . En las secciones siguientes se describe cómo llamar a cada cuadro de diálogo desde una aplicación.

Uso de la función PrintDlgEx

Llame a la función PrintDlgEx para mostrar la hoja de propiedades Print . Mediante el uso de la hoja de propiedades, el usuario puede especificar información sobre el trabajo de impresión. Por ejemplo, el usuario puede seleccionar un intervalo de páginas para imprimir, el número de copias, etc. PrintDlgEx también puede recuperar un identificador en un contexto de dispositivo para la impresora seleccionada. Puede usar el controlador para representar la salida en la impresora.

Para obtener código de ejemplo que muestra el uso de PrintDlgEx para recuperar un contexto de dispositivo de impresora, vea "Usar la hoja de propiedades de impresión" en Usar cuadros de diálogo comunes.

Uso de la función PrintDlg

Si la aplicación debe ejecutarse en un sistema que no admita la función PrintDlgEx , como en un sistema que ejecuta una versión de Windows anterior a Windows 2000, o no necesita la funcionalidad adicional que proporciona la función PrintDlgEx , use la función PrintDlg . En los pasos siguientes se describe cómo mostrar el cuadro de diálogo Común de impresión de estilo anterior.

  1. Inicialice la estructura de datos PRINTDLG .
  2. Llame a PrintDlg para mostrar el cuadro de diálogo Imprimir común al usuario.
  3. Si la llamada PrintDlg devuelve TRUE, bloquee la memoria de estructura DEVMODE devuelta. Si la llamada PrintDlg devuelve FALSE, el usuario presionó el botón Cancelar en el cuadro de diálogo Imprimir común para que no haya más que procesar.
  4. Asigne un búfer de memoria local lo suficientemente grande como para contener una copia de la estructura DEVMODE .
  5. Copie la estructura DEVMODE devuelta en la asignada localmente.
  6. Guarde otra información que se devuelva en la estructura PRINTDLG y que necesitará procesar el trabajo de impresión.
  7. Libere el PRINTDLG y los búferes de memoria a los que hace referencia.

En el código de ejemplo siguiente se muestra cómo usar la función PrintDlg para obtener el contexto del dispositivo y el nombre de la impresora seleccionada.

// 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 obtener más información sobre la función PrintDlg , vea "Mostrar el cuadro de diálogo imprimir" en Usar cuadros de diálogo comunes.