如何:从用户收集打印作业信息

本主题介绍如何从用户那里收集打印作业信息。

概述

通过调用 PrintDlg 函数从用户收集打印作业信息。 此函数向用户显示 “打印 通用”对话框,并在 PRINTDLG 数据结构中返回打印作业信息。

当用户启动 打印 作业时,将显示“打印通用”对话框。 “打印通用”对话框是模式对话框,这意味着在公共对话框关闭之前,用户无法与main窗口交互。

收集打印作业信息

  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. 如果用户单击“打印通用”对话框中的“取消”按钮,则不会执行进一步的处理。