Multi-page Scintilla printing with Header & Footer
Posted: Tue Jun 05, 2012 11:36 pm
This routine will print one or more copies of a scintilla file with optional header and footer data. It was a pain to figure out the footer because once you make the first #SCI_FORMATRANGE call to draw the first page, you can no longer use DrawText(). You have to StopDrawing() with each page, then restart.
This "should be" cross platform, since I am not using any API calls.
Features not yet implemented:
* Margins are in Pixels, not inches or millimeters. Feel free to update this.
* No Landscape or Portrait orientation. (Currently, it is chosen by the printer setting in the PrintRequester)
* Number of copies are set beforehand; I do not know how to read them from the PrintRequester() without API calls.
* Print Range is not implemented, although that could easily be added using #SCI_POSITIONFROMLINE.
*
I have a macro file that I use for my Sci gadgets, so I do not need the ScintillaSendMessage commands. This allows copying commands straight from the Sci help page. I tried to convert them all, but it does compile with EnableExplicit... if I missed one, let me know and I will update. This is not totally refactored (there may be a few unnecessary temporary variables); feel free to clean it up or add features and share.
Have fun!
This "should be" cross platform, since I am not using any API calls.
Features not yet implemented:
* Margins are in Pixels, not inches or millimeters. Feel free to update this.
* No Landscape or Portrait orientation. (Currently, it is chosen by the printer setting in the PrintRequester)
* Number of copies are set beforehand; I do not know how to read them from the PrintRequester() without API calls.
* Print Range is not implemented, although that could easily be added using #SCI_POSITIONFROMLINE.
*
I have a macro file that I use for my Sci gadgets, so I do not need the ScintillaSendMessage commands. This allows copying commands straight from the Sci help page. I tried to convert them all, but it does compile with EnableExplicit... if I missed one, let me know and I will update. This is not totally refactored (there may be a few unnecessary temporary variables); feel free to clean it up or add features and share.
Have fun!
Code: Select all
; Fill the global structure with the appropriate flags and data, and call filePrint().
Structure PrintSettingStruct
HeaderDate.i ; flags to include info in the header & footers.
HeaderFile.i
HeaderPath.i
HeaderPage.i
FooterDate.i
FooterFile.i
FooterPath.i
FooterPage.i
Color.i
WordWrap.i
Landscape.i ; not implemented.
Copies.i
MarginT.d ; These were originally intended to be double precision floats.
MarginL.d ; but there is no native PB command to get printer resolution.
MarginR.d
MarginB.d
EndStructure
Global PrintPref.PrintSettingStruct
Procedure filePrint(ActiveSci.i, openFName.s)
Protected.i drawresult, prn, copynum = 1
Protected FormatRange.FORMATRANGE
Protected.i headerht, headerwd, footerht, footerwd
Protected.i length, oversize, cut
Protected.i PageCount
Protected.s strDate, strFile, strPage ; temp string holders.
Protected.s header, footer, Output$
Protected.i PageWidth
If ScintillaSendMessage(ActiveSci, #SCI_GETLENGTH)
prn = PrintRequester()
If prn
With PrintPref
; Start header:
header = "" : strFile = ""
headerht = 0 : headerwd = 0
If \HeaderDate Or \HeaderFile Or \HeaderPath
StartDrawing(PrinterOutput())
headerht = 2 * TextHeight(openFName) ; use 2x so we get a space between.
If \HeaderDate : strDate = FormatDate("%yyyy/%mm/%dd", Date()) + "; " : EndIf
If \HeaderFile : strFile = GetFilePart(openFName) : EndIf
If \HeaderPath : strFile = openFName : EndIf
If \HeaderPage : strPage = " ; Page " : EndIf
If strFile <> ""
header = strFile + strDate
If strPage <> ""
header = header + strPage + "00000"
EndIf
headerwd = TextWidth(header)
PageWidth = PrinterPageWidth() - \MarginL -\MarginR
If headerwd > PageWidth
oversize = headerwd - PageWidth
cut = oversize / TextWidth("O")
length = Len(strFile) - cut - 1
strFile = Left(strFile, length)
EndIf
header = strDate + strFile + strPage
Else
header = strDate + strPage
EndIf
StopDrawing()
EndIf ; done with Header
; Start Footer:
footer = "" : strFile = ""
footerht = 0 : footerwd = 0
If \FooterDate Or \FooterFile Or \FooterPath
StartDrawing(PrinterOutput())
footerht = 2 * TextHeight(openFName)
If \FooterDate : strDate = FormatDate("%yyyy/%mm/%dd", Date()) + "; " : EndIf
If \FooterFile : strFile = GetFilePart(openFName) : EndIf
If \FooterPath : strFile = openFName : EndIf
If \FooterPage : strPage = " ; Page " : EndIf
If strFile <> ""
footer = strFile + strDate + strPage + "00000"
footerwd = TextWidth(footer)
PageWidth = PrinterPageWidth() - \MarginL -\MarginR
If footerwd > PageWidth
oversize = footerwd - PageWidth
cut = oversize / TextWidth("O")
length = (Len(strFile) - cut) - 1 ; one extra character, just in case
strFile = Left(strFile, length)
EndIf
footer = strDate + strFile + strPage
Else
footer = strDate + strPage
EndIf
StopDrawing()
EndIf ; done with Footer
; Set up the printer:
ScintillaSendMessage(ActiveSci, #SCI_SETPRINTWRAPMODE, \WordWrap)
ScintillaSendMessage(ActiveSci, #SCI_SETPRINTCOLOURMODE, \Color)
; rc is where to print
FormatRange\rc\left=\MarginL
FormatRange\rc\top =\MarginT + headerht
FormatRange\rc\right=PrinterPageWidth() - \MarginL -\MarginR ; width of the drawing area, in pixels
FormatRange\rc\bottom=PrinterPageHeight() - \MarginB - headerht - footerht ;
;rcPage is physically extents-- possible to print
FormatRange\rcPage\left=0
FormatRange\rcPage\top= 0
FormatRange\rcPage\right=PrinterPageWidth()
FormatRange\rcPage\bottom=PrinterPageHeight()
FormatRange\chrg\cpMin=0
FormatRange\chrg\cpMax=ScintillaSendMessage(ActiveSci, #SCI_GETLENGTH)
If StartPrinting(GetFilePart(openFName))
While copynum <= \Copies
PageCount = 1
FormatRange\chrg\cpMin=0 ; reset to character 0 to start over.
While FormatRange\chrg\cpMin < FormatRange\chrg\cpMax
drawresult = StartDrawing(PrinterOutput())
If drawresult = 0 : Break 2 : EndIf
FormatRange\hDC = drawresult
FormatRange\hdcTarget = drawresult
If header <> "" ; Print header:
Output$ = header
If strPage : Output$ + Str(PageCount) : EndIf
DrawText(10 + \MarginL, 10 + \MarginT , Output$, #Black, #White)
EndIf
If footer <> "" ; print footer:
Output$ = footer
If strPage : Output$ + Str(PageCount) : EndIf
DrawText(10 + \MarginL, (PrinterPageHeight() - footerht) - \MarginB, Output$, #Black, #White)
EndIf
FormatRange\chrg\cpMin = ScintillaSendMessage(ActiveSci, #SCI_FORMATRANGE, #True, FormatRange) ; Print this scintilla page:
PageCount + 1
StopDrawing() ; stop drawing between #SCI_FORMATRANGE calls, or the header will not draw.
ScintillaSendMessage(ActiveSci, #SCI_FORMATRANGE, #False, 0)
If FormatRange\chrg\cpMin < FormatRange\chrg\cpMax
NewPrinterPage()
EndIf
Wend
copynum + 1
If copynum <= \Copies
NewPrinterPage()
EndIf
Wend
StopPrinting()
EndIf
EndWith
EndIf
EndIf
EndProcedure