Here is an implementation of Printer class>>printerNames which uses the
EnumPrintersA API call to get the names of all network and local printers. -Carl Gundel DynamicLinkLibrary variableByteSubclass: #WinspoolDLL classVariableNames: '' poolDictionaries: '' ! !WinspoolDLL class methods ! fileName ^'winspool.drv' ! ! !WinspoolDLL methods ! enumPrinters: flags name: name level: level enumBuf: enum sizeBuf: size pNeeded: needed pReturned: returned <api: 'EnumPrintersA' long long long long long struct struct ulongReturn> ^self invalidArgument! setDefaultPrinter: name <api: 'SetDefaultPrinterA' struct boolean> ^self invalidArgument ! ! ! KernelDLL methods ! localAlloc: flags bytes: bytes <api: LocalAlloc ulong ulong ulongReturn> ^self invalidArgument! ! ! KernelDLL methods ! localLock: aHandle <api: LocalLock ulong ulongReturn> ^self invalidArgument! ! ! KernelDLL methods ! localReAlloc: hOldMem flags: flags bytes: bytes <api: LocalReAlloc ulong ulong ulong ulongReturn> ^self invalidArgument! ! ! KernelDLL methods ! rtlMoveMemory: printerInfo buffer: buffer length: printerInfoLength <api: RtlMoveMemory struct ulong ulong none> ^self invalidArgument! ! ! WinspoolDLL methods ! enumPrinters: flags name: name level: level enumBuf: enum sizeBuf: size pNeeded: needed pReturned: returned <api: 'EnumPrintersA' long long long long long struct struct ulongReturn> ^self invalidArgument! ! ! KernelDLL methods ! localReAlloc: hOldMem length: bufferSize flags: flags <api: LocalReAlloc ulong ulong ulong ulongReturn> ^self invalidArgument! ! ! Printer class methods ! getNetworkPrinterNames "use the Winspool.dll EnumPrinters API to get the network printer names." ^self enumPrinters: self printerEnumConnections! ! ! Printer class methods ! getPrinterNames "use the Winspool.dll EnumPrinters API to get the printer names" ^self getLocalPrinterNames, self getNetworkPrinterNames! ! " Printer getPrinterNames "! ! ! Printer class methods ! getLocalPrinterNames "use the Winspool.dll EnumPrinters API to get the local printer names." ^self enumPrinters: self printerEnumLocal! ! ! Printer class methods ! pcReturnedStruct "This specifies a structure that we use to get the printer name when using the EnumPrinters API" SelfDefinedStructure define: 'PCRETURNED' withFields: ( IdentityDictionary new at: #value put: #( 0 #ulong #yourself ); yourself ). ^SelfDefinedStructure named: 'PCRETURNED'! ! ! Printer class methods ! printerEnumLocal "This flag specifies that we want names of local printers when using EnumPrinters" ^2! ! ! Printer class methods ! printerEnumConnections "This flag specifies that we want names of network printers when using EnumPrinters" ^4! ! ! Printer class methods ! printerInfoLevel "This specifies which kind of information we expect back from EnumPrinters" ^4! ! ! Printer class methods ! printerInfoLength "Return the size of the printer info struct." ^(SelfDefinedStructure named: 'PRINTERINFO4') size! ! ! Printer class methods ! pcbNeededStruct "This specifies a structure that we use to get the printer name when using the EnumPrinters API" SelfDefinedStructure define: 'PCBNEEDED' withFields: ( IdentityDictionary new at: #value put: #( 0 #ulong #yourself ); yourself ). ^SelfDefinedStructure named: 'PCBNEEDED'! ! ! Printer class methods ! kernelMemMoveable "Used in a call to allocate memory for getting printer names" "_LMEM_MOVEABLE = 2" ^2! ! ! Printer class methods ! kernelMemZeroinit "Used in a call to allocate memory for getting printer names" "_LMEM_ZEROINIT = 64" ^64! ! ! Printer class methods ! printerInfo4Struct "This specifies a structure that we use to get the printer name when using the EnumPrinters API" SelfDefinedStructure define: 'PRINTERINFO4' withFields: ( IdentityDictionary new at: #ptrPrinterName put: #( 0 #struct #yourself ); at: #ptrServerName put: #( 4 #struct #yourself ); at: #attributes put: #( 8 #ulong #yourself); yourself ). ^SelfDefinedStructure named: 'PRINTERINFO4'! ! ! Printer class methods ! enumPrinters: flags "Use the Winspool.dll EnumPrinters API to get the list of printers as specified by flags." | pcbNeeded pcReturned printerInfo uFlags hMem pBuffer result count pointer printers movingPointer hOldMem | pcbNeeded := self pcbNeededStruct. pcReturned := self pcReturnedStruct. printerInfo := self printerInfo4Struct. uFlags := self kernelMemMoveable | self kernelMemZeroinit. hMem := KernelLibrary localAlloc: uFlags bytes: self printerInfoLength * 250. "good for 250 printer names" pBuffer := KernelLibrary localLock: hMem. result := WinspoolDLL current enumPrinters: flags name: 0 level: self printerInfoLevel enumBuf: pBuffer sizeBuf: self printerInfoLength * 250 "good for 250 printer names" pNeeded: pcbNeeded asParameter pReturned: pcReturned asParameter. result = 0 ifTrue: [ self osError ]. count := pcReturned value. movingPointer := pBuffer. printers := OrderedCollection new. 0 to: count - 1 do: [ :i | KernelLibrary rtlMoveMemory: printerInfo buffer: movingPointer length: self printerInfoLength. movingPointer := movingPointer + self printerInfoLength. pointer := printerInfo addressAtOffset: 0. printers add: (String fromAddress: pointer) ]. KernelLibrary localFree: hMem. ^printers " Printer enumPrinters: 0 "! ! ! Printer class methods ! printerNames "Answer a collection of all known printer names." "use getPrinterNames which uses Winspool.dll EnumPrintersA" ^self getPrinterNames! ! *** this signature added by listserv *** *** Visit http://www.listserv.dfn.de/archives/vswe-l.html *** *** for archive browsing and VSWE-L membership management *** |
Hi Carl
Thanks for sharing! -- Henrik Høyer Chief Software Architect [hidden email] * (+45) 4029 2092 Tigervej 27 * 4600 Køge www.sPeople.dk * (+45) 7023 7775 -----Original Message----- From: Using Visual Smalltalk for Windows/Enterprise [mailto:[hidden email]] On Behalf Of Carl Gundel Sent: 13. december 2013 21:57 To: [hidden email] Subject: EnumPrintersA implementation Here is an implementation of Printer class>>printerNames which uses the EnumPrintersA API call to get the names of all network and local printers. -Carl Gundel DynamicLinkLibrary variableByteSubclass: #WinspoolDLL classVariableNames: '' poolDictionaries: '' ! !WinspoolDLL class methods ! fileName ^'winspool.drv' ! ! !WinspoolDLL methods ! enumPrinters: flags name: name level: level enumBuf: enum sizeBuf: size pNeeded: needed pReturned: returned <api: 'EnumPrintersA' long long long long long struct struct ulongReturn> ^self invalidArgument! setDefaultPrinter: name <api: 'SetDefaultPrinterA' struct boolean> ^self invalidArgument ! ! ! KernelDLL methods ! localAlloc: flags bytes: bytes <api: LocalAlloc ulong ulong ulongReturn> ^self invalidArgument! ! ! KernelDLL methods ! localLock: aHandle <api: LocalLock ulong ulongReturn> ^self invalidArgument! ! ! KernelDLL methods ! localReAlloc: hOldMem flags: flags bytes: bytes <api: LocalReAlloc ulong ulong ulong ulongReturn> ^self invalidArgument! ! ! KernelDLL methods ! rtlMoveMemory: printerInfo buffer: buffer length: printerInfoLength <api: RtlMoveMemory struct ulong ulong none> ^self invalidArgument! ! ! WinspoolDLL methods ! enumPrinters: flags name: name level: level enumBuf: enum sizeBuf: size pNeeded: needed pReturned: returned <api: 'EnumPrintersA' long long long long long struct struct ulongReturn> ^self invalidArgument! ! ! KernelDLL methods ! localReAlloc: hOldMem length: bufferSize flags: flags <api: LocalReAlloc ulong ulong ulong ulongReturn> ^self invalidArgument! ! ! Printer class methods ! getNetworkPrinterNames "use the Winspool.dll EnumPrinters API to get the network printer names." ^self enumPrinters: self printerEnumConnections! ! ! Printer class methods ! getPrinterNames "use the Winspool.dll EnumPrinters API to get the printer names" ^self getLocalPrinterNames, self getNetworkPrinterNames! ! " Printer getPrinterNames "! ! ! Printer class methods ! getLocalPrinterNames "use the Winspool.dll EnumPrinters API to get the local printer names." ^self enumPrinters: self printerEnumLocal! ! ! Printer class methods ! pcReturnedStruct "This specifies a structure that we use to get the printer name when using the EnumPrinters API" SelfDefinedStructure define: 'PCRETURNED' withFields: ( IdentityDictionary new at: #value put: #( 0 #ulong #yourself ); yourself ). ^SelfDefinedStructure named: 'PCRETURNED'! ! ! Printer class methods ! printerEnumLocal "This flag specifies that we want names of local printers when using EnumPrinters" ^2! ! ! Printer class methods ! printerEnumConnections "This flag specifies that we want names of network printers when using EnumPrinters" ^4! ! ! Printer class methods ! printerInfoLevel "This specifies which kind of information we expect back from EnumPrinters" ^4! ! ! Printer class methods ! printerInfoLength "Return the size of the printer info struct." ^(SelfDefinedStructure named: 'PRINTERINFO4') size! ! ! Printer class methods ! pcbNeededStruct "This specifies a structure that we use to get the printer name when using the EnumPrinters API" SelfDefinedStructure define: 'PCBNEEDED' withFields: ( IdentityDictionary new at: #value put: #( 0 #ulong #yourself ); yourself ). ^SelfDefinedStructure named: 'PCBNEEDED'! ! ! Printer class methods ! kernelMemMoveable "Used in a call to allocate memory for getting printer names" "_LMEM_MOVEABLE = 2" ^2! ! ! Printer class methods ! kernelMemZeroinit "Used in a call to allocate memory for getting printer names" "_LMEM_ZEROINIT = 64" ^64! ! ! Printer class methods ! printerInfo4Struct "This specifies a structure that we use to get the printer name when using the EnumPrinters API" SelfDefinedStructure define: 'PRINTERINFO4' withFields: ( IdentityDictionary new at: #ptrPrinterName put: #( 0 #struct #yourself ); at: #ptrServerName put: #( 4 #struct #yourself ); at: #attributes put: #( 8 #ulong #yourself); yourself ). ^SelfDefinedStructure named: 'PRINTERINFO4'! ! ! Printer class methods ! enumPrinters: flags "Use the Winspool.dll EnumPrinters API to get the list of printers as specified by flags." | pcbNeeded pcReturned printerInfo uFlags hMem pBuffer result count pointer printers movingPointer hOldMem | pcbNeeded := self pcbNeededStruct. pcReturned := self pcReturnedStruct. printerInfo := self printerInfo4Struct. uFlags := self kernelMemMoveable | self kernelMemZeroinit. hMem := KernelLibrary localAlloc: uFlags bytes: self printerInfoLength * 250. "good for 250 printer names" pBuffer := KernelLibrary localLock: hMem. result := WinspoolDLL current enumPrinters: flags name: 0 level: self printerInfoLevel enumBuf: pBuffer sizeBuf: self printerInfoLength * 250 "good for 250 printer names" pNeeded: pcbNeeded asParameter pReturned: pcReturned asParameter. result = 0 ifTrue: [ self osError ]. count := pcReturned value. movingPointer := pBuffer. printers := OrderedCollection new. 0 to: count - 1 do: [ :i | KernelLibrary rtlMoveMemory: printerInfo buffer: movingPointer length: self printerInfoLength. movingPointer := movingPointer + self printerInfoLength. pointer := printerInfo addressAtOffset: 0. printers add: (String fromAddress: pointer) ]. KernelLibrary localFree: hMem. ^printers " Printer enumPrinters: 0 "! ! ! Printer class methods ! printerNames "Answer a collection of all known printer names." "use getPrinterNames which uses Winspool.dll EnumPrintersA" ^self getPrinterNames! ! *** this signature added by listserv *** *** Visit http://www.listserv.dfn.de/archives/vswe-l.html *** *** for archive browsing and VSWE-L membership management *** *** this signature added by listserv *** *** Visit http://www.listserv.dfn.de/archives/vswe-l.html *** *** for archive browsing and VSWE-L membership management *** |
Free forum by Nabble | Edit this page |