In order to work in ASCII and Unicode mode you have to change Len() to StringByteLenght() and the fixed count of 1 for the string terminator to SizeOf(Character). So this codeIdeasVacuum wrote:Stumbled across your code for presetting a printer - works really well (minor tweaks to suit PB4.61). How do I make it work when compiling as Unicode?
Code: Select all
TempString = PeekS(*Buffer + TempStringLength + 1)
TempStringLength = TempStringLength + Len(TempString) + 1
Code: Select all
TempString = PeekS(*Buffer + TempStringLength + SizeOf(Character))
TempStringLength = TempStringLength + StringByteLength(TempString) + SizeOf(Character)
Code: Select all
;=============================================================================
; Change global default settings for a printer
;
; Source code example from Microsoft in VisualBASIC for Word:
; "HOWTO: Set Duplex Printing for Word Automation"
; http://support.microsoft.com/kb/230743/en-us
;=============================================================================
EnableExplicit
Enumeration
#WindowPrinterDefaultSettings
EndEnumeration
Enumeration
#ComboPrinterNames
#FrameDuplex
#OptionHorizontal
#OptionVertical
#FrameSimplexDuplex
#OptionSimplex
#OptionDuplex
#FrameOrientation
#OptionPortrait
#OptionLandscape
#ButtonChange
#ButtonCancel
EndEnumeration
Define DuplexMode.I
Define NewDuplexState.I
Define NewPageOrientation.I
Define NumInstalledPrinters.I
Define OldDuplexState.I
Define OldPageOrientation.I
Define PageOrientation.I
Define WindowEvent.I
NewList PrinterName.S()
Declare.I ChangePrinterDefaultSettings(PrinterName.S)
Declare.I GetInstalledPrinters()
NumInstalledPrinters = GetInstalledPrinters()
If NumInstalledPrinters = 0
MessageRequester("Error", "Sorry, no installed printers found!", #MB_ICONERROR)
End
EndIf
OpenWindow(#WindowPrinterDefaultSettings, 516, 412, 272, 347, "Change Printer Default Settings", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
ComboBoxGadget(#ComboPrinterNames, 50, 15, 170, 20)
Frame3DGadget(#FrameDuplex, 50, 212, 177, 63, "")
OptionGadget(#OptionHorizontal, 62, 224, 159, 24, "Short Edge")
OptionGadget(#OptionVertical, 62, 248, 159, 24, "Long Edge (Book format)")
ButtonGadget(#ButtonChange, 40, 306, 72, 24, "Change")
ButtonGadget(#ButtonCancel, 156, 306, 72, 24, "Cancel")
Frame3DGadget(#FrameSimplexDuplex, 17, 148, 236, 138, "Simplex or Duplex Print")
OptionGadget(#OptionSimplex, 32, 170, 210, 24, "Print only on one side of page (Simplex)")
OptionGadget(#OptionDuplex, 32, 194, 210, 24, "Print on both sides of page (Duplex)")
Frame3DGadget(#FrameOrientation, 80, 50, 104, 76, "Page Orientation")
OptionGadget(#OptionPortrait, 92, 70, 80, 20, "Portrait")
OptionGadget(#OptionLandscape, 92, 94, 80, 20, "Landscape")
PageOrientation = #DMORIENT_PORTRAIT
SetGadgetState(#OptionPortrait, #True)
DuplexMode = #DMDUP_SIMPLEX
SetGadgetState(#OptionSimplex, #True)
DisableGadget(#FrameDuplex, #True)
DisableGadget(#OptionHorizontal, #True)
DisableGadget(#OptionVertical, #True)
ForEach PrinterName()
AddGadgetItem(#ComboPrinterNames, -1, PrinterName())
Next
SetGadgetState(#ComboPrinterNames, 0)
Repeat
WindowEvent = WaitWindowEvent()
If WindowEvent = #PB_Event_Gadget
Select EventGadget()
Case #OptionPortrait
PageOrientation = #DMORIENT_PORTRAIT
Case #OptionLandscape
PageOrientation = #DMORIENT_LANDSCAPE
Case #OptionSimplex
DisableGadget(#FrameDuplex, #True)
DisableGadget(#OptionHorizontal, #True)
DisableGadget(#OptionVertical, #True)
Case #OptionDuplex
DisableGadget(#FrameDuplex, #False)
DisableGadget(#OptionHorizontal, #False)
DisableGadget(#OptionVertical, #False)
SetGadgetState(#OptionVertical, #True)
Case #ButtonChange
If GetGadgetState(#OptionSimplex) = #True
DuplexMode = #DMDUP_SIMPLEX
Else
If GetGadgetState(#OptionHorizontal) = #True
DuplexMode = #DMDUP_HORIZONTAL
Else
DuplexMode = #DMDUP_VERTICAL
EndIf
EndIf
If ChangePrinterDefaultSettings(GetGadgetText(#ComboPrinterNames)) = #True
MessageRequester("Printer Settings", "Printer: " + GetGadgetText(#ComboPrinterNames) + #CR$ + #CR$ + "Old Page Orientation: " + Str(OldPageOrientation) + #CR$ + "New Page Orientation: " + Str(NewPageOrientation) + #CR$ + "Old Duplex Setting: " + Str(OldDuplexState) + #CR$ + "New Duplex Setting: " + Str(NewDuplexState))
EndIf
Break
Case #ButtonCancel
Break
EndSelect
EndIf
Until WindowEvent = #PB_Event_CloseWindow
End
Procedure.I ChangePrinterDefaultSettings(PrinterName.S)
Shared DuplexMode.I
Shared NewDuplexState.I
Shared NewPageOrientation.I
Shared OldDuplexState.I
Shared OldPageOrientation.I
Shared PageOrientation.I
Shared PrinterName.S()
Protected BufferSize.I
Protected BytesRetrieved.I
Protected *DEVMODEBuffer.DEVMODE
Protected *DEVMODEBufferCopy.DEVMODE
Protected DOCINFOStructure.DOCINFO
Protected ErrorMsg.S
Protected ModeFlag.I
Protected PrintText.S
Protected PRINTER_DEFAULTSStructure.PRINTER_DEFAULTS
Protected *PRINTER_INFO_2Buffer.PRINTER_INFO_2
Protected *PRINTER_INFO_2BufferCopy.PRINTER_INFO_2
Protected PrinterHandle.I
Protected Result.I
; ----- Get printer handle
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 = "Could not obtain printer handle!"
Result = #False
Goto CleanUp
EndIf
; ----- Get buffer size for DEVMODE structure
ModeFlag = 0
BufferSize = DocumentProperties_(0, PrinterHandle, @PrinterName, 0, 0, ModeFlag)
If BufferSize < 0 Or ModeFlag <> 0
ErrorMsg = "The size of the DEVMODE structure couldn't be obtained!"
Goto CleanUp
End
EndIf
; ----- Get memory buffer for DEVMODE structure
*DEVMODEBuffer = AllocateMemory(BufferSize)
If *DEVMODEBuffer = 0
ErrorMsg = "A memory request for the DEVMODE structure failed!"
Result = #False
Goto CleanUp
EndIf
; ----- Get memory buffer for copy of DEVMODE structure
*DEVMODEBufferCopy = AllocateMemory(BufferSize)
If *DEVMODEBufferCopy = 0
ErrorMsg = "A memory request for a copy of the DEVMODE structure failed!"
Result = #False
Goto CleanUp
EndIf
; ----- Generate DEVMODE structure
Result = DocumentProperties_(0, PrinterHandle, @PrinterName, *DEVMODEBuffer, 0, #DM_OUT_BUFFER)
If Result < 0
ErrorMsg = "The request for the DEVMODE structure failed!"
Result = #False
Goto CleanUp
EndIf
; ----- Copy DEVMODE structure
CopyMemory(*DEVMODEBuffer, *DEVMODEBufferCopy, BufferSize)
; ----- Does driver allow to activate duplex setting?
If *DEVMODEBufferCopy\dmFields & #DM_DUPLEX <> #DM_DUPLEX
ErrorMsg = "The duplex setting cannot be activated for this printer!"
Result = #False
Goto CleanUp
EndIf
; ----- Change page orientation in copy of DEVMODE structure
OldPageOrientation = *DEVMODEBufferCopy\dmOrientation
*DEVMODEBufferCopy\dmOrientation = PageOrientation
; ----- Change duplex setting in copy of DEVMODE structure
OldDuplexState = *DEVMODEBufferCopy\dmDuplex
*DEVMODEBufferCopy\dmDuplex = DuplexMode
; ----- Specify which parameters are to be changed
*DEVMODEBufferCopy\dmFields = #DM_ORIENTATION | #DM_DUPLEX
; ----- Overwrite DEVMODE structure with modified copy
CopyMemory(*DEVMODEBufferCopy, *DEVMODEBuffer, BufferSize)
; ----- Hand over the modified DEVMODE structure
Result = DocumentProperties_(0, PrinterHandle, @PrinterName, *DEVMODEBuffer, *DEVMODEBuffer, #DM_IN_BUFFER | #DM_OUT_BUFFER)
If Result <> #IDOK
ErrorMsg = "The hand over of the DEVMODE structure failed!"
Result = #False
Goto CleanUp
EndIf
; ----- Get buffer size for PRINTER_INFO_2-Struktur
BufferSize = 0
GetPrinter_(PrinterHandle, 2, 0, 0, @BufferSize)
If BufferSize = 0
ErrorMsg = "The size of the PRINTER_INFO_2 structure couldn't be obtained!"
Result = #False
Goto CleanUp
EndIf
BufferSize = BufferSize + 100
; ----- Get memory buffer for PRINTER_INFO_2 structure
*PRINTER_INFO_2Buffer = AllocateMemory(BufferSize)
If *PRINTER_INFO_2Buffer = 0
ErrorMsg = "A memory request for the PRINTER_INFO_2 structure failed!"
Result = #False
Goto CleanUp
EndIf
; ----- Get memory buffer for copy of PRINTER_INFO_2 structure
*PRINTER_INFO_2BufferCopy = AllocateMemory(BufferSize)
If *PRINTER_INFO_2BufferCopy = 0
ErrorMsg = "The memory request for a copy of the PRINTER_INFO_2 structure failed!"
Result = #False
Goto CleanUp
EndIf
; ----- Generate PRINTER_INFO_2 structure
Result = GetPrinter_(PrinterHandle, 2, *PRINTER_INFO_2Buffer, BufferSize, @BytesRetrieved)
If Result = 0
ErrorMsg = "The evaluation of printer settings failed!"
Goto CleanUp
EndIf
; ----- Copy PRINTER_INFO_2 structure
CopyMemory(*PRINTER_INFO_2Buffer, *PRINTER_INFO_2BufferCopy, BufferSize)
; ----- Change PRINTER_INFO_2 structure
*PRINTER_INFO_2BufferCopy\pDevMode = *DEVMODEBuffer
*PRINTER_INFO_2BufferCopy\pSecurityDescriptor = 0
; ----- Overwrite PRINTER_INFO_2 structure with modified copy
CopyMemory(*PRINTER_INFO_2BufferCopy, *PRINTER_INFO_2Buffer, BufferSize)
Result = SetPrinter_(PrinterHandle, 2, *PRINTER_INFO_2Buffer, 0)
If Result = 0
ErrorMsg = "The change of the printer settings failed!"
Else
Result = #True
EndIf
NewPageOrientation = *DEVMODEBuffer\dmOrientation
NewDuplexState = *DEVMODEBuffer\dmDuplex
; ----- Free printer handle and memory buffers
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
Procedure.I GetInstalledPrinters()
Shared PrinterName.S()
Protected *Buffer
Protected BufferSize.I
Protected PrinterName.S
Protected TempString.S
Protected TempStringLength.I
Protected TempPrinter.S
ClearList(PrinterName())
BufferSize = 8192
TempPrinter = Space(1024)
*Buffer = AllocateMemory(BufferSize)
If GetProfileString_("Devices", 0, "", *Buffer, BufferSize)
TempString = PeekS(*Buffer)
TempStringLength = StringByteLength(TempString)
While TempString <> ""
GetPrivateProfileString_("Devices", TempString, "", TempPrinter, 1024, "Win.Ini")
AddElement(PrinterName())
PrinterName() = TempString
TempString = PeekS(*Buffer + TempStringLength + SizeOf(Character))
TempStringLength = TempStringLength + StringByteLength(TempString) + SizeOf(Character)
Wend
EndIf
FreeMemory(*Buffer)
ProcedureReturn ListSize(PrinterName())
EndProcedure