PDA

View Full Version : Printer access



gav12345
09-04-2013, 02:13 AM
Hi,

I’m trying to gain access to default printer, to set printing from double sided to single sided (and then back again). However, I'm unable to get a handle on the printer. Can anyone suggest what I'm doing wrong here?

To do this, we’re using the OpenPrinter function (http://msdn.microsoft.com/en-us/library/windows/desktop/dd162751(v=vs.85).aspx)


In my code I've created a PRINTER_DEFAULTS type for the printer default values parameter of the OpenPrinter function:


Private Type PRINTER_DEFAULTS
pDatatype As Long
pDevmode As Long
DesiredAccess As Long
End Type



I have then created a constant named SERVER_ALL_ACCESS (set to appropriate hex value with high printer access privileges):

Private Const SERVER_ALL_ACCESS = &HF000C


I've then declared various variables to be passed to the OpenPrinter function, including one for the PRINTER_DEFAULTS type:

Dim hPrinter As Long
Dim pd As PRINTER_DEFAULTS
Dim sPrinterName As String


I've currently hard-coded the printer name, but hope to use ActivePrinter when this initial issue is resolved:

sPrinterName = “\\(ServerName)\(PrinterName)”


Have set the printer defaults DesiredAccess to the SERVER_ALL_ACCESS constant defined earlier:

pd.DesiredAccess = SERVER_ALL_ACCESS



When calling the OpenPrinter function, iRet always returns zero - i.e. I can't get a handle on the printer:

iRet = OpenPrinter(sPrinterName, hPrinter, pd)
If (iRet = 0) Or (hPrinter = 0) Then
Exit Function
End If


This is the call to the OpenPrinter function:

Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As PRINTER_DEFAULTS) As Long

Jay Freedman
09-06-2013, 07:31 PM
I suspect that you aren't getting a proper return from OpenPrinter because you don't have the right string for sPrinterName. If you want to use ActivePrinter eventually, why not do it now? Use this construction:


Dim sPrinterName As String
If InStr(ActivePrinter, " on ") Then
sPrinterName = Trim$(Left$(ActivePrinter, InStr(ActivePrinter, " on ")))
Else
sPrinterName = ActivePrinter
End If


If you want to select another printer, see http://word.mvps.org/FAQs/MacrosVBA/AvailablePrinters.htm.

A good series of articles on manipulating printer behavior is here:

Controlling the Printer from Word VBA by Jonathan West
Part 1: Using VBA to Select the Paper Tray
http://pubs.logicalexpressions.com/Pub0009/LPMArticle.asp?ID=101
Part 2: Using VBA to control Duplex, Color Mode and Print Quality
http://pubs.logicalexpressions.com/Pub0009/LPMArticle.asp?ID=116
Part 3: Dealing with Different Paper Sizes
http://pubs.logicalexpressions.com/Pub0009/LPMArticle.asp?ID=132
Part 4: Getting printer driver details
http://pubs.logicalexpressions.com/Pub0009/LPMArticle.asp?ID=183

gav12345
09-17-2013, 04:14 AM
Thanks Jay, sorry for the delay in replying. This turned out to be the security on the printer; when we set up a network printer, but from a local port, this worked OK.

This local option wasn't really practical, so instead of trying to figure out the security on the network printer, we instead created a seperate network printer which was set to print to single sided. We set the ActivePrinter to the single-sided printer whilst printing this particular type of document, and then set this back to the usual default double sided printer when we've finished. So we're changing the printer instead of the printer settings. A bit clunky but it works.

Best wishes, Gavin