Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PDF printing + Duplex in VB6.0

357 views
Skip to first unread message

AEJ45

unread,
Sep 21, 2010, 7:58:13 AM9/21/10
to
We store a lot of pdf documents that are either sent to us or scanned
by us. Our software is then used to print them out as and when needed
either automatically or by clicking a print icon on a form. No matter
what options
I set, I cannot get the pdf files to print in duplex. I am using the
AcroAVDoc to print the pdf files. Is there a duplex option in this?
The printers are HP 9040 DN and an HP 9050 MFP all with duplexing
capabilities.

TIA

Steve Rindsberg

unread,
Sep 21, 2010, 9:13:35 AM9/21/10
to
In article <dbb9467b-3625-4c80-9b05-

Duplexing would be a printer driver option, not an Acrobat/Reader one.

AEJ45

unread,
Sep 22, 2010, 7:58:13 AM9/22/10
to
On 21 Sep, 14:13, Steve Rindsberg <st...@rdpslides.com> wrote:
> In article <dbb9467b-3625-4c80-9b05-

Yes I know, but however I try to get it to print both sides it will
not do it. I set Printer.Duplex = 2 but it refuses to duplex print. It
only affects printing .pdf documents.

Steve Rindsberg

unread,
Sep 22, 2010, 9:22:03 AM9/22/10
to
In article <52125873-8da0-4c10-9b01-

Might this have a bearing? From vbhelp. Doesn't seem likely that it's the
cause (else you'd be seeing the same thing in other instances). Asking's
free though:

====================================================

Dim X As Printer
For Each X In Printers
If X.Orientation = vbPRORPortrait Then
' Set printer as system default.
Set Printer = X
' Stop looking for a printer.
Exit For
End If
Next

You designate one of the printers in the Printers collection as the default
printer by using the Set statement. The preceding example designates the
printer identified by the object variable X, the default printer for the
application.

Note If you use the Printers collection to specify a particular printer,
as in Printers(3), you can only access properties on a read-only basis. To
both read and write the properties of an individual printer, you must first
make that printer the default printer for the application."

============================================


Mike Williams

unread,
Sep 22, 2010, 3:13:06 PM9/22/10
to
"AEJ45" <All...@restons.co.uk> wrote in message
news:52125873-8da0-4c10...@a11g2000vbn.googlegroups.com...

>> Duplexing would be a printer driver option,
>> not an Acrobat/Reader one.
>
> Yes I know, but however I try to get it to print both sides
> it will not do it. I set Printer.Duplex = 2 but it refuses to
> duplex print. It only affects printing .pdf documents.

The changes you make to the VB Printer object's properties apply only to the
documents you print using the VB Printer Object itself. They do not have any
effect at all on the global settings for whatever printer it happens to be
using. This is of course normally exactly what most people want, and is how
you would normally ensure your code behaved no matter what method you were
using to print. The exception to this is if you are popping up a dialog
allowing your user set the VB Printer object to a specific desired printer
using the CommonDialog Control or the equivalent API dialog functions, and
where you have set the CommonDialog PrinterDefault property to True, but
even then the dialog will change /only/ the user's default printer itself to
the selected printer and it will not change any of its default properties
(it will change the properties only for the VB printer Object and for
documents you print using it).

In your case you are using something other than the VB Printer Object to
print your stuff (AcroAVDoc) and therefore if you want to change the
settings of the printer it uses then the best way would be to access
whatever properties AcroAVDoc itself provides. I don't have a full version
of Acrobat installed and I never use AcroAVDoc myself so I don't know what
settings it provides. If you cannot find suitable settings for duplex then
the only sensible option available to you would be to force a change to the
properties and settings of the user's default printer (or whatever other
printer AcroAVDoc is using) so that those settings apply by default to all
applications he is using. You can then immediately print your AcroAVDoc
document and then change the user's default printer settings and properties
back to whatever they were before. Personally I don't like doing this
(changing printer settings in a way that they also affect other
applictaions) but I suppose it is okay if you do it only for the time your
are printing your AcroAVDoc document.

Here is some code which should allow you to do that. To try it out start a
new VB project (just one Form with one Command Button on it) and paste the
following code into the Form. The code to wrap around your AcroAVDoc stuff
is as shown in the Command Button Click event.

Mike

Option Explicit
Private Declare Function ClosePrinter Lib "winspool.drv" _
(ByVal hPrinter As Long) As Long
Private Declare Function DocumentProperties Lib "winspool.drv" _
Alias "DocumentPropertiesA" (ByVal hwnd As Long, _
ByVal hPrinter As Long, ByVal pDeviceName As String, _
ByVal pDevModeOutput As Long, ByVal pDevModeInput As Long, _
ByVal fMode As Long) As Long
Private Declare Function GetPrinter Lib "winspool.drv" Alias _
"GetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, _
pPrinter As Byte, ByVal cbBuf As Long, pcbNeeded As Long) As Long
Private Declare Function OpenPrinter Lib "winspool.drv" Alias _
"OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, _
pDefault As PRINTER_DEFAULTS) As Long
Private Declare Function SetPrinter Lib "winspool.drv" Alias _
"SetPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, _
pPrinter As Byte, ByVal Command As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(pDest As Any, pSource As Any, ByVal cbLength As Long)
Private Type PRINTER_DEFAULTS
pDatatype As Long
pDevmode As Long
DesiredAccess As Long
End Type
Private Type PRINTER_INFO_2
pServerName As Long
pPrinterName As Long
pShareName As Long
pPortName As Long
pDriverName As Long
pComment As Long
pLocation As Long
pDevmode As Long
pSepFile As Long
pPrintProcessor As Long
pDatatype As Long
pParameters As Long
pSecurityDescriptor As Long
Attributes As Long
Priority As Long
DefaultPriority As Long
StartTime As Long
UntilTime As Long
Status As Long
cJobs As Long
AveragePPM As Long
End Type
Private Type DEVMODE
dmDeviceName As String * 32
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * 32
dmUnusedPadding As Integer
dmBitsPerPel As Integer
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
dmICMMethod As Long
dmICMIntent As Long
dmMediaType As Long
dmDitherType As Long
dmReserved1 As Long
dmReserved2 As Long
End Type
Private Const DM_DUPLEX = &H1000&
Private Const DM_IN_BUFFER = 8
Private Const DM_OUT_BUFFER = 2
Private Const PRINTER_ACCESS_ADMINISTER = &H4
Private Const PRINTER_ACCESS_USE = &H8
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const PRINTER_ALL_ACCESS = _
(STANDARD_RIGHTS_REQUIRED Or _
PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)
Private Const DMDUP_SIMPLEX = 1
Private Const DMDUP_VERTICAL = 2
Private Const DMDUP_HORIZONTAL = 3

Public Function SetPrinterDuplex(ByVal sPrinterName As String, _
ByVal nDuplexSetting As Long) As Boolean
Dim hPrinter As Long
Dim pd As PRINTER_DEFAULTS
Dim pinfo As PRINTER_INFO_2
Dim dm As DEVMODE
Dim yDevModeData() As Byte
Dim yPInfoMemory() As Byte
Dim nBytesNeeded As Long
Dim nRet As Long, nJunk As Long
On Error GoTo cleanup
If (nDuplexSetting < 1) Or (nDuplexSetting > 3) Then
' MsgBox "Error: dwDuplexSetting is incorrect."
Exit Function
End If
pd.DesiredAccess = PRINTER_ALL_ACCESS
nRet = OpenPrinter(sPrinterName, hPrinter, pd)
If (nRet = 0) Or (hPrinter = 0) Then
If Err.LastDllError = 5 Then
' MsgBox "Access denied -- See the article for more info."
Else
' MsgBox "Cannot open the printer specified " & _
"(make sure the printer name is correct)."
End If
Exit Function
End If
nRet = DocumentProperties(0, hPrinter, sPrinterName, 0, 0, 0)
If (nRet < 0) Then
' MsgBox "Cannot get the size of the DEVMODE structure."
GoTo cleanup
End If
ReDim yDevModeData(nRet + 100) As Byte
nRet = DocumentProperties(0, hPrinter, sPrinterName, _
VarPtr(yDevModeData(0)), 0, DM_OUT_BUFFER)
If (nRet < 0) Then
' MsgBox "Cannot get the DEVMODE structure."
GoTo cleanup
End If
Call CopyMemory(dm, yDevModeData(0), Len(dm))
If Not CBool(dm.dmFields And DM_DUPLEX) Then
' MsgBox "You cannot modify the duplex flag for this printer " & _
"because it does not support duplex or the driver " & _
"does not support setting it from the Windows API."
GoTo cleanup
End If
dm.dmDuplex = nDuplexSetting
Call CopyMemory(yDevModeData(0), dm, Len(dm))
nRet = DocumentProperties(0, hPrinter, sPrinterName, _
VarPtr(yDevModeData(0)), VarPtr(yDevModeData(0)), _
DM_IN_BUFFER Or DM_OUT_BUFFER)
If (nRet < 0) Then
' MsgBox "Unable to set duplex setting to this printer."
GoTo cleanup
End If
Call GetPrinter(hPrinter, 2, 0, 0, nBytesNeeded)
If (nBytesNeeded = 0) Then
GoTo cleanup
End If
ReDim yPInfoMemory(nBytesNeeded + 100) As Byte
nRet = GetPrinter(hPrinter, 2, yPInfoMemory(0), _
nBytesNeeded, nJunk)
If (nRet = 0) Then
' MsgBox "Unable to get shared printer settings."
GoTo cleanup
End If
Call CopyMemory(pinfo, yPInfoMemory(0), Len(pinfo))
pinfo.pDevmode = VarPtr(yDevModeData(0))
pinfo.pSecurityDescriptor = 0
Call CopyMemory(yPInfoMemory(0), pinfo, Len(pinfo))
nRet = SetPrinter(hPrinter, 2, yPInfoMemory(0), 0)
If (nRet = 0) Then
' MsgBox "Unable to set shared printer settings."
End If
SetPrinterDuplex = CBool(nRet)
cleanup:
If (hPrinter <> 0) Then
Call ClosePrinter(hPrinter)
End If
End Function

Private Sub Command1_Click()
Dim OriginalSetting As Integer
SetPrinterDuplex Printer.DeviceName, DMDUP_VERTICAL
' print your AcroAVDoc document here
SetPrinterDuplex Printer.DeviceName, OriginalSetting
End Sub


Mike Williams

unread,
Sep 22, 2010, 4:03:40 PM9/22/10
to
"Mike Williams" <Mi...@WhiskyAndCoke.com> wrote in message
news:i7dkfl$tl1$1...@speranza.aioe.org...

> Here is some code which should allow you to do that.

I've just noticed that in the code I posted in my previous response I forgot
to read the original Duplex setting. Here is the Command1_Click event code
again:

Private Sub Command1_Click()
Dim OriginalSetting As Integer

OriginalSetting = Printer.Duplex ' this line was ommitted in my previous
response


SetPrinterDuplex Printer.DeviceName, DMDUP_VERTICAL
' print your AcroAVDoc document here
SetPrinterDuplex Printer.DeviceName, OriginalSetting
End Sub

Mike


AEJ45

unread,
Sep 23, 2010, 3:12:55 AM9/23/10
to
On 22 Sep, 21:03, "Mike Williams" <M...@WhiskyAndCoke.com> wrote:
> "Mike Williams" <M...@WhiskyAndCoke.com> wrote in message

Thanks for the two posts Mike. I will try these at some point today
and let you know what happens.

Mike Williams

unread,
Sep 23, 2010, 4:13:26 AM9/23/10
to
"AEJ45" <All...@restons.co.uk> wrote in message
news:3ed6fbd5-f9a7-43d2...@k30g2000vbn.googlegroups.com...

>
> Thanks for the two posts Mike. I will try these at some
> point today and let you know what happens.

Okay. Don't forget that such stuff will not normally work unless you are
running an Admin account. If you are running a standard or limited User
Account then you will need to get your Admin to allow you the appropriate
permissions on those two printers.

Mike


AEJ45

unread,
Sep 23, 2010, 7:26:22 AM9/23/10
to

Mike, the code works a treat. Thank you indeed for your help.

0 new messages