Visual Basic System Services
SetDefaultPrinter: Changing Windows' Default Printer
Posted:   Wednesday January 05, 2005
Updated:   Monday December 26, 2011
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows XP
OS restrictions:   Windows 2000 or later
Author:   VBnet - Randy Birch


AddPort: Adding and Deleting Application-Defined Ports
AddPrinter: Add/Delete Local/Remote Printers using Existing Drivers
EnumPorts: Identify Windows' Available Ports
EnumPrinters: Enumerating Local and Network Printers
EnumPrinterDrivers: Enumerate Print Drivers on Specific Printer Server
SetDefaultPrinter: Changing Windows' Default Printer
WriteProfileString: Changing Windows' Default Printer
Windows 2000 or later in order to use SetDefaultPrinter.

Windows 2000 and later provides an API that can directly set the default printer by simply passing the appropriate printer string without resorting to enumerating registry values or ini file listings. This demo's so easy the code comments will take care of any oratory.

If a mechanism is required to set the default printer on earlier Windows versions, see WriteProfileString: Changing Windows' Default Printer.

 BAS Module Code

 Form Code
Create a form containing a list box and command button, using the default names. Add the following code to the form:

Option Explicit
' Copyright 1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
Private Type PRINTER_INFO_4
   pPrinterName As Long
   pServerName As Long
   Attributes As Long
End Type

'This is non-windows constant
'defined for this method
Private Const SIZEOFPRINTER_INFO_4 = 12

Private Const HWND_BROADCAST As Long = &HFFFF&
Private Const WM_WININICHANGE As Long = &H1A
Private Const PRINTER_LEVEL4 = &H4
Private Const PRINTER_ENUM_LOCAL = &H2

Private Declare Function EnumPrinters Lib "winspool.drv" _
   Alias "EnumPrintersA" _
  (ByVal Flags As Long, _
   ByVal Name As String, _
   ByVal Level As Long, _
   pPrinterEnum As Any, _
   ByVal cbBuffer As Long, _
   pcbNeeded As Long, _
   pcReturned As Long) As Long

Private Declare Function SendNotifyMessage Lib "user32" _
   Alias "SendNotifyMessageA" _
  (ByVal hwnd As Long, _
   ByVal msg As Long, _
   ByVal wParam As Long, _
    lParam As Any) As Long
Private Declare Function SetDefaultPrinter Lib "winspool.drv" _
   Alias "SetDefaultPrinterA" _
  (ByVal pszPrinter As String) As Long
Private Declare Function lstrcpyA Lib "kernel32" _
  (ByVal RetVal As String, ByVal ptr As Long) As Long
Private Declare Function lstrlenA Lib "kernel32" _
  (ByVal ptr As Any) As Long

Private Sub Form_Load()

   With Command1
      .Caption = "Set Default Printer"
      .Width = 2000
      .Enabled = List1.ListIndex > -1
   End With
   Call EnumPrintersWinNTPlus

End Sub

Private Sub Command1_Click()
  'set the default printer to the
  'selected item
   SetDefaultPrinter List1.List(List1.ListIndex)
  'broadcast the change
   Call SendNotifyMessage(HWND_BROADCAST, _
                          WM_WININICHANGE, _
                          0, ByVal "windows")

End Sub

Private Sub List1_Click()

   Command1.Enabled = List1.ListIndex > -1
End Sub

Private Function EnumPrintersWinNTPlus() As Long
   Dim cbRequired As Long
   Dim cbBuffer As Long
   Dim ptr() As PRINTER_INFO_4
   Dim nEntries As Long
   Dim cnt As Long
  'To determine the required buffer size,
  'call EnumPrinters with cbBuffer set to zero.
  'EnumPrinters fails, and Err.LastDLLError
  'in the cbRequired parameter with the size,
  'in bytes, of the buffer required to hold
  'the array of structures and their data.
   Call EnumPrinters(PRINTER_ENUM_LOCAL, _
                     vbNullString, _
                     PRINTER_LEVEL4, _
                     0, 0, _
                     cbRequired, _
  'The strings pointed to by each PRINTER_INFO_4
  'struct's members reside in memory after the end
  'of the array of structs. So we're not only
  'allocating memory for the structs themselves,
  'but all the strings pointed to by each struct's
  'member as well.
   ReDim ptr((cbRequired \ SIZEOFPRINTER_INFO_4))
  'Set cbBuffer equal to the size of the buffer
   cbBuffer = cbRequired
  'Enumerate the printers. If the function succeeds,
  'the return value is nonzero. If the function fails,
  'the return value is zero.
   If EnumPrinters(PRINTER_ENUM_LOCAL, _
                   vbNullString, _
                   PRINTER_LEVEL4, _
                   ptr(0), cbBuffer, _
                   cbRequired, nEntries) Then
      For cnt = 0 To nEntries - 1
         With ptr(cnt)
            List1.AddItem GetStrFromPtrA(.pPrinterName)

         End With
      Next cnt
      List1.AddItem "Error enumerating printers."
   End If  'EnumPrinters
   EnumPrintersWinNTPlus = nEntries
End Function

Private Function GetStrFromPtrA(ByVal lpszA As Long) As String

   GetStrFromPtrA = String$(lstrlenA(ByVal lpszA), 0)
   Call lstrcpyA(ByVal GetStrFromPtrA, ByVal lpszA)
End Function
Save the program and run. With the Printers folder open, change the default printer from the project. The appropriate printer icon should immediately reflect the change. See EnumPrinters: Enumerating Local and Network Printers for additional constants for enumerating remote and network printers.


PayPal Link
Make payments with PayPal - it's fast, free and secure!


Copyright 1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy


Hit Counter