We help IT Professionals succeed at work.

How to change Default Printer from VB6

u3520384
u3520384 asked
on
Medium Priority
10,867 Views
Last Modified: 2007-11-27
Dear Expert;

  Please answer me how to code.

I would like to Code VB6 to change default printer and Printer A to Printer B. So that I can print report
from Crystal report 8.

If this coding is finished, I can to select printer(Printer A and Printer B)  to print Report (Rpt1.rpt)
Comment
Watch Question

Ryan ChongSoftware Tead Lead / Business Analyst / System Analyst / Data Engineer
CERTIFIED EXPERT

Commented:
Hi,

How about using the Common Dialog Control?

> CommonDialog1.ShowPrinter
Valliappan ANSenior Tech Consultant
CERTIFIED EXPERT

Commented:
Hi, for the very similar purpose, I use the code. Try this:

http://www.freevbcode.com/ShowCode.Asp?ID=641 

It restores your original default printer, after
you terminate the class.
Commented:
See this link for the microsoft approach to setting the default printer...

http://support.microsoft.com/support/kb/articles/Q266/7/67.ASP

---------------------------------


However, I would do it with a more simple approach....

start a new standard exe project.

Add a combobox (cboPrinters) and a label (label1)

Then paste the following code into the program.

Private Sub cboPrinters_Click()
   
   Dim i As Integer
   Dim p As Printer
   For Each p In Printers
       If i = cboPrinters.ListIndex Then
           Set Printer = p
           Exit For
       End If
       i = i + 1
   Next p
   Label1.Caption = Printer.DeviceName
   
End Sub

Private Sub Form_Load()

   PopulatePrinters

End Sub
Private Sub PopulatePrinters()
   Dim p As Printer
   Dim i As Integer
   i = 0

   For Each p In Printers
       cboPrinters.AddItem p.DeviceName
       If p.DeviceName = Printer.DeviceName Then
           cboPrinters.ListIndex = i
       End If
       i = i + 1
   Next p
End Sub


What this does is allows you to set the default printer for that appliation, and for that instance.

If you know what printer you want to be the default for your application all the time, simply set it
upon loading the application.

ex:

Private Sub FormLoad()
   
   Dim i As Integer
   Dim p As Printer
   For Each p In Printers
       If p.DeviceName = "YourPrinter" Then
           Set Printer = p
           Exit For
       End If
   Next p
   
End Sub


hth

Wileecoy.
That will change default printer windows wide

'module
      Declare Function GetProfileString Lib "kernel32" _
      Alias "GetProfileStringA" _
      (ByVal lpAppName As String, _
      ByVal lpKeyName As String, _
      ByVal lpDefault As String, _
      ByVal lpReturnedString As String, _
      ByVal nSize As Long) As Long

      Declare Function WriteProfileString Lib "kernel32" _
      Alias "WriteProfileStringA" _
      (ByVal lpszSection As String, _
      ByVal lpszKeyName As String, _
      ByVal lpszString As String) As Long

      Declare Function SendMessage Lib "user32" _
      Alias "SendMessageA" _
      (ByVal hwnd As Long, _
      ByVal wMsg As Long, _
      ByVal wParam As Long, _
      lparam As String) As Long

      Public Const HWND_BROADCAST = &HFFFF
      Public Const WM_WININICHANGE = &H1A

      Public Type OSVERSIONINFO
         dwOSVersionInfoSize As Long
         dwMajorVersion As Long
         dwMinorVersion As Long
         dwBuildNumber As Long
         dwPlatformId As Long
         szCSDVersion As String * 128
      End Type

      Declare Function GetVersionExA Lib "kernel32" _
      (lpVersionInformation As OSVERSIONINFO) As Integer

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

      Public Declare Function SetPrinter Lib "winspool.drv" _
      Alias "SetPrinterA" _
      (ByVal hPrinter As Long, _
      ByVal Level As Long, _
      pPrinter As Any, _
      ByVal Command As Long) As Long

      Public Declare Function GetPrinter Lib "winspool.drv" _
      Alias "GetPrinterA" _
      (ByVal hPrinter As Long, _
      ByVal Level As Long, _
      pPrinter As Any, _
      ByVal cbBuf As Long, _
      pcbNeeded As Long) As Long

      Public Declare Function lstrcpy Lib "kernel32" _
      Alias "lstrcpyA" _
      (ByVal lpString1 As String, _
      ByVal lpString2 As Any) As Long

      Public Declare Function ClosePrinter Lib "winspool.drv" _
      (ByVal hPrinter As Long) As Long

      ' constants for DEVMODE structure
      Public Const CCHDEVICENAME = 32
      Public Const CCHFORMNAME = 32

      ' constants for DesiredAccess member of PRINTER_DEFAULTS
      Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
      Public Const PRINTER_ACCESS_ADMINISTER = &H4
      Public Const PRINTER_ACCESS_USE = &H8
      Public Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
      PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)

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

      'Constant for OSVERSIONINFO.dwPlatformId
      Public Const VER_PLATFORM_WIN32_WINDOWS = 1

      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 Long
              DesiredAccess As Long
      End Type


'form (Listbox and command button)
      Private Function PtrCtoVbString(Add As Long) As String

          Dim sTemp As String * 512, x As Long

          x = lstrcpy(sTemp, Add)
          If (InStr(1, sTemp, Chr(0)) = 0) Then
               PtrCtoVbString = ""
          Else
               PtrCtoVbString = Left(sTemp, InStr(1, sTemp, Chr(0)) - 1)
          End If
      End Function

      Private Sub SetDefaultPrinter(ByVal PrinterName As String, _
          ByVal DriverName As String, ByVal PrinterPort As String)
          Dim DeviceLine As String
          Dim r As Long
          Dim l As Long
          DeviceLine = PrinterName & "," & DriverName & "," & PrinterPort
          ' Store the new printer information in the [WINDOWS] section of
          ' the WIN.INI file for the DEVICE= item
          r = WriteProfileString("windows", "Device", DeviceLine)
          ' Cause all applications to reload the INI file:
          l = SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, "windows")
      End Sub

      Private Sub Win95SetDefaultPrinter()
          Dim Handle As Long          'handle to printer
          Dim PrinterName As String
          Dim pd As PRINTER_DEFAULTS
          Dim x As Long
          Dim need As Long            ' bytes needed
          Dim pi5 As PRINTER_INFO_5   ' your PRINTER_INFO structure
          Dim LastError As Long

          ' determine which printer was selected
          PrinterName = List1.List(List1.ListIndex)
          ' none - exit
          If PrinterName = "" Then
              Exit Sub
          End If

          ' set the PRINTER_DEFAULTS members
          pd.pDatatype = 0&
          pd.DesiredAccess = PRINTER_ALL_ACCESS Or pd.DesiredAccess

          ' Get a handle to the printer
          x = OpenPrinter(PrinterName, Handle, pd)
          ' failed the open
          If x = False Then
              'error handler code goes here
              Exit Sub
          End If

          ' Make an initial call to GetPrinter, requesting Level 5
          ' (PRINTER_INFO_5) information, to determine how many bytes
          ' you need
          x = GetPrinter(Handle, 5, ByVal 0&, 0, need)
          ' don't want to check Err.LastDllError here - it's supposed
          ' to fail
          ' with a 122 - ERROR_INSUFFICIENT_BUFFER
          ' redim t as large as you need
          ReDim t((need \ 4)) As Long

          ' and call GetPrinter for keepers this time
          x = GetPrinter(Handle, 5, t(0), need, need)
          ' failed the GetPrinter
          If x = False Then
              'error handler code goes here
              Exit Sub
          End If

          ' 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
              MsgBox "SetPrinterFailed. Error code: " & Err.LastDllError
              Exit Sub
          End If

          ' and close the handle
          ClosePrinter (Handle)

      End Sub

      Private 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, ",")
          If iDriver > 0 Then

              'Strip out the driver name
              DriverName = Left(Buffer, iDriver - 1)

              '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

      Private Sub ParseList(lstCtl As Control, ByVal Buffer As String)
          Dim i As Integer

          Dim s As String

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

      Private Sub WinNTSetDefaultPrinter()
          Dim Buffer As String
          Dim DeviceName As String
          Dim DriverName As String
          Dim PrinterPort As String
          Dim PrinterName As String
          Dim r As Long
          If List1.ListIndex > -1 Then
              'Get the printer information for the currently selected
              'printer in the list. The information is taken from the
              'WIN.INI file.
              Buffer = Space(1024)
              PrinterName = List1.Text
              r = GetProfileString("PrinterPorts", PrinterName, "", _
                  Buffer, Len(Buffer))

              'Parse the driver name and port name out of the buffer
              GetDriverAndPort Buffer, DriverName, PrinterPort

              If DriverName <> "" And PrinterPort <> "" Then
                  SetDefaultPrinter List1.Text, DriverName, PrinterPort
              End If
          End If
      End Sub

      Private Sub Command1_Click()
          Dim osinfo As OSVERSIONINFO
          Dim retvalue As Integer

          osinfo.dwOSVersionInfoSize = 148
          osinfo.szCSDVersion = Space$(128)
          retvalue = GetVersionExA(osinfo)
     
          If osinfo.dwPlatformId = VER_PLATFORM_WIN32_WINDOWS Then
              Call Win95SetDefaultPrinter
          Else
      'This assumes that future versions of Windows use the NT method
              Call WinNTSetDefaultPrinter
          End If
      End Sub

      Private Sub Form_Load()
          Dim r As Long
          Dim Buffer As String

          'Get the list of available printers from WIN.INI
          Buffer = Space(8192)
          r = GetProfileString("PrinterPorts", vbNullString, "", _
             Buffer, Len(Buffer))

          'Display the list of printer in the list box List1
          ParseList List1, Buffer
      End Sub


Commented:
iboutchkine,

My 'simple' code only sets the default printer for that application, for that instance.

With the cboPrinters_Click code, one can change the printer for that application at any time, while maintaining the default printer system-wide beyond the life of the application.


Wileecoy.
Valliappan ANSenior Tech Consultant
CERTIFIED EXPERT

Commented:
wileecoy,

Set Printer may not work for some versions of VB or SPs of VB. It was found as a problem by MS, and it appears they have given a FIX to it. The code, from the link I have provided already, states this clearly, so to use API is safer for any version. I have been using the code, and it works well. It is a class, so once you instantiate the class, the default printer will be changed, and once it is destroyed, then the prev. default printer will be restored, which might be required in some apps.

Cheers

Commented:
Thanks - Glad to help.