Практическое руководство. Сбор сведений о задании печати от пользователя

В этом разделе описывается сбор сведений о задании печати от пользователя.

Обзор

Сбор сведений о задании печати от пользователя путем вызова функции PrintDlg . Эта функция отображает пользователю общее диалоговое окно "Печать " и возвращает сведения о задании печати в структуре данных PRINTDLG .

При запуске задания печати отображается стандартное диалоговое окно " Печать ". Обычное диалоговое окно печати — это модальное диалоговое окно, которое означает, что пользователь не может взаимодействовать с главным окном до тех пор, пока общее диалоговое окно не будет закрыто.

Сбор сведений о задании печати

  1. Инициализируйте элемент структуры PRINTDLG .

    Прежде чем программа сможет отобразить общее диалоговое окно "Печать ", она должна выделить и инициализировать структуру PRINTDLG . Затем она передает эту структуру в функцию PrintDlg , которая отображает диалоговое окно и возвращает данные задания печати в той же структуре. В следующем примере кода показано, как выполняется этот шаг в примере программы.

    // Initialize the print dialog box's data structure.
    pd.lStructSize = sizeof( pd );
    pd.Flags = 
        // Return a printer device context
        PD_RETURNDC 
        // Don't allow separate print to file.
        | PD_HIDEPRINTTOFILE        
        | PD_DISABLEPRINTTOFILE 
        // Don't allow selecting individual document pages to print.
        | PD_NOSELECTION;
    
  2. Отображение общего диалогового окна "Печать ".

    Вызов PrintDlg с инициализированной структурой PRINTDLG для отображения общего диалогового окна "Печать " и сбора пользовательских данных, как показано в следующем примере кода.

    // Display the printer dialog and retrieve the printer DC
    pdReturn = PrintDlg(&pd);
    
  3. Сохраните поля из структуры PRINTDLG и запустите задание печати.

    Структура PRINTDLG содержит данные, описывающие выбранные пользователем параметры в диалоговом окне печати. Некоторые члены структуры PRINTDLG обрабатываются для объектов глобальной памяти. Программа "Пример печати" копирует данные из объектов глобальной памяти в блоки памяти, которыми программа управляет и копирует другие поля из структуры PRINTDLG в поля в структуре данных, определенной программой.

    После хранения данных из структуры PRINTDLG в структуре данных программы можно открыть диалоговое окно хода печати. Процедура выполнения печати обрабатывает сообщения диалогового окна и запускает поток обработки печати.

    В следующем примере кода показано, как скопировать данные из структуры PRINTDLG в структуру данных программы и как запустить задание печати.

    // A printer was returned so copy the information from 
    //  the dialog box structure and save it to the application's
    //  data structure.
    //
    //  Lock the handles to get pointers to the memory they refer to.
    PDEVMODE    devmode = (PDEVMODE)GlobalLock(pd.hDevMode);
    LPDEVNAMES  devnames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
    
    // Free any old devmode structures and allocate a new one and
    // copy the data to the application's data structure.
    if (NULL != threadInfo->devmode)
    {
        HeapFree(GetProcessHeap(), 0L, threadInfo->devmode);
    }
    
    threadInfo->devmode = (LPDEVMODE)HeapAlloc(
        GetProcessHeap(), 
        PRINT_SAMPLE_HEAP_FLAGS, 
        devmode->dmSize);
    
    if (NULL != threadInfo->devmode) 
    {
        memcpy(
            (LPVOID)threadInfo->devmode,
            devmode, 
            devmode->dmSize);
    }
    else
    {
        // Unable to allocate a new structure so leave
        // the pointer as NULL to indicate that it's empty.
    }
    
    // Save the printer name from the devmode structure
    //  This is to make it easier to use. It could be
    //  used directly from the devmode structure.
    threadInfo->printerName = threadInfo->devmode->dmDeviceName;
    
    // Set the number of copies as entered by the user
    threadInfo->copies = pd.nCopies;
    
    // Some implementations might support printing more than
    // one package in a print job. For this program, only
    // one package (XPS document) can be printed per print job.
    threadInfo->packages = 1;
    
    // free allocated buffers from PRINTDLG structure
    if (NULL != pd.hDevMode) GlobalFree(pd.hDevMode);
    if (NULL != pd.hDevNames) GlobalFree(pd.hDevNames);
    
    // Display the print progress dialog box
    DialogBox(
        threadInfo->applicationInstance, 
        MAKEINTRESOURCE(IDD_PRINT_DLG), 
        hWnd, 
        PrintDlgProc);
    
  4. Если пользователь нажимает кнопку "Отмена" в общем диалоговом окне "Печать ", дальнейшая обработка не выполняется.