• VB/VBA code to change HP Printer settings? (Word 2000)

    Home » Forums » AskWoody support » Productivity software by function » Visual Basic for Applications » VB/VBA code to change HP Printer settings? (Word 2000)

    Author
    Topic
    #371005

    Last year you kind folks helped me create a word macro that set paper tray settings based on the default printer ( see post #58637 ).

    The macro works great, except for one situation. If a user changes paper from letter size to legal size, the HP printer senses that and changes the default inside the printer to “Paper Size = Legal”. The next time someone uses my macro, it pulls from the wrong bin because the proper bin has the wrong paper size set inside of the printer setup.

    I’ve tried sending a new VBA papersize command, but this does not change the printer’s internal default. So, my question is: does anyone have any idea how to send a command to a HP printer that would reset the HP printer’s internal settings?

    I’ve posted this at the HP forum but no answers … hoping someone here might have some ideas.

    Thanks for any help!

    Andrew

    Viewing 0 reply threads
    Author
    Replies
    • #588531

      I don’t have the answer, but we have had a terrible problem with paper size changes on the manual feed tray of an HP 4050TN. It sometimes thinks it has letter, sometimes A4, sometimes envelopes. It sometimes changes back after printing and sometimes doesn’t. Our IT folks could not find a software solution, but told us that it is a problem with the PCL drivers and tried to switch everyone to PostScript drivers. I’m not sure it worked…

      I wonder if you could debug this by using print to file and looking at the codes Word is sending to the printer to change the paper size?

      • #589036

        I know there were some problems with the HP4050 … interestingly, I heard of a fix that involves getting the firmware on the HP printer updated. It addresses just what you were saying was happening. Supposed to be free if printer is still under warranty.

        Does anyone remember the “olden days” when you used to have to send escape codes to HP printers to get them to format correctly? I’m wondering if there is a way through a macro to send the escape codes and tell the printer that “paper type=draft and size=letter” so that the printer would reset itself ….

        A thought …. anyone else have an idea?

        thanks again …. Andrew

        • #589242

          Hi,
          Word is not really my thing, but I imagine you could get VBA to insert a PRINT field in the relevant place on your document and then delete it after printing. For (some of) the escape codes see Q135569
          Hope that helps.

          • #589245

            Thanks for the leads on the escape codes. The more I think about it, the more I’m not sure the codes will work. The problem lies in the fact that despite my telling the printer how I want to print my document (e.g. macro code says print from tray 1 with letter-size paper) if the printer thinks it has legal-sized paper in tray 1, then it will skip printing from tray 1 and use another tray.

            Maybe what I’m looking for is a PCL-type command to send to the printer via my macro to change the paper-type designation of tray 1. I’m going to spend some more time at the HP site looking into the PCL issue …

            thanks, Andrew

            • #589256

              Hmm, in that case I suspect you’ll need some API calls to get the printer device’s DEVMODE structure and amend it accordingly. If I get a chance, I’ll investigate it as it’s one of those things I keep meaning to look at when I get some time but every time I start, I take one look at the code involved and run away! grin

            • #589258

              It really isn’t that bad once you get inside it, Rory. You can download code from several places that will get you started. After that, you’re on your way. flee

            • #589259

              Thanks Rory — but if it gets too hairy/scary, don’t worry — remember you’re talking to a newbie that has to get this all to work!!! If it get’s too complex, it may get beyond my ability to implement!!

            • #589274

              Okay. This code will set the default number of copies for a printer. It can be modified (I think) to change other attributes:

                 Public Type PRINTER_DEFAULTS
              
                     pDatatype As Long
                     pDevmode As Long
                     DesiredAccess As Long
                 End Type
              
                 Public Type PRINTER_INFO_2
                     pServerName As Long
                     pPrinterName As Long
                     pShareName As Long
                     pPortName As Long
                     pDriverName As Long
                     pComment As Long
                     pLocation As Long
                     pDevmode As Long       ' Pointer to DEVMODE
                     pSepFile As Long
                     pPrintProcessor As Long
                     pDatatype As Long
                     pParameters As Long
                     pSecurityDescriptor As Long  ' Pointer to SECURITY_DESCRIPTOR
                     Attributes As Long
              
              
                     Priority As Long
                     DefaultPriority As Long
                     StartTime As Long
                     UntilTime As Long
                     Status As Long
                     cJobs As Long
                     AveragePPM As Long
                 End Type
              
                 Public Type DEVMODE
                     dmDeviceName As String * 32
              
                     dmSpecVersion As Integer
                     dmDriverVersion As Integer
                     dmSize As Integer
                     dmDriverExtra As Integer
                     dmFields As Long
                     dmOrientation As Integer
                     dmPaperSize As Integer
                     dmPaperLength As Integer
                     dmPaperWidth As Integer
                     dmScale As Integer
                     dmCopies As Integer
                     dmDefaultSource As Integer
                     dmPrintQuality As Integer
                     dmColor As Integer
                     dmDuplex As Integer
                     dmYResolution As Integer
                     dmTTOption As Integer
                     dmCollate As Integer
                     dmFormName As String * 32
                     dmUnusedPadding As Integer
                     dmBitsPerPel As Integer
                     dmPelsWidth As Long
                     dmPelsHeight As Long
                     dmDisplayFlags As Long
                     dmDisplayFrequency As Long
                     dmICMMethod As Long
                     dmICMIntent As Long
                     dmMediaType As Long
                     dmDitherType As Long
                     dmReserved1 As Long
                     dmReserved2 As Long
                 End Type
              
                 Public Const DM_DUPLEX = &H1000&
                 Public Const DM_IN_BUFFER = 8
                  Public Const DMRES_DRAFT = (-1)
                  Public Const DM_COPY = 2
                 Public Const DM_OUT_BUFFER = 2
                 Public Const PRINTER_ACCESS_ADMINISTER = &H4
                 Public Const PRINTER_ACCESS_USE = &H8
                 Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
                 Public Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
                           PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)
              
                 Public Declare Function ClosePrinter Lib "winspool.drv" _
                  (ByVal hPrinter As Long) As Long
                 Public Declare Function DocumentProperties Lib "winspool.drv" _
                   Alias "DocumentPropertiesA" (ByVal hwnd As Long, _
                   ByVal hPrinter As Long, ByVal pDeviceName As String, _
                   ByVal pDevModeOutput As Long, ByVal pDevModeInput As Long, _
                   ByVal fMode As Long) As Long
                 Public Declare Function GetPrinter Lib "winspool.drv" Alias _
                   "GetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, _
                   pPrinter As Byte, ByVal cbBuf As Long, pcbNeeded As Long) As Long
                 Public Declare Function OpenPrinter Lib "winspool.drv" Alias _
                   "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, _
                   pDefault As PRINTER_DEFAULTS) As Long
                 Public Declare Function SetPrinter Lib "winspool.drv" Alias _
                   "SetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, _
                   pPrinter As Byte, ByVal Command As Long) As Long
              
                 Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
                  (pDest As Any, pSource As Any, ByVal cbLength As Long)
                 Public Function SetPrinterCopies(ByVal sPrinterName As String, _
                          Optional plngCopies As Long = 1) As Boolean
              
                    Dim hPrinter As Long
                    Dim pd As PRINTER_DEFAULTS
                    Dim pinfo As PRINTER_INFO_2
                    Dim dm As DEVMODE
                 
                    Dim yDevModeData() As Byte
                    Dim yPInfoMemory() As Byte
                    Dim nBytesNeeded As Long
                    Dim nRet As Long, nJunk As Long
                 
                    On Error GoTo cleanup
                 
                    
                    pd.DesiredAccess = PRINTER_ALL_ACCESS
                    nRet = OpenPrinter(sPrinterName, hPrinter, pd)
                    If (nRet = 0) Or (hPrinter = 0) Then
                       If Err.LastDllError = 5 Then
                          MsgBox "Access denied -- See the article for more info."
                       Else
                          MsgBox "Cannot open the printer specified " & _
                            "(make sure the printer name is correct)."
                       End If
                       Exit Function
                    End If
                 
                    nRet = DocumentProperties(0, hPrinter, sPrinterName, 0, 0, 0)
                    If (nRet < 0) Then
                       MsgBox "Cannot get the size of the DEVMODE structure."
                       GoTo cleanup
                    End If
                 
                    ReDim yDevModeData(nRet + 100) As Byte
                    nRet = DocumentProperties(0, hPrinter, sPrinterName, _
                                VarPtr(yDevModeData(0)), 0, DM_OUT_BUFFER)
                    If (nRet < 0) Then
                       MsgBox "Cannot get the DEVMODE structure."
                       GoTo cleanup
                    End If
                 
                    Call CopyMemory(dm, yDevModeData(0), Len(dm))
                 
                    If Not CBool(dm.dmFields & DM_COPY) Then
                      MsgBox "You cannot modify the copies for this printer."
                       GoTo cleanup
                    End If
                 
                    dm.dmCopies = plngCopies
                    Call CopyMemory(yDevModeData(0), dm, Len(dm))
                 
                    nRet = DocumentProperties(0, hPrinter, sPrinterName, _
                      VarPtr(yDevModeData(0)), VarPtr(yDevModeData(0)), _
                      DM_IN_BUFFER Or DM_OUT_BUFFER)
              
                    If (nRet < 0) Then
                      MsgBox "Unable to set copies for this printer."
                      GoTo cleanup
                    End If
                 
                    Call GetPrinter(hPrinter, 2, 0, 0, nBytesNeeded)
                    If (nBytesNeeded = 0) Then GoTo cleanup
                 
                    ReDim yPInfoMemory(nBytesNeeded + 100) As Byte
              
                    nRet = GetPrinter(hPrinter, 2, yPInfoMemory(0), nBytesNeeded, nJunk)
                    If (nRet = 0) Then
                       MsgBox "Unable to get shared printer settings."
                       GoTo cleanup
                    End If
                 
                    Call CopyMemory(pinfo, yPInfoMemory(0), Len(pinfo))
                    pinfo.pDevmode = VarPtr(yDevModeData(0))
                    pinfo.pSecurityDescriptor = 0
                    Call CopyMemory(yPInfoMemory(0), pinfo, Len(pinfo))
                 
                    nRet = SetPrinter(hPrinter, 2, yPInfoMemory(0), 0)
                    If (nRet = 0) Then
                       MsgBox "Unable to set shared printer settings."
                    End If
                 
                    SetPrinterCopies = CBool(nRet)
              
              cleanup:
                    If (hPrinter  0) Then Call ClosePrinter(hPrinter)
              
                 End Function
              

              You do need to know the correct Device name for the printer to pass to the function (for my network printer it was simply servernamesharename)
              I knew it would be something simple…. grin

            • #589280

              Wow. Now the fun begins ……. compute

              This may take me some time to work through, but thanks for the headstart. I’ll report back if there is success or if I have to give up ….. surrender

              Thanks again! Andrew

            • #589449

              You might also take a look at this post for another example on manipulating printers.

    Viewing 0 reply threads
    Reply To: VB/VBA code to change HP Printer settings? (Word 2000)

    You can use BBCodes to format your content.
    Your account can't use all available BBCodes, they will be stripped before saving.

    Your information: