Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0093: Standard-Drucker systemweit setzen

 von 

Beschreibung 

Mit VB ist es von Haus aus nicht möglich, den Standard-Drucker systemweit zu setzen. Wie es doch geht und dabei noch dauerhaft, zeigt dieser Tipp.

Schwierigkeitsgrad:

Schwierigkeitsgrad 3

Verwendete API-Aufrufe:

ClosePrinter, GetPrinterA (GetPrinter), GetProfileStringA (GetProfileString), OpenPrinterA (OpenPrinter), SetPrinterA (SetPrinter), lstrcpyA (lstrcpy)

Download:

Download des Beispielprojektes [3,2 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Project1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Schaltfläche "Command1"
' Steuerelement: Listen-Steuerelement "List1"

Option Explicit

Private 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

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

Private 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

Private 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

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

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

Const CCHDEVICENAME = 32
Const CCHFORMNAME = 32
Const STANDARD_RIGHTS_REQUIRED = &HF0000
Const PRINTER_ATTRIBUTE_DEFAULT = 4
Const PRINTER_ACCESS_ADMINISTER = &H4
Const PRINTER_ACCESS_USE = &H8
Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
                            PRINTER_ACCESS_ADMINISTER Or _
                            PRINTER_ACCESS_USE)

Private 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
  dmICMIntent As Long
  dmMediaType As Long
  dmDitherType As Long
  dmReserved1 As Long
  dmReserved2 As Long
End Type

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

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

Dim m_sCurrPrinterDevName$, m_sPrevPrinterDevName$
Dim m_sPrevPrinterDriver$, m_sPrevPrinterPort$

Private Sub Form_Load()
  Dim x%
    For x = 0 To Printers.Count - 1
      List1.AddItem Printers(x).DeviceName
    Next x
End Sub

Private Sub Command1_Click()
  Dim Txt$, Prn$
    If List1.SelCount = 1 Then
      Prn$ = List1.List(List1.ListIndex)
      
      If SetPrinterAsDefault(Prn) Then
        Txt = Prn & " als Standartdrucker gesetzt !"
      Else
        Txt = "Der Versuch (" & Prn & ") fehlgeschlagen !"
      End If
    Else
      Txt = "Bitte einen Drucker aus der Liste wählen !"
    End If
    MsgBox (Txt)
End Sub

Private Function PtrCtoVbString(Add&) As String
  Dim sTemp As String * 512, x&
    
    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 Function SetPrinterAsDefault(ByVal DeviceName$) As Boolean
    Call Initialize
 
    If m_sCurrPrinterDevName <> DeviceName Then
      SetPrinterAsDefault = Win95SetDefaultPrinter(DeviceName)
    Else
      SetPrinterAsDefault = True
    End If
End Function

Private Sub Initialize()
  Dim Buffer$, r&, x&, y&
    
    Buffer = Space(8192)
    r = GetProfileString("windows", "Device", "", Buffer, Len(Buffer))
    If r Then
      Buffer = Mid(Buffer, 1, r)
        x = InStr(Buffer, ",")
        m_sPrevPrinterDevName = Mid(Buffer, 1, x - 1)
        y = InStr(x + 1, Buffer, ",")
        m_sPrevPrinterDriver = Mid(Buffer, x + 1, y - x - 1)
        m_sPrevPrinterPort = Mid(Buffer, y + 1)
    Else
        m_sPrevPrinterDevName = ""
        m_sPrevPrinterDriver = ""
        m_sPrevPrinterDevName = ""
    End If
    m_sCurrPrinterDevName = m_sPrevPrinterDevName
End Sub

Private Function Win95SetDefaultPrinter(DeviceName$) As Boolean
  Dim Handle&
  Dim pd As PRINTER_DEFAULTS
  Dim x As Long
  Dim need As Long
  Dim pi5 As PRINTER_INFO_5
  Dim LastError As Long

    If DeviceName = "" Then
      Win95SetDefaultPrinter = False
      Exit Function
    End If

    pd.pDatatype = 0&
    pd.DesiredAccess = PRINTER_ALL_ACCESS
    x = OpenPrinter(DeviceName, Handle, pd)
    
    If x = False Then
      Win95SetDefaultPrinter = False
      Exit Function
    End If

    x = GetPrinter(Handle, 5, ByVal 0&, 0, need)
    ReDim t((need \ 4)) As Long
    x = GetPrinter(Handle, 5, t(0), need, need)
    If x = False Then
      Win95SetDefaultPrinter = False
      Exit Function
    End If

    pi5.pPrinterName = PtrCtoVbString(t(0))
    pi5.pPortName = PtrCtoVbString(t(1))
    pi5.Attributes = t(2)
    pi5.DeviceNotSelectedTimeout = t(3)
    pi5.TransmissionRetryTimeout = t(4)
    pi5.Attributes = PRINTER_ATTRIBUTE_DEFAULT

    x = SetPrinter(Handle, 5, pi5, 0)
    If x = False Then
      Win95SetDefaultPrinter = False
      Exit Function
    End If

    Call ClosePrinter(Handle)
    m_sCurrPrinterDevName = DeviceName
    Win95SetDefaultPrinter = True
End Function
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei Project1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 7 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Ing. MIEDL Roman am 28.12.2007 um 00:42

Das hier funktioniert seit Jahren im Büroeinsatz getestet:
(vb5 + vb6 unter W2K + XP)

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



Private Function Printersetzen(NewDrucker As String)
Dim prnt As Printer
For Each prnt In Printers
If StrComp(prnt.DeviceName, NewDrucker, vbTextCompare) = 0 Then
Exit For
End If
Next prnt
If Not prnt Is Nothing Then
WriteProfileString "windows", "device", prnt.DeviceName & "," & prnt.DriverName & "," & prnt.Port
End If
End Function


Kommentar von Peter Rost am 08.05.2006 um 12:17

Super Tipp. Lösung suche ich schon lange. Doch leider funktioniert er nicht unter VB5+XP. Der Code ist bis zum API-Aufruf "SetPrinterAsDefault" nachzuvollziehen, dann wird aber der Drucker nicht gesetzt.

Wer hat eine Lösung für XP? (Kenne mich leider in der API-Funktionalität noch nicht so aus, das ich das Problem selbst lösen kann).

Danke im Voraus
Peter

Kommentar von Roman Herwig am 23.11.2005 um 15:06

Kürzer und zuverlässiger ist diese Lösung:

Dim objWSHNetwork As Object
Set objWSHNetwork = CreateObject("WScript.Network")
objWSHNetwork.SetDefaultPrinter Printers(i).DeviceName
Set objWSHNetwork = Nothing

Kommentar von Wolfgang Brunner am 26.06.2002 um 11:38

funktioniert unter 2k leider nicht.
siehe http://www.freevbcode.com/code/SetDefaultPrinter.zip

Kommentar von Thomas Fischer am 08.01.2002 um 11:10

Hallo,
ich habe folgendes Problem (sowohl bei WinNt als auch Win2000):
In der Function "Win95SetDefaultPrinter(DeviceName$) As Boolean" gibt die Anweisung "x= SetPrinter(Handle, 5, pi5, 0)" den Wert falsch zurück.
Habt Ihr eine Ahnung, was der Grund dafür sein könnte?
Wisst Ihr eine andere Möglichkeit?
Danke

Kommentar von da_hoschla am 01.11.2001 um 10:14

funktioniert unter 2k leider nicht.

Kommentar von Chris H. Tscheuschner am 24.11.2000 um 18:20

Siehe MS Knowledgebase Q167735 - dort gibt es die NT-Lösung...