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 // 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 */