Solved

How to select Printer Tray or PaperSource in VB.NET?

Posted on 2003-10-30
18
13,543 Views
Last Modified: 2011-10-26
Anybody manage to select a printer tray for printing?

                Dim pd As New PrintDocument
                pd.PrinterSettings.PrinterName = strDefaultPrinter

Now I want to enumerate the available printer trays, (say in a combobox), allow the user to set the chosen printer tray and print.

pd.PrinterSettings.PaperSources seems to be readonly?
0
Comment
Question by:westerdale
  • 8
  • 5
  • 4
  • +1
18 Comments
 
LVL 3

Accepted Solution

by:
the-edge earned 150 total points
Comment Utility
use
        pd.PrinterSettings.PaperSources
to get the collection of available trays

and
        pd.DefaultPageSettings.PaperSource
to set the tray to use

the edge
0
 
LVL 1

Author Comment

by:westerdale
Comment Utility
Wow That was quick!

I set the Paper Source as you suggested. However when I check the printer it is still set to the default paper source. Have I done something wrong? (The enumeration worked!


        Dim pd As New PrintDocument
        Dim PSource As System.Drawing.Printing.PaperSource
        Try
            pd.PrinterSettings.PrinterName = strDefaultPrinter

            For Each PSource In pd.PrinterSettings.PaperSources
                If PSource.SourceName = cboTray.Text Then
                    pd.DefaultPageSettings.PaperSource = PSource
                    Exit For
                End If
            Next
        Catch ex As Exception

        End Try

'Now I want to start a process to print something
e.g.
        Dim myProcess As New Process
        Dim startInfo As New ProcessStartInfo("C:\Programme\Adobe\Acrobat 5.0\Reader\AcroRd32.exe")
        startInfo.WindowStyle = ProcessWindowStyle.Minimized
        startInfo.Arguments = "/t """ & txtFilename.Text & """ """ & strDefaultPrinter & """ """ & lblPrinterDriver.Text & """ """ & lblPrinterPort.Text & """"
        'MsgBox(startInfo.Arguments)

        myProcess.Start(startInfo)


0
 
LVL 96

Assisted Solution

by:Bob Learned
Bob Learned earned 350 total points
Comment Utility
Setting PaperSource sets it for the PrintDocument, and not for the printer.  So when you run Acrobat Reader, the printer settings haven't changed.
0
 
LVL 1

Author Comment

by:westerdale
Comment Utility
I can't issue points untill the setting of the papersource issue is solved. There must be a way to set this in the default settings of the printer?

the-edge any suggestions here?
0
 
LVL 96

Expert Comment

by:Bob Learned
Comment Utility
I found some code to set the PaperSource from VB6.  It might take a little work to get it to work in VB.NET.  

Are you interested?
0
 
LVL 1

Author Comment

by:westerdale
Comment Utility
Certainly,

Though if it's: Then it will not work
Firstly. The Printers collection is readyonly
secondly using Printer object does not change the tray. Certainly not globally.
I wrote an activeX dll to test this (bit extreme I know:-)



Dim pr As Printer
    'pr.DeviceName = strPrinterName
   'pr.PaperBin = vbPRBNEnvManual
   
    'Set pr = Nothing
    'For Each pr In Printers
    '    If UCase$(pr.DeviceName) = UCase$(strPrinterName) Then
    '        Set Printer = p
         
    '        pr.PaperBin = vbPRBNEnvManual
    '        Set pr = Nothing
    '        Exit For
    '    End If
    'Next
0
 
LVL 1

Author Comment

by:westerdale
Comment Utility
Certainly,

Though if it's: Then it will not work
Firstly. The Printers collection is readyonly
secondly using Printer object does not change the tray. Certainly not globally.
I wrote an activeX dll to test this (bit extreme I know:-)



Dim pr As Printer
    'pr.DeviceName = strPrinterName
   'pr.PaperBin = vbPRBNEnvManual
   
    'Set pr = Nothing
    'For Each pr In Printers
    '    If UCase$(pr.DeviceName) = UCase$(strPrinterName) Then
    '        Set Printer = p
         
    '        pr.PaperBin = vbPRBNEnvManual
    '        Set pr = Nothing
    '        Exit For
    '    End If
    'Next
0
 
LVL 96

Assisted Solution

by:Bob Learned
Bob Learned earned 350 total points
Comment Utility
In this Micro$oft article it talks about setting the paper source using API calls:

FIX: Cannot Change Page Settings During Print Job
http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/Q180/6/45.asp&NoWebContent=1

You could modify it to fit your needs.
0
 
LVL 1

Author Comment

by:westerdale
Comment Utility
Thanks. I tried this already
I added the function below into a VB6 class: I tested the class under VB6 and VB.NET
the lngHwnd is the int32 handle from my VB.NEt app as the class does not have a handle

When I checked the Printer settings they appear not to have changed.




Public Function SetPrinterTray(lngHwnd As Long, strPrinterName As String, strPrinterDriverName As String, lngTray As Long) As Long
'vbPRBNUpper    1    Use paper from the upper bin.
'VbPRBNLower    2    Use paper from the lower bin.
'VbPRBNMiddle    3    Use paper from the middle bin.
'VbPRBNManual    4    Wait for manual insertion of each sheet of paper.
'VbPRBNEnvelope    5    Use envelopes from the envelope feeder.
'VbPRBNEnvManual    6    Use envelopes from the envelope feeder, but wait for manual insertion.
'VbPRBNAuto    7    (Default) Use paper from the current default bin.
'VbPRBNTractor    8    Use paper fed from the tractor feeder.
'VbPRBNSmallFmt    9    Use paper from the small paper feeder.
'VbPRBNLargeFmt    10    Use paper from the large paper bin.
'VbPRBNLargeCapacity    11    Use paper from the large capacity feeder.
'VbPRBNCassette    14    Use paper from the attached cassette cartridge.

          Dim di As DOCINFO
          Dim hPrintDc As Long
          Dim Ret As Long
          Dim LastError As Long
          'Dim tx$

          myHandle = lngHwnd 'Sets the handle to the process

          'tx$ = "Hello World!"
          hPrintDc = CreateDC(strPrinterDriverName, strPrinterName, 0, 0)
          di.cbSize = Len(di) ' 20
          'di.lpszDocName = "VB Test Document" ' Optional

          ' Initialize page settings.
          Ret = ResetPrinterDC(Printer.DeviceName, hPrintDc, lngTray, DMORIENT_PORTRAIT)

'          Ret = StartDoc(hPrintDc, di)
'          Ret = StartPage(hPrintDc)
'          Ret = TextOut(hPrintDc, 1000, 1000, tx$, Len(tx$))
'          Ret = EndPage(hPrintDc)

          ' Change page settings.
'          Ret = ResetPrinterDC(Printer.DeviceName, hPrintDc, _
'          DMBIN_LOWER, DMORIENT_LANDSCAPE)
'
'          Ret = StartPage(hPrintDc)
'          Ret = TextOut(hPrintDc, 1000, 1000, tx$, Len(tx$))
'          Ret = EndPage(hPrintDc)
'          Ret = EndDoc(hPrintDc)
          Ret = DeleteDC(hPrintDc)


   

End Function
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 96

Expert Comment

by:Bob Learned
Comment Utility
I tested the code in the article in a VB6 form, and it worked just fine.  But it, too, might only set the settings for the application, and not for the Acrobat reader.

Have to keep looking!
0
 
LVL 1

Author Comment

by:westerdale
Comment Utility
I think the key is the default settings. I even had a peak in the registry though I did not find anything useful.

These settings must be stored somewhere, trick is to find out where. Perhaps this is at the individual driver level? What do you think? I'll be using HP lasers.
0
 
LVL 3

Expert Comment

by:the-edge
Comment Utility
maybe this can be useful for you

the edge
0
 
LVL 3

Assisted Solution

by:the-edge
the-edge earned 150 total points
Comment Utility
0
 
LVL 3

Expert Comment

by:the-edge
Comment Utility
sorry missed the link in previoous comment:

http://www.fawcette.com/vsm/2002_02/magazine/columns/desktopdeveloper/

excuse me

the edge
0
 
LVL 1

Author Comment

by:westerdale
Comment Utility
The edge,

Those links were good especially the merrioncomputing link (this one was a new one for me).

Under Vb.NET
Dim myProcess As New Process
does not produce a valid handle until the myProcess.start is activated (and therefore too late to use the handle in the printer document process (see below).
I see no way to bind a process  (the Acrobat process) to a printer setttings change

Under VB6

 Ret = ResetPrinterDC(lngHwnd, strPrinterDriverName, hPrintDc, lngTray, DMORIENT_PORTRAIT)

     Function ResetPrinterDC(lngHwnd As Long, PrinterName As String, hPrtDc As Long, _
          PaperSource As Long, PaperOrient As Long) As Boolean
          Dim nSize As Long ' Size of DEVMODE
          Dim pDevMode As DEVMODE
          Dim PrinterHandle As Long ' handle to printer
          Dim LastError As Long ' return value for GetLastError
          Dim aDevMode() As Byte ' working DEVMODE

          ' Get a handle to the printer.
          If OpenPrinter(PrinterName, PrinterHandle, 0&) Then
              nSize = DocumentProperties(lngHwnd, PrinterHandle, _
              PrinterName, 0&, 0&, 0)
              ' Reserve memory for the actual size of the DEVMODE
              ReDim aDevMode(1 To nSize)

              ' Fill the DEVMODE from the printer.
              nSize = DocumentProperties(lngHwnd, PrinterHandle, _
              PrinterName, aDevMode(1), 0&, DM_OUT_BUFFER)
              ' Copy the predefined portion of the DEVMODE.
              Call CopyMemory(pDevMode, aDevMode(1), Len(pDevMode))

              ' Change the appropriate member in the DevMode.
              ' In this case, you want to change the paper bin and
              ' orientation.
              pDevMode.dmDefaultSource = PaperSource
              pDevMode.dmOrientation = PaperOrient
              ' Set the dmFields bit flag to indicate what you're changing.
              pDevMode.dmFields = DM_DEFAULTSOURCE Or DM_ORIENTATION

              ' Copy your changes back, then update DEVMODE.
              Call CopyMemory(aDevMode(1), pDevMode, Len(pDevMode))
              nSize = DocumentProperties(lngHwnd, PrinterHandle, _
              PrinterName, aDevMode(1), aDevMode(1), _
              DM_IN_BUFFER Or DM_OUT_BUFFER)

              nSize = ResetDC(hPrtDc, aDevMode(1)) ' Reset the DEVMODE

              ' Close the handle when you're done with it.
              ClosePrinter (PrinterHandle)
              ResetPrinterDC = True ' Reset succeeded!
          Else
              ResetPrinterDC = False ' Reset failed!
              LastError = GetLastError()
              MsgBox "Error changing Page settings. Error Code: " _
              & LastError, vbExclamation, "Print Error"
          End If
      End Function

Would be the way to go using the lngHwnd to bind to the process..
I thought to ShellExecute or CreateProcessA , but here the handle is 'too late' to be used to change the printer settings

So to me the only way to change the printer tray is to employ a knome to do it ;-)

Lastly I would like to issue points even though my question is not complete (you have really helped me with ideas) what is the protocol here?

0
 
LVL 96

Expert Comment

by:Bob Learned
Comment Utility
If you feel that only one person's answers helped you, then accept one of their comments as an Answer.  If you feel that both were helpful, then you can split the points between the two.
0
 
LVL 1

Author Comment

by:westerdale
Comment Utility
Thanks TheLearnedOne and The Edge

Maybe someone will find this useful. An undocmented feature that allows you to send PDFs to any printer on the fly. Though sadly, only to the default tray.


Dim myProcess As New Process
 Dim startInfo As New ProcessStartInfo("C:\Programme\Adobe\Acrobat 5.0\Reader\AcroRd32.exe")
            startInfo.WindowStyle = ProcessWindowStyle.Normal
            startInfo.Arguments = "/t """ & txtFilename.Text & """ """ & straPrinterName & """ """ & lblPrinterDriver.Text & """ """ & lblPrinterPort.Text & """"
            myProcess.Start(startInfo)


To get the Printer driver...
  Dim regKey As RegistryKey
 Dim keyValue As String

                        keyValue = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers\\" & strDefaultPrinter
                        regKey = Registry.LocalMachine.OpenSubKey(keyValue, False)
                        lblPrinterDriver.Text = regKey.GetValue("Printer Driver", 0)
                        lblPrinterPort.Text = regKey.GetValue("Port", 0)
                        regKey.Close()





0
 

Expert Comment

by:kavvis
Comment Utility
I reade this answear many times right now.

What did you come up to? "Though sadly, only to the default tray."
So you can´t write to tray 3 for exemple? only the default tray? It´s seems verry strange... ?
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Recently while returning home from work my wife (another .NET developer) was murmuring something. On further poking she said that she has been assigned a task where she has to serialize and deserialize objects and she is afraid of serialization. Wha…
In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now