KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q132909: HOWTO: Customize the Common Print Dialog Box

Article: Q132909
Product(s): Microsoft C Compiler
Version(s): 1.0,1.5,1.51,1.52,2.0,2.1,2.2,4.0,4.1,4.2,5.0,6.0
Operating System(s): 
Keyword(s): kbcode kbProgramming kbprint kbMFC kbPrinting kbVC100 kbVC150 kbVC200 kbVC400 kbVC410 k
Last Modified: 26-JUL-2002

-------------------------------------------------------------------------------
The information in this article applies to:

- The Microsoft Foundation Classes (MFC), used with:
   - Microsoft Visual C++ for Windows, 16-bit edition, versions 1.0, 1.5, 1.51, 1.52 
   - Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 2.2, 4.0, 4.1 
   - Microsoft Visual C++, 32-bit Enterprise Edition, versions 4.2, 5.0, 6.0 
   - Microsoft Visual C++, 32-bit Professional Edition, versions 4.2, 5.0, 6.0 
   - Microsoft Visual C++, 32-bit Learning Edition, version 6.0 
-------------------------------------------------------------------------------

SUMMARY
=======

This article explains how to modify and use the standard print dialog box in a
typical MFC application. Customizing the print dialog box involves modifying the
Microsoft Windows default common print dialog box template. When you customize
the common print dialog box, you can add new controls and remove existing
controls.

MORE INFORMATION
================

In some situations, you may find it necessary to customize the standard print
dialog box. This involves modifying the existing print dialog box template and
modifying the view implementation of printing to use this customized template.

Step-by-Step Procedure
----------------------

To implement a customized print dialog box, follow these steps:

1. Copy the PRINTDLGORD dialog box template (the ID is 1538) from Commdlg.rc to
  your application .rc file. In Visual C++ 4.x and 5.0, this dialog box
  template resides in the file Include\Prnsetup.dlg. In Visual C++ 6.0, you can
  find this file in \Samples\Vc98\Mfc\General\Clipart on the MSDN CD. To do
  this:

  a. Open Commdlg.rc in the Visual C++ .NET development environment. This file
     can be found in the directory \Samples\Vc\Mfc\General\Clipart on the
     distribution CDs.

  b. Enable cut-and-pasting of resources in your project resource file:

     a. Open your project .rc file in Resource Editor mode (instead of the
        default Resource View mode). To do this, close the Resource View window
        of your project. Find your project .rc file in the Solution Explorer
        window. Right-click the .rc file in the Solution Explorer window, and
        then click Open With. In the Open With dialog box, click to select
        Resource Editor as the program to open the .rc file with, and then
        click Open.

     b. If you are using Visual C++ 4.x or 5.0, add the line #include
        "windows.h" to the top of the file Include\prnsetup.dlg. Save and close
        this file. Reopen it as "Resources" by using the Open As box in the
        File Open dialog box.

  c. In the Resource Editor window of the Commdlg.rc file, right-click the
     PRINTDLGORD dialog resource, and then click Copy. The PRINTDLGORD ID is
     1538. This PRINTDLGORD symbol is defined in the header file Dlgs.h.

  d. In the Resource Editor window of your project .rc file, right-click Dialog
     and then click Paste. Now, save and close the project .rc file in the
     Resource Editor window, and then reopen the default Resource View window
     of your project.

If you are using Visual C++ 6.0, there are no context menus for copying
resources. On the File menu, click Open to open the Commdlg.rc file, and then
open the Resource View menu for your project. Select the 1538 resource ID in
Commdlg.rc, hold down the CTRL key, and then drag the dialog box resource from
the Commdlg.rc window to your Resource View window.
2. On the Project menu, click Add Class. (Note that the Add Class menu is
  context-sensitive, and does not appear when the Resource View is active.
  Switch to Solution Explorer before you select Add Class on the Project menu).
  Click to select the MFC category and the MFC class template, and then click
  Open. Use the MFC Class Wizard to add a Visual C++ class (such as
  CMyPrintDialog) for this dialog box template. Derive this new class from
  CPrintDialog.

3. Change all references from CDialog to CPrintDialog in both the header and
  implementation file of the newly-created class. Note that this step is not
  necessary if you have derived your class directly from CPrintDialog.

4. Because the constructor of CPrintDialog differs from CDialog, modify the
  constructor of CMyPrintDialog by using the following code:

NOTE: This step is not necessary if you have derived your class directly from
CPrintDialog.

        // Header file of CMyPrintDialog.
        class CMyPrintDialog : public CPrintDialog
        {
        // Construction.
        public:

        // The arguments to the following constructor closely match
        // CPrintDialog. Note the difference in the second argument.
        CMyPrintDialog(BOOL bPrintSetupOnly,
                       // TRUE for Print Setup, FALSE for Print Dialog.
                         DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES |
                                      PD_HIDEPRINTTOFILE,
                       // Combination of flags. Refer to the Windows SDK
                       // documentation for PRINTDLG structure for a
                       // description of all the flags that can be used.
                          CWnd* pParentWnd = NULL);

        // Rest of the class declaration.
        ...

        DECLARE_MESSAGE_MAP()
        };

        // Implementation file of CMyPrintDialog.
        CMyPrintDialog::CMyPrintDialog(BOOL bPrintSetupOnly,
          DWORD dwFlags /* = PD_ALLPAGES | PD_USEDEVMODECOPIES |
                        PD_HIDEPRINTTOFILE */,
          CWnd* pParentWnd /* = NULL */)
          : CPrintDialog(bPrintSetupOnly, dwFlags, pParentWnd)
        {
          //{{AFX_DATA_INIT(CMyPrintDialog)
          // NOTE: the ClassWizard will add member initialization here.
          //}}AFX_DATA_INIT
        }
   

5. Make any desired changes to the copied dialog box template and associated
  source code.

NOTE: Do not delete any of the controls that are present in the original dialog
box template. Deleting the controls causes problems in the DoDataExchange
function of CPrintDialog. Instead, either disable the unwanted controls or hide
them in an overridden OnInitDialog member function of your CPrintDialog-derived
class.
6. Modify the CView-derived class (for example, CMyView) to use the customized
  print dialog box by using the following code:

        //  Implementation file of the view (for example, in myview.cpp).
        ...
        #include "MyPrintDialog.h"  // Include the CMyPrintDialog header file.
        ...

        // Override OnPreparePrinting of the CView-derived class as below:
        BOOL CMyView::OnPreparePrinting(CPrintInfo* pInfo)
        {
           // Delete the CPrintDialog object created in the CPrintInfo
           // constructor, and substitute with customized print dialog.
           delete pInfo->m_pPD;

           // Construct and substitute with customized print dialog.
           pInfo->m_pPD = new CMyPrintDialog(FALSE);

           // Set the page range.
           pInfo->m_pPD->m_pd.nMinPage = 1;      // one based page numbers.
           pInfo->m_pPD->m_pd.nMaxPage = 0xffff; // how many pages is unknown.

           // Change the PRINTDLG struct so that the custom print dialog box will
           // be used.
           pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
           pInfo->m_pPD->m_pd.lpPrintTemplateName =
                                                MAKEINTRESOURCE(1538);

           // Set the Flags of the PRINTDLG structure as shown, else the
           // changes will have no effect.
           pInfo->m_pPD->m_pd.Flags |= PD_ENABLEPRINTTEMPLATE;

           // For details about these flags, refer to the SDK documentation
           // on the PRINTDLG structure.

           return DoPreparePrinting(pInfo);
        }

REFERENCES
==========

For more information, see the PRINTDLG structure in the Windows SDK
documentation and the "OnPreparePrinting" and "CPrintDialog" topics in the
Foundation Class documentation.

Additional query words: CFileDialog

======================================================================
Keywords          : kbcode kbProgramming kbprint kbMFC kbPrinting kbVC100 kbVC150 kbVC200 kbVC400 kbVC410 kbVC420 kbVC500 kbVC600 kbFAQ kbDSupport kbGrpDSMFCATL 
Technology        : kbAudDeveloper kbMFC
Version           : :1.0,1.5,1.51,1.52,2.0,2.1,2.2,4.0,4.1,4.2,5.0,6.0
Issue type        : kbhowto

=============================================================================

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.