Print on two sides

I have an application that printed multiple pages and I have a printer 
(BROTHER 5370DW) that allows this.  I select the printer using the 
CommonDialog1.ShowPrinter command and then click on the printer 
preferences to select two-sided printing.  However, when the actual 
printing takes place is does not  print  two-sided.

Is there something in VB print methods that would over-ride  this option 
or not allow it?

Marv
0
M
6/15/2010 9:40:59 PM
vb.general.discussion 1016 articles. 0 followers. Follow

13 Replies
1249 Views

Similar Articles

[PageSpeed] 6

On Jun 15, 2:40=A0pm, M Wade <nowh...@columbus.rr.com> wrote:
> I have an application that printed multiple pages and I have a printer
> (BROTHER 5370DW) that allows this. =A0I select the printer using the
> CommonDialog1.ShowPrinter command and then click on the printer
> preferences to select two-sided printing. =A0However, when the actual
> printing takes place is does not =A0print =A0two-sided.
>
> Is there something in VB print methods that would over-ride =A0this optio=
n
> or not allow it?
>
> Marv

Hi Marv:

While the VB6 Printer Object has a duplex setting (Printer.Duplex) I
don't believe the CommonDialog has that property.

Sooo... you need to Apply the setting using your Brother Print Setup.
I know you think you are doing that now by clicking on the Printer
Preferences button... but unfortunately it doesn't get translated to
the print object or to common dialog.

The answer is to right click on the Brother printer icon in the print
dialog and choose Printer Preferences from the context menu that pops
up.  You'll note in this option an "Apply":button magically appears in
the setup window.  After you've set your options then click Apply,
then Ok.  Now the duplex thing should work.  You'll need to go back to
undo duplex when finished since that has now become the default.  The
Apply button only appears when choosing Printing Preferences from the
context menu.  It is not available if you just click the Preference
button.

The other way would be to create your own duplex option variable.  A
value of 1 is simplex (singled sided), 2 is double sided horizontal
and 3 is double sided vertical.

Tom

0
Shotgun
6/16/2010 4:08:40 AM
"M Wade" <nowhere@columbus.rr.com> wrote in message 
news:us2krNNDLHA.3492@TK2MSFTNGP02.phx.gbl...

> I have an application that printed multiple pages and
> I have a printer (BROTHER 5370DW) that allows this.
>  I select the printer using the CommonDialog1.ShowPrinter
> command and then click on the printer preferences to select
> two-sided printing.  However, when the actual printing
> takes place is does not  print  two-sided. Is there something
> in VB print methods that would over-ride  this option or not allow it?

Under normal usage (from WinXP onwards) the CommonDialog Control changes 
only the printer to be used and not any of its properties (although the user 
can on most systems manually edit the properties in the dialog by right 
clicking as suggested by Shotgun Thom, but in that case you need to 
specifically advise your user to do something that he would not normally do 
and those edits would "stick" beyond your own application and become the 
default properties for all applications unless you asked your user to 
specifically negate them afterwards, and for both of those reasons it is not 
something I would advise).

If you want to change the VB Printer Object's properties to those selected 
by the user in the CommonDialog then you need to transfer them from the 
CommonDialog properties to the equivalent VB Printer Object properties. 
However, the CommonDialog Control does not have a Duplex property and so you 
cannot do that in this specific case. In any case, I would personally advise 
against using the CommonDialog in the normal way anyway, because when the 
user selects a printer in it then that printer becomes the user's new system 
default printer (unless you set the PrinterDefault property to False, which 
in most cases defeats the object altogether). This is not how most 
applications behave. The best way is to allow your user to select the 
desired printer and for that printer to be used only for your own VB 
application, without it altering the user's system default printer or any of 
its default properties.

Of all the available methods (of which there are many) the one I would 
advise you to use is to display a printer dialog (using either the 
CommonDialog Control or the equivalent API dialog) and ask it to return a DC 
for you. Your VB application can then print to that returned DC safe in the 
knowledge that the printer will be set up /exactly/ as the user has selected 
in the printer dialog, including all of the sometimes rather esoteric 
settings that certain specialist printers have and that are simply not 
accessible by any other means (for example, the "use metallic gold ribbon" 
setting on a Citizen Printiva printer, which is something that Windows 
itself knows nothing about). That is by far the best method, and it is 
essentially the method used by most professional applications. The problem 
with this method of course is that you cannot effectively use it with the VB 
Printer Object and so you will need to perform all your printing output 
using the equivalent API printing methods. It is however what I would 
advise.

If you woud prefer to stick with the VB Printer Object then there are other 
methods you can use to display a dialog that returns more information for 
you than does the CommonDialog Control, and that avoids the "printer 
settings sticks as the default" problem and allows your use to select from 
most of the common properties, including your own desired duplex printing 
option. Your code can then transfer those settings to the VB printer Object 
for printing.

There is a Micro$oft DLL that can help you to do this (from memory I think 
it is called msvbprndlg.dll or something similar) but you can do the same 
sort of thing without needing to package a DLL by using standard API dialog 
calls, although you need to take account of the fact that some printers 
(probably mostly network printers) have a device name that is longer than 
the standard maximum 32 character length for dmDeviceName in the DEVMODE 
structure and so you need to make sure that your code takes account of such 
a possibility. As they say in all the best TV cookery programs, here's 
something I prepared earlier (see below) ;-)

Printing is still an evolving thing of course, and so if this code does not 
work for your specific printer then perhaps you might like to consider my 
other suggestion (asking the printer dialog to return a DC for you and 
printing to that DC using API printing methods, which will definitely work 
as long as your printer driver is installed properly). If you have any 
problems then post again, although I imagine that the following code will 
probably do the trick for you (paste it into a VB Form):

Mike

Option Explicit
Private Declare Function GetDeviceCaps Lib "gdi32" _
(ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function PrintDialog Lib "comdlg32.dll" _
  Alias "PrintDlgA" (pPrintdlg As PRINTDLG_TYPE) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias _
  "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, _
  ByVal cbCopy As Long)
Private Declare Function GlobalLock Lib "kernel32" _
  (ByVal hMem As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" _
  (ByVal hMem As Long) As Long
Private Declare Function GlobalAlloc Lib "kernel32" _
  (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" _
  (ByVal hMem As Long) As Long
Private Declare Function SetBkMode Lib "gdi32" _
  (ByVal hdc As Long, ByVal nBkMode As Long) As Long
Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32
Private Const GMEM_MOVEABLE = &H2
Private Const GMEM_ZEROINIT = &H40
Private Const DM_DUPLEX = &H1000&
Private Const DM_ORIENTATION = &H1&
Private Const PD_PRINTSETUP = &H40
Private Const PD_DISABLEPRINTTOFILE = &H80000
Private Const PHYSICALOFFSETX As Long = 112
Private Const PHYSICALOFFSETY As Long = 113
Private Const OPAQUE = 0
Private Const TRANSPARENT = 1
Private Type PRINTDLG_TYPE
  lStructSize As Long
  hwndOwner As Long
  hDevMode As Long
  hDevNames As Long
  hdc As Long
  flags As Long
  nFromPage As Integer
  nToPage As Integer
  nMinPage As Integer
  nMaxPage As Integer
  nCopies As Integer
  hInstance As Long
  lCustData As Long
  lpfnPrintHook As Long
  lpfnSetupHook As Long
  lpPrintTemplateName As String
  lpSetupTemplateName As String
  hPrintTemplate As Long
  hSetupTemplate As Long
End Type
Private Type DEVNAMES_TYPE
  wDriverOffset As Integer
  wDeviceOffset As Integer
  wOutputOffset As Integer
  wDefault As Integer
  extra As String * 200
End Type
Private Type DEVMODE_TYPE
  dmDeviceName As String * CCHDEVICENAME
  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 * CCHFORMNAME
  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
  dmPanningWidth As Long
  dmPanningHeight As Long
End Type

Private Sub SetPrinterOrigin(x As Single, y As Single)
With Printer
  .ScaleLeft = .ScaleX(GetDeviceCaps _
      (.hdc, PHYSICALOFFSETX), _
      vbPixels, .ScaleMode) - x
  .ScaleTop = .ScaleY(GetDeviceCaps _
      (.hdc, PHYSICALOFFSETY), _
      vbPixels, .ScaleMode) - y
  .CurrentX = 0
  .CurrentY = 0
End With
End Sub

Private Function SelectPrinter(frmOwner As Form, Optional _
  InitialPrinter As String, Optional _
  PrintFlags As Long = PD_PRINTSETUP) _
  As Boolean
Dim LongPrinterName As String
Dim PrintDlg As PRINTDLG_TYPE
Dim DevMode As DEVMODE_TYPE
Dim DevName As DEVNAMES_TYPE
Dim lpDevMode As Long, lpDevName As Long
Dim bReturn As Integer, OriginalPrinter As String
Dim p1 As Printer, NewPrinterName As String
PrintDlg.lStructSize = Len(PrintDlg)
PrintDlg.hwndOwner = frmOwner.hWnd
PrintDlg.flags = PrintFlags
On Error Resume Next
OriginalPrinter = Printer.DeviceName
If Len(InitialPrinter) > 0 Then
  For Each p1 In Printers
    If InStr(1, p1.DeviceName, InitialPrinter, _
        vbTextCompare) > 0 Then
      Set Printer = p1
      Exit For
    End If
  Next
End If
DevMode.dmDeviceName = Printer.DeviceName
DevMode.dmSize = Len(DevMode)
DevMode.dmFields = DM_ORIENTATION
DevMode.dmPaperWidth = Printer.Width
DevMode.dmOrientation = Printer.Orientation
DevMode.dmPaperSize = Printer.PaperSize
On Error GoTo 0
PrintDlg.hDevMode = GlobalAlloc(GMEM_MOVEABLE Or _
  GMEM_ZEROINIT, Len(DevMode))
lpDevMode = GlobalLock(PrintDlg.hDevMode)
If lpDevMode > 0 Then
  CopyMemory ByVal lpDevMode, DevMode, Len(DevMode)
  bReturn = GlobalUnlock(PrintDlg.hDevMode)
End If
With DevName
  .wDriverOffset = 8
  .wDeviceOffset = .wDriverOffset + 1 + Len _
    (Printer.DriverName)
  .wOutputOffset = .wDeviceOffset + 1 + Len(Printer.Port)
  .wDefault = 0
End With
With Printer
  DevName.extra = .DriverName & Chr(0) & _
    .DeviceName & Chr(0) & .Port & Chr(0)
End With
PrintDlg.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or _
  GMEM_ZEROINIT, Len(DevName))
lpDevName = GlobalLock(PrintDlg.hDevNames)
If lpDevName > 0 Then
  CopyMemory ByVal lpDevName, DevName, Len(DevName)
  bReturn = GlobalUnlock(lpDevName)
End If
If PrintDialog(PrintDlg) <> 0 Then
CopyMemory DevName, ByVal lpDevName, Len(DevName)
LongPrinterName = Mid$(DevName.extra, _
    DevName.wDeviceOffset - DevName.wDriverOffset + 1)
LongPrinterName = Left$(LongPrinterName, _
    InStr(LongPrinterName, Chr$(0)) - 1)
  DoEvents ' allow dialog to remove itself from display
  Me.Refresh
  SelectPrinter = True
  lpDevName = GlobalLock(PrintDlg.hDevNames)
  CopyMemory DevName, ByVal lpDevName, 45
  bReturn = GlobalUnlock(lpDevName)
  GlobalFree PrintDlg.hDevNames
  lpDevMode = GlobalLock(PrintDlg.hDevMode)
  CopyMemory DevMode, ByVal lpDevMode, Len(DevMode)
  bReturn = GlobalUnlock(PrintDlg.hDevMode)
  GlobalFree PrintDlg.hDevMode
  NewPrinterName = UCase$(Left(DevMode.dmDeviceName, _
    InStr(DevMode.dmDeviceName, Chr$(0)) - 1))
  If Printer.DeviceName <> _
    LongPrinterName Then
    For Each p1 In Printers
      If p1.DeviceName = _
        LongPrinterName Then
        Set Printer = p1
      End If
    Next
  End If
  On Error Resume Next
  ' Transfer settings from the Devmode structure to the
  ' VB printer object (this example just transfers some
  ' of them but you can of course use transfer more)
  Printer.Copies = DevMode.dmCopies
  Printer.Duplex = DevMode.dmDuplex
  Printer.Orientation = DevMode.dmOrientation
  Printer.PaperSize = DevMode.dmPaperSize
  Printer.PrintQuality = DevMode.dmPrintQuality
  Printer.ColorMode = DevMode.dmColor
  Printer.PaperBin = DevMode.dmDefaultSource
  SetBkMode Printer.hdc, TRANSPARENT
  '
  On Error GoTo 0
Else
  SelectPrinter = False ' user cancelled
  For Each p1 In Printers
    If p1.DeviceName = OriginalPrinter Then
      Set Printer = p1
      Exit For
    End If
  Next
  GlobalFree PrintDlg.hDevNames
  GlobalFree PrintDlg.hDevMode
End If
End Function

Private Sub Command1_Click()
' Note: Specifying Printer.DeviceName in the following
' line will start the dialog off with the default
' printer initially selected in the selection box, but
' you can use any other string you wish. For example,
' using "Epson" will cause the dialog to start with
' the first printer it finds with the word "Epson"
' in its device name.
If SelectPrinter(Me, Printer.DeviceName) Then
  Printer.TrackDefault = False
  Printer.ScaleMode = vbInches
  ' set origin to top left corner of physical page
  ' (otherwise it would be the top left corner of
  ' the printable area, which is not the same)
  SetPrinterOrigin 0, 0
  Printer.CurrentX = 1: Printer.CurrentY = 1
  Printer.Print "Hello World"
  Printer.EndDoc
End If
End Sub









 


0
Mike
6/16/2010 4:52:22 PM
Mike,I much appreciate you response and that from Shotgun Thom.  My use 
of VB6 is almost totally for my own use and some I  have developed for 
churches and a privately owned travel agency, so I am not a professional 
programmer.  The specific program I am working on now is to catalog 
books and being able to search by author's name,Book Series and Book 
Title. If I print all of the entries it could go quite a few pages, 
hence the desire to use the duplex capability of the printer which is a 
network device.

I can easily change the printer setting before running the program and 
reset it  after the printing is done but I am interested enough to want 
to try something within the program.  At age 77 and long retired I have 
the time to do that (hopefully).

I am not very clear on using APIs and haven't the foggiest  idea what 
the reference to DC is, but I am going to see if I can understand the 
code you supplied.

Thanks again.

Marv





On 6/16/2010 12:52 PM, Mike Williams wrote:
> "M Wade"<nowhere@columbus.rr.com>  wrote in message
> news:us2krNNDLHA.3492@TK2MSFTNGP02.phx.gbl...
>
>> I have an application that printed multiple pages and
>> I have a printer (BROTHER 5370DW) that allows this.
>>   I select the printer using the CommonDialog1.ShowPrinter
>> command and then click on the printer preferences to select
>> two-sided printing.  However, when the actual printing
>> takes place is does not  print  two-sided. Is there something
>> in VB print methods that would over-ride  this option or not allow it?
>
> Under normal usage (from WinXP onwards) the CommonDialog Control changes
> only the printer to be used and not any of its properties (although the user
> can on most systems manually edit the properties in the dialog by right
> clicking as suggested by Shotgun Thom, but in that case you need to
> specifically advise your user to do something that he would not normally do
> and those edits would "stick" beyond your own application and become the
> default properties for all applications unless you asked your user to
> specifically negate them afterwards, and for both of those reasons it is not
> something I would advise).
>
> If you want to change the VB Printer Object's properties to those selected
> by the user in the CommonDialog then you need to transfer them from the
> CommonDialog properties to the equivalent VB Printer Object properties.
> However, the CommonDialog Control does not have a Duplex property and so you
> cannot do that in this specific case. In any case, I would personally advise
> against using the CommonDialog in the normal way anyway, because when the
> user selects a printer in it then that printer becomes the user's new system
> default printer (unless you set the PrinterDefault property to False, which
> in most cases defeats the object altogether). This is not how most
> applications behave. The best way is to allow your user to select the
> desired printer and for that printer to be used only for your own VB
> application, without it altering the user's system default printer or any of
> its default properties.
>
> Of all the available methods (of which there are many) the one I would
> advise you to use is to display a printer dialog (using either the
> CommonDialog Control or the equivalent API dialog) and ask it to return a DC
> for you. Your VB application can then print to that returned DC safe in the
> knowledge that the printer will be set up /exactly/ as the user has selected
> in the printer dialog, including all of the sometimes rather esoteric
> settings that certain specialist printers have and that are simply not
> accessible by any other means (for example, the "use metallic gold ribbon"
> setting on a Citizen Printiva printer, which is something that Windows
> itself knows nothing about). That is by far the best method, and it is
> essentially the method used by most professional applications. The problem
> with this method of course is that you cannot effectively use it with the VB
> Printer Object and so you will need to perform all your printing output
> using the equivalent API printing methods. It is however what I would
> advise.
>
> If you woud prefer to stick with the VB Printer Object then there are other
> methods you can use to display a dialog that returns more information for
> you than does the CommonDialog Control, and that avoids the "printer
> settings sticks as the default" problem and allows your use to select from
> most of the common properties, including your own desired duplex printing
> option. Your code can then transfer those settings to the VB printer Object
> for printing.
>
> There is a Micro$oft DLL that can help you to do this (from memory I think
> it is called msvbprndlg.dll or something similar) but you can do the same
> sort of thing without needing to package a DLL by using standard API dialog
> calls, although you need to take account of the fact that some printers
> (probably mostly network printers) have a device name that is longer than
> the standard maximum 32 character length for dmDeviceName in the DEVMODE
> structure and so you need to make sure that your code takes account of such
> a possibility. As they say in all the best TV cookery programs, here's
> something I prepared earlier (see below) ;-)
>
> Printing is still an evolving thing of course, and so if this code does not
> work for your specific printer then perhaps you might like to consider my
> other suggestion (asking the printer dialog to return a DC for you and
> printing to that DC using API printing methods, which will definitely work
> as long as your printer driver is installed properly). If you have any
> problems then post again, although I imagine that the following code will
> probably do the trick for you (paste it into a VB Form):
>
> Mike
>
> Option Explicit
> Private Declare Function GetDeviceCaps Lib "gdi32" _
> (ByVal hdc As Long, ByVal nIndex As Long) As Long
> Private Declare Function PrintDialog Lib "comdlg32.dll" _
>    Alias "PrintDlgA" (pPrintdlg As PRINTDLG_TYPE) As Long
> Private Declare Sub CopyMemory Lib "kernel32" Alias _
>    "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, _
>    ByVal cbCopy As Long)
> Private Declare Function GlobalLock Lib "kernel32" _
>    (ByVal hMem As Long) As Long
> Private Declare Function GlobalUnlock Lib "kernel32" _
>    (ByVal hMem As Long) As Long
> Private Declare Function GlobalAlloc Lib "kernel32" _
>    (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
> Private Declare Function GlobalFree Lib "kernel32" _
>    (ByVal hMem As Long) As Long
> Private Declare Function SetBkMode Lib "gdi32" _
>    (ByVal hdc As Long, ByVal nBkMode As Long) As Long
> Private Const CCHDEVICENAME = 32
> Private Const CCHFORMNAME = 32
> Private Const GMEM_MOVEABLE =&H2
> Private Const GMEM_ZEROINIT =&H40
> Private Const DM_DUPLEX =&H1000&
> Private Const DM_ORIENTATION =&H1&
> Private Const PD_PRINTSETUP =&H40
> Private Const PD_DISABLEPRINTTOFILE =&H80000
> Private Const PHYSICALOFFSETX As Long = 112
> Private Const PHYSICALOFFSETY As Long = 113
> Private Const OPAQUE = 0
> Private Const TRANSPARENT = 1
> Private Type PRINTDLG_TYPE
>    lStructSize As Long
>    hwndOwner As Long
>    hDevMode As Long
>    hDevNames As Long
>    hdc As Long
>    flags As Long
>    nFromPage As Integer
>    nToPage As Integer
>    nMinPage As Integer
>    nMaxPage As Integer
>    nCopies As Integer
>    hInstance As Long
>    lCustData As Long
>    lpfnPrintHook As Long
>    lpfnSetupHook As Long
>    lpPrintTemplateName As String
>    lpSetupTemplateName As String
>    hPrintTemplate As Long
>    hSetupTemplate As Long
> End Type
> Private Type DEVNAMES_TYPE
>    wDriverOffset As Integer
>    wDeviceOffset As Integer
>    wOutputOffset As Integer
>    wDefault As Integer
>    extra As String * 200
> End Type
> Private Type DEVMODE_TYPE
>    dmDeviceName As String * CCHDEVICENAME
>    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 * CCHFORMNAME
>    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
>    dmPanningWidth As Long
>    dmPanningHeight As Long
> End Type
>
> Private Sub SetPrinterOrigin(x As Single, y As Single)
> With Printer
>    .ScaleLeft = .ScaleX(GetDeviceCaps _
>        (.hdc, PHYSICALOFFSETX), _
>        vbPixels, .ScaleMode) - x
>    .ScaleTop = .ScaleY(GetDeviceCaps _
>        (.hdc, PHYSICALOFFSETY), _
>        vbPixels, .ScaleMode) - y
>    .CurrentX = 0
>    .CurrentY = 0
> End With
> End Sub
>
> Private Function SelectPrinter(frmOwner As Form, Optional _
>    InitialPrinter As String, Optional _
>    PrintFlags As Long = PD_PRINTSETUP) _
>    As Boolean
> Dim LongPrinterName As String
> Dim PrintDlg As PRINTDLG_TYPE
> Dim DevMode As DEVMODE_TYPE
> Dim DevName As DEVNAMES_TYPE
> Dim lpDevMode As Long, lpDevName As Long
> Dim bReturn As Integer, OriginalPrinter As String
> Dim p1 As Printer, NewPrinterName As String
> PrintDlg.lStructSize = Len(PrintDlg)
> PrintDlg.hwndOwner = frmOwner.hWnd
> PrintDlg.flags = PrintFlags
> On Error Resume Next
> OriginalPrinter = Printer.DeviceName
> If Len(InitialPrinter)>  0 Then
>    For Each p1 In Printers
>      If InStr(1, p1.DeviceName, InitialPrinter, _
>          vbTextCompare)>  0 Then
>        Set Printer = p1
>        Exit For
>      End If
>    Next
> End If
> DevMode.dmDeviceName = Printer.DeviceName
> DevMode.dmSize = Len(DevMode)
> DevMode.dmFields = DM_ORIENTATION
> DevMode.dmPaperWidth = Printer.Width
> DevMode.dmOrientation = Printer.Orientation
> DevMode.dmPaperSize = Printer.PaperSize
> On Error GoTo 0
> PrintDlg.hDevMode = GlobalAlloc(GMEM_MOVEABLE Or _
>    GMEM_ZEROINIT, Len(DevMode))
> lpDevMode = GlobalLock(PrintDlg.hDevMode)
> If lpDevMode>  0 Then
>    CopyMemory ByVal lpDevMode, DevMode, Len(DevMode)
>    bReturn = GlobalUnlock(PrintDlg.hDevMode)
> End If
> With DevName
>    .wDriverOffset = 8
>    .wDeviceOffset = .wDriverOffset + 1 + Len _
>      (Printer.DriverName)
>    .wOutputOffset = .wDeviceOffset + 1 + Len(Printer.Port)
>    .wDefault = 0
> End With
> With Printer
>    DevName.extra = .DriverName&  Chr(0)&  _
>      .DeviceName&  Chr(0)&  .Port&  Chr(0)
> End With
> PrintDlg.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or _
>    GMEM_ZEROINIT, Len(DevName))
> lpDevName = GlobalLock(PrintDlg.hDevNames)
> If lpDevName>  0 Then
>    CopyMemory ByVal lpDevName, DevName, Len(DevName)
>    bReturn = GlobalUnlock(lpDevName)
> End If
> If PrintDialog(PrintDlg)<>  0 Then
> CopyMemory DevName, ByVal lpDevName, Len(DevName)
> LongPrinterName = Mid$(DevName.extra, _
>      DevName.wDeviceOffset - DevName.wDriverOffset + 1)
> LongPrinterName = Left$(LongPrinterName, _
>      InStr(LongPrinterName, Chr$(0)) - 1)
>    DoEvents ' allow dialog to remove itself from display
>    Me.Refresh
>    SelectPrinter = True
>    lpDevName = GlobalLock(PrintDlg.hDevNames)
>    CopyMemory DevName, ByVal lpDevName, 45
>    bReturn = GlobalUnlock(lpDevName)
>    GlobalFree PrintDlg.hDevNames
>    lpDevMode = GlobalLock(PrintDlg.hDevMode)
>    CopyMemory DevMode, ByVal lpDevMode, Len(DevMode)
>    bReturn = GlobalUnlock(PrintDlg.hDevMode)
>    GlobalFree PrintDlg.hDevMode
>    NewPrinterName = UCase$(Left(DevMode.dmDeviceName, _
>      InStr(DevMode.dmDeviceName, Chr$(0)) - 1))
>    If Printer.DeviceName<>  _
>      LongPrinterName Then
>      For Each p1 In Printers
>        If p1.DeviceName = _
>          LongPrinterName Then
>          Set Printer = p1
>        End If
>      Next
>    End If
>    On Error Resume Next
>    ' Transfer settings from the Devmode structure to the
>    ' VB printer object (this example just transfers some
>    ' of them but you can of course use transfer more)
>    Printer.Copies = DevMode.dmCopies
>    Printer.Duplex = DevMode.dmDuplex
>    Printer.Orientation = DevMode.dmOrientation
>    Printer.PaperSize = DevMode.dmPaperSize
>    Printer.PrintQuality = DevMode.dmPrintQuality
>    Printer.ColorMode = DevMode.dmColor
>    Printer.PaperBin = DevMode.dmDefaultSource
>    SetBkMode Printer.hdc, TRANSPARENT
>    '
>    On Error GoTo 0
> Else
>    SelectPrinter = False ' user cancelled
>    For Each p1 In Printers
>      If p1.DeviceName = OriginalPrinter Then
>        Set Printer = p1
>        Exit For
>      End If
>    Next
>    GlobalFree PrintDlg.hDevNames
>    GlobalFree PrintDlg.hDevMode
> End If
> End Function
>
> Private Sub Command1_Click()
> ' Note: Specifying Printer.DeviceName in the following
> ' line will start the dialog off with the default
> ' printer initially selected in the selection box, but
> ' you can use any other string you wish. For example,
> ' using "Epson" will cause the dialog to start with
> ' the first printer it finds with the word "Epson"
> ' in its device name.
> If SelectPrinter(Me, Printer.DeviceName) Then
>    Printer.TrackDefault = False
>    Printer.ScaleMode = vbInches
>    ' set origin to top left corner of physical page
>    ' (otherwise it would be the top left corner of
>    ' the printable area, which is not the same)
>    SetPrinterOrigin 0, 0
>    Printer.CurrentX = 1: Printer.CurrentY = 1
>    Printer.Print "Hello World"
>    Printer.EndDoc
> End If
> End Sub
>
>
>
>
>
>
>
>
>
>
>
>

0
M
6/16/2010 5:54:20 PM
Mike,I much appreciate you response and that from Shotgun Thom.  My use 
of VB6 is almost totally for my own use and some I  have developed for 
churches and a privately owned travel agency, so I am not a professional 
programmer.  The specific program I am working on now is to catalog 
books and being able to search by author's name,Book Series and Book 
Title. If I print all of the entries it could go quite a few pages, 
hence the desire to use the duplex capability of the printer which is a 
network device.

I can easily change the printer setting before running the program and 
reset it  after the printing is done but I am interested enough to want 
to try something within the program.  At age 77 and long retired I have 
the time to do that (hopefully).

I am not very clear on using APIs and haven't the foggiest  idea what 
the reference to DC is, but I am going to see if I can understand the 
code you supplied.

Thanks again.

Marv





On 6/16/2010 12:52 PM, Mike Williams wrote:
> "M Wade"<nowhere@columbus.rr.com>  wrote in message
> news:us2krNNDLHA.3492@TK2MSFTNGP02.phx.gbl...
>
>> I have an application that printed multiple pages and
>> I have a printer (BROTHER 5370DW) that allows this.
>>   I select the printer using the CommonDialog1.ShowPrinter
>> command and then click on the printer preferences to select
>> two-sided printing.  However, when the actual printing
>> takes place is does not  print  two-sided. Is there something
>> in VB print methods that would over-ride  this option or not allow it?
>
> Under normal usage (from WinXP onwards) the CommonDialog Control changes
> only the printer to be used and not any of its properties (although the user
> can on most systems manually edit the properties in the dialog by right
> clicking as suggested by Shotgun Thom, but in that case you need to
> specifically advise your user to do something that he would not normally do
> and those edits would "stick" beyond your own application and become the
> default properties for all applications unless you asked your user to
> specifically negate them afterwards, and for both of those reasons it is not
> something I would advise).
>
> If you want to change the VB Printer Object's properties to those selected
> by the user in the CommonDialog then you need to transfer them from the
> CommonDialog properties to the equivalent VB Printer Object properties.
> However, the CommonDialog Control does not have a Duplex property and so you
> cannot do that in this specific case. In any case, I would personally advise
> against using the CommonDialog in the normal way anyway, because when the
> user selects a printer in it then that printer becomes the user's new system
> default printer (unless you set the PrinterDefault property to False, which
> in most cases defeats the object altogether). This is not how most
> applications behave. The best way is to allow your user to select the
> desired printer and for that printer to be used only for your own VB
> application, without it altering the user's system default printer or any of
> its default properties.
>
> Of all the available methods (of which there are many) the one I would
> advise you to use is to display a printer dialog (using either the
> CommonDialog Control or the equivalent API dialog) and ask it to return a DC
> for you. Your VB application can then print to that returned DC safe in the
> knowledge that the printer will be set up /exactly/ as the user has selected
> in the printer dialog, including all of the sometimes rather esoteric
> settings that certain specialist printers have and that are simply not
> accessible by any other means (for example, the "use metallic gold ribbon"
> setting on a Citizen Printiva printer, which is something that Windows
> itself knows nothing about). That is by far the best method, and it is
> essentially the method used by most professional applications. The problem
> with this method of course is that you cannot effectively use it with the VB
> Printer Object and so you will need to perform all your printing output
> using the equivalent API printing methods. It is however what I would
> advise.
>
> If you woud prefer to stick with the VB Printer Object then there are other
> methods you can use to display a dialog that returns more information for
> you than does the CommonDialog Control, and that avoids the "printer
> settings sticks as the default" problem and allows your use to select from
> most of the common properties, including your own desired duplex printing
> option. Your code can then transfer those settings to the VB printer Object
> for printing.
>
> There is a Micro$oft DLL that can help you to do this (from memory I think
> it is called msvbprndlg.dll or something similar) but you can do the same
> sort of thing without needing to package a DLL by using standard API dialog
> calls, although you need to take account of the fact that some printers
> (probably mostly network printers) have a device name that is longer than
> the standard maximum 32 character length for dmDeviceName in the DEVMODE
> structure and so you need to make sure that your code takes account of such
> a possibility. As they say in all the best TV cookery programs, here's
> something I prepared earlier (see below) ;-)
>
> Printing is still an evolving thing of course, and so if this code does not
> work for your specific printer then perhaps you might like to consider my
> other suggestion (asking the printer dialog to return a DC for you and
> printing to that DC using API printing methods, which will definitely work
> as long as your printer driver is installed properly). If you have any
> problems then post again, although I imagine that the following code will
> probably do the trick for you (paste it into a VB Form):
>
> Mike
>
> Option Explicit
> Private Declare Function GetDeviceCaps Lib "gdi32" _
> (ByVal hdc As Long, ByVal nIndex As Long) As Long
> Private Declare Function PrintDialog Lib "comdlg32.dll" _
>    Alias "PrintDlgA" (pPrintdlg As PRINTDLG_TYPE) As Long
> Private Declare Sub CopyMemory Lib "kernel32" Alias _
>    "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, _
>    ByVal cbCopy As Long)
> Private Declare Function GlobalLock Lib "kernel32" _
>    (ByVal hMem As Long) As Long
> Private Declare Function GlobalUnlock Lib "kernel32" _
>    (ByVal hMem As Long) As Long
> Private Declare Function GlobalAlloc Lib "kernel32" _
>    (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
> Private Declare Function GlobalFree Lib "kernel32" _
>    (ByVal hMem As Long) As Long
> Private Declare Function SetBkMode Lib "gdi32" _
>    (ByVal hdc As Long, ByVal nBkMode As Long) As Long
> Private Const CCHDEVICENAME = 32
> Private Const CCHFORMNAME = 32
> Private Const GMEM_MOVEABLE =&H2
> Private Const GMEM_ZEROINIT =&H40
> Private Const DM_DUPLEX =&H1000&
> Private Const DM_ORIENTATION =&H1&
> Private Const PD_PRINTSETUP =&H40
> Private Const PD_DISABLEPRINTTOFILE =&H80000
> Private Const PHYSICALOFFSETX As Long = 112
> Private Const PHYSICALOFFSETY As Long = 113
> Private Const OPAQUE = 0
> Private Const TRANSPARENT = 1
> Private Type PRINTDLG_TYPE
>    lStructSize As Long
>    hwndOwner As Long
>    hDevMode As Long
>    hDevNames As Long
>    hdc As Long
>    flags As Long
>    nFromPage As Integer
>    nToPage As Integer
>    nMinPage As Integer
>    nMaxPage As Integer
>    nCopies As Integer
>    hInstance As Long
>    lCustData As Long
>    lpfnPrintHook As Long
>    lpfnSetupHook As Long
>    lpPrintTemplateName As String
>    lpSetupTemplateName As String
>    hPrintTemplate As Long
>    hSetupTemplate As Long
> End Type
> Private Type DEVNAMES_TYPE
>    wDriverOffset As Integer
>    wDeviceOffset As Integer
>    wOutputOffset As Integer
>    wDefault As Integer
>    extra As String * 200
> End Type
> Private Type DEVMODE_TYPE
>    dmDeviceName As String * CCHDEVICENAME
>    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 * CCHFORMNAME
>    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
>    dmPanningWidth As Long
>    dmPanningHeight As Long
> End Type
>
> Private Sub SetPrinterOrigin(x As Single, y As Single)
> With Printer
>    .ScaleLeft = .ScaleX(GetDeviceCaps _
>        (.hdc, PHYSICALOFFSETX), _
>        vbPixels, .ScaleMode) - x
>    .ScaleTop = .ScaleY(GetDeviceCaps _
>        (.hdc, PHYSICALOFFSETY), _
>        vbPixels, .ScaleMode) - y
>    .CurrentX = 0
>    .CurrentY = 0
> End With
> End Sub
>
> Private Function SelectPrinter(frmOwner As Form, Optional _
>    InitialPrinter As String, Optional _
>    PrintFlags As Long = PD_PRINTSETUP) _
>    As Boolean
> Dim LongPrinterName As String
> Dim PrintDlg As PRINTDLG_TYPE
> Dim DevMode As DEVMODE_TYPE
> Dim DevName As DEVNAMES_TYPE
> Dim lpDevMode As Long, lpDevName As Long
> Dim bReturn As Integer, OriginalPrinter As String
> Dim p1 As Printer, NewPrinterName As String
> PrintDlg.lStructSize = Len(PrintDlg)
> PrintDlg.hwndOwner = frmOwner.hWnd
> PrintDlg.flags = PrintFlags
> On Error Resume Next
> OriginalPrinter = Printer.DeviceName
> If Len(InitialPrinter)>  0 Then
>    For Each p1 In Printers
>      If InStr(1, p1.DeviceName, InitialPrinter, _
>          vbTextCompare)>  0 Then
>        Set Printer = p1
>        Exit For
>      End If
>    Next
> End If
> DevMode.dmDeviceName = Printer.DeviceName
> DevMode.dmSize = Len(DevMode)
> DevMode.dmFields = DM_ORIENTATION
> DevMode.dmPaperWidth = Printer.Width
> DevMode.dmOrientation = Printer.Orientation
> DevMode.dmPaperSize = Printer.PaperSize
> On Error GoTo 0
> PrintDlg.hDevMode = GlobalAlloc(GMEM_MOVEABLE Or _
>    GMEM_ZEROINIT, Len(DevMode))
> lpDevMode = GlobalLock(PrintDlg.hDevMode)
> If lpDevMode>  0 Then
>    CopyMemory ByVal lpDevMode, DevMode, Len(DevMode)
>    bReturn = GlobalUnlock(PrintDlg.hDevMode)
> End If
> With DevName
>    .wDriverOffset = 8
>    .wDeviceOffset = .wDriverOffset + 1 + Len _
>      (Printer.DriverName)
>    .wOutputOffset = .wDeviceOffset + 1 + Len(Printer.Port)
>    .wDefault = 0
> End With
> With Printer
>    DevName.extra = .DriverName&  Chr(0)&  _
>      .DeviceName&  Chr(0)&  .Port&  Chr(0)
> End With
> PrintDlg.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or _
>    GMEM_ZEROINIT, Len(DevName))
> lpDevName = GlobalLock(PrintDlg.hDevNames)
> If lpDevName>  0 Then
>    CopyMemory ByVal lpDevName, DevName, Len(DevName)
>    bReturn = GlobalUnlock(lpDevName)
> End If
> If PrintDialog(PrintDlg)<>  0 Then
> CopyMemory DevName, ByVal lpDevName, Len(DevName)
> LongPrinterName = Mid$(DevName.extra, _
>      DevName.wDeviceOffset - DevName.wDriverOffset + 1)
> LongPrinterName = Left$(LongPrinterName, _
>      InStr(LongPrinterName, Chr$(0)) - 1)
>    DoEvents ' allow dialog to remove itself from display
>    Me.Refresh
>    SelectPrinter = True
>    lpDevName = GlobalLock(PrintDlg.hDevNames)
>    CopyMemory DevName, ByVal lpDevName, 45
>    bReturn = GlobalUnlock(lpDevName)
>    GlobalFree PrintDlg.hDevNames
>    lpDevMode = GlobalLock(PrintDlg.hDevMode)
>    CopyMemory DevMode, ByVal lpDevMode, Len(DevMode)
>    bReturn = GlobalUnlock(PrintDlg.hDevMode)
>    GlobalFree PrintDlg.hDevMode
>    NewPrinterName = UCase$(Left(DevMode.dmDeviceName, _
>      InStr(DevMode.dmDeviceName, Chr$(0)) - 1))
>    If Printer.DeviceName<>  _
>      LongPrinterName Then
>      For Each p1 In Printers
>        If p1.DeviceName = _
>          LongPrinterName Then
>          Set Printer = p1
>        End If
>      Next
>    End If
>    On Error Resume Next
>    ' Transfer settings from the Devmode structure to the
>    ' VB printer object (this example just transfers some
>    ' of them but you can of course use transfer more)
>    Printer.Copies = DevMode.dmCopies
>    Printer.Duplex = DevMode.dmDuplex
>    Printer.Orientation = DevMode.dmOrientation
>    Printer.PaperSize = DevMode.dmPaperSize
>    Printer.PrintQuality = DevMode.dmPrintQuality
>    Printer.ColorMode = DevMode.dmColor
>    Printer.PaperBin = DevMode.dmDefaultSource
>    SetBkMode Printer.hdc, TRANSPARENT
>    '
>    On Error GoTo 0
> Else
>    SelectPrinter = False ' user cancelled
>    For Each p1 In Printers
>      If p1.DeviceName = OriginalPrinter Then
>        Set Printer = p1
>        Exit For
>      End If
>    Next
>    GlobalFree PrintDlg.hDevNames
>    GlobalFree PrintDlg.hDevMode
> End If
> End Function
>
> Private Sub Command1_Click()
> ' Note: Specifying Printer.DeviceName in the following
> ' line will start the dialog off with the default
> ' printer initially selected in the selection box, but
> ' you can use any other string you wish. For example,
> ' using "Epson" will cause the dialog to start with
> ' the first printer it finds with the word "Epson"
> ' in its device name.
> If SelectPrinter(Me, Printer.DeviceName) Then
>    Printer.TrackDefault = False
>    Printer.ScaleMode = vbInches
>    ' set origin to top left corner of physical page
>    ' (otherwise it would be the top left corner of
>    ' the printable area, which is not the same)
>    SetPrinterOrigin 0, 0
>    Printer.CurrentX = 1: Printer.CurrentY = 1
>    Printer.Print "Hello World"
>    Printer.EndDoc
> End If
> End Sub
>
>
>
>
>
>
>
>
>
>
>
>

0
M
6/16/2010 5:55:03 PM
"M Wade" <nowhere@columbus.rr.com> wrote in message 
news:4C190FCC.8090905@columbus.rr.com...

> I am not very clear on using APIs and haven't the
> foggiest  idea what the reference to DC is, but I
> am going to see if I can understand the code you
> supplied.

If you have the time to study the code then of course it is often a 
rewarding thing to do, but if you don't have the time to do so, or if there 
are other more important things for you to be getting on with, then that's 
fine as well. Essentially the bulk of the code can be viewed as simply a 
"black box" that performs a specific task for you.

You do really need to study the code in the Command Button Click Event 
though, which is the part that shows you how to call the two routines in 
order to allow the user to select the printer and to position your output 
accurately on the page. Post again if you have any questions on that part, 
or in fact on any other part of the code. By the way, I forgot to mentioned 
that you should paste the code into a VB Form containing a Command Button 
(although I'm sure you've already done that by now).

Mike




0
Mike
6/16/2010 8:11:43 PM
Marv:

The Microsoft DLL that is a replacement for the common dialog ocx that
Mike mentioned earlier is named vbprndlg.dll.

It can be found here:  http://support.microsoft.com/kb/322710

It's a pretty solid wrapper for the API.  It may be worth taking a
look at as well.  It will return your duplex option.

Mike:

The biggest problem I've had with the vpprndlg.dll, or for that fact,
API code is for special printer options.  I have a client that has a
Konica C350 by Minolta.  It not only collates but can staple, punch 2
or 3 ring binder holes and makes you a cup of expresso while you
wait..  It's one of those we can do everything printers.

I have never been able to figure out how to set these esoteric options
other than right clicking on the printer icon and setting the printer
settings for a particular job that requires them and then resetting
those properties when finished.  I know it can be done because even
simple Notepad can set these properties through the printers
properties setup for just the current print job without having to go
back and reset them.  I just don't have a clue on how to do it in VB.

Tom

0
Shotgun
6/17/2010 6:13:12 AM
"Shotgun Thom" <tmoran4511@gmail.com> wrote in message 
news:c9670b3a-076a-4d2b-8d6f-4b7dcdcabc24@z15g2000prh.googlegroups.com...

> Mike: The biggest problem I've had with the vpprndlg.dll,
> or for that fact, API code is for special printer options.  I
> have a client that has a Konica C350 by Minolta.  It not only
> collates but can staple, punch 2 or 3 ring binder holes and
> makes you a cup of expresso while you wait..  It's one of
> those we can do everything printers. I have never been able
> to figure out how to set these esoteric options other than right
> clicking on the printer icon and setting the printer settings for
> a particular job that requires them and then resetting those
> properties when finished.

When you use the MS vbprndlg DLL or any other equivalent method (API dialogs 
or the CommonDialog control) in a way that transfers the user's settings 
from the dialog to the VB Printer Object then you simply cannot get access 
to all possible printer settings, especially those esoteric settings that I 
mentioned myself in my response to the OP, the printiva "use metallic gold 
ribbon", and the other esoteric settings you have mentioned, the "punch 3 
ring binder holes and make a cup of expresso while you're waiting" stuff ;-) 
That's partly because the VB Printer Object cannot "eat" such settings and 
partly because Windows itself does not really know about such things (at 
least not in detail in a standard Windows way). The details of such esoteric 
settings are of course stored in Devmode Extras, but as far as Windows 
itself is concerned some of that information is "just a bunch of numbers" 
and many of them are known and understood in detail only by the printer 
driver itself. You can however give your user access to all those settings, 
but you cannot do so in a way that allows you to use the VB Printer object 
for your printing, at least not without resorting to the kind of methods you 
have mentioned, such as requiring the user to right click the printer and 
change its default settings and then change them back again afterwards.

In order to get at all that stuff in a way that does not require you to mess 
about with right clicking or changing default settings, you need to present 
a printer dialog to the user in the normal way but you need to ask the 
dialog to return a DC for you. That returned DC will contain all of the 
things that the user has selected in the printer dialog, the printer itself 
and all the user's settings, including all those esoteric settings, and you 
can then draw and print stuff to that DC in much the same way as you would 
draw and print things to any DC. This of course means that you cannot use 
the VB Printer Object and you must instead use the Windows StartDoc, EndDoc 
etc methods to create the document and use the standard TextOut and Drawtext 
and StretchBlt etc methods for drawing text and lines and boxes and images, 
etc. You can use whichever method you personally prefer for showing the 
dialog. Here is an example in which I have used the standard CommonDialog 
Control. As is the case with just about everything I write, it is not (and 
never will be) a "finished product" because I am just a hobbyist and I 
usually take things only as far as I need to in order to convince myself 
that I can do something. It should give you a good start though.

Paste the following code into a VB Form containing a CommonDialog Control, a 
Command Button and an Image Control. For test purposes set the Image 
Control's Stretch property to True (so that you can see the whole image and 
know that it prints properly) and set its Picture property to a picture that 
exists on your own machine. The example prints a couple of rectangles and a 
picture and some text, using two pages. Since it is just test code it makes 
no attempt to maintain the original aspect ratio of the picture when 
printing it, but you can of course easily add code to do that.

Mike

Option Explicit
Private Declare Function StartDoc Lib "gdi32" Alias _
  "StartDocA" (ByVal hdc As Long, lpdi As DOCINFO) As Long
Private Declare Function EndDoc Lib "gdi32" _
  (ByVal hdc As Long) As Long
Private Declare Function StartPage Lib "gdi32" _
  (ByVal hdc As Long) As Long
Private Declare Function EndPage Lib "gdi32" _
  (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" _
  (ByVal hdc As Long) As Long
Private Declare Function CreateFontIndirect Lib "gdi32" _
  Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
Private Declare Function SelectObject Lib "gdi32" _
  (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function CreatePen Lib "gdi32" _
  (ByVal nPenStyle As Long, ByVal nWidth As Long, _
  ByVal crColor As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
   (ByVal hObject As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" _
  (ByVal hdc As Long) As Long
Private Declare Function StretchBlt Lib "gdi32" _
  (ByVal hdc As Long, _
  ByVal x As Long, ByVal y As Long, _
  ByVal nWidth As Long, ByVal nHeight As Long, _
  ByVal hSrcDC As Long, ByVal xSrc As Long, _
  ByVal ySrc As Long, _
  ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, _
  ByVal dwRop As Long) As Long
Private Declare Function SetStretchBltMode Lib "gdi32" _
  (ByVal hdc As Long, ByVal nStretchMode As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias _
"TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal _
y As Long, ByVal lpString As String, ByVal nCount _
As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" _
  (ByVal hdc As Long, ByVal nindex As Long) As Long
Private Declare Function SetBkMode Lib "gdi32" _
  (ByVal hdc As Long, ByVal nBkMode As Long) As Long
Private Declare Function Rectangle Lib "gdi32" _
  (ByVal hdc As Long, ByVal x1 As Long, ByVal y1 As Long, _
  ByVal x2 As Long, ByVal y2 As Long) As Long
Private Const LF_FACESIZE As Long = 32&
Private Const LOGPIXELSX As Long = 88&
Private Const LOGPIXELSY As Long = 90&
Private Const PHYSICALOFFSETX As Long = 112&
Private Const PHYSICALOFFSETY As Long = 113&
Private Const PHYSICALWIDTH As Long = 110&
Private Const PHYSICALHEIGHT As Long = 111&
Private Const POINTSPERINCH As Long = 72&
Private Const NORMAL As Long = 400&
Private Const BOLD As Long = 700&
Private Const TRANSPARENT As Long = 1&
Private Const OPAQUE As Long = 2&
Private Const STRETCH_ANDSCANS As Long = 1&
Private Const STRETCH_ORSCANS As Long = 2&
Private Const STRETCH_DELETESCANS As Long = 3&
Private Const STRETCH_HALFTONE As Long = 4&
Private Const PS_SOLID As Long = 0&
Private Type DOCINFO
  cbSize As Long
  lpszDocName As String
  lpszOutput As String
  lpszDatatype As String
  fwType As Long
End Type
Private Type LOGFONT
  lfHeight As Long
  lfWidth As Long
  lfEscapement As Long
  lfOrientation As Long
  lfWeight As Long
  lfItalic As Byte
  lfUnderline As Byte
  lfStrikeOut As Byte
  lfCharSet As Byte
  lfOutPrecision As Byte
  lfClipPrecision As Byte
  lfQuality As Byte
  lfPitchAndFamily As Byte
  lfFaceName As String * LF_FACESIZE
End Type
Private Type PrinterInfo
  Handle As Long
  PixPerInchX As Long
  PixPerInchY As Long
  OffsetX As Long
  OffsetY As Long
  PageWidthInches As Single
  PageHeightInches As Single
End Type
Private MyPrinter As PrinterInfo
Private UserCancelled As Boolean
Private LF1 As LOGFONT
Private oldFont As Long, oldPen As Long
Private myFont1 As Long, myFont2 As Long, myFont3 As Long
Private myPen1 As Long, myPen2 As Long

Private Sub GetMyPrinter()
UserCancelled = False
CommonDialog1.PrinterDefault = False
CommonDialog1.CancelError = True
' The following cdlPDReturnDC flag is essential, but
' you can combine it with other flags if you wish
CommonDialog1.Flags = cdlPDReturnDC
On Error GoTo dlgError
CommonDialog1.ShowPrinter
On Error GoTo 0
MyPrinter.Handle = CommonDialog1.hdc
MyPrinter.PixPerInchX = GetDeviceCaps _
  (MyPrinter.Handle, LOGPIXELSX)
MyPrinter.PixPerInchY = GetDeviceCaps _
  (MyPrinter.Handle, LOGPIXELSY)
MyPrinter.OffsetX = GetDeviceCaps _
  (MyPrinter.Handle, PHYSICALOFFSETX)
MyPrinter.OffsetY = GetDeviceCaps _
  (MyPrinter.Handle, PHYSICALOFFSETY)
MyPrinter.PageWidthInches = CSng(GetDeviceCaps _
  (MyPrinter.Handle, PHYSICALWIDTH)) / _
  MyPrinter.PixPerInchX
MyPrinter.PageHeightInches = CSng(GetDeviceCaps _
  (MyPrinter.Handle, PHYSICALHEIGHT)) / _
  MyPrinter.PixPerInchY
' Set up a few fonts that can be easily used
' throughout the printing code (this is just the
' way I personally prefer to do it rather than
' create and destroy a font each time I use one)
With LF1
  .lfFaceName = "Times New Roman" + Chr$(0)
  ' 12 point standard
  .lfEscapement = 0
  .lfHeight = 12 * (-MyPrinter.PixPerInchY / POINTSPERINCH)
  .lfWeight = NORMAL
End With
myFont1 = CreateFontIndirect(LF1)
With LF1
  .lfFaceName = "Times New Roman" + Chr$(0)
  ' 16 point standard
  .lfEscapement = 0
  .lfHeight = 16 * (-MyPrinter.PixPerInchY / POINTSPERINCH)
  .lfWeight = NORMAL
End With
myFont2 = CreateFontIndirect(LF1)
With LF1
  .lfFaceName = "Times New Roman" + Chr$(0)
  ' 12 point rotated by 90 degrees
  .lfEscapement = 900
  .lfHeight = 12 * (-MyPrinter.PixPerInchY / POINTSPERINCH)
  .lfWeight = NORMAL
End With
myFont3 = CreateFontIndirect(LF1)
' store the old font handle and set the initial font to myFont1
oldFont = SelectObject(MyPrinter.Handle, myFont1)
' set up a couple of black pens (0.01 inches and 0.025 inches)
myPen1 = CreatePen(PS_SOLID, MyPrinter.PixPerInchX * 0.01, vbBlack)
myPen2 = CreatePen(PS_SOLID, MyPrinter.PixPerInchX * 0.025, vbBlack)
' store the old pen handle and set the initial pen to myPen1
oldPen = SelectObject(MyPrinter.Handle, myPen1)
SetBkMode MyPrinter.Handle, TRANSPARENT ' FontTransparent
' Set the stretch mode to the desired mode
SetStretchBltMode MyPrinter.Handle, STRETCH_DELETESCANS
'SetStretchBltMode MyPrinter.Handle, STRETCH_HALFTONE
Exit Sub
dlgError:
UserCancelled = True
End Sub

Private Sub TextPrint(s1 As String, x As Single, y As Single)
Dim xpos As Long, ypos As Long
xpos = x * MyPrinter.PixPerInchX - MyPrinter.OffsetX
ypos = y * MyPrinter.PixPerInchY - MyPrinter.OffsetY
TextOut MyPrinter.Handle, xpos, ypos, s1, Len(s1)
End Sub

Private Sub RectPrint(x1 As Single, y1 As Single, _
        x2 As Single, y2 As Single)
Rectangle MyPrinter.Handle, _
  x1 * MyPrinter.PixPerInchX - MyPrinter.OffsetX, _
  y1 * MyPrinter.PixPerInchY - MyPrinter.OffsetY, _
  x2 * MyPrinter.PixPerInchX - MyPrinter.OffsetX, _
  y2 * MyPrinter.PixPerInchY - MyPrinter.OffsetY
End Sub

Private Function PrintImage(p1 As StdPicture, _
        x As Single, y As Single, wide As Single, _
        high As Single) As Boolean
Dim hOldBitmap As Long, hMemoryDC As Long
hMemoryDC = CreateCompatibleDC(Me.hdc)
hOldBitmap = SelectObject(hMemoryDC, p1.Handle)
' Note: I use StretchBlt here because it is what
' I normally use for the printing of various
' images, but you could probably use the
' Render method instead if you wish
StretchBlt MyPrinter.Handle, _
  x * MyPrinter.PixPerInchX - MyPrinter.OffsetX, _
  y * MyPrinter.PixPerInchY - MyPrinter.OffsetY, _
  wide * MyPrinter.PixPerInchX, _
  high * MyPrinter.PixPerInchY, _
  hMemoryDC, _
  0, 0, _
  Me.ScaleX(p1.Width, vbHimetric, vbPixels), _
  Me.ScaleY(p1.Height, vbHimetric, vbPixels), _
  vbSrcCopy
hOldBitmap = SelectObject(hMemoryDC, hOldBitmap)
DeleteDC hMemoryDC
End Function

Private Sub Command1_Click()
Dim lret As Long, s1 As String, docinf As DOCINFO
' Display a printer dialog and set up a printer DC
' in accordance with the user's selection and set
' up a few fonts and a couple of pens
GetMyPrinter
' Exit if the user pressed Cancel in the dialog
If UserCancelled Then
  Exit Sub
End If
' start a document
docinf.cbSize = 20 ' Size of DOCINFO structure
lret = StartDoc(MyPrinter.Handle, docinf) 'Start document
If lret < 0 Then
  MsgBox "Failed to start document"
  Exit Sub
End If
lret = StartPage(MyPrinter.Handle) 'Start a new page
If lret < 0 Then
  MsgBox "Failed to start page!"
  EndDoc MyPrinter.Handle
  Exit Sub
End If
' print a rectangle using myPen1 with an exact one
' inch all round border
SelectObject MyPrinter.Handle, myPen1
RectPrint 1, 1, MyPrinter.PageWidthInches - 1, _
  MyPrinter.PageHeightInches - 1
' print a rectangle just inside it using the thicker myPen2
SelectObject MyPrinter.Handle, myPen2
RectPrint 1.1, 1.1, MyPrinter.PageWidthInches - 1.1, _
  MyPrinter.PageHeightInches - 1.1
' print an image at location 1.2,1.2 at size 3 x 2 inches
PrintImage Image1.Picture, 1.2, 1.2, 3, 2
' print some text using myFont1
SelectObject MyPrinter.Handle, myFont1
s1 = "This is some text on page ONE "
TextPrint s1, 1.2, 1.2 ' print some text (positions in inches)
' print some more text using myFont2
SelectObject MyPrinter.Handle, myFont2
s1 = "This should be in myFont2, which we have set to 16 points"
TextPrint s1, 1.2, 2
' print some m ore text using myFont3
SelectObject MyPrinter.Handle, myFont3
s1 = "And this should be 12 points rotated at 90 degrees."
TextPrint s1, 1.2, 7
lret = EndPage(MyPrinter.Handle) 'End the page
lret = StartPage(MyPrinter.Handle) ' start a new page
' now change back to myFont1
SelectObject MyPrinter.Handle, myFont1
s1 = "And this is on page Two"
TextPrint s1, 1, 1
lret = EndPage(MyPrinter.Handle) 'End the page
lret = EndDoc(MyPrinter.Handle) 'End the document
' Reset font back to original and delete font we created
SelectObject MyPrinter.Handle, oldFont
DeleteObject myFont1  'Delete the fonts
DeleteObject myFont2
DeleteObject myFont3
SelectObject MyPrinter.Handle, oldPen
DeleteObject myPen1 ' Delete the pens
DeleteObject myPen2
' Delete the printer DC
DeleteDC MyPrinter.Handle
End Sub





0
Mike
6/17/2010 11:58:24 AM
Thanks, Mike.  I see what you're doing.  This will be helpful in
future projects and I thank you.

The problem with the Konica client is that we are using the TxText
control, which has two internal print routines.  A print page method
and a print doc method.  When calling these methods we actually do
pass the Printer.hDC to the control.  However, it seems to have no
impact on the settings of those special print options.  Still have to
change the defaults directly in the printer and then set it back
afterwards for it to take effect.  I really don't like doing it that
way.

BTW, one danger of doing it this way is duplicate settings.  You'll
love this.  The Konica allows you to select the number of copies to
print directly in it's setup program.  He needed 44 copies and set the
copies option to 44.  After clicking OK he noticed the copies number
in the command dialog box said 1 so he changed it to 44.  Hit print...
and you guessed it.... he got 44 sets of 44 copies.  Cleaned out the
paper bins before he realized it. :)

Thanks, again, Mike!

Tom

0
Shotgun
6/17/2010 5:29:09 PM
"Shotgun Thom" <tmoran4511@gmail.com> wrote in message 
news:8ddc34e9-af22-43f5-85cb-13feac34ffcb@x27g2000prf.googlegroups.com...

> Thanks, Mike.  I see what you're doing.  This will be
> helpful in future projects and I thank you.

You're welcome.

> The problem with the Konica client is that we are using the
> TxText control, which has two internal print routines.  A
> print page method and a print doc method.  When calling
> these methods we actually do pass the Printer.hDC to the
> control.  However, it seems to have no impact on the settings
> of those special print options.  Still have to change the defaults
> directly in the printer and then set it back afterwards for it to
> take effect.  I really don't like doing it that way.

Well it won't succeed if you are passing the VB Printer Object's hDC (as is 
implied in your statement, "we pass the Printer.hDC") because the VB Printer 
Object has not been set up to deal with (and actually cannot be set up to 
deal with) those special print options. I've never heard of the TxText 
control and therefore have no knowledge of how it fits into your program, 
but you will have much more chance of success if you use the code I posted 
to show the printer dialog to the user in such a way that it returns a DC 
from the dialog (exactly as it does in the code I posted) and if you pass 
/the returned hDC/ to the TxText control.

> BTW, one danger of doing it this way is duplicate settings.  You'll
> love this.  The Konica allows you to select the number of copies
> to print directly in it's setup program.  He needed 44 copies and
> set the copies option to 44.  After clicking OK he noticed the copies
> number in the command dialog box said 1 so he changed it to 44.
> Hit print...and you guessed it.... he got 44 sets of 44 copies.
> Cleaned out the paper bins before he realized it. :)

That's a good one! I don't know how the Konica deals with such things, nor 
from your brief explanation do I know the full details of how this actually 
occurred (perhaps the TxText Control you are using and the Konica itself 
ended up /both/ being set for 44 copies, and I'm sure there is a way of 
making sure it does not happen like that again) but it is interesting 
nonetheless. Maybe under such circumstances you could hang the surplus 1892 
pages on the back of the toilet door (or do they perhaps call them something 
other than toilets on your side of the big pond?). At least they'd be of 
some use there ;-)  You'd need to alter your code so that it does /not/ do 
duplex printing though. I think for such a use at least one side of the page 
should have no ink on it ;-)

> Thanks, again, Mike!

You're welcome.

Mike



0
Mike
6/17/2010 9:26:15 PM
"Shotgun Thom" <tmoran4511@gmail.com> wrote in message 
news:8ddc34e9-af22-43f5-85cb-13feac34ffcb@x27g2000prf.googlegroups.com...

Further to the response I've just posted, I think there is something else I 
need to add, just to clarify things a little for you. In your own response 
you said, "When calling these methods we actually do pass the Printer.hDC to 
the control but it seems to have no impact on the settings".

I my own response to that statement I said that you should instead pass the 
hDC returned  by the printer dialog in the code I posted, which should work 
okay for you because that hDC is fully modified by all the user's selections 
in the dialog. However, in view of what you said, I think I should also make 
a few comments regarding your act of passing the printer Object's hDC, and 
explain to you in more detail why that particular method would in fact not 
work.

As far as your VB code is concerned, regardless of the state of the dialog's 
PrinterDefault property, from WinXP onwards only the printer itself is 
regarded as a "user setting", but its properties are not. In other words, 
the act of the user changing the printer name in your dialog will change the 
default printer for that user, but the act of him also changing various 
properties of that printer will /not/change the default properties for that 
printer for that user (does that make sense the way I have explained it?). 
In Win98 the act of the user changing the printer and its properties in the 
dialog would result in /all/ those changes being reflected in the default 
printer, whereas in XP onwards only the default printer itself would change, 
but none of its default properties

So, what happens when you present a printer dialog to the user is the actual 
"default printer to use" gets changed, but none of its default properties do 
(they all remain the same as they were before). That is why the various 
options to deal with that problem, including the MS vbprndlg DLL, rely on 
"reading" the changes made by the user in the dialog and then passing them 
on to the VB Printer Object's own equivalent properties. If you did not do 
that then when you used the VB Printer Object to print something it would go 
to the correct printer okay, but it would use the pre-existing default 
properties of that printer. (I've had quite a few glasses of wine tonight, 
but hopefully I am still making sense?). And, of course, the printer dialog 
does not itself have any properties for the esoteric settings you are 
talking about, and even if it did do so the VB Printer Object could not 
"eat" them.

The alternative method that I posted does not need to concern itself with 
any of that stuff, because the dialog itself returns a DC for you and that 
DC is set up by the user exactly in accordance with the printer he wants to 
use and also in accordance with all the settings he has chosen for that 
printer, including all of the esoteric setting we have been talking about. 
Printing to that DC should work fine, because it has nothing whatsoever to 
do with the VB printer Object's hDC.

Have I helped at all in that supplementary explanation, or have I perhaps 
just "muddied the waters"? (I must confess that I'm slightly inebriated at 
the moment!).

Anyway, if you do what I suggested in my previous response then you should 
be okay (although I've never heard of and never used your TxText Control and 
so I cannot be absolutely certain of that).

Mike




0
Mike
6/17/2010 10:08:01 PM
On Jun 17, 3:08=A0pm, "Mike Williams" <M...@WhiskeyAndCoke.com> wrote:
> "Shotgun Thom" <tmoran4...@gmail.com> wrote in message
>
> news:8ddc34e9-af22-43f5-85cb-13feac34ffcb@x27g2000prf.googlegroups.com...
>
> Further to the response I've just posted, I think there is something else=
 I
> need to add, just to clarify things a little for you. In your own respons=
e
> you said, "When calling these methods we actually do pass the Printer.hDC=
 to
> the control but it seems to have no impact on the settings".
>
> I my own response to that statement I said that you should instead pass t=
he
> hDC returned =A0by the printer dialog in the code I posted, which should =
work
> okay for you because that hDC is fully modified by all the user's selecti=
ons
> in the dialog. However, in view of what you said, I think I should also m=
ake
> a few comments regarding your act of passing the printer Object's hDC, an=
d
> explain to you in more detail why that particular method would in fact no=
t
> work.
>
> As far as your VB code is concerned, regardless of the state of the dialo=
g's
> PrinterDefault property, from WinXP onwards only the printer itself is
> regarded as a "user setting", but its properties are not. In other words,
> the act of the user changing the printer name in your dialog will change =
the
> default printer for that user, but the act of him also changing various
> properties of that printer will /not/change the default properties for th=
at
> printer for that user (does that make sense the way I have explained it?)=
..
> In Win98 the act of the user changing the printer and its properties in t=
he
> dialog would result in /all/ those changes being reflected in the default
> printer, whereas in XP onwards only the default printer itself would chan=
ge,
> but none of its default properties
>
> So, what happens when you present a printer dialog to the user is the act=
ual
> "default printer to use" gets changed, but none of its default properties=
 do
> (they all remain the same as they were before). That is why the various
> options to deal with that problem, including the MS vbprndlg DLL, rely on
> "reading" the changes made by the user in the dialog and then passing the=
m
> on to the VB Printer Object's own equivalent properties. If you did not d=
o
> that then when you used the VB Printer Object to print something it would=
 go
> to the correct printer okay, but it would use the pre-existing default
> properties of that printer. (I've had quite a few glasses of wine tonight=
,
> but hopefully I am still making sense?). And, of course, the printer dial=
og
> does not itself have any properties for the esoteric settings you are
> talking about, and even if it did do so the VB Printer Object could not
> "eat" them.
>
> The alternative method that I posted does not need to concern itself with
> any of that stuff, because the dialog itself returns a DC for you and tha=
t
> DC is set up by the user exactly in accordance with the printer he wants =
to
> use and also in accordance with all the settings he has chosen for that
> printer, including all of the esoteric setting we have been talking about=
..
> Printing to that DC should work fine, because it has nothing whatsoever t=
o
> do with the VB printer Object's hDC.
>
> Have I helped at all in that supplementary explanation, or have I perhaps
> just "muddied the waters"? (I must confess that I'm slightly inebriated a=
t
> the moment!).
>
> Anyway, if you do what I suggested in my previous response then you shoul=
d
> be okay (although I've never heard of and never used your TxText Control =
and
> so I cannot be absolutely certain of that).
>
> Mike

I think I understand, and I believe that's what I'm doing with the
TxText Control.  The control has a property which must be set before
printing.  TXTextControl1.PrintDevice =3D Printer.hDC

I obtain that hDC by setting the cdlPDReturnDC flag in the
vbprndlg.dll print dialog.  I believe the DC then get's set in the
Printer.hDC property (at least according to MS help docs).  It's then
passed to the control.  It selects the correct printer but only passes
the defaults.

Isn't that the same DC as I would get using your code?

API Printing is not practical with the TxTextControl.  It has highly
specialized formatting, style sheets, formats in .doc,
docx, .rtf, .html, xml and so forth.  There are MS merge and mail
merge fields, Columns, PDF printing, etc. Text boxes, floating
images... very much like Word.

Tom
0
Shotgun
6/18/2010 5:29:42 AM
"Shotgun Thom" <tmoran4511@gmail.com> wrote in message 
news:8ddc34e9-af22-43f5-85cb-13feac34ffcb@x27g2000prf.googlegroups.com...

> The problem with the Konica client is that we are using the
> TxText control, which has two internal print routines.  A
> print page method and a print doc method.  When calling
> these methods we actually do pass the Printer.hDC to the
> control.  However, it seems to have no impact on the . . .

Looking again at what I wrote in my last couple of responses there may be 
something I didn't make quite clear, mostly because of my old habit of 
sometimes using "non standard" naming conventions. When I said you should 
pass the hDC that my sample code returns to the TxText control I meant the 
handle that it picks up from the CommonDialog property and that it dumps 
into the MyPrinter (PrinterInfo) UDT, so if you're using my code, or an 
extract from it, then you should pass MyPrinter.Handle to the TxText 
control.

Having said that, the code I posted was intended to show how you can do the 
things you have asked for (pick up /all/ the user's printer dialog settings, 
including the special settings) and how you can draw stuff to the selected 
printer (text, boxes, graphics etc) using the standard GDI printing and 
drawing functions. If (as it now appears) you are drawing the entire 
document using /only/ the functions exposed by the TxTextControl, which 
apparently requires you to pass it the selected printer's hDC, then  you 
will not need most of the GDI code in the example I posted.

If the above is the case then you can much more simply use just a standard 
CommonDialog Control which you use in the normal VB way without all the 
extra GDI code I posted and when the user has finished with the dialog you 
can pass the Common Dialog's hDC property to the TxText control. This hDC 
property will be the DC of the printer selected by the user and it will be 
set up with /all/ of the settings selected by the user in the dialog, 
including all of those esoteric and otherwise hard to get at properties. 
This will require you to use much less code. The important thing is that 
when using the CommonDialog control you should set its Printerdefault 
property to False and should include at least the cdlPDReturnDC flag in the 
Common Dialog's Flags property.

Mike









0
Mike
6/18/2010 6:09:36 AM
"Shotgun Thom" <tmoran4511@gmail.com> wrote in message 
news:90a325b5-c6cd-484a-a811-93cead96a773@a16g2000prg.googlegroups.com...

> I think I understand, and I believe that's what I'm doing
> with the TxText Control.  The control has a property
> which must be set before printing . . .
> TXTextControl1.PrintDevice = Printer.hDC
> I obtain that hDC by setting the cdlPDReturnDC flag in
> the vbprndlg.dll print dialog.  I believe the DC then get's
> set in the Printer.hDC property (at least according to
> MS help docs).

Well I don't ever use the MS vbprndlg.dll myself but I have written code 
that uses it in the past, just out of curiosity, and I'm fairly certain 
that's not the way it works. If the MS help docs say that the vbprndlg 
returned DC gets set in the VB Printer.hDC property then they are wrong, or 
perhaps you have misread them? MS have always been rusbbish at writing help 
files! What you need to pass to the TxText Control in that specific case is 
the prnDlg.hDC property, not the VB Printer.hDC property. Coincidentally I 
had just posted an other response just minutes before I saw this one come in 
from you, which explained how to do the same thing using just the standard 
VB CommonDialog Control. Either of those methods should work for you.

Mike




0
Mike
6/18/2010 6:36:32 AM
Reply:

Similar Artilces:

How do I print a list of the directory contents
I need to print the disk directory contents. In DOS this was possible. Is it possible in WORD? Thanks No - but you could use the freeware Printfolders utility you can download from my web site that will produce a text listing that you can open in Word. -- <>>< ><<> ><<> <>>< ><<> <>>< <>><<> Graham Mayor - Word MVP My web site www.gmayor.com Word MVP web site http://word.mvps.org <>>< ><<> ><<> <>>< ><<> <>>< <...

printing copies
under print options: Number of copies___. It will only print out 1 copy. I say 5 and it still prints out 1. I am a new user of 2007 Excel I suspect the problem is with the printer. Try getting the newest driver best wishes -- Bernard V Liengme Microsoft Excel MVP http://people.stfx.ca/bliengme remove caps from email "Val in Texas" <Val in Texas@discussions.microsoft.com> wrote in message news:78A83505-189A-4731-AF25-CD5505E33510@microsoft.com... > under print options: Number of copies___. It will only print out 1 copy. > I > say 5 and it still prints out 1. ...

Ghosted print and print preview
Hello everyone, I have a problem with printing in excel. The print and print preview options appear ghosted. I still can print through the print icon on the toolbar. Any suggestions??? Martin ...

Print Dynamic Range
I have a basic excel template used for ordering parts. It runs from A1:N250 and I can print easily repeating rows 1:11 on each page (contains job details) . Trouble is sometimes there may only be 10 part numbers requiring only first page and I finish up throwing away trees by printing entire sheet! I know I can reset print area each time am setting this up on Sharepoint for multi users and need a macro/button to recognise number of items and print accordingly. Any help greatly appreciated -- Message posted via http://www.officekb.com Sub SetPrintArea() 'change this cons...

TCP/IP printing
Hello, I have a networking question. I have a print device with a static IP address on one network. A computer on another network can connect to the printer (NBT is enabled and so is LPR) and the drivers are installed but cannot print. I know this is correct behavior but want to know in detail why it seems to half work. I am guessing it has to do with port 138,139 and 515 but not positive. Probably a better question to ask a networking forum but hey. Thanks can you access the printer through the printer IP address? -- ashvin :D Just chill -pls post your feedback on...

NIC setup with two gateways in SBS 2003
Ok I have a Windows 2003 SBS, it only has one NIC, now I have two internet lines ont T1 and one DSL which each has diferent registered names like mycompnay.com and mycompanywx.com. My problem is that when I dont't add one of my gateway (firewall) DSL line, users can not connect to the mycompanywx. Now when I add it as a second gateway it works fine, but my excahnge email server stop getting emails. So my question is do I need to set something on the metrics for the gateways ? Or any ideas why ip stip getting eamil with two gateways ? Thanks Start ny making sure that DNS suffix ...

Printing booklet
I am producing a 50 to 60 page booklet using Pubisher 2003. The page format will be using 8.5 x 11 paper folded in half. I need to print both sides of the paper. How do I print the booklet so that I print half the project on one side of the paper and the other half on the back. Will publisher keep track of the pages so that for example; that page 2 and page 50 print on the same side/sheet of paper so when all pages are printed, folded and bound the book reads correctly. Thanks John Houston, Tx more info...I am using a single side printer so I have to run the pages through twice ...

Check printing in GP 7.0
Dear Guys, I have check payments for vendors, where I'm dealing with LOCAL CURRENCY & FORIGHN CURRENCY. When I paid by check in LOCAL CURRENCY then the amount in words prints perfectly but if i paid by check in FORIGN CURRENCY then the amount in word prints in numeric which i want to print amount in words instead of numbers. Please help me to print checks amount in words for FORIGN CURRENCY as well. Your suggestion would be appricated on above issue thnx Shamin ...

Populating a field conditional of the input of two cells
Hello All, I'm trying to write a simple formula that puts a specific answe conditional of the answers supplied in two other cells. I have followe the formula structure as I understand it, however microsoft Excel X doesn't like the (and statements. Could anyone enlighten me on th correct way of doing this? Many thanks. (The formula is below) > =IF(AND(F4=1,F6="XLPE"),"1",IF(AND(F4<>1,F6="XLPE"),"2",IF(AND(F4=1,F6="PE"),"3",IF(AND(F4<>1,F6="PE"),"4",IF(AND(F4=1,F6="PVC"),"5&quo...

Excel BUG (All Versions) Excel Macro Margins using Print Preview
Where can i post this BUG? (Excel Macro Margins using Print Preview) Is there an Excel BUG reporting site? Steps: 1) New worksheet, write something in it 2) Start recording a new macro 3) File -> Print Preview 4) Click on the Margins Button, the page margins will appear, so that you can visually change and move them 5) Set one or more margins 6) Close the Print Preview 7) Stop the Macro What happened is that in the VBA code there will be writtenthe following lines: ..LeftMargin = Application.InchesToPoints(0.91) ..RightMargin = Application.InchesToPoints() Where in second line ther...

CHtmlView and Printing
Hi Everyone, The CHtmlView is giving me alot of head aches. Here is what I am doing. I am opening an XML file (being formatted using XLST) in a hidden CHtmlView and printing it. Here is how the process goes: 1. I create the XML file on the fly. 2. load the XML file in to CHtmlView. 3. Once loaded I tell it to print the resulting HTML page. 4, I need to delete XML file after the printing is done. (this is the problem). I can't figure out how to find out when the CHtmlView is done printing. CHtmlView::OnFilePrint is asynchronous. And CHtmlView doesn't tell me that it is currently p...

"Tiled" print setting.
I just want the page that I designed to print on one page! I can't change the print setting "tiled" and as it is, it's printing on four pages all broken up. It is possible that you have created your document on a paper size that is not supported by your printer. Try changing your paper size to 8 1/2 by 11 and see if the print options are more to your liking. "MissMarple" <MissMarple@discussions.microsoft.com> wrote in message news:A6776BEA-37EE-4645-B389-866A6CDB2D96@microsoft.com... >I just want the page that I designed to print on one ...

Reportviewer with Two Tables
Is there a way to hand reportviewer mulitple tables that are linked? In crystal, there can be mulitple table in a dataset with relational links. You had crystal the dataset and it treats them as a unit and will display information from both tables on the same report. I'm just switching over to reportviewer and I can't seem to figure out how to get RV it take the whole dataset and not just one table. Thanks, Bernie Yes. You can place multiple list objects on the body of the report (.rdlc file). Each list object can have its own datasource. In each listobject y...

Problems with printing
Dear all I have an application, which has been working without problems for the last 7 years. The application has some printing capabilities. Now, we have just gotten a new printer (HP Laserjet CM4370), and when I try to print, my application crashes. The app crashes in the print setup dialog even before I press OK. If I select any other printer as default printer, the app doesn't crash. Then I can show the print setup dialog without problems. But then, when I select the CM4370, the app crashes again, even if I do not press OK. Even if I choose to not show the print setup dialog, and j...

Printing--How not to Print Bkground
In my wrksht there is a cell range highlighted with an autofill color. We use this to show the user where to enter the data. Is there anyway to avoid printing this background color. We want to keep the color in the cell range in our wrksht but we dont want it printed. Hi Jeff, have you tried Print preview, Setup, Sheet, Black & white? Gilles "Jeff" <anonymous@discussions.microsoft.com> wrote in message news:001201c3ba81$023b8af0$a301280a@phx.gbl... > In my wrksht there is a cell range highlighted with an > autofill color. We use this to show the user where t...

Printing in Vista
After each document prints another sheet prints which has the filename, directory,title, subject, author, creation date, last saved on, total editing time, last printed on. These are just some of the items that print on this one sheet of paper. Can anyone help me? In your Print dialog, uncheck "Document Properties." On Nov 30, 1:34=A0pm, peppermint patty <peppermint pa...@discussions.microsoft.com> wrote: > After each document prints another sheet prints which has the filename, > directory,title, subject, author, creation date, last saved on, total edi= ti...

How do you customize the 'Print View'?
Ho do you customize the print view of the different type of records? TIA Antony On Apr 24, 5:09 pm, "Antony" <info AT webpc DOT biz> wrote: > Ho do youcustomizetheprintviewof the different type of records? > TIA > Antony You are probably going to need to create a custom SQL Server Report to get what you need. Or you can create a mail merge via MS word and access a CRM Table or View using ODBC. Post what you need exactly and you might get some more specific direction, or possibly someone has what you need already. Scott Moore www.easiintl.com ...

Printing problem
I have Window 7 Home Premium. I have Microsoft Office 2010 beta. I have HP LaserJet P1005 printer. Here is my problem: Printing from Word document to 8.5 x 11" size paper no problem. But I can not print any size of envelopes or custom setup paper size. I cannot print anything from Microsoft Publisher 2010 (Beta). Does any one know how to fix? There is a driver for your printer with a 11-2009 timestamp on the HP site, maybe newer than the one you have now. http://h10025.www1.hp.com/ewfrf/wc/softwareList?os=4062&lc=en&dlc=en&cc=us&lang=en&produ...

Print a report without displaying print preview
Hi, Please can someone tell me in a really basic way how can I print a report WITHOUT it also previewing. I'm using 2007 I have several forms which have a print button ( created with the command button wizard, report operations, print report, then relevant report is chosen to print). This works great, and prints the relevant report for the the associated record, however when you click the print button it also displays the print preview and doesn't close it again. This means that until the preview is closed the same thing keeps printing when the button is clicked....

Intersection of two lines #2
I've got the following data: Vectra WRX 5-40 3.7 5.9 5-60 5.6 7.6 5-80 7.7 8.9 5-100 10.4 11 5-120 14.4 13.8 5-140 19 17.5 5-160 26.5 21 5-180 36.5 27.3 How do I determine in XL where the two lines intersect? -- Julian Milano | (To reply, remove NOSPAM from the email address) | See http://andypope.info/charts/intersection.htm http://groups.google.com/groups?selm=%23q2S3aHA%24GA.249%40cppssbbsa05 Jerry Julian Milano wrote: > I've got the following data: > > Vectra WRX > 5-40 3.7 5.9 > 5-...

Currency to Print
Is there a way to set up the defaut "Currency To Print:" to Originating when printe the Invoice from the Sales Batch ID. There is no problem to print the Invoice from Sales transaction Entry, because the default Currency was set using Originating. Thanks, Kevin, Yes. When you select the Print icon in Sales Batch, print options window will open where you specify Originating in Print currency in Dropdown. This should work the same way as printing invoice from sales transaction entry -- Thanks Janakiram M.P. MCP-GP http://janakirammp.blogspot.com "Kevin Zhou" wro...

Printing clips the side of the document words
Hello, I've just installed all the updates for Windows XP that were required and others also and have Office 2003 with Outlook 2003. I've tried to print an email message and the words in the narrative are clipped on the right and left margins. The "TO" "FROM" "SUBJECT" and all the other header information is aligned correctly and the problem is only with the main text portion. When I print regular WORD documents, I don't have this problem and my printer can print directly to the edge of the paper (Laser). The formatting is coming from Outlook a...

Printing
Hi, I have a custom list control (base class is not CListCtrl but simply CWnd). I need to implement printing. I once created a whole printing function for a standard CListCtrl, by making complete custom drawing routines to take data out of the list control and draw it onto a printer DC. However, I have seen how "Custom Grid Control" and other controls can somehow simply map the screen (including icons and everything) onto the printer.. it's not simply a screen print obviously, because it adapts to the printer resolution, but I do wonder if there isn't just a standard print...

Slowing Printing with Publisher & Merged Database
I am doing a newsletter that prints out customers addresses by pulling them off an Excel spreadsheet. I have about 1200 records in the spreadsheet. As the printer runs, it prints out each newsletter with one customers address and then moves down to the next record. The problem I am having is that it takes an extremely and I mean extremely long time to print. 10 copies takes about 15 to 20 minutes. My Publisher file is about seven megabytes. I am using Publisher 2003 and Windows XP Pro SP2 printing to a Xerox 3535 creo Spire. The Spire shows the file as being 900 MB for each 100...

Printing on banner paper
Hi, I have an HP1220C printer, and am running Publisher 2000 on Windows 98. I would like to print on HP banner paper, but even when I set the paper type to banner, it breaks across the page with spaces between the letters. Can you help me? After managing to set up OE-QuoteFix on his new PC, Ed reads a message from Peter <Peter@ascboston.org>... > I have an HP1220C printer, and am running Publisher 2000 > on Windows 98. I would like to print on HP banner paper, > but even when I set the paper type to banner, it breaks > across the page with spaces between the letters. ...