Member Avatar for Member #1123523

Hi, I've been given a task of printing from a grid in VB6 and came across the article shown below.

https://www.daniweb.com/software-development/visual-basic-4-5-6/threads/431714/print-from-mshflexgrid-in-vb-6-0

I've implemented the code provided (re-typed, not copy/paste) and when I run it I get a run-time error 383 saying the printer properties are read only. For example, if I try to set the orientation to landscape by coding Ptr.Orientation = 2 the error tells me that the 'Orientation' property is read only. If I comment this line out, I get the same error on the next printer property, for example, Ptr.CurrentY.

I'm correctly identifying the default printer and do not get an error when setting the Ptr.Font.Name or Ptr.Font.Size.

I realise the original post is over two years old but I need to solve this problem if possible. Does anyone have any ideas as to what my code may be throwing these errors?

Thanks and best regards

Peter

Dani AI

Generated

This is a classic VB6 pitfall rather than a Service Pack bug. The symptoms you describe (Font.Name/Size works but Ptr.Orientation and Ptr.CurrentX/CurrentY raise runtime error 383) strongly indicate that Ptr is an item taken directly from the Printers collection — those collection entries expose read-only properties. To change printer settings you must make the chosen printer the active, writable Printer object first. PrinterCollection docs.

Quick, practical fix: assign the Printers() item to the global Printer object before changing orientation or coordinates. For example:

Set Printer = objPrinter    ' make the selected printer the writable Printer
Printer.Orientation = vbPRORLandscape

Or inside your routine call Set Printer = Ptr (where Ptr is the Printers(...) item) before you touch Orientation/CurrentX/CurrentY, then print and call Printer.EndDoc. The Print‑Dialog helper maps many dialog fields onto the writable Printer object; that mapping is what the PrintDlg/PrinterDlg code uses. (See the Microsoft HOWTO for the PrinterDlg mapping.)

A few extra notes: modifying Ptr.Font.Name worked because Font returns a StdFont object you can edit even when the parent Printers collection entry is read-only — that doesn't change the collection item itself. Also, some drivers ignore or reject particular properties (or behave differently across drivers), so if you still see errors or no effect after making the printer writable, the driver may not support that setting. If you post what GetDefaultPrinter actually returns (as asked) it will confirm whether you’re passing a Printers(...) item; since mentioned SP6, that’s not the likely cause if you already have SP6 installed.

References: Microsoft PrinterCollection documentation and Print‑Dialog KB (how properties map), and the note that drivers control which Printer properties are actually supported.

Recommended Answers

All 5 Replies

please post your code so we can check it.

Member Avatar for Member #1123523

Hi, it's on a different laptop so I'll post it when I get home in a few hours. Thanks

Member Avatar for Member #1123523

Here's the code. I get error 383 on any property referred to by the Ptr object

'-------------------------------------------------------------------------------------------------
' This routine is in a specific form
'-------------------------------------------------------------------------------------------------
Private Sub btnPrint_Click()
    Dim objPrinter As Printer
    Set objPrinter = GetDefaultPrinter
    PrintGridContents objPrinter, fgAddresses, 0, 0
    Set objPrinter = Nothing

End Sub

'-------------------------------------------------------------------------------------------------
' This routine is in a library of commonly used routines
'-------------------------------------------------------------------------------------------------
Public Sub PrintGridContents(ByVal Ptr As Object, ByVal GridName As Control, ByVal xmin As Single, ByVal ymin As Single)
    Const GAP = 60

    Dim xmax As Single
    Dim ymax As Single
    Dim X As Single
    Dim c As Integer
    Dim r As Integer

    With Ptr.Font
        .Name = GridName.Font.Name
        .Size = GridName.Font.Size
    End With

    Ptr.Orientation = 2

    With GridName
        xmax = xmin + GAP
        For c = 0 To .Cols - 1
            xmax = xmax + .ColWidth(c) + 2 * GAP
        Next c

        Ptr.CurrentY = ymin
        For r = 0 To .Rows - 1
            'Draw a line above this row
            If r > 0 Then Ptr.Line (xmin, Ptr.CurrentY)-(xmax, Ptr.CurrentY)
            Ptr.CurrentY = Ptr.CurrentY + GAP
            'Print the entries on this row
            X = xmin + GAP
            For c = 0 To .Cols - 1
                Ptr.CurrentX = X
                Ptr.Print BoundedText(Ptr, .TextMatrix(r, c), .ColWidth(c));
                X = X + .ColWidth(c) + 2 * GAP
            Next c
            Ptr.CurrentY = Ptr.CurrentY + GAP
            'Move to next line
            Ptr.Print
        Next r
        ymax = Ptr.CurrentY

        'Draw a box around everything
        Ptr.Line (xmin, ymin)-(xmax, ymax), , B

        'Draw lines between the columns
        X = xmin
            For c = 0 To .Cols - 2
            X = X + .ColWidth(c) + 2 * GAP
        Ptr.Line (X, ymin)-(X, ymax)
        Next c

    End With

    Ptr.EndDoc

End Sub

The Orientation property isn't available on VB6 by default (IICRC).

You need service pack 6 (maybe 5, not sure anymore), not the service pack from MS website.

Just search the web for the SPs.

Member Avatar for Member #1123523

I'm already running Service Pack 6, have been for many years. I have another function in my code that uses the Print Dialog and that let's me set the Orientation as shown in the following code so it has to be something obtuse, just don't know what that something is:

'-----------------------------------------------------------------------------------
' This is a working example using the Print Dialog
'-----------------------------------------------------------------------------------
Dim printDlg as PrinterDlg
Set printDlg = New printDlg
With printDlg
    .DriverName = Printer.DriverName
    .Port = Printer.Port
    .PrinterName = Printer.DeviceName
    .PaperBin = Printer.PaperBin
    If Orientation = "Landscape" Then
        .Orientation = 2
    Else
        .Orientation = 1
    End if
    .Copies = Copies        'The variable "Copies" is set elsewhere
    If Not .ShowPrinter (Me.hwnd) Then
        Exit Sub
    End if
End With
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.