|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Determining Available Paper Sizes on PrinterWhat would you recommend to determine the available paper sizes on a
printer? It appears that Printer.PaperSize can be used to both Set and Determine the paper size. And it appears that setting to an unavailable size gives an Invalid Property Value error. So I guess I could loop through all available sizes, and see what didn't Err. Is there a better/easier way? Like a collection of paper sizes available? -- Regards, Rick Raisley heavymetal-A-T-bellsouth-D-O-T-net "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message The problem with the looping method (apart from the time it takes) is there news:%23SajMJcnJHA.1288@TK2MSFTNGP02.phx.gbl... > What would you recommend to determine the available > paper sizes on a printer? It appears that Printer.PaperSize > can be used to both Set and Determine the paper size. And > it appears that setting to an unavailable size gives an Invalid > Property Value error. So I guess I could loop through all available > sizes, and see what didn't Err. are some paper sizes that do not match with the paper numbers listed in the VB help files and on many (in fact most) printers there are also lots of paper numbers that are not listed in the help files at all. In fact one printer I used to own had a paper number of 32767, and you would need to loop for a long time to get that one, considering the slow response of Printer.PaperSize! The GetDeviceCapabilities will get the paper size information for you though. The following example gets the paper size information for whatever you have set as the current VB Printer, although it is capable of course of getting such information for any printer on your system. Paste the example into a VB Form containing a ListBox and a Command Button. Mike Option Explicit Private Declare Function DeviceCapabilities Lib _ "winspool.drv" Alias "DeviceCapabilitiesA" _ (ByVal lpsDeviceName As String, ByVal lpPort _ As String, ByVal iIndex As Long, lpOutput As Any, _ ByVal dev As Long) As Long Private Type POINTAPI x As Long y As Long End Type Private Const DC_PAPERNAMES = 16 Private Const DC_PAPERS = 2 Private Const DC_PAPERSIZE = 3 Private Sub Command1_Click() Dim lPaperCount As Long, lCounter As Long Dim hprinter As Long, sDeviceName As String Dim sDevicePort As String, sPaperNamesList As String Dim sNextString As String, numPaper() As Long Dim paperNumbers() As Integer, paperSizes() As POINTAPI List1.Clear lPaperCount = DeviceCapabilities(Printer.DeviceName, _ Printer.Port, DC_PAPERNAMES, ByVal vbNullString, 0) ReDim numPaper(1 To lPaperCount) sPaperNamesList = String(64 * lPaperCount, 0) ' Get paper names lPaperCount = DeviceCapabilities(Printer.DeviceName, _ Printer.Port, DC_PAPERNAMES, ByVal sPaperNamesList, 0) ' Get matching paper numbers ReDim paperNumbers(1 To lPaperCount) lPaperCount = DeviceCapabilities(Printer.DeviceName, _ Printer.Port, DC_PAPERS, paperNumbers(1), 0) ReDim paperSizes(1 To lPaperCount) lPaperCount = DeviceCapabilities(Printer.DeviceName, _ Printer.Port, DC_PAPERSIZE, paperSizes(1), 0) For lCounter = 1 To lPaperCount sNextString = Mid(sPaperNamesList, _ 64 * (lCounter - 1) + 1, 64) sNextString = Left(sNextString, _ InStr(1, sNextString, Chr(0)) - 1) List1.AddItem paperNumbers(lCounter) & vbTab & vbTab _ & Format(paperSizes(lCounter).x / 254, "0.00") & " x " _ & Format(paperSizes(lCounter).y / 254, "0.00") _ & " inch" & vbTab & vbTab & sNextString Next lCounter End Sub Thanks, Mike, that works well. and is very informative. And you're right
about looping, I looped through only the sizes given in the VB help and online, and it worked okay, but there are a lot of other print sizes available on many printers (including the HP LaserJet 5200 I'm using), that you get with your routine, that wouldn't be practical with the other method. Like 32767 for PostScript Custom Page Size. ;-) Unfortunately, neither of these is as helpful to me as I was hoping, as it lists all the funny sizes that we have no paper for, and which is never loaded on a network/shared printer, so providing those options to a normal user will just end up hanging the printer waiting for a special paper size to be loaded. In addition, for this HP 5200, it shows, both with your program, my process of trying to set the paper size and catching errors, and even on the printer setup itself, that it will handle C-size sheets (17" x 22"), whereas the printer's maximum sheet size is 11x17! How weird! I mean, the width of the printers output opening is only a bit larger than 11" So, what I am /really/ after is what size of paper is loaded in the printer and ready to use. I haven't found anything on that (although if you know of something that would be great). My compromise solution, for now, is simply to add a check box [x] User 11" x 17" paper if available. That way, I can keep the printer set for 8 1/2" x 11" normal printing, but get the prints using this program at 11x17 if I want them. All I do here is when printing, save the current paper size, set the paper size to 17 (11x17), print, then set the paper size back. It works, but it's pretty clunky method (although easy enough for the user). Anyhow, thanks again for your help and the very useful code. ;-) -- Show quoteHide quoteRegards, Rick Raisley heavymetal-A-T-bellsouth-D-O-T-net "Mike Williams" <M***@WhiskyAndCoke.com> wrote in message news:Ofg1qbdnJHA.5420@TK2MSFTNGP04.phx.gbl... > "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message > news:%23SajMJcnJHA.1288@TK2MSFTNGP02.phx.gbl... > >> What would you recommend to determine the available >> paper sizes on a printer? It appears that Printer.PaperSize >> can be used to both Set and Determine the paper size. And >> it appears that setting to an unavailable size gives an Invalid >> Property Value error. So I guess I could loop through all available >> sizes, and see what didn't Err. > > The problem with the looping method (apart from the time it takes) is > there are some paper sizes that do not match with the paper numbers listed > in the VB help files and on many (in fact most) printers there are also > lots of paper numbers that are not listed in the help files at all. In > fact one printer I used to own had a paper number of 32767, and you would > need to loop for a long time to get that one, considering the slow > response of Printer.PaperSize! The GetDeviceCapabilities will get the > paper size information for you though. The following example gets the > paper size information for whatever you have set as the current VB > Printer, although it is capable of course of getting such information for > any printer on your system. Paste the example into a VB Form containing a > ListBox and a Command Button. > > Mike > > Option Explicit > Private Declare Function DeviceCapabilities Lib _ > "winspool.drv" Alias "DeviceCapabilitiesA" _ > (ByVal lpsDeviceName As String, ByVal lpPort _ > As String, ByVal iIndex As Long, lpOutput As Any, _ > ByVal dev As Long) As Long > Private Type POINTAPI > x As Long > y As Long > End Type > Private Const DC_PAPERNAMES = 16 > Private Const DC_PAPERS = 2 > Private Const DC_PAPERSIZE = 3 > > Private Sub Command1_Click() > Dim lPaperCount As Long, lCounter As Long > Dim hprinter As Long, sDeviceName As String > Dim sDevicePort As String, sPaperNamesList As String > Dim sNextString As String, numPaper() As Long > Dim paperNumbers() As Integer, paperSizes() As POINTAPI > List1.Clear > lPaperCount = DeviceCapabilities(Printer.DeviceName, _ > Printer.Port, DC_PAPERNAMES, ByVal vbNullString, 0) > ReDim numPaper(1 To lPaperCount) > sPaperNamesList = String(64 * lPaperCount, 0) > ' Get paper names > lPaperCount = DeviceCapabilities(Printer.DeviceName, _ > Printer.Port, DC_PAPERNAMES, ByVal sPaperNamesList, 0) > ' Get matching paper numbers > ReDim paperNumbers(1 To lPaperCount) > lPaperCount = DeviceCapabilities(Printer.DeviceName, _ > Printer.Port, DC_PAPERS, paperNumbers(1), 0) > ReDim paperSizes(1 To lPaperCount) > lPaperCount = DeviceCapabilities(Printer.DeviceName, _ > Printer.Port, DC_PAPERSIZE, paperSizes(1), 0) > For lCounter = 1 To lPaperCount > sNextString = Mid(sPaperNamesList, _ > 64 * (lCounter - 1) + 1, 64) > sNextString = Left(sNextString, _ > InStr(1, sNextString, Chr(0)) - 1) > List1.AddItem paperNumbers(lCounter) & vbTab & vbTab _ > & Format(paperSizes(lCounter).x / 254, "0.00") & " x " _ > & Format(paperSizes(lCounter).y / 254, "0.00") _ > & " inch" & vbTab & vbTab & sNextString > Next lCounter > End Sub > > I notice that when looking at Printer Properties, there is a Paper Available
window, apparently showing the paper sizes actually installed in the printer. Any idea how to get that information from VB, rather than all the sizes the printer can handle? -- Show quoteHide quoteRegards, Rick Raisley heavymetal-A-T-bellsouth-D-O-T-net "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message news:O31%23tWmnJHA.4540@TK2MSFTNGP04.phx.gbl... > Thanks, Mike, that works well. and is very informative. And you're right > about looping, I looped through only the sizes given in the VB help and > online, and it worked okay, but there are a lot of other print sizes > available on many printers (including the HP LaserJet 5200 I'm using), > that you get with your routine, that wouldn't be practical with the other > method. Like 32767 for PostScript Custom Page Size. ;-) > > Unfortunately, neither of these is as helpful to me as I was hoping, as it > lists all the funny sizes that we have no paper for, and which is never > loaded on a network/shared printer, so providing those options to a normal > user will just end up hanging the printer waiting for a special paper size > to be loaded. In addition, for this HP 5200, it shows, both with your > program, my process of trying to set the paper size and catching errors, > and even on the printer setup itself, that it will handle C-size sheets > (17" x 22"), whereas the printer's maximum sheet size is 11x17! How weird! > I mean, the width of the printers output opening is only a bit larger than > 11" > > So, what I am /really/ after is what size of paper is loaded in the > printer and ready to use. I haven't found anything on that (although if > you know of something that would be great). My compromise solution, for > now, is simply to add a check box [x] User 11" x 17" paper if available. > That way, I can keep the printer set for 8 1/2" x 11" normal printing, but > get the prints using this program at 11x17 if I want them. All I do here > is when printing, save the current paper size, set the paper size to 17 > (11x17), print, then set the paper size back. It works, but it's pretty > clunky method (although easy enough for the user). > > Anyhow, thanks again for your help and the very useful code. ;-) > > -- > Regards, > > Rick Raisley > heavymetal-A-T-bellsouth-D-O-T-net > > "Mike Williams" <M***@WhiskyAndCoke.com> wrote in message > news:Ofg1qbdnJHA.5420@TK2MSFTNGP04.phx.gbl... >> "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message >> news:%23SajMJcnJHA.1288@TK2MSFTNGP02.phx.gbl... >> >>> What would you recommend to determine the available >>> paper sizes on a printer? It appears that Printer.PaperSize >>> can be used to both Set and Determine the paper size. And >>> it appears that setting to an unavailable size gives an Invalid >>> Property Value error. So I guess I could loop through all available >>> sizes, and see what didn't Err. >> >> The problem with the looping method (apart from the time it takes) is >> there are some paper sizes that do not match with the paper numbers >> listed in the VB help files and on many (in fact most) printers there are >> also lots of paper numbers that are not listed in the help files at all. >> In fact one printer I used to own had a paper number of 32767, and you >> would need to loop for a long time to get that one, considering the slow >> response of Printer.PaperSize! The GetDeviceCapabilities will get the >> paper size information for you though. The following example gets the >> paper size information for whatever you have set as the current VB >> Printer, although it is capable of course of getting such information for >> any printer on your system. Paste the example into a VB Form containing a >> ListBox and a Command Button. >> >> Mike >> >> Option Explicit >> Private Declare Function DeviceCapabilities Lib _ >> "winspool.drv" Alias "DeviceCapabilitiesA" _ >> (ByVal lpsDeviceName As String, ByVal lpPort _ >> As String, ByVal iIndex As Long, lpOutput As Any, _ >> ByVal dev As Long) As Long >> Private Type POINTAPI >> x As Long >> y As Long >> End Type >> Private Const DC_PAPERNAMES = 16 >> Private Const DC_PAPERS = 2 >> Private Const DC_PAPERSIZE = 3 >> >> Private Sub Command1_Click() >> Dim lPaperCount As Long, lCounter As Long >> Dim hprinter As Long, sDeviceName As String >> Dim sDevicePort As String, sPaperNamesList As String >> Dim sNextString As String, numPaper() As Long >> Dim paperNumbers() As Integer, paperSizes() As POINTAPI >> List1.Clear >> lPaperCount = DeviceCapabilities(Printer.DeviceName, _ >> Printer.Port, DC_PAPERNAMES, ByVal vbNullString, 0) >> ReDim numPaper(1 To lPaperCount) >> sPaperNamesList = String(64 * lPaperCount, 0) >> ' Get paper names >> lPaperCount = DeviceCapabilities(Printer.DeviceName, _ >> Printer.Port, DC_PAPERNAMES, ByVal sPaperNamesList, 0) >> ' Get matching paper numbers >> ReDim paperNumbers(1 To lPaperCount) >> lPaperCount = DeviceCapabilities(Printer.DeviceName, _ >> Printer.Port, DC_PAPERS, paperNumbers(1), 0) >> ReDim paperSizes(1 To lPaperCount) >> lPaperCount = DeviceCapabilities(Printer.DeviceName, _ >> Printer.Port, DC_PAPERSIZE, paperSizes(1), 0) >> For lCounter = 1 To lPaperCount >> sNextString = Mid(sPaperNamesList, _ >> 64 * (lCounter - 1) + 1, 64) >> sNextString = Left(sNextString, _ >> InStr(1, sNextString, Chr(0)) - 1) >> List1.AddItem paperNumbers(lCounter) & vbTab & vbTab _ >> & Format(paperSizes(lCounter).x / 254, "0.00") & " x " _ >> & Format(paperSizes(lCounter).y / 254, "0.00") _ >> & " inch" & vbTab & vbTab & sNextString >> Next lCounter >> End Sub >> >> > > "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message I'm not sure which window you are talking about? Do you mean a window on the news:udQAl5mnJHA.1248@TK2MSFTNGP03.phx.gbl... > I notice that when looking at Printer Properties, there is a > Paper Available window, apparently showing the paper > sizes actually installed in the printer. Any idea how to get > that information from VB, rather than all the sizes the printer can > handle? main manufacturer's driver dialog (the various windows that display after you click the "Printing Preferences" button) or do you mean the initial "MS Windows" part of the dialog (the window that first appears when you right click the printer and select Properties)? If you mean the latter, which I suspect you do, then you are probably talking about the information displayed under the General tab under the "Paper Available" heading. I don't usually deal with printers with multiple general purpose bins (such as your HP LaserJet 5200 which appears to have two general purpose bins as standard and a third as an optional extra) but as far as I am aware the papers listed under "Paper Available" in that window are the paper sizes that have been assigned as default to each of the bins, and so it will list just one page size for each bin. Those are the paper sizes assigned to the bin by the person who last set up the Printer Properties and it does not necessarily mean that the paper mentioned is actually the paper that is currently physically installed in any bin. For example if you have the permissions to do so you should be able to click the Device Settings tab and you'll see the various trays available and the paper size that is currently assigned to each tray. If you click one of the trays on that window you will be able to change the assignment to a different paper size, and thereafter that specific size (instead of the one previously shown) will be displayed on the General tab under the "Paper Available" heading, even though the bin in fact does not actually contain such a paper size. So, you can only rely on that information being true if the person who initially set it up entered the correct information in accordance with the paper that was actually physically installed in the trays (which of course you should have the right to expect!) but also only if nobody else has since removed a stack of (for example) A3 paper from a tray and substituted it with a stack of A4. For example, on my own printer I can see A4 as the paper being available in that window, but even if I use Printer Properties / Printing Preferences to set the default paper size to A5 and if I place a stack of A5 paper in the tray I can still see A4 as being available in the window we are talking about, when of course it is not actually available at all! It is entirely possible that people over time have done that sort of thing many times without realising that in order to update the paper available display to its new A5 setting they must also click the Device Settings tab on the initial Printer Properties window and change the tray asignments. I suppose that information is better than nothing though and it might be of use to you, but I'm afraid that at the moment I don't know how to get it. I'm sure there is a way to do so because tray assignment appears to be a "Windows knows about this" thing rather than a specific to driver thing. I sometimes use code to set the paper bin and of course to set the paper size but I haven't yet looked into determining which bin is assigned which paper size as its default. If I get time later, or perhaps some time during the next few days depending on what my wife has lined up for me over the weekend(!), I'll see if I can discover anything in the DeviceCapabilities API stuff that might help. Or perhaps someone else here already knows how to do that? If they do then I'm sure they'll post an answer for you. Mike "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message Further to my previous response to this question I've now got some time to news:udQAl5mnJHA.1248@TK2MSFTNGP03.phx.gbl... > I notice that when looking at Printer Properties, there is a Paper > Available window, apparently showing the paper sizes actually > installed in the printer. Any idea how to get that information . . . check it out properly and I've managed to get what you have asked for using the DeviceCapabilities function in winspool.drv in much the same way as in the previous code I posted (which got the names and numbers of all supported paper types for a specific printer) but using it slightly differently to get only the names of the papers currently assigned to one of the printer's trays by using DC_MEDIAREADY as the Index. The papers returned should agree with the information you see against "Paper Available" on the General tab when right clicking a printer in Control Panel and selecting Properties. There doesn't appear to be a matching Index value to get the matching Peper Numbers for the returned paper names (as there is when using DC_PAPERNAMES to get the names of all papers supported by a specific printer), or at least I can't see it at the moment, but that shouldn't matter because armed with a list of paper names for the "Papers Available", which the following code will get for you, you should be able to dig out the matching paper number from the list of "paper numbers and names" generated by the previous code I posted which lists the paper names and matching paper numbers all papers which the printer supports. Just modify that previous code to place the numbers and names in matching arrays (instead of merely listing them to a ListBox as the example code currently does) and you will then be able to pick out the appropriate paper number of the paper name generated by this code from that array. Anyway, paste the following example into a VB Form containing a ListBox and a Command Button. Clicking the Command button when you run the program shpould populate the ListBox with the names of the papers that are currently available on the printer (the papers that have been assigned to a tray). I'll lkeave it to you to combine this code with the code I previously posted, which generates a list of all supported papers whether they are currently marked as available or not. Mike Option Explicit Private Declare Function DeviceCapabilities Lib _ "winspool.drv" Alias "DeviceCapabilitiesA" _ (ByVal lpsDeviceName As String, ByVal lpPort _ As String, ByVal iIndex As Long, lpOutput As Any, _ ByVal dev As Long) As Long Private Const DC_MEDIAREADY As Long = 29 Private Sub GetPapersAvailable(p1 As Printer) Dim n As Long, p As Long, nMedia As Long Dim sBuffer As String, MediaNames() As String ' get number of papers ready and assigned ' to a tray (the same information as you ' would get by right clicking printer in ' Control Panel and selecting Properties ' and clicking the General Tab where you ' will see the papers available (which ' you can modify under the Device Settings ' tab on the same window and altering the ' Form to Tray assignment. nMedia = DeviceCapabilities(p1.DeviceName, _ p1.Port, DC_MEDIAREADY, ByVal 0, 0) If nMedia < 1 Then List1.AddItem p1.DeviceName & " does not " _ & "have any papers ready." Exit Sub ' so kick me! End If ReDim MediaNames(1 To nMedia) ' assign a buffer of sufficient length ' to retrieve the names of the papers sBuffer = String$(nMedia * 64, Chr$(0)) ' read the names into the buffer n = DeviceCapabilities(p1.DeviceName, _ p1.Port, DC_MEDIAREADY, ByVal sBuffer, 0) ' pick out the names (null terminated) For n = 1 To nMedia MediaNames(n) = Mid$(sBuffer, 64 * (n - 1) + 1, 64) p = InStr(MediaNames(n), Chr$(0)) If p > 0 Then MediaNames(n) = Left$(MediaNames(n), p - 1) End If Next n List1.Clear List1.AddItem p1.DeviceName & " has " _ & nMedia & " papers ready (assigned to a tray):" For n = 1 To UBound(MediaNames) List1.AddItem MediaNames(n) Next n End Sub Private Sub Command1_Click() GetPapersAvailable Printer End Sub Just what I'm looking for, Mike, I'll check it out. Thanks again. ;-)
-- Show quoteHide quoteRegards, Rick Raisley heavymetal-A-T-bellsouth-D-O-T-net "Mike Williams" <M***@WhiskyAndCoke.com> wrote in message news:%23Dwlgs1nJHA.5980@TK2MSFTNGP06.phx.gbl... > "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message > news:udQAl5mnJHA.1248@TK2MSFTNGP03.phx.gbl... > >> I notice that when looking at Printer Properties, there is a Paper >> Available window, apparently showing the paper sizes actually >> installed in the printer. Any idea how to get that information . . . > > Further to my previous response to this question I've now got some time to > check it out properly and I've managed to get what you have asked for > using the DeviceCapabilities function in winspool.drv in much the same way > as in the previous code I posted (which got the names and numbers of all > supported paper types for a specific printer) but using it slightly > differently to get only the names of the papers currently assigned to one > of the printer's trays by using DC_MEDIAREADY as the Index. The papers > returned should agree with the information you see against "Paper > Available" on the General tab when right clicking a printer in Control > Panel and selecting Properties. There doesn't appear to be a matching > Index value to get the matching Peper Numbers for the returned paper names > (as there is when using DC_PAPERNAMES to get the names of all papers > supported by a specific printer), or at least I can't see it at the > moment, but that shouldn't matter because armed with a list of paper names > for the "Papers Available", which the following code will get for you, you > should be able to dig out the matching paper number from the list of > "paper numbers and names" generated by the previous code I posted which > lists the paper names and matching paper numbers all papers which the > printer supports. Just modify that previous code to place the numbers and > names in matching arrays (instead of merely listing them to a ListBox as > the example code currently does) and you will then be able to pick out the > appropriate paper number of the paper name generated by this code from > that array. Anyway, paste the following example into a VB Form containing > a ListBox and a Command Button. Clicking the Command button when you run > the program shpould populate the ListBox with the names of the papers that > are currently available on the printer (the papers that have been assigned > to a tray). I'll lkeave it to you to combine this code with the code I > previously posted, which generates a list of all supported papers whether > they are currently marked as available or not. > > Mike > > Option Explicit > Private Declare Function DeviceCapabilities Lib _ > "winspool.drv" Alias "DeviceCapabilitiesA" _ > (ByVal lpsDeviceName As String, ByVal lpPort _ > As String, ByVal iIndex As Long, lpOutput As Any, _ > ByVal dev As Long) As Long > Private Const DC_MEDIAREADY As Long = 29 > > Private Sub GetPapersAvailable(p1 As Printer) > Dim n As Long, p As Long, nMedia As Long > Dim sBuffer As String, MediaNames() As String > ' get number of papers ready and assigned > ' to a tray (the same information as you > ' would get by right clicking printer in > ' Control Panel and selecting Properties > ' and clicking the General Tab where you > ' will see the papers available (which > ' you can modify under the Device Settings > ' tab on the same window and altering the > ' Form to Tray assignment. > nMedia = DeviceCapabilities(p1.DeviceName, _ > p1.Port, DC_MEDIAREADY, ByVal 0, 0) > If nMedia < 1 Then > List1.AddItem p1.DeviceName & " does not " _ > & "have any papers ready." > Exit Sub ' so kick me! > End If > ReDim MediaNames(1 To nMedia) > ' assign a buffer of sufficient length > ' to retrieve the names of the papers > sBuffer = String$(nMedia * 64, Chr$(0)) > ' read the names into the buffer > n = DeviceCapabilities(p1.DeviceName, _ > p1.Port, DC_MEDIAREADY, ByVal sBuffer, 0) > ' pick out the names (null terminated) > For n = 1 To nMedia > MediaNames(n) = Mid$(sBuffer, 64 * (n - 1) + 1, 64) > p = InStr(MediaNames(n), Chr$(0)) > If p > 0 Then > MediaNames(n) = Left$(MediaNames(n), p - 1) > End If > Next n > List1.Clear > List1.AddItem p1.DeviceName & " has " _ > & nMedia & " papers ready (assigned to a tray):" > For n = 1 To UBound(MediaNames) > List1.AddItem MediaNames(n) > Next n > End Sub > > Private Sub Command1_Click() > GetPapersAvailable Printer > End Sub > > Works perfectly, Mike. Very helpful.
Now if I can just figure out why the HP 5200, with both Letter and 11x17 paper installed, reports only Letter, both in your code AND in the printer's property box, despite there being 11x17 paper installed and it prints fine with it! lol! But anyhow, your code reported the same (although incorrect) information that the printer dialog reports, and that's exactly what I wanted. Thanks again! ;-) -- Show quoteHide quoteRegards, Rick Raisley heavymetal-A-T-bellsouth-D-O-T-net "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message news:OB2zM2NoJHA.4872@TK2MSFTNGP04.phx.gbl... > Just what I'm looking for, Mike, I'll check it out. Thanks again. ;-) > > -- > Regards, > > Rick Raisley > heavymetal-A-T-bellsouth-D-O-T-net > > "Mike Williams" <M***@WhiskyAndCoke.com> wrote in message > news:%23Dwlgs1nJHA.5980@TK2MSFTNGP06.phx.gbl... >> "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message >> news:udQAl5mnJHA.1248@TK2MSFTNGP03.phx.gbl... >> >>> I notice that when looking at Printer Properties, there is a Paper >>> Available window, apparently showing the paper sizes actually >>> installed in the printer. Any idea how to get that information . . . >> >> Further to my previous response to this question I've now got some time >> to check it out properly and I've managed to get what you have asked for >> using the DeviceCapabilities function in winspool.drv in much the same >> way as in the previous code I posted (which got the names and numbers of >> all supported paper types for a specific printer) but using it slightly >> differently to get only the names of the papers currently assigned to one >> of the printer's trays by using DC_MEDIAREADY as the Index. The papers >> returned should agree with the information you see against "Paper >> Available" on the General tab when right clicking a printer in Control >> Panel and selecting Properties. There doesn't appear to be a matching >> Index value to get the matching Peper Numbers for the returned paper >> names (as there is when using DC_PAPERNAMES to get the names of all >> papers supported by a specific printer), or at least I can't see it at >> the moment, but that shouldn't matter because armed with a list of paper >> names for the "Papers Available", which the following code will get for >> you, you should be able to dig out the matching paper number from the >> list of "paper numbers and names" generated by the previous code I posted >> which lists the paper names and matching paper numbers all papers which >> the printer supports. Just modify that previous code to place the numbers >> and names in matching arrays (instead of merely listing them to a ListBox >> as the example code currently does) and you will then be able to pick out >> the appropriate paper number of the paper name generated by this code >> from that array. Anyway, paste the following example into a VB Form >> containing a ListBox and a Command Button. Clicking the Command button >> when you run the program shpould populate the ListBox with the names of >> the papers that are currently available on the printer (the papers that >> have been assigned to a tray). I'll lkeave it to you to combine this code >> with the code I previously posted, which generates a list of all >> supported papers whether they are currently marked as available or not. >> >> Mike >> >> Option Explicit >> Private Declare Function DeviceCapabilities Lib _ >> "winspool.drv" Alias "DeviceCapabilitiesA" _ >> (ByVal lpsDeviceName As String, ByVal lpPort _ >> As String, ByVal iIndex As Long, lpOutput As Any, _ >> ByVal dev As Long) As Long >> Private Const DC_MEDIAREADY As Long = 29 >> >> Private Sub GetPapersAvailable(p1 As Printer) >> Dim n As Long, p As Long, nMedia As Long >> Dim sBuffer As String, MediaNames() As String >> ' get number of papers ready and assigned >> ' to a tray (the same information as you >> ' would get by right clicking printer in >> ' Control Panel and selecting Properties >> ' and clicking the General Tab where you >> ' will see the papers available (which >> ' you can modify under the Device Settings >> ' tab on the same window and altering the >> ' Form to Tray assignment. >> nMedia = DeviceCapabilities(p1.DeviceName, _ >> p1.Port, DC_MEDIAREADY, ByVal 0, 0) >> If nMedia < 1 Then >> List1.AddItem p1.DeviceName & " does not " _ >> & "have any papers ready." >> Exit Sub ' so kick me! >> End If >> ReDim MediaNames(1 To nMedia) >> ' assign a buffer of sufficient length >> ' to retrieve the names of the papers >> sBuffer = String$(nMedia * 64, Chr$(0)) >> ' read the names into the buffer >> n = DeviceCapabilities(p1.DeviceName, _ >> p1.Port, DC_MEDIAREADY, ByVal sBuffer, 0) >> ' pick out the names (null terminated) >> For n = 1 To nMedia >> MediaNames(n) = Mid$(sBuffer, 64 * (n - 1) + 1, 64) >> p = InStr(MediaNames(n), Chr$(0)) >> If p > 0 Then >> MediaNames(n) = Left$(MediaNames(n), p - 1) >> End If >> Next n >> List1.Clear >> List1.AddItem p1.DeviceName & " has " _ >> & nMedia & " papers ready (assigned to a tray):" >> For n = 1 To UBound(MediaNames) >> List1.AddItem MediaNames(n) >> Next n >> End Sub >> >> Private Sub Command1_Click() >> GetPapersAvailable Printer >> End Sub >> >> > > "Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message Pleased to be of help. By the way, regarding the failure to report the 11x17 news:%23f73RTOoJHA.3984@TK2MSFTNGP02.phx.gbl... > Works perfectly, Mike. Very helpful. Now if I can just figure out why the > HP 5200, with both Letter > and 11x17 paper installed, reports only Letter, both in your code > AND in the printer's property box, despite there being 11x17 > paper installed and it prints fine with it! lol! But anyhow, your > code reported the same (although incorrect) information that > the printer dialog reports, and that's exactly what I wanted. > Thanks again! ;-) paper as being available (both my code and the printer's Properties window in Control Panel), it is almost certainly because the 11x17 paper has not been officially assigned to a tray, although that doesn't mean you can't use the paper of course (as you have discovered by the fact that you can still print to it). In fact it is possible for a printer to report that no papers are available at all, and you will still be able to print to whatever paper it actually contains. In fact, as I think I mentioned in one of my previous responses in this thread, you can even deliberately set things up so that the printer's Properties window shows A5 paper as being available for a printer that contains only A4 paper, so that A5 paper is not actually physically available at all, even though it is reported as being available. In this case you would not be able to print to the paper size that is reported as available (A5) because it is not actually available, but you will be able to print to the paper that is not reported as available (A4). The "papers available" details (both those that you see in the printer's Properties window and those that are returned by the code I posted) can only be taken as a guide. That's just the way things are. In order for the Properties window (or the code I posted) to show the correct 'paper available' details then the person who installed the printer, or the person who last changed the papers it provides, needs to set up the 'paper to tray' assignment properly. When anyone installs a printer, whether it be multi tray or single tray, and when they decide what paper they are normally going to place in the tray (or trays) then they should ensure that they mark those specific paper sizes as being available, just in case the driver installation's defaults are not what they actually using. This is not very important in a single user situation (a home user for example) but it is a wise thing to do when installing a shared printer. You can make the assignments by right clicking the printer in the Control Panel Printers applet and selecting Properties and then clicking the Device Settings tab, where you'll see an entry for each of the trays that the printer contains (and probably an entry for any 'optional extra' tray that the printer does not actually contain). If you click the current entry against each tray you will see a drop down list containing an item for each paper that the printer supports plus an additional item called 'not available'. Select the paper size that is actually fitted into the specific tray (or select 'not available' if the tray is not actually fitted or if you never normally place a stack of paper in it). Once you have done this for each of the trays then the 'Papers Available' item on the General tab will correctly reflect all available papers (these details are for Vista, but as I recall they are very similar for XP). Personally I don't use network printers myself (and I think you said that you are using such a printer) but I imagine that with such a network printer this tray to paper assignment will need to be done at the server end and the option to assign papers to trays may not be available at your end (although I'm not sure on that point having never used network printers). Anyway, once the assignment has been correctly made you should see the correct papers, including the 11x17, in the Properties window and the code I posted yesterday should also return it. Mike
Show quote
Hide quote
"Rick Raisley" <heavymetal-A-T-bellsouth-D-O-Tnet> wrote in message I'm afraid printing in Windows is still not an exact science, at least as news:O31%23tWmnJHA.4540@TK2MSFTNGP04.phx.gbl... > Thanks, Mike, that works well. and is very informative. And you're > right about looping, I looped through only the sizes given in the VB > help and online, and it worked okay, but there are a lot of other print > sizes available on many printers (including the HP LaserJet 5200 I'm > using), that you get with your routine, that wouldn't be practical with > the other method. Like 32767 for PostScript Custom Page Size. ;-) > Unfortunately, neither of these is as helpful to me as I was hoping, as > it lists all the funny sizes that we have no paper for, and which is > never loaded on a network/shared printer, so providing those options > to a normal user will just end up hanging the printer waiting for a > special paper size to be loaded. far as paper sizes or special printing arrangements is concerned. Some printers are bristling with sensors that detect the size of paper (or the presence or absence of paper) in each available tray and some are not, and even for those that are there is still no "standard" way of communicating such information to Windows. For example, I've just used Micro$oft Word 2007, which by its pedigree should know just about everything there is to know about printing in Windows, to print an A4 document to my own HP printer which was set to A5 as default and which actually contained A5 paper. The printing was carried out without any notification from either the printer or from Windows, with the result that the right hand half of each page was simply missing (the A4 output flowing over the edge of the A5 paper). Some printers behave like this and some will contain sensors that detect the actual size of paper in each tray and notify the user accordingly when he attempts to print something that does not actually fit on the page, with such notification more often than not coming from message boxes displayed by the driver rather than by Windows itself. Another thing I tried, on a printer that does properly detect an A5 page in the main tray, was to simply turn the A5 page around and insert it into the printer tray in landscape orientation. This completely "foxed" the printer because the sensor measures the paper width at the leading edge and does not in fact have any sensors to measure its "length", thereby le4ading the printer to assume that A4 was loaded in its standard portrait orientation. > In addition, for this HP 5200, it shows, both with your program, my Those kind of things vary from printer to printer. It may be that your own > process of trying to set the paper size and catching errors, and even > on the printer setup itself, that it will handle C-size sheets (17" x > 22"), > whereas the printer's maximum sheet size is 11x17! How weird! I mean, > the width of the printers output opening is only a bit larger than 11" LaserJet 5200 allows you to specify a 17x22 inch paper size but that it actually prints each "page" in "multiple page poster" format, so that it in fact prints two separate 11x17 inch sheets for each 17x22 inch page in a way that enables you to "stick them together" after printing. Or in fact it could be that the printer driver you are using is a "generic for the model range" driver that can (at least in part) be used for various models in the range. > So, what I am /really/ after is what size of paper is loaded in I'm afraid not, at least not as an unattended operation. For example many > the printer and ready to use. I haven't found anything on that > (although if you know of something that would be great). printers which are capable of printing onto special paper sizes or onto special media will have ways of detecting if any such media is actually loaded in the appropriate tray (a printer that can print directly onto printable CDs and DVDs for example) but many will not. And even on those that do the messages "insert a disk into the CD tray" (or whatever) will be displayed on the printer itself and Windows will in that case know nothing about it. The problem is that in general a lot of money has been poured into providing standardised drivers which all obey a standard set of Windows instructions for graphics cards (DX 10 for example) because gamers spend a lot of money on machines and never stop spending extra money to keep up with the top end, and there is a lot of money in "keeping them sweet", but nothing like that amount of resources has gone into the printing side of things. Currently lots of different manufacturers produce machines with lots of different "new and better"! functions (in an attempt to keep the money rolling), most of which appeal to "the average Joe Public" rather than to businesses, but almost all of the information regarding the new or special functions is contained in a block of memory which actually does exist in Windows (in the extras section) but which only the printer driver actually understands. So the printer driver (and its associated software) can do things with the printer that Windows does not actually have any native methods for. > My compromise solution, for now, is simply to add a check You don't need to save the current paper size or restore it if you are > box [x] User 11" x 17" paper if available. That way, I can keep the > printer set for 8 1/2" x 11" normal printing, but get > the prints using this program at 11x17 if I want them. All I > do here is when printing, save the current paper size, set the > paper size to 17 (11x17), print, then set the paper size back. > It works, but it's pretty clunky method (although easy enough > for the user). setting the paper size using the Printer.Papersize method. That's because all such Printer Object settings affect only the DC which the Printer Object is currently using and they do not change the default printer settings. In fact even if you are using the dreaded CommonDialog Control and if you are allowing your user to select 11x17 paper in that it will still not affect the default printer paper settings, even if CommonDialog PrinterDefault is set to True (at least not if you are using somehting later than Win 98) because the system allows it to change the printer itself (which is regarded as a user setting) but not any of its properties. Mike Just Thought I'd mention:
I was once using an A3 printer that listed about 100 different paper sizes, well actually about 50, but each paper size was kinda duplicated. it would list A4 Portrait A4 Landscape A3 Portrait A3 Landscape etc etc.. The daft thing was it's own custon dialog box also had the Portrait/Landscape option buttons! I literally had nearly a minute of fun confusing myself :-) Ivar |
|||||||||||||||||||||||