views:

89

answers:

1

I'm changing some crufty old printing code to use the Visual Basic Print Dialog Control to pass printer information to a CrystalReport object. It works great except for one thing - the page selection box is consistently disabled no matter what flags I pass the object. Here is my code:

Public Enum PrintDialogFlags
    NoFlag = 0
    DisablePagesButton = 1
    LoadIntoPrnObject = 2
    AutoStartPrint = 4
End Enum

Public Function ShowPrintDialogCR(ByVal hwnd As Long, ByRef cr As CrystalReport, _
        Optional PrintFlags As Long = 0) As Boolean

    //this function assumes cr is a valid report object
    On Error GoTo ShowPrintDialogCR_Error
    Dim PD As New vbprndlglib.PrinterDlg
    //load default settings
    PD.PrinterName = Printer.DeviceName
    PD.DriverName = Printer.DriverName
    PD.Port = Printer.Port
    PD.PaperBin = Printer.PaperBin
    PD.CancelError = True
    PD.flags = (vbprndlglib.cdlPDNoSelection Or vbprndlglib.cdlPDHidePrintToFile)
    // commented the line below out to see if it was something with my logic
    // Still disables page selection without this line
    //If PrintFlags And DisablePagesButton Then PD.flags = PD.flags Or vbprndlglib.cdlPDNoPageNums
    Printer.TrackDefault = False
    PD.ShowPrinter (hwnd)

    cr.PrinterPort = PD.Port
    cr.PrinterDriver = PD.DriverName
    cr.PrinterName = PD.PrinterName
    cr.CopiesToPrinter = PD.Copies
    If PD.flags And vbprndlglib.cdlPDPageNums Then
        cr.PrinterStartPage = PD.FromPage
        cr.PrinterStopPage = PD.ToPage
    End If
    If PrintFlags And PrintDialogFlags.LoadIntoPrnObject Then
        //copy these settings to the printer object
        Dim prn As Printer
        For Each prn In Printers
            If prn.DeviceName = PD.PrinterName Then
                Set Printer = prn
                Exit For
            End If
        Next prn
        Printer.PaperBin = PD.PaperBin
        Printer.PaperSize = PD.PaperSize
        Printer.Duplex = PD.Duplex
        Printer.Copies = PD.Copies
        Printer.ColorMode = PD.ColorMode
        Printer.Orientation = PD.Orientation
        Printer.PrintQuality = PD.PrintQuality
    End If
    Set PD = Nothing
    If PrintFlags And PrintDialogFlags.AutoStartPrint Then cr.Action = 1
    ShowPrintDialogCR = True
    Printer.TrackDefault = True
    Exit Function
ShowPrintDialogCR_Error:
    If Err.Number = 20545 Then //request cancelled by user
        MsgBox "The print request was cancelled after being submitted to the print spooler." & vbNewLine & _
            "If you cancelled a print to file dialog, this is a normal message. " & vbNewLine & _
            "Otherwise, this message could mean your printer is not accepting print requests from us at this time." _
            , vbOKOnly + vbExclamation, "Print Request Cancelled"
        ErrorLogger Err, "ShowPrintDialogCR"
    ElseIf Err.Number <> 32755 Then
        //something else besides clicking cancel, show the error
        MsgBox "Error " & Err.Number & " - " & Err.Description & vbNewLine & "Source: " & _
            Err.Source & vbNewLine & vbNewLine & "Document not printed.", vbOKOnly + vbCritical, "Print Failure"
        ErrorLogger Err, "ShowPrintDialogCR"
    End If
    Err.Clear
    ShowPrintDialogCR = False
    Printer.TrackDefault = False
End Function

I don't see what I'm doing wrong here. I've passed several combinations of unrelated flags just to see if the box would enable itself with no success. I've encountered VB6 quirks before and I'm really hoping this isn't one of them. Any help is much appreciated!

+1  A: 

I found this in the KB article you linked to:

To enable the Select Pages portion of the Print dialog box, Max must be set to a number that is larger than Min.

So, at the very least, you need to set the Min and Max properties on the print dialog object to something reasonable before you set the flags:

PD.CancelError = True

'Set Min and Max to enable page selection'
PD.Min = 1
PD.Max = 32767 'Or any large number really'

PD.flags = (vbprndlglib.cdlPDNoSelection Or vbprndlglib.cdlPDHidePrintToFile)

In my own experimenting I also found out the following few things:

  • If you just set Min and Max, the page selection will default both the "To" and "From" fields to 1.
  • If you set Min to 1 and Max to -1, and also set FromPage to 1 and ToPage to -1, the "From" field will default 1 and the "To" field will be empty. It's interesting that this works since the documentation states that Max must be larger than Min, but it looks like -1 is treated more like an "empty" or "null" value.
  • If you set the vbPrnDlg.cdlPageNums flag, the Print Dialog will default to the Pages radio button when it's displayed. If you omit the vbPrnDlg.cdlPageNums flag, the dialog will default to the All radio button.
Mike Spross
I knew I had to be missing something so obvious I looked right over it, LOL. I can't count the times I looked at that KB article and never saw that part. Thank you *SO* much, it works beautifully now!
Heather
Glad to help. I actually had to look at the article a few times before I saw that part, so you weren't the only one ;-)
Mike Spross