Hier ist ein (etwas komplizierteres) Komplett-Beispiel, das alle Papiereinzugsfächer des Default-Druckers zur Auswahl anbietet, aus dem ausgewählten Fach eine Seite einzieht und die Seite mit der Bezeichnung des Faches versehen ausdruckt:
Code: Alles auswählen
EnableExplicit
#BinNameLength = 24
Procedure.L ChangeBin(PrinterName.S, BinID.W)
Protected BufferSize.L
Protected BytesRetrieved.L
Protected *DEVMODEBuffer.DEVMODE
Protected *DEVMODEBufferCopy.DEVMODE
Protected ErrorMsg.S
Protected ModeFlag.L
Protected PRINTER_DEFAULTSStructure.PRINTER_DEFAULTS
Protected PrinterHandle.L
Protected Result.L
; ----- Drucker Handle ermitteln
PRINTER_DEFAULTSStructure\DesiredAccess = #STANDARD_RIGHTS_REQUIRED | #PRINTER_ACCESS_ADMINISTER | #PRINTER_ACCESS_USE
Result = OpenPrinter_(@PrinterName, @PrinterHandle, @PRINTER_DEFAULTSStructure)
If Result = #False Or PrinterHandle = 0
ErrorMsg = "Die Windows-Funktion OpenPrinter() ist fehlgeschlagen!"
Result = #False
Goto CleanUp
EndIf
; ----- Buffer für DEVMODE-Struktur
ModeFlag = 0
BufferSize = DocumentProperties_(0, PrinterHandle, @PrinterName, 0, 0, ModeFlag)
If BufferSize < 0 Or ModeFlag <> 0
ErrorMsg = "Die Größe der DEVMODE-Struktur konnte nicht ermittelt werden!"
Goto CleanUp
End
EndIf
; ----- Speicher-Buffer für DEVMODE-Struktur
*DEVMODEBuffer = AllocateMemory(BufferSize)
If *DEVMODEBuffer = 0
ErrorMsg = "Die Speicheranforderung für die DEVMODE-Struktur ist gescheitert!"
Result = #False
Goto CleanUp
EndIf
; ----- Speicher-Buffer für Kopier der DEVMODE-Struktur
*DEVMODEBufferCopy = AllocateMemory(BufferSize)
If *DEVMODEBufferCopy = 0
ErrorMsg = "Die Speicheranforderung für eine Kopie der DEVMODE-Struktur ist gescheitert!"
Result = #False
Goto CleanUp
EndIf
; ----- DEVMODE-Struktur generieren lassen
Result = DocumentProperties_(0, PrinterHandle, @PrinterName, *DEVMODEBuffer, 0, #DM_OUT_BUFFER)
If Result < 0
ErrorMsg = "Die Windows-Funktion DocumentProperties() ist fehlgeschlagen!"
Result = #False
Goto CleanUp
EndIf
; ----- DEVMODE-Struktur kopieren
CopyMemory(*DEVMODEBuffer, *DEVMODEBufferCopy, BufferSize)
; ----- Einzugsfach abändern
*DEVMODEBufferCopy\dmDefaultSource = BinID
; ----- Papierformat definieren
*DEVMODEBufferCopy\dmPaperSize = #DMPAPER_A4
; ----- Angeben, welche Parameter geändert werden sollen
*DEVMODEBufferCopy\dmFields = #DM_DEFAULTSOURCE | #DM_PAPERSIZE
; ----- DEVMODE-Struktur mit modifizierter Kopie überschreiben
CopyMemory(*DEVMODEBufferCopy, *DEVMODEBuffer, BufferSize)
; ----- Modifizierte DEVMODE-Struktur übergeben
Result = DocumentProperties_(0, PrinterHandle, @PrinterName, *DEVMODEBuffer, *DEVMODEBuffer, #DM_IN_BUFFER | #DM_OUT_BUFFER)
If Result <> #IDOK
ErrorMsg = "Die Übergabe der modifizierten DEVMODE-Struktur ist gescheitert!"
Result = #False
EndIf
; ----- Drucker Handle und Speicherbereiche freigeben
CleanUp:
If PrinterHandle <> 0
ClosePrinter_(PrinterHandle)
EndIf
If *DEVMODEBufferCopy <> 0
FreeMemory(*DEVMODEBufferCopy)
EndIf
If Result = #False
If *DEVMODEBuffer <> 0
FreeMemory(*DEVMODEBuffer)
EndIf
MessageRequester("Error", ErrorMsg, #MB_ICONERROR)
ProcedureReturn #False
EndIf
ProcedureReturn *DEVMODEBuffer
EndProcedure
Define BinID.L
Define BinIDBuffer.S
Define BinNameBuffer.S
Define Buffer.S
Define DefaultPrinterName.S
Define DefaultPortName.S
Define *DEVMODEBuffer
Define DocInfo.DOCINFO
Define Driver.S
Define i.L
Define Info.S
Define NumBins.L
Define PrinterDC.L
Define Result.L
Define SelectedBinID.W
Define SelectedBinName.S
Define Text.S
Define WindowEvent.L
BinIDBuffer = Space(20 * 2) ; maximal 20 Papiereinzugfach-IDs passen hier hinein!
BinNameBuffer = Space(20 * #BinNameLength) ; maximal 20 Papiereinzugfach-Namen passen hier hinein!
Buffer = Space(260)
; ----- Default-Druckernamen und Drucker-Port ermitteln
GetPrivateProfileString_("WINDOWS", "DEVICE", "", @Buffer, 260, "Win.Ini")
DefaultPrinterName = StringField(Buffer, 1, ",")
DefaultPortName = StringField(Buffer, 3, ",")
; ----- Namen der Fächer ermitteln
NumBins = DeviceCapabilities_(@DefaultPrinterName, @DefaultPortName, #DC_BINNAMES, @BinNameBuffer, 0)
Select NumBins
Case -1
MessageRequester("Fehler", "Der Aufruf der Windows-Funktion DeviceCapabilities() ist fehlgeschlagen!", #MB_ICONERROR)
End
Case 0
MessageRequester("Fehler", "Der Abfrage der Papiereinzugfach-Namen wird vom Druckertreiber nicht unterstützt!", #MB_ICONERROR)
End
EndSelect
If OpenWindow(0, 0, 0, 200, 100, "Fach-Auswahl", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
If CreateGadgetList(WindowID(0))
ComboBoxGadget(0, 10, 10, 180, 200)
ButtonGadget(1, 50, 70, 100, 20, "Drucken")
For i = 0 To NumBins - 1
AddGadgetItem(0, -1, Trim(PeekS(@BinNameBuffer + i * #BinNameLength)))
Next i
SetGadgetState(0, 0)
WindowEvent = WaitWindowEvent()
Repeat
WindowEvent = WaitWindowEvent()
Select WindowEvent
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
If EventGadget() = 1 And EventType() = #PB_EventType_LeftClick
Break
EndIf
EndSelect
ForEver
EndIf
EndIf
SelectedBinName = GetGadgetText(0)
SelectedBinID = GetGadgetState(0)
CloseWindow(0)
; ----- Einzugfach-ID ermitteln
NumBins = DeviceCapabilities_(@DefaultPrinterName, @DefaultPortName, #DC_BINS, @BinIDBuffer, 0)
Select NumBins
Case -1
MessageRequester("Fehler", "Der Aufruf der Windows-Funktion DeviceCapabilities() ist fehlgeschlagen!", #MB_ICONERROR)
End
Case 0
MessageRequester("Fehler", "Der Abfrage der Papiereinzugfach-Namen wird vom Druckertreiber nicht unterstützt!", #MB_ICONERROR)
End
EndSelect
SelectedBinID = PeekW(@BinIDBuffer + SelectedBinID * 2)
; ----- Papiereinzugfach wechseln
*DEVMODEBuffer = ChangeBin(DefaultPrinterName, SelectedBinID)
If *DEVMODEBuffer = 0
End
EndIf
; ----- Test-Seite ausdrucken und dabei Papier aus gewünschtem Fach ziehen
PrinterDC = CreateDC_(@Driver, @DefaultPrinterName, 0, *DEVMODEBuffer)
DocInfo\cbSize = SizeOf(DOCINFO)
DocInfo\lpszDocName = @"PureBASIC Test-Seite"
DocInfo\lpszOutput = #Null
Text = "Diese Seite sollte aus dem Fach " + SelectedBinName + " gezogen worden sein!"
If StartDoc_(PrinterDC, @DocInfo) > 0
If StartPage_(PrinterDC) > 0
TextOut_(PrinterDC, 300, 100, Text, Len(Text))
EndPage_(PrinterDC)
EndIf
EndDoc_(PrinterDC)
EndIf
FreeMemory(*DEVMODEBuffer)
If PrinterDC <> 0
DeleteDC_(PrinterDC)
EndIf