Hallo,
kennt jemand eine Möglichkeit, wie ich mit PB Systemweit (unter Windows) die Anzahl der Exemplare die ein Drucker ausgeben soll setzen kann?
Ich denke, dass dies nur über irgendwelche API-Aufrufe geht.
Gruß
Rolf
Anzahl der Druckkopien
-
- Beiträge: 13
- Registriert: 26.07.2006 03:26
Die Aufgabe, die Anzahl Kopien im Druck-Requester standardmäßig abzuändern (d.h. die Einstellung gilt nicht nur für den aktuellen Druck, sondern dauerhaft, also auch nach einem Rechner-Neustart), ist in der Tat nicht trivial und bedingt - wie vermutet - den heftigen Einsatz des WinAPI. Folgender Artikel in der Microsoft Knowledge Base bietet eine Lösung in VisualBASIC für die Änderung der Duplex-Druckeinstellung aus Word heraus, die aber abgewandelt auch zur Änderung der Anzahl Kopien oder für die Umschaltung zwischen Hoch- und Querdruck verwendet werden kann:
http://support.microsoft.com/kb/230743/en-us
Eine Umsetzung für PureBASIC:
Die vorgenommene Änderung gilt nur für den Default-Drucker. Soll die Anzahl Kopien für einen anderen Drucker abgeändert werden, wird entweder an die Prozedur SetPrinterDefaultNumCopies(PrinterName, NumCopies) der Name eines anderen Druckers übergeben oder es wird dem Anwender eine Liste der installierten Drucker zur Auswahl angeboten. Wie man eine Liste der installierten Drucker erstellt, hat gnozal bereits gezeigt:
http://www.purebasic.fr/english/viewtopic.php?t=11883
http://support.microsoft.com/kb/230743/en-us
Eine Umsetzung für PureBASIC:
Code: Alles auswählen
Procedure.L SetPrinterDefaultNumCopies(PrinterName.S, NumCopies.L)
BufferSize.L
BytesRetrieved.L
*DEVMODEBuffer.DEVMODE
*DEVMODEBufferCopy.DEVMODE
ErrorMsg.S
ModeFlag.L
PRINTER_DEFAULTSStructure.PRINTER_DEFAULTS
*PRINTER_INFO_2Buffer.PRINTER_INFO_2
*PRINTER_INFO_2BufferCopy.PRINTER_INFO_2
PrinterHandle.L
Result.L
; ----- Drucker-Handle für gewünschten Drucker anfordern
PRINTER_DEFAULTSStructure\DesiredAccess = #STANDARD_RIGHTS_REQUIRED | #PRINTER_ACCESS_ADMINISTER | #PRINTER_ACCESS_USE
Result = OpenPrinter_(@PrinterName, @PrinterHandle, @PRINTER_DEFAULTSStructure)
If Result = #False
ErrorMsg = "Der Drucker " + PrinterName + " konnte nicht geöffnet werden!"
Goto CleanUp
EndIf
If PrinterHandle = 0
ErrorMsg = "Es konnte kein Drucker-Handle ermittelt werden!"
Result = #False
Goto CleanUp
EndIf
; ----- Erforderliche Puffergröße für die DEVMODE-Struktur ermitteln
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
; ----- Speicherblock für die DEVMODE-Struktur anfordern
*DEVMODEBuffer = AllocateMemory(BufferSize)
If *DEVMODEBuffer = 0
ErrorMsg = "Die Speicheranforderung für die DEVMODE-Struktur ist gescheitert!"
Result = #False
Goto CleanUp
EndIf
; ----- Speicherblock für eine Kopie der DEVMODE-Struktur anfordern
*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 Übergabe der DEVMODE-Struktur ist gescheitert!"
Result = #False
Goto CleanUp
EndIf
; ----- DEVMODE-Struktur kopieren
CopyMemory(*DEVMODEBuffer, *DEVMODEBufferCopy, BufferSize)
; ----- Prüfen ob die Duplex-Einstellung abgeändert werden kann
If *DEVMODEBufferCopy\dmFields & #DM_COPIES <> #DM_COPIES
ErrorMsg = "Die Einstellung der Kopien-Anzahl kann für diesen Drucker nicht geändert werden!"
Result = #False
Goto CleanUp
EndIf
; ----- Duplex-Einstellung in Kopie der DEVMODE-Struktur abändern
*DEVMODEBufferCopy\dmCopies = NumCopies
; ----- Angeben, welche Parameter geändert worden sind
*DEVMODEBufferCopy\dmFields = #DM_COPIES
; ----- DEVMODE-Struktur mit veränderter Kopie überschreiben
CopyMemory(*DEVMODEBufferCopy, *DEVMODEBuffer, BufferSize)
; ----- Veränderte DEVMODE-Struktur übergeben
Result = DocumentProperties_(0, PrinterHandle, @PrinterName, *DEVMODEBuffer, *DEVMODEBuffer, #DM_IN_BUFFER | #DM_OUT_BUFFER)
If Result <> #IDOK
ErrorMsg = "Die Änderung der Kopienzahl ist auf diesem Drucker gescheitert!"
Result = #False
Goto CleanUp
EndIf
; ----- Erforderliche Puffergröße für PRINTER_INFO_2-Struktur ermitteln
BufferSize = 0
GetPrinter_(PrinterHandle, 2, 0, 0, @BufferSize)
If BufferSize = 0
ErrorMsg = "Die Ermittlung der Puffergröße für den Drucker ist gescheitert!"
Result = #False
Goto CleanUp
EndIf
BufferSize = BufferSize + 100
; ----- Speicherblock für die PRINTER_INFO_2-Struktur anfordern
*PRINTER_INFO_2Buffer = AllocateMemory(BufferSize)
If *PRINTER_INFO_2Buffer = 0
ErrorMsg = "Die Speicheranforderung für die PRINTER_INFO_2-Struktur ist gescheitert!"
Result = #False
Goto CleanUp
EndIf
; ----- Speicherblock für eine Kopie der PRINTER_INFO_2-Struktur anfordern
*PRINTER_INFO_2BufferCopy = AllocateMemory(BufferSize)
If *PRINTER_INFO_2BufferCopy = 0
ErrorMsg = "Die Speicheranforderung für eine Kopie der PRINTER_INFO_2-Struktur ist gescheitert!"
Result = #False
Goto CleanUp
EndIf
; ----- PRINTER_INFO_2-Struktur generieren lassen
Result = GetPrinter_(PrinterHandle, 2, *PRINTER_INFO_2Buffer, BufferSize, @BytesRetrieved)
If Result = 0
ErrorMsg = "Die Ermittlung der Drucker-Einstellungen ist gescheitert!"
Goto CleanUp
EndIf
; ----- PRINTER_INFO_2-Struktur kopieren
CopyMemory(*PRINTER_INFO_2Buffer, *PRINTER_INFO_2BufferCopy, BufferSize)
; ----- PRINTER_INFO_2-Struktur abändern
*PRINTER_INFO_2BufferCopy\pDevMode = *DEVMODEBuffer
; ----- PRINTER_INFO_2-Struktur mit veränderter Kopie überschreiben
CopyMemory(*PRINTER_INFO_2BufferCopy, *PRINTER_INFO_2Buffer, BufferSize)
Result = SetPrinter_(PrinterHandle, 2, *PRINTER_INFO_2Buffer, 0)
If Result = 0
ErrorMsg = "Die Abänderung der Drucker-Einstellungen ist gescheitert!"
Else
Result = #True
EndIf
MessageRequester("Drucker: " + PrinterName, "Neue Standard-Einstellung im Druck-Requester:" + #CR$ + "Anzahl Kopien = " + Str(*DEVMODEBuffer\dmCopies), #MB_ICONINFORMATION)
; ----- Printer-Handle und Speicherbereiche freigeben
CleanUp:
If PrinterHandle <> 0
ClosePrinter_(PrinterHandle)
EndIf
If *DEVMODEBuffer <> 0
FreeMemory(*DEVMODEBuffer)
EndIf
If *DEVMODEBufferCopy <> 0
FreeMemory(*DEVMODEBufferCopy)
EndIf
If *PRINTER_INFO_2Buffer <> 0
FreeMemory(*PRINTER_INFO_2Buffer)
EndIf
If *PRINTER_INFO_2BufferCopy <> 0
FreeMemory(*PRINTER_INFO_2BufferCopy)
EndIf
If Result = #False
MessageRequester("Fehler", ErrorMsg, #MB_ICONERROR)
EndIf
ProcedureReturn Result
EndProcedure
; Prozedur zum Ermitteln des Default-Druckers
; http://www.purebasic.fr/english/viewtopic.php?t=11883
Procedure.S GetDefaultPrinter()
PrinterNameBuffer.S
PrinterNameBuffer = Space(260)
If GetPrivateProfileString_("WINDOWS", "DEVICE", "", @PrinterNameBuffer, Len(PrinterNameBuffer), "Win.Ini")
ProcedureReturn StringField(PrinterNameBuffer, 1, ",")
EndIf
MessageRequester("Fehler", "Die Ermittlung des Default-Druckers ist fehlgeschlagen!", #MB_ICONERROR)
ProcedureReturn ""
EndProcedure
DefaultNumCopies.S
PrinterName.S
PrinterName = GetDefaultPrinter()
If PrinterName <> ""
DefaultNumCopies = InputRequester("Drucker: " + PrinterName, "Anzahl standardmäßig zu druckender Kopien?", "")
If DefaultNumCopies <> "" And Val(DefaultNumCopies)
SetPrinterDefaultNumCopies(PrinterName, Val(DefaultNumCopies))
EndIf
EndIf
http://www.purebasic.fr/english/viewtopic.php?t=11883