Share via


Procedura: Recuperare un contesto del dispositivo stampante

Questo argomento descrive come recuperare un contesto del dispositivo stampante. È possibile recuperare un contesto del dispositivo stampante chiamando direttamente la funzione CreateDC oppure può essere restituita da una finestra di dialogo Stampa comune.

Quando si visualizza una finestra di dialogo Stampa comune, un utente sarà in grado di selezionare la stampante, le pagine del documento e il numero di copie dei documenti da stampare. La finestra di dialogo Stampa comune restituisce queste selezioni in una struttura di dati.

Questo argomento descrive come ottenere un contesto del dispositivo stampante usando i metodi seguenti.

Chiamare CreateDC

Se si conosce il dispositivo a cui si vuole stampare, è possibile chiamare CreateDC e passare tali informazioni direttamente alla funzione. CreateDC restituisce un contesto del dispositivo in cui è possibile eseguire il rendering del contenuto da stampare.

La chiamata più semplice per recuperare un contesto del dispositivo è illustrata nell'esempio di codice seguente. Il codice in questo esempio recupera un contesto del dispositivo nel dispositivo di visualizzazione predefinito.

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

Per eseguire il rendering in una stampante specifica, è necessario specificare "WINSPOOL" come dispositivo e passare il nome corretto della stampante a CreateDC. È anche possibile passare una struttura DEVMODE nella chiamata a CreateDC se si desidera fornire dati di inizializzazione specifici del dispositivo per il driver di dispositivo quando si crea il contesto del dispositivo.

Nell'esempio seguente viene illustrata una chiamata a CreateDC in cui è selezionato il driver "WINSPOOL" e il nome della stampante viene specificato in base al nome.

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

È possibile ottenere la stringa esatta del nome della stampante da passare a CreateDC chiamando la funzione EnumPrinters . Nell'esempio di codice seguente viene illustrato come chiamare EnumPrinters e ottenere i nomi delle stampanti locali e connesse in locale. Poiché le dimensioni del buffer richiesto non possono essere note in anticipo, gli EnumPrinters vengono chiamati due volte. La prima chiamata restituisce le dimensioni del buffer richiesto. Queste informazioni vengono usate per allocare un buffer delle dimensioni necessarie e la seconda chiamata a EnumPrinters restituisce i dati desiderati.

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

Visualizzare una finestra di dialogo Stampa comune

È possibile scegliere tra due finestre di dialogo comuni di stampa da visualizzare a un utente; la finestra di dialogo più recente, che è possibile visualizzare chiamando la funzione PrintDlgEx e la finestra di dialogo stile precedente, che è possibile visualizzare chiamando la funzione PrintDlg . Le sezioni seguenti descrivono come chiamare ogni finestra di dialogo da un'applicazione.

Uso della funzione PrintDlgEx

Chiamare la funzione PrintDlgEx per visualizzare il foglio delle proprietà Print . Usando il foglio delle proprietà, l'utente può specificare informazioni sul processo di stampa. Ad esempio, l'utente può selezionare un intervallo di pagine da stampare, il numero di copie e così via. PrintDlgEx può anche recuperare un handle in un contesto di dispositivo per la stampante selezionata. È possibile usare l'handle per eseguire il rendering dell'output nella stampante.

Per il codice di esempio che illustra l'uso di PrintDlgEx per recuperare un contesto del dispositivo stampante, vedere "Uso del foglio delle proprietà di stampa" in Uso delle finestre di dialogo comuni.

Uso della funzione PrintDlg

Se l'applicazione deve essere eseguita in un sistema che non supporta la funzione PrintDlgEx, ad esempio in un sistema che esegue una versione di Windows precedente a Windows 2000 o non richiede la funzionalità aggiuntiva fornita dalla funzione PrintDlgEx, usare la funzione PrintDlgEx. I passaggi seguenti descrivono come visualizzare la finestra di dialogo Stampa comune stile precedente.

  1. Inizializzare la struttura di dati PRINTDLG .
  2. Chiamare PrintDlg per visualizzare la finestra di dialogo Stampa comune all'utente.
  3. Se la chiamata PrintDlg restituisce TRUE, bloccare la memoria della struttura DEVMODE restituita. Se la chiamata PrintDlg restituisce FALSE, l'utente ha premuto il pulsante Annulla nella finestra di dialogo Stampa comune in modo che non vi sia altro da elaborare.
  4. Allocare un buffer di memoria locale sufficiente per contenere una copia della struttura DEVMODE .
  5. Copiare la struttura DEVMODE restituita in quella allocata in locale.
  6. Salvare altre informazioni restituite nella struttura PRINTDLG e che sarà necessario elaborare il processo di stampa.
  7. Liberare PRINTDLG e i buffer di memoria a cui fa riferimento.

Il codice di esempio seguente illustra come usare la funzione PrintDlg per ottenere il contesto del dispositivo e il nome della stampante selezionata.

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

Per altre informazioni sulla funzione PrintDlg , vedere "Visualizzazione della finestra di dialogo stampa" in Uso di finestre di dialogo comuni.