Page 1 of 1

List Printers Connected to computer (Answered)

Posted: Mon Sep 07, 2015 5:13 am
by collectordave
Does anyone know how to list all printers connected to a computer?

Even operating system specific answers would be great as i can use the OS version etc to select the code.

Re: List Printers Connected to computer

Posted: Mon Sep 07, 2015 7:05 am
by infratec
Hi,

copied from the Printer_Lib.pb 1.10:

Code: Select all

Procedure.l ipprint_EnumPrinters(enum.l=#PRINTER_ENUM_LOCAL|#PRINTER_ENUM_CONNECTIONS) ; Enumerates all Printers
  Protected buf,cnt,mem,bytes,cntret,size,i
  
  
  If EnumPrinters_(enum,0,1,0,0,@buf,@cnt)=0
    mem=AllocateMemory(buf)
    If mem And EnumPrinters_(enum,0,1,mem,buf,@bytes,@cntret)
      size=SizeOf(PRINTER_INFO_1)
      If cntret
        For i=0 To cntret-1
          Debug PeekS(PeekL(mem+i*size+ 8))
        Next
      EndIf
      FreeMemory(mem)
      ProcedureReturn 1
    EndIf
  EndIf
EndProcedure


ipprint_EnumPrinters()
Bernd

Re: List Printers Connected to computer

Posted: Mon Sep 07, 2015 7:24 am
by collectordave
Great

Working on my windows machine. Is this one just for windows? Not had chance to test on MAC OSX.

Is there also a routine to select supported paper sizes?

Sorry to be a bother.

Re: List Printers Connected to computer

Posted: Mon Sep 07, 2015 7:30 am
by infratec
Hi,

it's windows only, and yes, you can also get the papersizes:

http://www.purebasicpower.de/?PrinterLib_%28Windows%29

Bernd

Re: List Printers Connected to computer

Posted: Mon Sep 07, 2015 7:41 am
by wilbert
Try this on Mac OSX

Code: Select all

ImportC ""
  CFArrayGetCount(theArray.i)
  CFArrayGetValueAtIndex(theArray.i, idx.i)
  PMPaperGetHeight(paper, *paperHeight.Double) 
  PMPaperGetWidth(paper, *paperWidth.Double)
  PMPaperGetPPDPaperName(paper.i, *paperName)
  PMPrinterGetName(printer.i)
  PMPrinterGetPaperList(printer.i, *paperList) 
  PMPrinterIsDefault(printer.i)
  PMServerCreatePrinterList(server.i, *printerList)
EndImport

point2mm.d = 254 / 720

PMServerCreatePrinterList(0, @printers)
printerCount = CFArrayGetCount(printers)

For i = 0 To printerCount - 1
  printer = CFArrayGetValueAtIndex(printers, i)
  
  printerName.s = PeekS(CocoaMessage(0, PMPrinterGetName(printer), "UTF8String"), -1, #PB_UTF8)
  If PMPrinterIsDefault(printer)
    Debug printerName + " (default)"
  Else
    Debug printerName
  EndIf
  
  PMPrinterGetPaperList(printer, @paperList)
  paperCount = CFArrayGetCount(paperList)
  
  For j = 0 To paperCount - 1
    paper = CFArrayGetValueAtIndex(paperList, j)
    PMPaperGetPPDPaperName(paper, @paperName_)
    
    PMPaperGetWidth(paper, @paperWidth.d)
    PMPaperGetHeight(paper, @paperHeight.d)
    paperWidth * point2mm
    paperHeight * point2mm
    
    paperName.s = PeekS(CocoaMessage(0, paperName_, "UTF8String"), -1, #PB_UTF8)
    Debug "   " + paperName + " (" + StrD(paperWidth, 0) +" x " + StrD(paperHeight, 0) + " mm)"
  Next
  
Next

Re: List Printers Connected to computer

Posted: Mon Sep 07, 2015 7:46 am
by TI-994A
collectordave wrote:Does anyone know how to list all printers connected to a computer?
This might do the trick for Windows and OSX, although I've only tested it on the specified platform versions:

Code: Select all

;
; tested with PureBasic v5.31 (x64)
; on Windows 8.1 Professional
; and OSX Mavericks (10.9.5)
;
; adapted from code by srod & Shardik
;

Procedure ListPrinters(Array p.s(1))
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    enumFlags = #PRINTER_ENUM_LOCAL | #PRINTER_ENUM_CONNECTIONS
    If EnumPrinters_(enumFlags, #Null, 1, 0, 0, @deviceNamesBufferSize, @printerCount) = 0
      deviceNamesBuffer = AllocateMemory(deviceNamesBufferSize)
      If deviceNamesBuffer And EnumPrinters_(enumFlags, #Null, 1, 
         deviceNamesBuffer, deviceNamesBufferSize, @sizeRDB, @printerCount)
        If printerCount
          pInfoNameOffset = OffsetOf(PRINTER_INFO_1\pName)
          For i = 0 To (printerCount - 1)
            ReDim p(i)
            p(i) = PeekS(PeekL(deviceNamesBuffer + 
                   i * (SizeOf(PRINTER_INFO_1)) + pInfoNameOffset))
          Next
        EndIf
        FreeMemory(deviceNamesBuffer)
      EndIf
    EndIf      
    
  CompilerElseIf #PB_Compiler_OS = #PB_OS_MacOS
    printers = CocoaMessage(0, 0, "NSPrinter printerNames")
    If printers
      printerCount = CocoaMessage(0, printers, "count")
      For i = 0 To (printerCount - 1)
        ReDim p(i)
        p(i) = PeekS(CocoaMessage(0, CocoaMessage(0, printers, 
               "objectAtIndex:", i), "UTF8String"), -1, #PB_UTF8)
      Next i
    EndIf
    
  CompilerEndIf
  
  ProcedureReturn printerCount
EndProcedure

Dim printers.s(0)
Debug "List of attached printers (" + ListPrinters(printers()) + " detected):"
For i = 0 To ArraySize(printers())
  Debug Str(i + 1) + ". " + printers(i)  
Next i
Hope it helps. :wink:

Re: List Printers Connected to computer

Posted: Mon Sep 07, 2015 1:33 pm
by collectordave
Hi All

All the above code samples worked on both windows and OSX(except the windows only one of course). just tested on my new MAC mini.

The MAC version of my print and preview code also worked correctly on the MAC with no Offsets. Not tested with HP Envy printer yet.

Just could not get my head round listing papers and sizes for the windows version. :?

I will be encorporating some of these into my Print and Preview code.

Thank you to all that helped

Re: List Printers Connected to computer (Answered)

Posted: Wed Sep 23, 2015 12:35 pm
by stefanpape
Thank you, now I have the names of the printers.
But how can I print now on one of this printers - without print requester and not on the standard printer.
I think this is impossible, or not?

Re: List Printers Connected to computer (Answered)

Posted: Wed Sep 23, 2015 5:06 pm
by TI-994A
stefanpape wrote:...how can I print now on one of this printers - without print requester...
Not impossible, but not trivial either.

As you could see, the printer names are simply strings returned from API function calls. In and of themselves, they are practically useless. However, along with various other device information, they could be used to create compatible device contexts, which could then be drawn to, and eventually printed.

This would be outside the purview of PureBasic's printing library, and would require the respective OS's API functions.

For Windows, the required functions would include (among others):
- OpenPrinter()
- ClosePrinter()
- DocumentProperties()
- CreateDC()
- StartDoc()
- EndDoc()


And for OSX:
- PMCreateSession()
- PMCreatePageFormat()
- PMCreatePrintSettings()
- PMSessionGetCGGraphicsContext()
- PMSessionBeginCGDocumentNoDialog()
- PMSessionEndDocumentNoDialog()


You can obtain more information from Microsoft's Windows Dev Center and Apple's Mac Developer Library.

Re: List Printers Connected to computer (Answered)

Posted: Wed Sep 23, 2015 5:19 pm
by wilbert
On OSX you can change the default printer with PMPrinterSetDefault and after that use the PB procedure DefaultPrinter() .
There is however a big catch. PMPrinterSetDefault is system wide so it affects all other applications which is a bad thing :shock: