Welcome to MSDN Blogs Sign in | Join | Help

Get the available paper bins from a printer

Sometimes you might want to find out how many paper bins a printer has. (Thanks to Barbara P for original question, code.)

 

 

 

lcPrinterName = GETPRINTER()

nPrinters=APRINTERS(laAvailPrinters)

FOR i = 1 TO nPrinters

      IF UPPER(laAvailPrinters[i,1]) = UPPER(lcPrinterName)

            lcPort = laAvailPrinters[i,2]

            lcPort = CHRTRAN(lcPort,':','')

            EXIT

      ENDIF

ENDFOR

?"lcPort",lcPort

?"lcPrinterName",lcPrinterName

 

#define DC_BINS             6

#define DC_BINNAMES         12

DECLARE INTEGER DeviceCapabilities IN winspool.drv;

      STRING pDevice, STRING pPort, INTEGER fwCapability,;

      STRING @pOutput, INTEGER pDevMode

 

DECLARE INTEGER GetLastError IN kernel32

 

nResult= DeviceCapabilities(lcPrinterName, lcPort, DC_BINS, 0, 0)

IF nResult=-1

      ?"Err getting DC_BINS size",GetLastError()

      RETURN

ENDIF

?nResult

cstr=SPACE(nResult* 2)  && WORD is 2 bytes each

nResult=DeviceCapabilities(lcPrinterName, lcPort, DC_BINS, @cstr, 0)

IF nResult=-1

      ?     "Err getting DC_BINS",GetLastError()

ENDIF

nBins=nResult

?"Bins"

DIMENSION aBins[nBins]

FOR i = 1 TO nBins

      aBins[i]=CTOBIN(SUBSTR(cstr,i*2-1,2),"2rs")

      ?aBins[i]

ENDFOR

 

cstr=SPACE(nBins*24)

nResult=DeviceCapabilities(lcPrinterName, lcPort, DC_BINNAMES, @cstr, 0)

IF nResult=-1

      ?     "Err getting DC_BINNAMES",GetLastError()

ENDIF

FOR i = 1 TO nBins

      ?CHRTRAN(SUBSTR(cstr,(i-1)*24+1,24),CHR(0),"")

ENDFOR

 

 

 

Published Tuesday, September 27, 2005 10:37 AM by Calvin_Hsia

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Get the available paper bins from a printer

Thursday, October 27, 2005 1:26 PM by Tracy Holzer
I was fortunate to receive assistance from Yuri Rubinov and Simon Clark back in July 2003 on this. They developed some handy code for viewing all papertrays on all printers you may find useful:

<PRE>
* Courtesy Simon Clark and Yuri Rubinov, Universal Thread July 2003
* Thread #808875 Message #815017

* put a DEFAULTSOURCE=<bin number> in the EXPR column
* of the FRX row with OBJTYPE=53 after selection

oform=CREATEOBJECT('papertrayform')
oform.SHOW()
READ EVENTS
RETURN

DEFINE CLASS papertrayform AS FORM


TOP = 0
LEFT = 1
HEIGHT = 365
WIDTH = 631
DOCREATE = .T.
CAPTION = "Paper Tray Selection Form"
NAME = "PAPERTRAYS"
DIMENSION paperbins[1,4]


ADD OBJECT list1 AS LISTBOX WITH ;
FONTNAME = "Courier New", ;
FONTSIZE = 9, ;
BOUNDCOLUMN = 1, ;
ROWSOURCETYPE = 6, ;
ROWSOURCE='',;
CONTROLSOURCE = "m.selection", ;
HEIGHT = 300, ;
COLUMNLINES = .T., ;
LEFT = 8, ;
MULTISELECT = .F., ;
TABINDEX = 10, ;
TOP = 39, ;
WIDTH = 612, ;
NAME = "List1"


ADD OBJECT label1 AS LABEL WITH ;
CAPTION = "Press <ENTER> to select a paper tray";
+"or Double-Click on any item to select it", ;
HEIGHT = 17, ;
LEFT = 8, ;
TOP = 11, ;
WIDTH = 580, ;
NAME = "Label1"


PROCEDURE buf2word
*PROCEDURE buf2word && Convert BUF to WORD
PARAMETERS QQbuffer
* ---INTERFACE---
PRIVATE ALL LIKE QQ*
* IMPORTS:
* A buffer/pointer
*
* EXPORTS:
* The passed in buffer converted to a word format
*

* ---INITIALISE---
QQudfRet = ASC(SUBSTR(QQbuffer, 1,1)) + ASC(SUBSTR(QQbuffer, 2,1)) * 256

RETURN QQudfRet
ENDPROC


PROCEDURE INIT
IF USED('trays')
USE IN trays
ENDIF
IF FILE('trays.dbf')
DELETE FILE trays.DBF
ENDIF
CLEAR
DODEFAULT()
SET SAFETY OFF
*For the FRX's it easy, you just put a
*DEFAULTSOURCE=<bin number> in the EXPR column
*of the FRX row with OBJTYPE=53 (same for DUPLEX= by the way...).

#DEFINE GMEM_FIXED 0
#DEFINE DC_PAPERS 2
#DEFINE DC_BINS 6
#DEFINE DC_SIZE 8
#DEFINE DC_VERSION 10
#DEFINE DC_BINNAMES 12
#DEFINE DC_PAPERNAMES 16
#DEFINE DEFAULT_VALUES 0

* Needed to interrogate the printer driver for paper bins/trays
DECLARE INTEGER DeviceCapabilities IN winspool.drv;
STRING pDevice, STRING pPort, INTEGER fwCapability,;
STRING @pOutput, INTEGER pDevMode

=APRINTERS(pPrinters)
FOR ip = 1 TO ALEN(pPrinters,1)
*QQprintername=SET("PRINTER",2) && windows own default printer
QQprintername=pPrinters(ip,1)
pPort=ALLTRIM(pPrinters(ip,2))
* Windows API declarations
* Hook in here to determine the paper trays and their bin numbers
QQbinBfr = REPLICATE(CHR(0), 16384)
QQbinBf2 = REPLICATE(CHR(0), 1024)
* provide valid printer and port names
QQnCount = DeviceCapabilities(QQprintername, pPort, DC_BINNAMES, @QQbinBfr, 0)
QQnCnt2 = DeviceCapabilities(QQprintername, pPort, DC_BINS, @QQbinBf2, 0)
* Set the number of bins available on this printer property
p_bin_count=IIF(QQnCount<0, 0, QQnCount)
IF p_bin_count>0
* each string buffer is 24 characters long, terminated with a NULL / chr(0)
* and contains the name of a paper bin
DIMENSION p_bin_names[QQnCount], p_bin_labels[QQnCount]
FOR QQindex=1 TO QQnCount
QQbinName = SUBSTR(QQbinBfr, (QQindex-1)*24+1, 24) + CHR(0)
QQbinName = SUBSTR(QQbinName, 1, AT(CHR(0), QQbinName)-1)
p_bin_names[QQindex] = QQbinName
ENDFOR
QQptr = 1
FOR QQindex=1 TO QQnCnt2*2 STEP 2
QQbinNum = THISFORM.buf2word(SUBSTR(QQbinBf2, QQindex, 2))
p_bin_labels[QQptr] = QQbinNum
QQptr = QQptr + 1
ENDFOR
ENDIF
IF ALEN(p_bin_names,1)=ALEN(p_bin_labels,1)
FOR i = 1 TO ALEN(p_bin_names,1)
IF TYPE('thisform.paperbins')="U"
DIMENSION THISFORM.paperbins(i,4)
ELSE
DIMENSION THISFORM.paperbins(ALEN(THISFORM.paperbins,1)+1,4)
ENDIF
THISFORM.paperbins(ALEN(THISFORM.paperbins,1),1)=QQprintername
THISFORM.paperbins(ALEN(THISFORM.paperbins,1),2)=p_bin_names(i)
THISFORM.paperbins(ALEN(THISFORM.paperbins,1),3)=p_bin_labels(i)
THISFORM.paperbins(ALEN(THISFORM.paperbins,1),4)=pPort
ENDFOR
ENDIF
ENDFOR
nlen1=0
nlen2=0
nlen3=4
nlen4=0
=ACOPY(THISFORM.paperbins,paperbins)
FOR i = 1 TO ALEN(paperbins,1)
IF TYPE('paperbins(i,1)')<>"L"
IF LEN(ALLTRIM(paperbins(i,1)))>nlen1
nlen1=LEN(ALLTRIM(paperbins(i,1)))
ENDIF
ENDIF
IF TYPE('paperbins(i,2)')<>"L"
IF LEN(ALLTRIM(paperbins(i,2)))>nlen2
nlen2=LEN(ALLTRIM(paperbins(i,2)))
ENDIF
ENDIF
IF TYPE('paperbins(i,4)')<>"L"
IF LEN(ALLTRIM(paperbins(i,4)))>nlen4
nlen4=LEN(ALLTRIM(paperbins(i,4)))
ENDIF
ENDIF
ENDFOR
IF nlen1=0
nlen1=1
ENDIF
IF nlen2=0
nlen2=1
ENDIF
IF nlen4=0
nlen4=1
ENDIF
CREATE CURSOR trays (pname c(nlen1),;
pbin c(nlen2), pbinno c(nlen3), pPort c(nlen4))
SELE trays
FOR i = 1 TO ALEN(paperbins,1)
IF TYPE('paperbins(i,1)')<>"L"
SELE trays
APPEND BLANK
*!* The below will only display the printer name once instead of in
*!* every row, but capturing the printername would have to be
*!* changed then on selection in the listbox since that field maybe
*!* blank
*!* IF i > 1
*!* ta=i-1
*!* IF TYPE('paperbins(i,1)')=TYPE('paperbins(ta,1)') ;
*!* .and. paperbins(i,1) <> paperbins(ta,1)
*!* REPLACE trays.pname WITH ALLTRIM(paperbins(i,1))
*!* ELSE
*!* IF TYPE('paperbins(i,1)')!=TYPE('paperbins(ta,1)')
*!* REPLACE trays.pname WITH ALLTRIM(paperbins(i,1))
*!* ENDIF
*!* ENDIF
*!* ENDIF
REPLACE trays.pname WITH ALLTRIM(paperbins(i,1))
IF TYPE('paperbins(i,2)')<>"L"
REPLACE trays.pbin WITH ALLTRIM(paperbins(i,2))
ENDIF
IF TYPE('paperbins(i,3)')<>"L"
REPLACE trays.pbinno WITH ALLTRIM(STR(paperbins(i,3)))
ENDIF
IF TYPE('paperbins(i,4)')<>"L"
REPLACE trays.pPort WITH ALLTRIM(paperbins(i,4))
ENDIF
ENDIF
ENDFOR
GO TOP
THISFORM.list1.ROWSOURCE = 'LEFT(trays.pname,45)+" ";
+left(trays.pbin,20)+" "+LEFT(trays.pbinno,20)+" ";
+LEFT(trays.pport,10)'
THISFORM.list1.REFRESH
ENDPROC

PROCEDURE RELEASE
DODEFAULT()
ENDPROC

PROCEDURE UNLOAD
IF USED('TRAYS')
USE IN trays
ENDIF
CLEAR EVENTS
DODEFAULT()
ENDPROC

PROCEDURE list1.DBLCLICK
IF USED('TRAYS') .AND. RECCOUNT('TRAYS')>0 .AND. !EOF('TRAYS')
mchoice=trays.pbinno
ENDIF
MESSAGEBOX('You chose: '+CHR(13)+CHR(13);
+"Printer: "+ALLTRIM(trays.pname)+ CHR(13);
+"Tray: "+trays.pbin+CHR(13);
+"Bin No: "+trays.pbinno+CHR(13),0,'Paper Tray Selectioin')
NODEFAULT
THISFORM.RELEASE()
ENDPROC


PROCEDURE list1.KEYPRESS
LPARAMETERS nKeyCode, nShiftAltCtrl

IF LASTKEY() = 13 .OR. LASTKEY() = -9
nKeyCode = 13
nShiftAltCtrl = 0
ENDIF

mchoice=""
DO CASE

CASE nKeyCode = 13 .OR. nKeyCode = -9

IF USED('TRAYS') .AND. RECCOUNT('TRAYS')>0 .AND. !EOF('TRAYS')
mchoice=trays.pbinno
ENDIF
MESSAGEBOX('You chose: '+CHR(13)+CHR(13);
+"Printer: "+ALLTRIM(trays.pname)+ CHR(13);
+"Tray: "+trays.pbin+CHR(13);
+"Bin No: "+trays.pbinno+CHR(13),0,'Paper Tray Selectioin')
NODEFAULT
THISFORM.RELEASE()

OTHERWISE

mchoice=""
DODEFAULT()

ENDCASE
ENDPROC


PROCEDURE list1.REFRESH
IF !USED('trays') .OR. RECCOUNT('trays')=0
THIS.ENABLED=.F.
ELSE
THIS.ENABLED=.T.
ENDIF
DODEFAULT()
ENDPROC


ENDDEFINE
</PRE>

# re: Get the available paper bins from a printer

Tuesday, July 17, 2007 11:05 AM by weberrp

Hi Calvin,

I have searched high and low for a very simple solution to my printing problem with no good answer.

platform(s):

Windows Xp Pro

MS VFP 9.0 SP1

HP LJ 4050TN & HP LJ 4350 DTNSL

History:

Existing MS VFP 6.0 program produced (printed) Avery # 5960 (3x10) labels from tray 2 and certificates (5" x 8") from Tray 1 and letterhead from Tray 3 while all other print output went to Tray 4 (plain paper).

Problem:

After recent upgrade from VFP 6.0 to VFP 9.0 SP1 now the print output always goes to Tray 4 (plain paper). I have resaved each .frx and .lbx with what I think to be the appropriate settings, including the tray selection, but output still goes to Tray 4.

Question:

There must be a very simple solution (like SET REPORT BEHAVIOUR  or  SET ENGINE BEHAVIOUR) since the only change was the VFP version on the PCs and no printer changes. I've seen various solutions involving classes and pages of code but it just can't be that complicated can it?  Any help will be greatly appreciated.

RPWeber

# re: Get the available paper bins from a printer

Tuesday, July 17, 2007 3:27 PM by Calvin_Hsia

Hi RPWeber:

From VFP team member Richard:

I think that property is removed when the “Print Environment” option is unchecked on the FRX. This is because the tray information is printer specific, so the option wouldn’t work unless the report is always run on the same printer type.

However, the paper tray setting can be stored as an option in the EXPR field on the first record of the FRX. They can update the EXPR field to have a DEFAULTSOURCE property that specifies which bin to use, the actual values depend on the printer. (For example the one on our floor has a value like this DEFAULTSOURCE=258)

As long a TAG and TAG2 are empty, the report will use the default printer and attempt to set the properties on the printer to the ones set in EXPR.

Leave a Comment

(required) 
required 
(required) 
 
Page view tracker