cDialogPrint class

A cDialogPrint shows the Windows Print dialog, in which the user picks a printer, a range of pages and a number of copies. The class prints nothing: it returns the choices as properties and, by default, a device context for the printer the user chose, on which the program prints. It also describes the choice as a line of text.

Properties: AllowPageRange, AllowPrintToFile, AllowSelection, Cancelled, Collate, Copies, FromPage, hDC, HidePrintToFile, LastError, MaxPage, MinPage, OwnerHwnd, PrintRangeMode, PrintToFile, ReturnDC, ToPage. Methods: Reset, ShowDialog, ToDescription. Enumerations: PrintRange.

Create an object with Dim dlg As New cDialogPrint. The class is declared [COMCreatable(False)], so CreateObject cannot make one, and New can.

Private Declare PtrSafe Function PrDeleteDC Lib "gdi32" Alias "DeleteDC" (ByVal hDC As LongPtr) As Long

Private Sub ChooseAndPrint()
    Dim dlg As New cDialogPrint

    dlg.MinPage = 1
    dlg.MaxPage = 12
    dlg.FromPage = 1
    dlg.ToPage = 12
    If dlg.ShowDialog() Then
        Debug.Print dlg.ToDescription()
        ' ... print on dlg.hDC ...
        PrDeleteDC dlg.hDC
    ElseIf dlg.Cancelled Then
        Debug.Print "Cancelled"
    Else
        Debug.Print "Error " & dlg.LastError
    End If
End Sub

How the dialog is shown

ShowDialog calls PrintDlgW, the classic Print dialog, not the newer PrintDlgEx. The properties set these flags when they have the value shown: ReturnDC True (PD_RETURNDC), Collate True (PD_COLLATE), PrintToFile True (PD_PRINTTOFILE), AllowSelection False (PD_NOSELECTION), AllowPageRange False (PD_NOPAGENUMS), HidePrintToFile True (PD_HIDEPRINTTOFILE) and AllowPrintToFile False (PD_DISABLEPRINTTOFILE). PrintRangeMode adds PD_SELECTION or PD_PAGENUMS. The class passes no printer settings and sets no hook, template or help button. The dialog is modal and has the title Print; its printer is the default printer of the computer until the user changes it.

When the user chooses OK, ShowDialog stores the page range, the number of copies, the collate and print-to-file choices, the kind of range and, with ReturnDC, the device context in the properties, and returns True. Cancelled is then False. When the user chooses Cancel, or closes the dialog, it returns False and sets Cancelled to True, and the other properties are unchanged. When the call itself fails, it returns False, leaves Cancelled False and stores the error code in LastError.

The class frees the printer data that Windows allocates for the dialog. The printer that the user chose, its paper, its orientation and the other settings of its driver are therefore not returned as such. They are in the device context, which is set up for the chosen printer with its settings, so a program that needs to know them asks the context with the API function GetDeviceCaps.

Important

With ReturnDC True, which is the default, every OK creates a device context that the class never deletes. The program must delete it with the API function DeleteDC when it has finished with it, as the sample at the head of the page does, or set ReturnDC to False when it does not need the context. Reset, and a later ShowDialog that returns True, replace the handle without deleting the old context.

Note

The page numbers and the number of copies are passed to Windows as 16-bit integers. A FromPage, ToPage, MinPage, MaxPage or Copies that does not fit, one above 32,767 or one below -32,768, makes ShowDialog raise error 6, Overflow, before the dialog opens.

Properties

AllowPageRange

Whether the user may choose a range of pages.

Syntax: object.AllowPageRange [ = value ]

A Boolean, True by default. When it is False, ShowDialog sets PD_NOPAGENUMS, and the Pages button and the from and to boxes are shown disabled.

Dim dlg As New cDialogPrint

dlg.AllowPageRange = False
Debug.Print dlg.AllowPageRange

AllowPrintToFile

Whether the user may choose Print to file.

Syntax: object.AllowPrintToFile [ = value ]

A Boolean, True by default. When it is False, ShowDialog sets PD_DISABLEPRINTTOFILE, and the Print to file box is shown disabled. To remove the box, use HidePrintToFile.

Dim dlg As New cDialogPrint

dlg.AllowPrintToFile = False
Debug.Print dlg.AllowPrintToFile

AllowSelection

Whether the user may choose Selection.

Syntax: object.AllowSelection [ = value ]

A Boolean, True by default. When it is False, ShowDialog sets PD_NOSELECTION, and the Selection button is shown disabled. Set it to False when the program has no selection to print.

Dim dlg As New cDialogPrint

dlg.AllowSelection = False
Debug.Print dlg.AllowSelection

Cancelled

Whether the last ShowDialog ended because the user cancelled.

Syntax: object.Cancelled

A read-only Boolean, False by default. A ShowDialog that returns True sets it to False, one the user cancelled sets it to True, and one that failed sets it to False, so the three outcomes can be told apart with LastError.

Dim dlg As New cDialogPrint

If Not dlg.ShowDialog() Then
    If dlg.Cancelled Then Debug.Print "The user cancelled"
End If

Collate

Whether the copies are collated.

Syntax: object.Collate [ = value ]

A Boolean, False by default. When it is True, ShowDialog sets PD_COLLATE and the Collate box starts selected. The box is disabled while Copies is 1. After OK it holds the state the user left.

Dim dlg As New cDialogPrint

dlg.Copies = 3
dlg.Collate = True
Debug.Print dlg.ToDescription()

Copies

The number of copies.

Syntax: object.Copies [ = value ]

A Long, 1 by default. A value of 0 or less is ignored, without an error. The dialog shows it in the Number of copies box, and after OK it holds the number the user left. It must fit a 16-bit integer: see the note at the head of the page.

Dim dlg As New cDialogPrint

dlg.Copies = 3
dlg.Copies = 0          ' ignored
dlg.Copies = -2         ' ignored
Debug.Print dlg.Copies
' Output:
' 3

FromPage

The first page of the range.

Syntax: object.FromPage [ = value ]

A Long, 1 by default. It is the from box of the dialog. After a ShowDialog that returned True it holds the first page the user typed or left; when the user chose All or Selection, it keeps the value the dialog was given. It is meaningful when PrintRangeMode is PageRange.

Dim dlg As New cDialogPrint

dlg.MinPage = 1
dlg.MaxPage = 20
dlg.PrintRangeMode = PrintRange.PageRange
dlg.FromPage = 3
dlg.ToPage = 7
If dlg.ShowDialog() Then Debug.Print dlg.FromPage & "-" & dlg.ToPage

hDC

The device context of the chosen printer.

Syntax: object.hDC

A read-only LongPtr, 0 by default. After a ShowDialog that returned True with ReturnDC True, it holds a device context for the printer that the user chose, with the settings the user chose, and the program must delete it: see the note under How the dialog is shown. With ReturnDC False Windows returns no context and the property is 0. A cancelled or failed call leaves the property as it was.

Private Declare PtrSafe Function PrDeleteDC2 Lib "gdi32" Alias "DeleteDC" (ByVal hDC As LongPtr) As Long

Private Sub UseContext()
    Dim dlg As New cDialogPrint

    If dlg.ShowDialog() Then
        Debug.Print dlg.hDC <> 0
        PrDeleteDC2 dlg.hDC
    End If
End Sub

HidePrintToFile

Whether the dialog hides Print to file.

Syntax: object.HidePrintToFile [ = value ]

A Boolean, False by default. When it is True, ShowDialog sets PD_HIDEPRINTTOFILE, and the Print to file box is not shown.

Dim dlg As New cDialogPrint

dlg.HidePrintToFile = True
Debug.Print dlg.HidePrintToFile

LastError

The error code of the last call that failed.

Syntax: object.LastError

A read-only Long, 0 by default. When the call to Windows fails and the user did not cancel, ShowDialog stores the value of CommDlgExtendedError here. A later call that succeeds or is cancelled does not reset it; only Reset does.

Dim dlg As New cDialogPrint

If Not dlg.ShowDialog() Then
    If Not dlg.Cancelled Then Debug.Print "Failed: " & dlg.LastError
End If

MaxPage

The largest page number the user may enter.

Syntax: object.MaxPage [ = value ]

A Long, 9999 by default. It must fit a 16-bit integer: with 32,768 or more, ShowDialog raises error 6, Overflow.

Dim dlg As New cDialogPrint

dlg.MaxPage = 40000
On Error Resume Next
Debug.Print dlg.ShowDialog()
Debug.Print Err.Number
' Output:
' 6

MinPage

The smallest page number the user may enter.

Syntax: object.MinPage [ = value ]

A Long, 1 by default. It must fit a 16-bit integer, as MaxPage must.

Dim dlg As New cDialogPrint

dlg.MinPage = 1
dlg.MaxPage = 50
Debug.Print dlg.MinPage

OwnerHwnd

The window that owns the dialog.

Syntax: object.OwnerHwnd [ = value ]

A LongPtr window handle, 0 by default, which gives the dialog no owner. ShowDialog passes it as the owner window of the call. Reset does not change it.

Private Sub ChoosePrinter(ByVal ownerWindow As LongPtr)
    Dim dlg As New cDialogPrint

    dlg.OwnerHwnd = ownerWindow         ' the handle of a window of the program
    dlg.ReturnDC = False
    Debug.Print dlg.OwnerHwnd
    Debug.Print dlg.ShowDialog()
End Sub

PrintRangeMode

Which pages are printed.

Syntax: object.PrintRangeMode [ = value ]

A PrintRange, AllPages by default. It selects the button of the Print range group that the dialog starts with, and after OK it holds the button that was selected. PageRange uses FromPage and ToPage. A number that is not a member of PrintRange is passed without a flag, so the dialog starts with All, and ToDescription writes no range for it.

Dim dlg As New cDialogPrint

dlg.PrintRangeMode = PrintRange.Selection
Debug.Print dlg.ToDescription()

PrintToFile

Whether the output goes to a file.

Syntax: object.PrintToFile [ = value ]

A Boolean, False by default. When it is True, ShowDialog sets PD_PRINTTOFILE and the Print to file box starts selected. After OK it holds the state the user left. The class does not ask for a file name and does not print: it is for the program to send its output to a file when the property is True.

Dim dlg As New cDialogPrint

dlg.PrintToFile = True
Debug.Print dlg.ToDescription()

ReturnDC

Whether the dialog returns a device context for the chosen printer.

Syntax: object.ReturnDC [ = value ]

A Boolean, True by default. When it is True, ShowDialog sets PD_RETURNDC and hDC holds the context after OK. The program must delete the context: see the note under How the dialog is shown.

Dim dlg As New cDialogPrint

dlg.ReturnDC = False       ' the program only needs the page range
Debug.Print dlg.ReturnDC

ToPage

The last page of the range.

Syntax: object.ToPage [ = value ]

A Long, 1 by default. It is the to box of the dialog, and is handled as FromPage is.

Dim dlg As New cDialogPrint

dlg.FromPage = 2
dlg.ToPage = 5
Debug.Print dlg.ToPage

Methods

Reset

Restores the properties to their starting values.

Syntax: object.Reset

FromPage, ToPage, MinPage and Copies become 1, MaxPage 9999, PrintRangeMode AllPages, Collate, PrintToFile and HidePrintToFile False, the three Allow properties and ReturnDC True, hDC and LastError 0 and Cancelled False. It does not delete a device context, and it does not change OwnerHwnd.

Dim dlg As New cDialogPrint

dlg.Copies = 4
dlg.MaxPage = 40
dlg.PrintRangeMode = PrintRange.Selection
dlg.Reset
Debug.Print dlg.ToDescription()
Debug.Print dlg.MaxPage
' Output:
' All pages, 1 copy
' 9999

ShowDialog

Shows the Print dialog.

Syntax: object.ShowDialog ( ) As Boolean

Returns True when the user chose OK, and then the properties hold the choice. Returns False when the user cancelled (Cancelled is True) or when the call failed (LastError holds the code). It raises error 6 when a page number or the number of copies does not fit a 16-bit integer. It sends nothing to a printer. See How the dialog is shown.

Dim dlg As New cDialogPrint

dlg.ReturnDC = False
dlg.MinPage = 1
dlg.MaxPage = 20
dlg.PrintRangeMode = PrintRange.PageRange
dlg.FromPage = 3
dlg.ToPage = 7
If dlg.ShowDialog() Then
    Debug.Print dlg.ToDescription()
End If

ToDescription

Returns the choice as a line of text.

Syntax: object.ToDescription ( ) As String

The range, then the number of copies, then , Collated and , Print to file for each that is True. The range is All pages, Selection, or Pages followed by FromPage, - and ToPage. The copies are 1 copy or n copies.

Dim dlg As New cDialogPrint

Debug.Print dlg.ToDescription()
dlg.PrintRangeMode = PrintRange.PageRange
dlg.FromPage = 2
dlg.ToPage = 4
dlg.Copies = 3
dlg.Collate = True
dlg.PrintToFile = True
Debug.Print dlg.ToDescription()
' Output:
' All pages, 1 copy
' Pages 2 - 4, 3 copies, Collated, Print to file

Enumerations

PrintRange

Which pages are printed, the type of PrintRangeMode.

Member Value Meaning
AllPages 0 Every page.
Selection 1 The selection of the program.
PageRange 2 The pages from FromPage to ToPage.

The enumeration is declared inside the class. A program names its members with the name of the enumeration in front, as in the samples, or by the member alone, such as Selection. The name of the class cannot be put in front: cDialogPrint.PrintRange.Selection is refused with TB5079, Unrecognized symbol ‘cDialogPrint’.

See Also