Subject Re: printer paper source
From <rich@autotraker.com> <<rich@autotraker.com>>
Date Tue, 11 Aug 2020 09:05:26 -0400
Newsgroups dbase.getting-started
Attachment(s) getBinInfo.cc

Thanks Mervyn for getting him something to use so I don't have to work my
brain.
I see you have him covered. I found the CC I made some years ago.
Maybe its of some help.
I build 2 parallels arrays, one for the bin numbers and one for the
descriptions.
I had to roll my own select printer form so this was to get the bin info for
that form.
If I recall its because choosePrinter didn't allow you to select a bin,
maybe?
If you want that form too, I'll dig it out. I don't recall why I ended up
rolling my own instead of using choosePrinter(). Maybe it was before we have
the _app.printer object.
I stored the printer & bin info in a INI for use later to pass to Crystal
Reports so they can select different printers for different reports.
Rich....




"Mervyn Bick"  wrote in message news:Ms$Jrw0bWHA.2624@ip-AC1E04A7...

On 2020-08-10 20:06, Ken Mayer wrote:

>
> Thanks for the work you put in on these things!

It's not work if you're having fun. :-)

Mervyn.



version = "$VERSION 1.04 {06/14/2011 02:43:04 PM} VERSION$"
clear

// 06/14/2011 - REM - Added abilities to return the default bin info.

// 05/24/2007 - REM - Added abilities to return paper source info.
// 03/02/2006 - REM - Generally just cleaned it up.
// 03/09/2006 - REM = Increased buffer size, lpszOutput. I'd rather have too
big a buffer than too small.
                // I noticed a buffer too small error in Funcky where he most likely use
the standardize
      // buffer size when calling a HP printer. Our problem seems to be also
isolated to a HP printer.

// http://msdn2.microsoft.com/en-us/library/ms535506.aspx


/* device capabilities indices */
#define DC_FIELDS             1
#define DC_PAPERS             2
#define DC_PAPERSIZE          3
#define DC_MINEXTENT          4
#define DC_MAXEXTENT          5
#define DC_BINS               6
#define DC_DUPLEX             7
#define DC_SIZE               8
#define DC_EXTRA              9
#define DC_VERSION           10
#define DC_DRIVER            11
#define DC_BINNAMES          12
#define DC_ENUMRESOLUTIONS   13
#define DC_FILEDEPENDENCIES  14
#define DC_TRUETYPE          15
#define DC_PAPERNAMES        16
#define DC_ORIENTATION       17
#define DC_COPIES            18

/* bin selections */
#define DMBIN_FIRST         DMBIN_UPPER
#define DMBIN_UPPER         1
#define DMBIN_ONLYONE       1
#define DMBIN_LOWER         2
#define DMBIN_MIDDLE        3
#define DMBIN_MANUAL        4
#define DMBIN_ENVELOPE      5
#define DMBIN_ENVMANUAL     6
#define DMBIN_AUTO          7
#define DMBIN_TRACTOR       8
#define DMBIN_SMALLFMT      9
#define DMBIN_LARGEFMT      10
#define DMBIN_LARGECAPACITY 11
#define DMBIN_CASSETTE      14
#define DMBIN_FORMSOURCE    15
#define DMBIN_LAST          DMBIN_FORMSOURCE
#define DMBIN_USER          256     /* device specific bins start at 256 */

/* paper selections */
#define DMPAPER_FIRST                DMPAPER_LETTER
#define DMPAPER_LETTER               1  /* Letter 8 1/2 x 11 in
*/
#define DMPAPER_LETTERSMALL          2  /* Letter Small 8 1/2 x 11 in
*/
#define DMPAPER_TABLOID              3  /* Tabloid 11 x 17 in
*/
#define DMPAPER_LEDGER               4  /* Ledger 17 x 11 in
*/
#define DMPAPER_LEGAL                5  /* Legal 8 1/2 x 14 in
*/
#define DMPAPER_STATEMENT            6  /* Statement 5 1/2 x 8 1/2 in
*/
#define DMPAPER_EXECUTIVE            7  /* Executive 7 1/4 x 10 1/2 in
*/
#define DMPAPER_A3                   8  /* A3 297 x 420 mm
*/
#define DMPAPER_A4                   9  /* A4 210 x 297 mm
*/
#define DMPAPER_A4SMALL             10  /* A4 Small 210 x 297 mm
*/
#define DMPAPER_A5                  11  /* A5 148 x 210 mm
*/
#define DMPAPER_B4                  12  /* B4 (JIS) 250 x 354
*/
#define DMPAPER_B5                  13  /* B5 (JIS) 182 x 257 mm
*/
#define DMPAPER_FOLIO               14  /* Folio 8 1/2 x 13 in
*/
#define DMPAPER_QUARTO              15  /* Quarto 215 x 275 mm
*/
#define DMPAPER_10X14               16  /* 10x14 in
*/
#define DMPAPER_11X17               17  /* 11x17 in
*/
#define DMPAPER_NOTE                18  /* Note 8 1/2 x 11 in
*/
#define DMPAPER_ENV_9               19  /* Envelope #9 3 7/8 x 8 7/8
*/
#define DMPAPER_ENV_10              20  /* Envelope #10 4 1/8 x 9 1/2
*/
#define DMPAPER_ENV_11              21  /* Envelope #11 4 1/2 x 10 3/8
*/
#define DMPAPER_ENV_12              22  /* Envelope #12 4 \276 x 11
*/
#define DMPAPER_ENV_14              23  /* Envelope #14 5 x 11 1/2
*/
#define DMPAPER_CSHEET              24  /* C size sheet
*/
#define DMPAPER_DSHEET              25  /* D size sheet
*/
#define DMPAPER_ESHEET              26  /* E size sheet
*/
#define DMPAPER_ENV_DL              27  /* Envelope DL 110 x 220mm
*/
#define DMPAPER_ENV_C5              28  /* Envelope C5 162 x 229 mm
*/
#define DMPAPER_ENV_C3              29  /* Envelope C3  324 x 458 mm
*/
#define DMPAPER_ENV_C4              30  /* Envelope C4  229 x 324 mm
*/
#define DMPAPER_ENV_C6              31  /* Envelope C6  114 x 162 mm
*/
#define DMPAPER_ENV_C65             32  /* Envelope C65 114 x 229 mm
*/
#define DMPAPER_ENV_B4              33  /* Envelope B4  250 x 353 mm
*/
#define DMPAPER_ENV_B5              34  /* Envelope B5  176 x 250 mm
*/
#define DMPAPER_ENV_B6              35  /* Envelope B6  176 x 125 mm
*/
#define DMPAPER_ENV_ITALY           36  /* Envelope 110 x 230 mm
*/
#define DMPAPER_ENV_MONARCH         37  /* Envelope Monarch 3.875 x 7.5 in
*/
#define DMPAPER_ENV_PERSONAL        38  /* 6 3/4 Envelope 3 5/8 x 6 1/2 in
*/
#define DMPAPER_FANFOLD_US          39  /* US Std Fanfold 14 7/8 x 11 in
*/
#define DMPAPER_FANFOLD_STD_GERMAN  40  /* German Std Fanfold 8 1/2 x 12 in
*/
#define DMPAPER_FANFOLD_LGL_GERMAN  41  /* German Legal Fanfold 8 1/2 x 13
in */
//#if(WINVER >= 0x0400)
#define DMPAPER_ISO_B4              42  /* B4 (ISO) 250 x 353 mm
*/
#define DMPAPER_JAPANESE_POSTCARD   43  /* Japanese Postcard 100 x 148 mm
*/
#define DMPAPER_9X11                44  /* 9 x 11 in
*/
#define DMPAPER_10X11               45  /* 10 x 11 in
*/
#define DMPAPER_15X11               46  /* 15 x 11 in
*/
#define DMPAPER_ENV_INVITE          47  /* Envelope Invite 220 x 220 mm
*/
#define DMPAPER_RESERVED_48         48  /* RESERVED--DO NOT USE
*/
#define DMPAPER_RESERVED_49         49  /* RESERVED--DO NOT USE
*/
#define DMPAPER_LETTER_EXTRA        50  /* Letter Extra 9 \275 x 12 in
*/
#define DMPAPER_LEGAL_EXTRA         51  /* Legal Extra 9 \275 x 15 in
*/
#define DMPAPER_TABLOID_EXTRA       52  /* Tabloid Extra 11.69 x 18 in
*/
#define DMPAPER_A4_EXTRA            53  /* A4 Extra 9.27 x 12.69 in
*/
#define DMPAPER_LETTER_TRANSVERSE   54  /* Letter Transverse 8 \275 x 11 in
*/
#define DMPAPER_A4_TRANSVERSE       55  /* A4 Transverse 210 x 297 mm
*/
#define DMPAPER_LETTER_EXTRA_TRANSVERSE 56 /* Letter Extra Transverse 9\275
x 12 in */
#define DMPAPER_A_PLUS              57  /* SuperA/SuperA/A4 227 x 356 mm
*/
#define DMPAPER_B_PLUS              58  /* SuperB/SuperB/A3 305 x 487 mm
*/
#define DMPAPER_LETTER_PLUS         59  /* Letter Plus 8.5 x 12.69 in
*/
#define DMPAPER_A4_PLUS             60  /* A4 Plus 210 x 330 mm
*/
#define DMPAPER_A5_TRANSVERSE       61  /* A5 Transverse 148 x 210 mm
*/
#define DMPAPER_B5_TRANSVERSE       62  /* B5 (JIS) Transverse 182 x 257 mm
*/
#define DMPAPER_A3_EXTRA            63  /* A3 Extra 322 x 445 mm
*/
#define DMPAPER_A5_EXTRA            64  /* A5 Extra 174 x 235 mm
*/
#define DMPAPER_B5_EXTRA            65  /* B5 (ISO) Extra 201 x 276 mm
*/
#define DMPAPER_A2                  66  /* A2 420 x 594 mm
*/
#define DMPAPER_A3_TRANSVERSE       67  /* A3 Transverse 297 x 420 mm
*/
#define DMPAPER_A3_EXTRA_TRANSVERSE 68  /* A3 Extra Transverse 322 x 445 mm
*/
//#endif /* WINVER >= 0x0400 */

//#if(WINVER >= 0x0500)
#define DMPAPER_DBL_JAPANESE_POSTCARD 69 /* Japanese Double Postcard 200 x
148 mm */
#define DMPAPER_A6                  70  /* A6 105 x 148 mm
*/
#define DMPAPER_JENV_KAKU2          71  /* Japanese Envelope Kaku #2
*/
#define DMPAPER_JENV_KAKU3          72  /* Japanese Envelope Kaku #3
*/
#define DMPAPER_JENV_CHOU3          73  /* Japanese Envelope Chou #3
*/
#define DMPAPER_JENV_CHOU4          74  /* Japanese Envelope Chou #4
*/
#define DMPAPER_LETTER_ROTATED      75  /* Letter Rotated 11 x 8 1/2 11 in
*/
#define DMPAPER_A3_ROTATED          76  /* A3 Rotated 420 x 297 mm
*/
#define DMPAPER_A4_ROTATED          77  /* A4 Rotated 297 x 210 mm
*/
#define DMPAPER_A5_ROTATED          78  /* A5 Rotated 210 x 148 mm
*/
#define DMPAPER_B4_JIS_ROTATED      79  /* B4 (JIS) Rotated 364 x 257 mm
*/
#define DMPAPER_B5_JIS_ROTATED      80  /* B5 (JIS) Rotated 257 x 182 mm
*/
#define DMPAPER_JAPANESE_POSTCARD_ROTATED 81 /* Japanese Postcard Rotated
148 x 100 mm */
#define DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED 82 /* Double Japanese Postcard
Rotated 148 x 200 mm */
#define DMPAPER_A6_ROTATED          83  /* A6 Rotated 148 x 105 mm
*/
#define DMPAPER_JENV_KAKU2_ROTATED  84  /* Japanese Envelope Kaku #2 Rotated
*/
#define DMPAPER_JENV_KAKU3_ROTATED  85  /* Japanese Envelope Kaku #3 Rotated
*/
#define DMPAPER_JENV_CHOU3_ROTATED  86  /* Japanese Envelope Chou #3 Rotated
*/
#define DMPAPER_JENV_CHOU4_ROTATED  87  /* Japanese Envelope Chou #4 Rotated
*/
#define DMPAPER_B6_JIS              88  /* B6 (JIS) 128 x 182 mm
*/
#define DMPAPER_B6_JIS_ROTATED      89  /* B6 (JIS) Rotated 182 x 128 mm
*/
#define DMPAPER_12X11               90  /* 12 x 11 in
*/
#define DMPAPER_JENV_YOU4           91  /* Japanese Envelope You #4
*/
#define DMPAPER_JENV_YOU4_ROTATED   92  /* Japanese Envelope You #4
Rotated*/
#define DMPAPER_P16K                93  /* PRC 16K 146 x 215 mm
*/
#define DMPAPER_P32K                94  /* PRC 32K 97 x 151 mm
*/
#define DMPAPER_P32KBIG             95  /* PRC 32K(Big) 97 x 151 mm
*/
#define DMPAPER_PENV_1              96  /* PRC Envelope #1 102 x 165 mm
*/
#define DMPAPER_PENV_2              97  /* PRC Envelope #2 102 x 176 mm
*/
#define DMPAPER_PENV_3              98  /* PRC Envelope #3 125 x 176 mm
*/
#define DMPAPER_PENV_4              99  /* PRC Envelope #4 110 x 208 mm
*/
#define DMPAPER_PENV_5              100 /* PRC Envelope #5 110 x 220 mm
*/
#define DMPAPER_PENV_6              101 /* PRC Envelope #6 120 x 230 mm
*/
#define DMPAPER_PENV_7              102 /* PRC Envelope #7 160 x 230 mm
*/
#define DMPAPER_PENV_8              103 /* PRC Envelope #8 120 x 309 mm
*/
#define DMPAPER_PENV_9              104 /* PRC Envelope #9 229 x 324 mm
*/
#define DMPAPER_PENV_10             105 /* PRC Envelope #10 324 x 458 mm
*/
#define DMPAPER_P16K_ROTATED        106 /* PRC 16K Rotated
*/
#define DMPAPER_P32K_ROTATED        107 /* PRC 32K Rotated
*/
#define DMPAPER_P32KBIG_ROTATED     108 /* PRC 32K(Big) Rotated
*/
#define DMPAPER_PENV_1_ROTATED      109 /* PRC Envelope #1 Rotated 165 x 102
mm */
#define DMPAPER_PENV_2_ROTATED      110 /* PRC Envelope #2 Rotated 176 x 102
mm */
#define DMPAPER_PENV_3_ROTATED      111 /* PRC Envelope #3 Rotated 176 x 125
mm */
#define DMPAPER_PENV_4_ROTATED      112 /* PRC Envelope #4 Rotated 208 x 110
mm */
#define DMPAPER_PENV_5_ROTATED      113 /* PRC Envelope #5 Rotated 220 x 110
mm */
#define DMPAPER_PENV_6_ROTATED      114 /* PRC Envelope #6 Rotated 230 x 120
mm */
#define DMPAPER_PENV_7_ROTATED      115 /* PRC Envelope #7 Rotated 230 x 160
mm */
#define DMPAPER_PENV_8_ROTATED      116 /* PRC Envelope #8 Rotated 309 x 120
mm */
#define DMPAPER_PENV_9_ROTATED      117 /* PRC Envelope #9 Rotated 324 x 229
mm */
#define DMPAPER_PENV_10_ROTATED     118 /* PRC Envelope #10 Rotated 458 x
324 mm */
//#endif /* WINVER >= 0x0500 */

//#if (WINVER >= 0x0500)
#define DMPAPER_LAST                DMPAPER_PENV_10_ROTATED
//#elif (WINVER >= 0x0400)
//#define DMPAPER_LAST                DMPAPER_A3_EXTRA_TRANSVERSE
//#else
//#define DMPAPER_LAST                DMPAPER_FANFOLD_LGL_GERMAN
//#endif

#define DMPAPER_USER                256










#define Chr_Zeros(nZ)  replicate(chr(0), nZ)

/*  Rich - www.autotraker.com
        Returns paper tray and paper source information for a printer.

   Parameters:
   cDevice = "Printer name"
   cPort = "Printer Port"

   2 parallel arrays are returned. aBinNames is the actual bin names used
for display and
   aBins are the bin codes used for setting the printer to the proper paper
tray.
   Also
   2 parallel arrays are returned. aSourceNames is the actual source names
used for display and
   aSources are the Source codes used for setting the printer to the proper
paper source.

        Examples:
   Printer cDevice is as it appears in printer configureation and you can
use
   either the path to the printer or the port as cPort. Local printers
normally
   use "LPT1:" or NT machines may use virtual ports such as "Ne00:" but you
can also
   use actual path such as "\\TOWER66\HP895se" as returned by WSH or WMI
functions.
   (See sample WSH and WMI code at end of this document)

//   x = new getBinInfo("Auto HP DeskJet 895Cse on TOWER66", "Ne00:")

   x = new getBinInfo("Auto HP DeskJet 895Cse on TOWER66",
"\\TOWER66\HP895se")
   for i = 1 to x.aBinNames.size
      ? x.aBinNames[i]
      ?? " " + x.aBins[i]
   endfor

   for i = 1 to x.aSourceNames.size
      ? x.aSourceNames[i]
      ?? " " + x.aSources[i]
   endfor


*/




class getBinInfo(cDevice, cPort)

//        #include <WINDEF.H>
//   extern CINT REM_DeviceCapabilities(LPCSTR, LPCSTR, WORD, ;
                   LPSTR, LPSTRUCTURE) winspool.drv ;
                   from "DeviceCapabilitiesA"

   if not type("REM_DeviceCapabilities") == "FP"
      extern cint REM_DeviceCapabilities( ;
      cstring, cstring, cword, cptr, cptr);
      winspool.drv from 'DeviceCapabilitiesA'
   endif

   this.nDefaultBin  = 7 // Auto
   this.cDefaultBin  = ""

   this.nMax                         = 64 // max buffer size
   this.cDevice                 = cDevice
   this.cPort                         = cPort
   this.aBinNames         = class::getBinNames()
   this.aBins                         = class::getBinCodes()
   this.aSourceNames = class::getSourceNames()
   this.aSources                 = class::getSourceCodes()

   function getSourceNames
      Local lpdm,lpszOutput,nSourceMax,nSize,aSourceNames,nSource

      // init the API to recover the number of sources to setup lpszOutput
buffer
      lpdm = NULL
      lpszOutput = NULL
      nSourceMax =
REM_DeviceCapabilities(this.cDevice,this.cPort,DC_PAPERNAMES,lpszOutput,lpdm
)
      if nSourceMax == -1
         return new array()
      endif

      nSize = 64/2 // each source name, 64 bytes wide, but returned as
single byte string

      // create the buffers
      lpdm = 0
      lpszOutput = Chr_Zeros(nSourceMax * this.nMax) // * nSize

                // get the source names loading them into the buffer
      nSourceMax =
REM_DeviceCapabilities(this.cDevice,this.cPort,DC_PAPERNAMES,lpszOutput,lpdm
)
      if nSourceMax == -1
         return new array()
      endif

      aSourceNames = new array(nSourceMax)
      for nSource = 1 to nSourceMax
         // convert single wide buffer string to double wide and put into
array
              aSourceNames[nSource] = class::A_SBCSZToDBCS(substr(lpszOutput,
(nSource*nSize) - (nSize-1), nSize))
              //? aSourceNames[nSource]
      endfor
      release lpszOutput
      return aSourceNames


   function getBinNames
      Local lpdm,lpszOutput,nBinMax,nSize,aBinNames,nSource

      // init the API to recover the number of bins to setup lpszOutput
buffer
      lpdm = NULL
      lpszOutput = NULL
      nBinMax =
REM_DeviceCapabilities(this.cDevice,this.cPort,DC_BINNAMES,lpszOutput,lpdm)
      if nBinMax == -1
         return new array()
      endif

      nSize = 24/2 // each bin name, 24 bytes wide, but returned as single
byte string

      // create the buffers
     lpdm = 0
     lpszOutput = Chr_Zeros(nBinMax * this.nMax) // * nSize

                // get the bin names loading them into the buffer
      nBinMax =
REM_DeviceCapabilities(this.cDevice,this.cPort,DC_BINNAMES,lpszOutput,lpdm)
      if nBinMax == -1
         return new array()
      endif

      aBinNames = new array(nBinMax)
      for nSource = 1 to nBinMax
         // convert single wide buffer string to double wide and put into
array
              aBinNames[nSource] = class::A_SBCSZToDBCS(substr(lpszOutput,
(nSource*nSize) - (nSize-1), nSize))
              //? aBinNames[nSource]

                        if "auto" $ aBinNames[nSource]
                 this.nDefaultBin  = nSource
                 this.cDefaultBin  = aBinNames[nSource]
         endif

      endfor
      release lpszOutput
      return aBinNames

   function getSourceCodes
      Local lpdm,lpszOutput,nMaxSources,aSources,nSource

      // init the API to recover the number of sources to setup lpszOutput
buffer
      lpdm = NULL
      lpszOutput = NULL
      nMaxSources =
REM_DeviceCapabilities(this.cDevice,this.cPort,DC_PAPERS,lpszOutput,lpdm)
      if nMaxSources == -1
              return new array()
      endif

      // create the buffers
      lpdm = 0
      lpszOutput = Chr_Zeros(nMaxSources * this.nMax)

      // load bin codes into buffer
      nMaxSources =
REM_DeviceCapabilities(this.cDevice,this.cPort,DC_PAPERS,lpszOutput,lpdm)
      if nMaxSources == -1
         return new array()
      endif

      aSources = new array(nMaxSources)
      for nSource = 1 to nMaxSources
         // read buffer converting each 16bit 'C' number into a numeric and
store in array
              aSources[nSource] = class::A_Chr2Num16(substr(lpszOutput,
(nSource*1), 1), 0)
              //? aSources[nSource]
      endfor
      release lpszOutput
      return aSources

   function getBinCodes
      Local lpdm,lpszOutput,nMaxBins,aBins,nSource

      // init the API to recover the number of bins to setup lpszOutput
buffer
      lpdm = NULL
      lpszOutput = NULL
      nMaxBins =
REM_DeviceCapabilities(this.cDevice,this.cPort,DC_BINS,lpszOutput,lpdm)
      if nMaxBins == -1
              return new array()
      endif

      // create the buffers
      lpdm = 0
      lpszOutput = Chr_Zeros(nMaxBins * this.nMax)

      // load bin codes into buffers
      nMaxBins =
REM_DeviceCapabilities(this.cDevice,this.cPort,DC_BINS,lpszOutput,lpdm)
      if nMaxBins == -1
         return new array()
      endif

      aBins = new array(nMaxBins)
      for nSource = 1 to nMaxBins
         // read buffer converting each 16bit 'C' number into a numeric and
store in array
              aBins[nSource] = class::A_Chr2Num16(substr(lpszOutput, (nSource*1),
1), 0)
              //? aBins[i]
      endfor
      release lpszOutput
      return aBins

   function A_Chr2Num16(cBuff, nIndex)
      // Converts 16bit 'C' to number
      local b1, b2, w16
      b1 = cBuff.GetByte(nIndex)
      b2 = cBuff.GetByte(nIndex+1)
      w16 = b1+;
          b2*256
      return w16

   function A_SBCSZToDBCS(cStr)
           // convert single byte string into double byte
      // 16bit 'C' string to double
      local cTemp, nChar, nLen, cChar
      nLen = (len(cStr)*2)-1
      cTemp = ''
      for nChar = 0 to nLen
         cChar = chr(cStr.getByte(nChar))
         if cChar == chr(0)
            // replace the 'C' null string terminator with a space
            // since terminators may exist within the string
                                cChar = " "
         endif
         cTemp += cChar
      endfor
      return cTemp.rightTrim() // trim spaces at end of string

endclass


/* Sample WSH and WMI code

      objLocator = new OleAutoClient("WbemScripting.SWbemLocator")
      objWMI=objLocator.ConnectServer(".", "root\cimv2")
      objWMI.Security_.ImpersonationLevel=3 // Impersonate
      oItems = objWMI.ExecQuery("Select * from Win32_Printer")
                for i = 1 to oItems.count()
              ? oItems[i-1].name
              ? oItems[i-1].portName
              ? oItems[i-1].default
                endfor
      release object objWMI
      release object objLocator


      x = new OleAutoClient("WScript.Network")
      // Get list of printers
      oPrinters = x.EnumPrinterConnections()
      // assign printers to array
      for i = 0 to oPrinters.count() -1 step 2
          ? oPrinters.Item(i+1) // name
          ? oPrinters.Item(i) // port
                endfor

*/