timpeters
asked on
Change default printer?
Is it possible to change your computer's default printer through VB code. I know you can change which printer you want to print a blank page to at that time, but I don't believe that changes your default printer. Some code would be nice.
The easiest way is to use the Common Dialog control (or equiv. API calls) and use the combobox in the Common Printer Dialog to make the change. Else to change the printer without interface or user intervention system API call are required.
ASKER
I knew that API calls were needed, I am not sure though wich API calls to use.
This is the kind of code you can use
Private Sub cmdPrint_Click()
' Set the printer dialog flags to disables the selection option button,
' record how many copies the user wants, and the hide the "Print to File" option
CommonDialog1.Flags = cdlPDNoSelection + cdlPDUseDevModeCopies + cdlPDHidePrintToFile
CommonDialog1.CancelError = True ' Let the procedure know when cancel is pressed
On Error GoTo errhandler ' Handle error messages.
CommonDialog1.ShowPrinter ' Display the Print dialog box
' Print whatever stuff you want to
Exit Sub
errhandler: ' Don't display error messages
On Error GoTo 0
Exit Sub
End Sub
Private Sub cmdPrint_Click()
' Set the printer dialog flags to disables the selection option button,
' record how many copies the user wants, and the hide the "Print to File" option
CommonDialog1.Flags = cdlPDNoSelection + cdlPDUseDevModeCopies + cdlPDHidePrintToFile
CommonDialog1.CancelError = True ' Let the procedure know when cancel is pressed
On Error GoTo errhandler ' Handle error messages.
CommonDialog1.ShowPrinter ' Display the Print dialog box
' Print whatever stuff you want to
Exit Sub
errhandler: ' Don't display error messages
On Error GoTo 0
Exit Sub
End Sub
Hi !
I think here the answer for changing the default printer without prompting user ^_^.
1) WriteProfileString("window s", "device", profileStr)
2) WriteProfileString(NULL, NULL, NULL)
3) SendMessage(HWND_BROADCAST , M_WININICHANGE, 0, 0)
The profile string you need here can be get from the Printers(index) collection. Just concatinate printers(index).devicename & "," & printers(index).drivername & "," & printers(index).port
Those functions prototype and windows contants please refer to WINAPI documentation.
I'd tested this, its worked !!
If you are winnt user this may not work but I can let know you what you need to know.
I think here the answer for changing the default printer without prompting user ^_^.
1) WriteProfileString("window
2) WriteProfileString(NULL, NULL, NULL)
3) SendMessage(HWND_BROADCAST
The profile string you need here can be get from the Printers(index) collection. Just concatinate printers(index).devicename
Those functions prototype and windows contants please refer to WINAPI documentation.
I'd tested this, its worked !!
If you are winnt user this may not work but I can let know you what you need to know.
Here is the best solution, I use in all my applications :
call Win95SetDefaultPrinter under Win95
call WinNTSetDefaultPrinter under WinNT
Option Explicit
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
Public 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
Public Declare Function GetLastError Lib "kernel32" () 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
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
Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
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
Public 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("window s", "Device", DeviceLine)
' *** Cause all applications to reload the INI file:
l = SendMessage(HWND_BROADCAST , WM_WININICHANGE, 0, "windows")
End Sub
Public Sub Win95SetDefaultPrinter(sPr inter As String)
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 = sPrinter
' none - exit
If PrinterName = "" Then Exit Sub
' set the PRINTER_DEFAULTS members
pd.pDatatype = 0&
pd.DesiredAccess = PRINTER_ALL_ACCESS
' Get a handle to the printer
x = OpenPrinter(PrinterName, Handle, pd)
' failed the open
If x = False Then Exit Sub
' 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 GetLastError 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 Exit Sub
' 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.DeviceNotSelectedTimeo ut = t(3)
pi5.TransmissionRetryTimeo ut = 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, ",")
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
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
End Sub
Public Sub WinNTSetDefaultPrinter(sPr inter As String)
Dim Buffer As String
Dim DeviceName As String
Dim DriverName As String
Dim PrinterPort As String
Dim PrinterName As String
Dim r As Long
Buffer = Space(1024)
PrinterName = sPrinter
r = GetProfileString("PrinterP orts", 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 sPrinter, DriverName, PrinterPort
End If
End Sub
call Win95SetDefaultPrinter under Win95
call WinNTSetDefaultPrinter under WinNT
Option Explicit
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
Public 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
Public Declare Function GetLastError Lib "kernel32" () 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
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
Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long
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
Public 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("window
' *** Cause all applications to reload the INI file:
l = SendMessage(HWND_BROADCAST
End Sub
Public Sub Win95SetDefaultPrinter(sPr
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 = sPrinter
' none - exit
If PrinterName = "" Then Exit Sub
' set the PRINTER_DEFAULTS members
pd.pDatatype = 0&
pd.DesiredAccess = PRINTER_ALL_ACCESS
' Get a handle to the printer
x = OpenPrinter(PrinterName, Handle, pd)
' failed the open
If x = False Then Exit Sub
' 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 GetLastError 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 Exit Sub
' 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.DeviceNotSelectedTimeo
pi5.TransmissionRetryTimeo
' 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, ",")
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
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
End Sub
Public Sub WinNTSetDefaultPrinter(sPr
Dim Buffer As String
Dim DeviceName As String
Dim DriverName As String
Dim PrinterPort As String
Dim PrinterName As String
Dim r As Long
Buffer = Space(1024)
PrinterName = sPrinter
r = GetProfileString("PrinterP
' 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
End Sub
ASKER
Waty's answer gave me more of what I was looking for. He deserves the points.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.