Changing the default printer

Hi,
I'm trying to printer to a printer whitch is not the default one (I don't care makeing it the default one and then print).
I'm trying to use the code givven in the VB help:
"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"

But it seems to be not working.
Sometimes the printer is neing change and sometimes not.
Is it a bug?
What can I do else?

' *** constant that goes into PRINTER_INFO_5 Attributes member to set it as default
Public Const PRINTER_ATTRIBUTE_DEFAULT = 4

Public Type DEVMODE
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
dmLogPixels As Integer
dmBitsPerPel As Long
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
dmICMMethod As Long ' // Windows 95 only
dmICMIntent As Long ' // Windows 95 only
dmMediaType As Long ' // Windows 95 only
dmDitherType As Long ' // Windows 95 only
dmReserved1 As Long ' // Windows 95 only
dmReserved2 As Long ' // Windows 95 only
End Type

Public Type PRINTER_INFO_5
pPrinterName As String
pPortName As String
Attributes As Long
DeviceNotSelectedTimeout As Long
TransmissionRetryTimeout As Long
End Type

Public Type PRINTER_DEFAULTS
pDatatype As Long
pDevMode As DEVMODE
DesiredAccess As Long
End Type

' *** constant that goes into PRINTER_INFO_5 Attributes member to set it as default
Public Const PRINTER_ATTRIBUTE_DEFAULT = 4

Public Type DEVMODE
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
dmLogPixels As Integer
dmBitsPerPel As Long
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
dmICMMethod As Long ' // Windows 95 only
dmICMIntent As Long ' // Windows 95 only
dmMediaType As Long ' // Windows 95 only
dmDitherType As Long ' // Windows 95 only
dmReserved1 As Long ' // Windows 95 only
dmReserved2 As Long ' // Windows 95 only
End Type

Public Type PRINTER_INFO_5
pPrinterName As String
pPortName As String
Attributes As Long
DeviceNotSelectedTimeout As Long
TransmissionRetryTimeout As Long
End Type

Public Type PRINTER_DEFAULTS
pDatatype As Long
pDevMode As DEVMODE
DesiredAccess As Long
End Type

' set the members of the pi5 structure for use with SetPrinter.
' PtrCtoVbString copies the memory pointed at by the two string
' pointers contained in the t() array into a Visual Basic string.
' The other three elements are just DWORDS (long integers) and
' don 't require any conversion
pi5.pPrinterName = PtrCtoVbString(t(0))
pi5.pPortName = PtrCtoVbString(t(1))
pi5.Attributes = t(2)
pi5.DeviceNotSelectedTimeout = t(3)
pi5.TransmissionRetryTimeout = t(4)

' this is the critical flag that makes it the default printer
pi5.Attributes = PRINTER_ATTRIBUTE_DEFAULT

' call SetPrinter to set it
X = SetPrinter(Handle, 5, pi5, 0)

' failed the SetPrinter
If X = False Then Exit Sub

' and close the handle
ClosePrinter (Handle)

End Sub

Public Sub GetDriverAndPort(ByVal Buffer As String, DriverName As String, PrinterPort As String)

Dim iDriver As Integer
Dim iPort As Integer

DriverName = ""
PrinterPort = ""

' The driver name is first in the string terminated by a comma
iDriver = InStr(Buffer, ",")

' The port name is the second entry after the driver name separated by commas.
iPort = InStr(iDriver + 1, Buffer, ",")
If iPort > 0 Then
' Strip out the port name
PrinterPort = Mid(Buffer, iDriver + 1, _
iPort - iDriver - 1)
End If
End If

End Sub

Public Sub ParseList(lstCtl As Control, ByVal Buffer As String)

Dim i As Integer

lstCtl.Clear

Do
i = InStr(Buffer, Chr(0))
If i > 0 Then
If (Trim(Left(Buffer, i - 1)) <> "") Then lstCtl.AddItem Left(Buffer, i - 1)
Buffer = Mid(Buffer, i + 1)
Else
If (Trim(Buffer) <> "") Then lstCtl.AddItem Buffer
Buffer = ""
End If
Loop While i > 0

' Parse the driver name and port name out of the buffer
GetDriverAndPort Buffer, DriverName, PrinterPort
If DriverName <> "" And PrinterPort <> "" Then
SetDefaultPrinter sPrinter, DriverName, PrinterPort
End If

Why shouldn't the Printer object work? Your code looks ok, but perhaps you need to search for the device name of the printer as well. This code always works on my machine (and the Linotronic printer is not the default):

Private Sub Command1_Click()
Dim p As Printer
For Each p In Printers
If (p.Orientation = vbPRORPortrait) And _
(p.DeviceName Like "*Linotronic*") Then
Set Printer = p
Exit For
End If
Next
MsgBox p.DeviceName & vbCrLf & p.Orientation
Form1.PrintForm
Printer.EndDoc
End Sub

0

eyaltilAuthor Commented: 1999-11-15

It seemes that the default printer is being change (I can see that when I'm debuging the code) but when I rich the first command of the printer (like printer.enddoc, printer.print ...) the default printer is beeing changed to the first one.