Declare Function EnumPrinters Lib "winspool.drv" Alias "EnumPrintersA" (ByVal flags As Long, ByVal name As String, ByVal Level As Long, pPrinterEnum As Long, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Platforms: Win 95/98, Win NT
EnumPrinters finds and returns information about one or more printers which the computer has access to. These include both local printers (physically connected to the machine) and network printers (accessible via the network). Under Win 95/98, the information can be passed in a PRINTER_INFO_1, PRINTER_INFO_2, or PRINTER_INFO_5 structure. Under Win NT, the information can be passed in a PRINTER_INFO_1, PRINTER_INFO_2, or PRINTER_INFO_4 structure. Note that structures 4 and 5 are the quickest ones to use. The attributes of the chosen structure determine what kinds of information about the printer(s) is returned. The information itself is put into the array passed as pPrinterEnum, which can then be copied into an array of data structures. The function returns 1 if successful, or 0 if an error occured.
Note for Visual Basic users: Due to limitations in the Visual Basic language, it is impossible to pass an array of PRINTER_INFO_* structures as pPrinterEnum -- the array must be of Long-type elements. Also, for some reason the CopyMemory function cannot be used to successfully transfer the array information into the structure. Instead, each individual member of the data structure must be set manually. Look at the two examples for details how. In order to convert a Long-type string pointer (in the array) to a string, variants of the lstrcpy and lstrlen function must be used. Again, see the examples. CopyMemory, however, can be used to copy the data structures which make up parts of the PRINTER_INFO_2 data structure.
Example #1:
' Get information about all of the local printers using structure 1. Note how
' the elements of the array are loaded into an array of data structures manually. Also
' note how the following special declares must be used to allow numeric string pointers
' to be used in place of strings:
Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Declare Function lstrlen Lib "kernel32.dll" Alias "lstrlenA" (ByVal lpString As Long) As Long
Dim longbuffer() As Long ' resizable array receives information from the function
Dim printinfo() As PRINTER_INFO_1 ' values inside longbuffer() will be put into here
Dim numbytes As Long ' size in bytes of longbuffer()
Dim numneeded As Long ' receives number of bytes necessary if longbuffer() is too small
Dim numprinters As Long ' receives number of printers found
Dim c As Integer, retval As Long ' counter variable & return value
' Get information about the local printers
numbytes = 3076 ' should be sufficiently big, but it may not be
ReDim longbuffer(0 To numbytes / 4) As Long ' resize array -- note how 1 Long = 4 bytes
retval = EnumPrinters(PRINTER_ENUM_LOCAL, "", 1, longbuffer(0), numbytes, numneeded, numprinters)
If retval = 0 Then ' try enlarging longbuffer() to receive all necessary information
numbytes = numneeded
ReDim longbuffer(0 To numbytes / 4) As Long ' make it large enough
retval = EnumPrinters(PRINTER_ENUM_LOCAL, "", 1, longbuffer(0), numbytes, numneeded, numprinters)
If retval = 0 ' failed again!
Debug.Print "Could not successfully enumerate the printes."
End ' abort program
End If
End If
' Convert longbuffer() data into printinfo()
ReDim printinfo(0 To numprinters - 1) As PRINTER_INFO_1 ' room for each printer
For c = 0 To numprinters - 1 ' loop, putting each set of information into each element
' longbuffer(4 * c) = .flags, longbuffer(4 * c + 1) = .pDescription, etc.
' For each string, the string is first buffered to provide enough room, and then the string is copied.
printinfo(c).flags = longbuffer(4 * c)
printinfo(c).pDescription = Space(lstrlen(longbuffer(4 * c + 1)))
retval = lstrcpy(printinfo(c).pDescription, longbuffer(4 * c + 1))
printinfo(c).pName = Space(lstrlen(longbuffer(4 * c + 2)))
retval = lstrcpy(printinfo(c).pName, longbuffer(4 * c + 2))
printinfo(c).pComment = Space(lstrlen(longbuffer(4 * c + 3)))
retval = lstrcpy(printinfo(c).pComment, longbuffer(4 * c + 3))
Next c
' Display name of each printer
For c = 0 To numprinters - 1
Debug.Print "Name of printer"; c + 1; " is: "; printinfo(c).pName
Next c
Example #2:
' Get information about all of the local printers using structure 2. Note how
' the elements of the array are loaded into an array of data structures manually. Also
' note how the following special declares must be used to allow numeric string pointers
' to be used in place of strings:
Declare Function lstrcpy Lib "kernel32.dll" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
Declare Function lstrlen Lib "kernel32.dll" Alias "lstrlenA" (ByVal lpString As Long) As Long
Dim longbuffer() As Long ' resizable array receives information from the function
Dim printinfo() As PRINTER_INFO_2 ' values inside longbuffer() will be put into here
Dim numbytes As Long ' size in bytes of longbuffer()
Dim numneeded As Long ' receives number of bytes necessary if longbuffer() is too small
Dim numprinters As Long ' receives number of printers found
Dim c As Integer, retval As Long ' counter variable & return value
' Get information about the local printers
numbytes = 3076 ' should be sufficiently big, but it may not be
ReDim longbuffer(0 To numbytes / 4) As Long ' resize array -- note how 1 Long = 4 bytes
retval = EnumPrinters(PRINTER_ENUM_LOCAL, "", 2, longbuffer(0), numbytes, numneeded, numprinters)
If retval = 0 Then ' try enlarging longbuffer() to receive all necessary information
numbytes = numneeded
ReDim longbuffer(0 To numbytes / 4) As Long ' make it large enough
retval = EnumPrinters(PRINTER_ENUM_LOCAL, "", 2, longbuffer(0), numbytes, numneeded, numprinters)
If retval = 0 ' failed again!
Debug.Print "Could not successfully enumerate the printes."
End ' abort program
End If
End If
' Convert longbuffer() data into printinfo()
ReDim printinfo(0 To numprinters - 1) As PRINTER_INFO_2 ' room for each printer
For c = 0 To numprinters - 1 ' loop, putting each set of information into each element
' longbuffer(21 * c) = .pServerName, longbuffer(21 * c + 1) = .pPrinterName, etc.
' For each string, the string is first buffered to provide enough room, and then the string is copied.
' For each structure, the memory of it is directly copied via CopyMemory using the pointer.
printinfo(c).pServerName = Space(lstrlen(longbuffer(21 * c)))
retval = lstrcpy(printinfo(c).pServerName, longbuffer(21 * c))
printinfo(c).pPrinterName = Space(lstrlen(longbuffer(21 * c + 1)))
retval = lstrcpy(printinfo(c).pPrinterName, longbuffer(21 * c + 1))
printinfo(c).pShareName = Space(lstrlen(longbuffer(21 * c + 2)))
retval = lstrcpy(printinfo(c).pShareName, longbuffer(21 * c + 2))
printinfo(c).pPortName = Space(lstrlen(longbuffer(21 * c + 3)))
retval = lstrcpy(printinfo(c).pPortName, longbuffer(21 * c + 3))
printinfo(c).pDriverName = Space(lstrlen(longbuffer(21 * c + 4)))
retval = lstrcpy(printinfo(c).pDriverName, longbuffer(21 * c + 4))
printinfo(c).pComment = Space(lstrlen(longbuffer(21 * c + 5)))
retval = lstrcpy(printinfo(c).pComment, longbuffer(21 * c + 5))
printinfo(c).pLocation = Space(lstrlen(longbuffer(21 * c + 6)))
retval = lstrcpy(printinfo(c).pLocation, longbuffer(21 * c + 6))
CopyMemory printinfo(c).pDevMode, longbuffer(21 * c + 7), Len(printinfo(c).pDevMode)
printinfo(c).pSepFile = Space(lstrlen(longbuffer(21 * c + 8)))
retval = lstrcpy(printinfo(c).pSepFile, longbuffer(21 * c + 8))
printinfo(c).pPrintProcessor = Space(lstrlen(longbuffer(21 * c + 9)))
retval = lstrcpy(printinfo(c).pPrintProcessor, longbuffer(21 * c + 9))
printinfo(c).pDatatype = Space(lstrlen(longbuffer(21 * c + 10)))
retval = lstrcpy(printinfo(c).pDatatype, longbuffer(21 * c + 10))
printinfo(c).pParameters = Space(lstrlen(longbuffer(21 * c + 11)))
retval = lstrcpy(printinfo(c).pParameters, longbuffer(21 * c + 11))
CopyMemory printinfo(c).pSecurityDescriptor, longbuffer(21 * c + 12), Len(printinfo(c).pSecurityDescriptor)
printinfo(c).Attributes = longbuffer(21 * c + 13)
printinfo(c).Priority = longbuffer(21 * c + 14)
printinfo(c).DefaultPriority = longbuffer(21 * c + 15)
printinfo(c).StartTime = longbuffer(21 * c + 16)
printinfo(c).UntilTime = longbuffer(21 * c + 17)
printinfo(c).Status = longbuffer(21 * c + 18)
printinfo(c).cJobs = longbuffer(21 * c + 19)
printinfo(c).AveragePPM = longbuffer(21 * c + 20)
Next c
' Display the name of each printer and its average page per minute (ppm) rate
For c = 0 To numprinters - 1
Debug.Print printinfo(c).pPrinterName; " prints an average of"; printinfo(c).AveragePPM; "pages per minute."
Next c
Category: Printers
Go back to the alphabetical Function listing.
Go back to the Reference section index.
This page is copyright © 2000 Paul Kuliniewicz. Copyright Information.
Go back to the Windows API Guide home page.
E-mail: vbapi@vbapi.com Send Encrypted E-Mail
This page is at http://www.vbapi.com/ref/e/enumprinters.html