Platforms to show: All Mac Windows Linux Cross-Platform
Required plugins for this example: MBS DynaPDF Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /DynaPDF/Print PDF
This example is the version from Thu, 31th Jul 2019.
Project "Print PDF.xojo_binary_project"
FileTypes
Filetype text
Filetype Pref
End FileTypes
MenuBar MenuBar1
MenuItem UntitledMenu1 = ""
MenuItem FileMenu = "&File"
MenuItem FileQuit = "Quit"
MenuItem UntitledMenu5 = ""
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem UntitledMenu0 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "Clear"
MenuItem UntitledMenu4 = ""
MenuItem UntitledMenu3 = ""
MenuItem UntitledMenu2 = ""
End MenuBar
Class App Inherits Application
EventHandler Sub Open()
#if TargetWin32 then
// ok
#else
MsgBox "This example is only for Windows."
#endif
System.DebugLog "Xojo "+RBVersionString
End EventHandler
End Class
Class MyDynaPDFMBS Inherits DynaPDFMBS
EventHandler Function Error(ErrorCode as integer, ErrorMessage as string, ErrorType as integer) As integer
// output all messages on the console:
System.DebugLog str(ErrorCode)+": "+ErrorMessage
// and display dialog:
Dim d as New MessageDialog //declare the MessageDialog object
Dim b as MessageDialogButton //for handling the result
d.icon=MessageDialog.GraphicCaution //display warning icon
d.ActionButton.Caption="Continue"
d.CancelButton.Visible=True //show the Cancel button
// a warning or an error?
if BitAnd(ErrorType, me.kE_WARNING) = me.kE_WARNING then
// if user decided to ignore, we'll ignore
if IgnoreWarnings then Return 0
d.Message="A warning occurred while processing your PDF code."
// we add a third button to display all warnings
d.AlternateActionButton.Caption = "Ignore warnings"
d.AlternateActionButton.Visible = true
else
d.Message="An error occurred while processing your PDF code."
end if
d.Explanation = str(ErrorCode)+": "+ErrorMessage
b=d.ShowModal //display the dialog
Select Case b //determine which button was pressed.
Case d.ActionButton
Return 0 // ignore
Case d.AlternateActionButton
IgnoreWarnings = true
Return 0 // ignore
Case d.CancelButton
Return -1 // stop
End select
End EventHandler
EventHandler Sub InitProgress(ProgType as integer, MaxCount as integer)
ProgressMaxCount = MaxCount
ProgressPrinting = (ProgType = kptPrintPage)
End EventHandler
EventHandler Function Progress(ActivePage as integer) As integer
if printing then
if g <> nil then
// draw something on each page
dim m as string = "Xojo Page "+str(ActivePage-1) + " of " + str(ProgressMaxCount)
g.DrawString m, 50, 50
// next page?
if ActivePage > 1 then
// start new page
'System.DebugLog "nextpage"
g.NextPage
end if
end if
// now we are on ActivePage
// show progress
CurrentPage = ActivePage
app.YieldToNextThread
end if
End EventHandler
Property CurrentPage As Integer
Property IgnoreWarnings As Boolean
Property NumberOfPages As Integer
Property PrinterFlags As Integer
Property PrinterHandle As Integer
Property PrinterMargin As DynaPDFRectMBS
Property PrintingDone As Boolean
Property ProgressMaxCount As Integer
Property ProgressPrinting As Boolean
Property g As Graphics
Property mode As Integer
Property printerName As string
Property printing As Boolean
End Class
Class PrintWindow Inherits Window
Control PushButton1 Inherits PushButton
ControlInstance PushButton1 Inherits PushButton
EventHandler Sub Action()
dim f as FolderItem = GetOpenFolderItem(FileTypes1.Pdf)
SetPDF f
End EventHandler
End Control
Control InputPath Inherits Label
ControlInstance InputPath Inherits Label
End Control
Control PrintButton Inherits PushButton
ControlInstance PrintButton Inherits PushButton
EventHandler Sub Action()
PrintWithXojoGraphics
End EventHandler
End Control
Control RadioColor Inherits RadioButton
ControlInstance RadioColor Inherits RadioButton
End Control
Control Label1 Inherits Label
ControlInstance Label1 Inherits Label
End Control
Control RadioGray Inherits RadioButton
ControlInstance RadioGray Inherits RadioButton
End Control
Control RadioBW Inherits RadioButton
ControlInstance RadioBW Inherits RadioButton
End Control
Control CheckAuto Inherits CheckBox
ControlInstance CheckAuto Inherits CheckBox
End Control
Control Label2 Inherits Label
ControlInstance Label2 Inherits Label
End Control
Control CheckShrink Inherits CheckBox
ControlInstance CheckShrink Inherits CheckBox
End Control
Control CheckFirst Inherits CheckBox
ControlInstance CheckFirst Inherits CheckBox
End Control
Control bar Inherits ProgressBar
ControlInstance bar Inherits ProgressBar
End Control
Control Info Inherits Label
ControlInstance Info Inherits Label
End Control
Control Thread1 Inherits Thread
ControlInstance Thread1 Inherits Thread
EventHandler Sub Run()
if pdf <> nil then
timer1.mode = timer.ModeMultiple
if pdf.printerName = "" then
// print to graphics from xojo
dim e as boolean = pdf.PrintPDFFile(nil, "test", pdf.PrinterHandle, pdf.PrinterFlags, pdf.PrinterMargin)
else
// print to named printer
dim e as boolean = pdf.PrintPDFFile(nil, "test", pdf.printerName, pdf.PrinterFlags, pdf.PrinterMargin)
end if
// done
pdf.printing = False
call pdf.CloseFile
pdf.PrintingDone = true
end if
End EventHandler
End Control
Control Timer1 Inherits Timer
ControlInstance Timer1 Inherits Timer
EventHandler Sub Action()
if pdf.PrintingDone then
dim g as Graphics = pdf.g
if g <> nil then
// draw something on last page
dim m as string = "Xojo printing done."
g.DrawString m, 50, 50
// cleanup
g = nil
end if
// cleanup pdf
pdf = nil
// done
info.Visible = False
bar.Visible = false
me.mode = 0
MsgBox "Printing done."
Return
end if
dim s as string = str(pdf.CurrentPage)+" of "+str(pdf.NumberOfPages)
System.DebugLog s
bar.Value = pdf.CurrentPage
info.Text = s
End EventHandler
End Control
Control PrinterButton Inherits PushButton
ControlInstance PrinterButton Inherits PushButton
EventHandler Sub Action()
PrintToNamedPrinter
End EventHandler
End Control
Control Label3 Inherits Label
ControlInstance Label3 Inherits Label
End Control
Control printerName Inherits TextField
ControlInstance printerName Inherits TextField
End Control
Control Label4 Inherits Label
ControlInstance Label4 Inherits Label
End Control
Control Label5 Inherits Label
ControlInstance Label5 Inherits Label
End Control
Control Label6 Inherits Label
ControlInstance Label6 Inherits Label
End Control
Control PrinterDialogButton Inherits PushButton
ControlInstance PrinterDialogButton Inherits PushButton
EventHandler Sub Action()
PrintToPrinterWithDialog
End EventHandler
End Control
Control SaveButton Inherits PushButton
ControlInstance SaveButton Inherits PushButton
EventHandler Sub Action()
if PrintSettings = "" then
// nothing to save
Return
end if
dim f as FolderItem = GetSaveFolderItem(FileTypes.Pref, "settings.pref")
if f = nil then Return
dim b as BinaryStream = BinaryStream.Create(f, true)
b.Write PrintSettings
End EventHandler
End Control
Control LoadButton Inherits PushButton
ControlInstance LoadButton Inherits PushButton
EventHandler Sub Action()
dim f as FolderItem = GetOpenFolderItem(FileTypes.Pref)
if f = nil then Return
dim b as BinaryStream = BinaryStream.Open(f)
PrintSettings = b.Read(b.Length)
End EventHandler
End Control
Control CheckPrintPageAsIS Inherits CheckBox
ControlInstance CheckPrintPageAsIS Inherits CheckBox
End Control
Control PrinterPageDialogButton Inherits PushButton
ControlInstance PrinterPageDialogButton Inherits PushButton
EventHandler Sub Action()
PrintPageToPrinterWithDialog
End EventHandler
End Control
EventHandler Sub Open()
// for testing, preload a PDF
dim f as FolderItem = SpecialFolder.Desktop.Child("test.pdf")
SetPDF f
End EventHandler
Function PreparePDF(g as Graphics = nil) As Boolean
// start new PDF context
pdf = new MyDynapdfMBS
call pdf.CreateNewPDF nil
// import PDF
dim n as integer = pdf.OpenImportFile(InputFile, 0, "")
if n < 0 then
Return false
end if
// print
if CheckFirst.Value then
// import first page?
call pdf.ImportPDFPage(1)
else
// import all pages?
'call pdf.ImportPDFFile(1)
// import selected pages in given number of copies
dim copies as integer = 1
dim firstPage as integer = 1
dim numPages as integer = pdf.GetInPageCount // pages in PDF
dim lastPage as integer = numPages
if g <> nil then
copies = g.Copies
firstPage = g.FirstPage
lastPage = g.LastPage
System.DebugLog "g.FirstPage: "+str(g.FirstPage)
System.DebugLog "g.LastPage: "+str(g.LastPage)
end if
if firstPage < 1 then
firstPage = 1
end if
if lastPage > numPages then
lastPage = numPages
end if
for c as integer = 1 to Copies
for i as integer = firstPage to lastPage
call pdf.ImportPDFPage(i)
next
next
end if
pdf.NumberOfPages = pdf.GetPageCount
System.DebugLog "NumberOfPages: "+str(pdf.NumberOfPages)
if pdf.NumberOfPages = 0 then
MsgBox "No pages?"
Return false
end if
Return true
End Function
Sub PrintPageToPrinterWithDialog()
if not PreparePDF then Return
// flags we need to pass for using Xojo's graphics class
dim flags as integer = 0
// color or black/white?
if RadioBW.Value then
flags = BitwiseOr(flags, pdf.kpff1Bit)
elseif RadioColor.Value then
flags = BitwiseOr(flags, pdf.kpffColor)
end if
// rotate if needed
if CheckAuto.Value then
flags = BitwiseOr(flags, pdf.kpffAutoRotateAndCenter)
end if
// shrink if needed
if CheckShrink.Value then
flags = BitwiseOr(flags, pdf.kpffShrinkToPrintArea)
end if
if CheckPrintPageAsIS.Value then
flags = BitwiseOr(flags, pdf.kpffPrintPageAsIs)
end if
bar.Maximum = 1
bar.Value = 0
bar.Visible = true
pdf.PrinterMargin = nil
pdf.PrinterFlags = flags
pdf.printing = true
pdf.PrintingDone = false
pdf.printerName = printerName.Text
if PrintSettings <> "" then
if pdf.PrintSetDevMode(PrintSettings) then
// ok
else
MsgBox "Failed to load print settings."
end if
end if
// print to named printer
dim e as boolean = pdf.PrintPDFPageWithDialog(1, "test", pdf.PrinterFlags, pdf.PrinterMargin, nil, self)
// query print settings
PrintSettings = pdf.PrintGetDevMode
// you can use WindowsDeviceModeMBS class to edit those settings
if PrintSettings <> "" then
SaveButton.Enabled = true
end if
if e then
MsgBox "Printed."
end if
// cleanup
pdf = nil
End Sub
Sub PrintToNamedPrinter()
if not PreparePDF then Return
// flags we need to pass for using Xojo's graphics class
dim flags as integer = 0
// color or black/white?
if RadioBW.Value then
flags = BitwiseOr(flags, pdf.kpff1Bit)
elseif RadioColor.Value then
flags = BitwiseOr(flags, pdf.kpffColor)
end if
// rotate if needed
if CheckAuto.Value then
flags = BitwiseOr(flags, pdf.kpffAutoRotateAndCenter)
end if
// shrink if needed
if CheckShrink.Value then
flags = BitwiseOr(flags, pdf.kpffShrinkToPrintArea)
end if
if CheckPrintPageAsIS.Value then
flags = BitwiseOr(flags, pdf.kpffPrintPageAsIs)
end if
bar.Maximum = pdf.numberOfPages
bar.Value = 0
bar.Visible = true
pdf.PrinterMargin = nil
pdf.PrinterFlags = flags
pdf.printing = true
pdf.PrintingDone = false
pdf.printerName = printerName.Text
Thread1.run
End Sub
Sub PrintToPrinterWithDialog()
if not PreparePDF then Return
// flags we need to pass for using Xojo's graphics class
dim flags as integer = 0
// color or black/white?
if RadioBW.Value then
flags = BitwiseOr(flags, pdf.kpff1Bit)
elseif RadioColor.Value then
flags = BitwiseOr(flags, pdf.kpffColor)
end if
// rotate if needed
if CheckAuto.Value then
flags = BitwiseOr(flags, pdf.kpffAutoRotateAndCenter)
end if
// shrink if needed
if CheckShrink.Value then
flags = BitwiseOr(flags, pdf.kpffShrinkToPrintArea)
end if
if CheckPrintPageAsIS.Value then
flags = BitwiseOr(flags, pdf.kpffPrintPageAsIs)
end if
bar.Maximum = pdf.numberOfPages
bar.Value = 0
bar.Visible = true
pdf.PrinterMargin = nil
pdf.PrinterFlags = flags
pdf.printing = true
pdf.PrintingDone = false
pdf.printerName = printerName.Text
if PrintSettings <> "" then
if pdf.PrintSetDevMode(PrintSettings) then
// ok
else
MsgBox "Failed to load print settings."
end if
end if
// print to named printer
dim e as boolean = pdf.PrintPDFFileWithDialog(nil, "test", pdf.PrinterFlags, pdf.PrinterMargin, nil, self)
// query print settings
PrintSettings = pdf.PrintGetDevMode
// you can use WindowsDeviceModeMBS class to edit those settings
if PrintSettings <> "" then
SaveButton.Enabled = true
end if
if e then
MsgBox "Printed."
end if
// cleanup
pdf = nil
End Sub
Sub PrintWithXojoGraphics()
if RBVersion >= 2016.04 then
// Warning: Printing with Xojo Graphics doesn't work for Xojo 2016r4 and 2017r1
// due to bugs related to switch to DirectDraw. Feedback case 47467
break
end if
if pdf.GetPageCount < 1 then
MsgBox "No PDF pages loaded?"
return
end if
// print
dim ps as new PrinterSetup
dim g as Graphics = OpenPrinterDialog(ps)
if g = nil then
Return
end if
if not PreparePDF(g) then Return
System.DebugLog "g.width: "+str(g.Width)
System.DebugLog "g.height: "+str(g.height)
dim h as integer = g.Handle(g.HandleTypeHDC)
if h = 0 then
MsgBox "no graphics handle?"
Return
end if
dim r as new DynaPDFRectMBS
r.Left = 0 // Compensate margin from xojo?
r.top = 0
r.Bottom = 0
r.Right = 0
// flags we need to pass for using Xojo's graphics class
dim flags as integer = Bitwise.BitOr(pdf.kpffNoEndDoc, pdf.kpffNoStartDoc, pdf.kpffNoStartPage)
// color or black/white?
if RadioBW.Value then
flags = BitwiseOr(flags, pdf.kpff1Bit)
elseif RadioColor.Value then
flags = BitwiseOr(flags, pdf.kpffColor)
end if
// rotate if needed
if CheckAuto.Value then
flags = BitwiseOr(flags, pdf.kpffAutoRotateAndCenter)
end if
// shrink if needed
if CheckShrink.Value then
flags = BitwiseOr(flags, pdf.kpffShrinkToPrintArea)
end if
if CheckPrintPageAsIS.Value then
flags = BitwiseOr(flags, pdf.kpffPrintPageAsIs)
end if
bar.Maximum = pdf.numberOfPages
bar.Value = 0
bar.Visible = true
pdf.PrinterMargin = r
pdf.PrinterHandle = h
pdf.PrinterFlags = flags
pdf.printing = true
pdf.PrintingDone = false
pdf.g = g
Thread1.run
End Sub
Sub SetPDF(f as FolderItem)
if f <> nil and f.Exists then
InputFile = f
InputPath.Text = f.NativePath
PrintButton.Enabled = true
PrinterButton.Enabled = true
PrinterDialogButton.Enabled = true
PrinterPageDialogButton.Enabled = true
end if
End Sub
Property InputFile As FolderItem
Property PDF As MyDynaPDFMBS
Property PrintSettings As String
End Class
FileTypes1
Filetype application/pdf
End FileTypes1
End Project
The items on this page are in the following plugins: MBS DynaPDF Plugin.