LPRINT_plus

Share your advanced PureBasic knowledge/code with the community.
User avatar
Ferdinand
New User
New User
Posts: 9
Joined: Tue Mar 10, 2015 1:43 pm
Location: Netherlands
Contact:

LPRINT_plus

Post by Ferdinand »

Here is an include file with "LPRINT" and simple reporting functions

examples of use can be downloaded from this website
http://home.kpn.nl/fschinkel/purebasic

Note: I found it very useful during testing to use a printer to PDF, such as comes with the Foxit PDF reader.

Code: Select all

;
;======================================================================================================================================
;========================= START OF LPRINT INCLUDE ====================================================================================
;======================================================================================================================================
;
; name: LPRINT_plus
; version: 1.0.1 - some very minor cosmetic changes
; version: 1.0.0 - first version - basically complete
; PureBasic version: 5.31
; author: Ferdinand Schinkel
;
; (some code-snippets by Shardik, Dean Hodgson and Maddin)
;
; features: LPRINT("text") and LPRINTN("text") to print text to the printer as PRINT/PRINTN does to the console;
;           LPRINTF("filename") to print the contents of a file; default printer or selection of printer, 
;           optional setting of page orientation; optional page title; optional page numbering and page-number prefix; 
;           printing of one text-string over multiple lines/pages; TAB to a print position; 
;           changing of font(-color, -style) for title and text; setting the page width (in mm) of the print output
;
; FUNCTIONS: 
;    LP_SET_PAGE_PREFS(LP_Nr=0, LP_Title.s="", LP_PageOrientation.s="")
;                  - when this function is not used, default values are used
;                  - if used, this function has to be called before LP_START_PRINTING
;                  - optionally set the starting page number and/or the page title and/or the page orientation ("P" or "L")
;                    page title + ".TMP" is the job name For the printer
;                    1st param = 0  --> no page numbers, otherwise the starting page number (normally 1)
;                                       page number prefix (default: "page ") is the global LP_PageNumber_Prefix
;                                       and can be changed at the programmer's pleasure
;                    2nd param = "" --> no page title;
;                                       the page title can be changed anywhere in the program (variable LP_Title_Name)
;                    3rd param = "" --> default page orientation set on the printer
;                                       other than the empty string, accepted values are "P" or "L"
;
;    LP_START_PRINTING(LP_usedialog=1) - necessary function !
;                                      - this initializes the printer and purebasic for printing
;                                      - if LP_usedialog=1 then a userdialog for choosing a printer opens (PrintRequester)
;                                      - if LP_usedialog=0 then the standard printer is automatically selected
;
;    LP_END_PRINTING()  - necessary function !
;                         this closes the printer and purebasic printing
;                         page preferences are deleted
;
;    there is no limit to the amount of times the combination of LP_START_PRINTING and LP_END_PRINTING 
;    can be used in a program; LP_SET_PAGE_PREFS cannot be used inbetween LP_START_PRINTING and LP_END_PRINTING,
;    but before every LP_START_PRINTING, LP_SET_PAGE_PREFS can be called to change the default values (which are
;    reset at every LP_END_PRINTING)
;
;    LPRINT() and LPRINTN() reflect the behaviour of the console statements PRINT() and PRINTN()
;    LPRINT(LP_prns$)  - LPRINT without linefeed; LPRINT texts are printed directly after any previous text;
;                        if the text goes over the right page margin, it is continued on a new line
;    LPRINTN(LP_prns$) - LPRINT with linefeed after the text; 
;                        If there was any text from LPRINT statement(s) before, the LPRINTN text is printed directly after that;
;                        if the text goes over the right page margin, it is continued on a new line
;    LPRINTF(LP_FileToPrint.s="") - print the contents of a file (read as ASCII characters), line by line
;    LP_TAB(x)         - start printing the next text at character position x on the line
;    LP_SET_WIDTH(x)   - sets the width of the printed output to x millimeters
;    LP_NEWPAGE()      - prints a new page with an (optional) title after (optionally) printing a page number on the old page
;                        the use of page numbers and page title is set in LP_SET_PAGE_PREFS
;                        the global LP_PageBreak is set after every new page and can thus be checked in the code to print headers, etc.
;
;    LP_SETCOLOR(LP_colour=0,LP_bkcolour=-1) - sets the color of the font and background 
;                                            - expects RGB values for LP_colour, LP_bkcolour
;                                            - standard setting is (of course) black on white
;
; SETTING THE FONT OF TITLE AND TEXT - no procedure call necessary:
;    - this is done by changing the value of the global variables:
;      for the title: LP_Title_Font, LP_Title_Fontsize, LP_Title_Font_Bold, LP_Title_Font_Italic, LP_Title_Font_Underline        
;      for text     : LP_Text_Font, LP_Text_Fontsize, LP_Text_Font_Bold, LP_Text_Font_Italic, LP_Text_Font_Underline
;      >>> in case of an incorrectly named font the system will replace it automatically 
;          with the best choice it can make or a default font (no error message)
;      >>> LPRINT statements with text over multiple lines work only correctly with monospace fonts, 
;          such as Courier New and Lucida Console;
;          the same idea goes for the title which is always centered on the page; non-monospace fonts
;          will see the title easily go off-center
;
; LEFT AND RIGHT MARGINS are set in LP_START_PRINTING to 17mm each;
; left and right margins are implicitely set in the LP_SET_WIDTH function, both to the same value;
; to change left and/or right margin settings separately (in the program using this LPRINT include file):
; copy the relevant line(s) from LP_START_PRINTING() and set the margin(s) to the desired value(s)
;
;
; "internal" functions:
;    LP_Print_Title 
;    LP_Setfont_Title
;    LP_Setfont_Text
;    LP_Print_Page_Number
;    LP_Set_Printer_Orientation
;    LP_NewLine
;    LP_Calc_Chars_Line
;
;
Global LP_PageNumber
Global LP_Title_Name.s  ; title on the page and name of the print job  
Global LP_xpixels,LP_ypixels ; postion of cursor in pixels
Global LP_LMargin, LP_RMargin ; margins in pixels
Global LP_CharHeight ; in pixels
Global LP_CharWidth ; in pixels
Global LP_PageHeight  ; in pixels
Global LP_PageWidth   ; in millimeters (odd one out)
Global LP_PageBreak   ; a switch that is set to true in LP_NEWPAGE so that, when checked in the program, any new-page 
                      ; specific coding can be done (printing of headers, etc.);
                      ; set to false at any LPRINT/LPRINTN statement as then there is no new page situation any more
Global LP_LineOfChars ; number of characters on a line
Global LP_LineCh_Index=1 ; printing position of the next character on the line
Global LP_Original_PageOrientation.i ; for saving the page orientation of the printer to restore it later
Global LP_Title_Font.s="Courier New"
Global LP_Title_Fontsize=10
Global LP_Title_Font_Bold
Global LP_Title_Font_Italic
Global LP_Title_Font_Underline
Global LP_Text_Font.s="Courier New"
Global LP_Text_Fontsize=10
Global LP_Text_Font_Bold
Global LP_Text_Font_Italic
Global LP_Text_Font_Underline
;
Global LP_PageNumber_Prefix.s="page "
;
; some switches
Global LP_Printing_Active 
Global LP_Drawing_Active  
Global LP_Title_Printing   
Global LP_Newline_Flag     
;
Declare LP_Print_Title()
Declare LP_NEWPAGE()
Declare LP_END_PRINTING()

;set colour for printing
Procedure LP_SETCOLOR(LP_colour=0,LP_bkcolour=-1)
   If LP_Drawing_Active=#True
      If LP_bkcolour=-1
         LP_bkcolour=RGB(255,255,255)
      EndIf
      BackColor(LP_bkcolour)
      FrontColor(LP_colour)
   EndIf
EndProcedure

Procedure LP_Calc_Chars_Line()
  LP_LineOfChars=(PrinterPageWidth()-LP_LMargin-LP_RMargin)/LP_CharWidth
EndProcedure

;set up the printing font for thwe title
;uses font id 1
Procedure LP_Setfont_Title()
  
   If LP_Drawing_Active   ; StartDrawing() is active
     StopDrawing()
   EndIf  
   
   If Not LP_Printing_Active
     MessageRequester("LPRINT ERROR","setting title font call before LP_START_PRINTING",4112) ; 4112 = on top with error symbol
     End
   EndIf
   
   LP_temp_fontstyle=0
   If LP_Title_Font_Bold=#True : LP_temp_fontstyle=LP_temp_fontstyle | #PB_Font_Bold : EndIf
   If LP_Title_Font_Italic=#True : LP_temp_fontstyle=LP_temp_fontstyle | #PB_Font_Italic : EndIf
   If LP_Title_Font_Underline=#True : LP_temp_fontstyle=LP_temp_fontstyle | #PB_Font_Underline : EndIf

   If IsFont(1)
     FreeFont(1)
   EndIf
   ;
   ; code by Maddin for setting the fontsize from points to YSize 
   ; the factor on the fontsize line was originally 3.8
   ; the result is a fair approximation...
   If LP_Title_Fontsize
     hDC = StartDrawing(PrinterOutput()) 
     VerRes = GetDeviceCaps_(hDC,#VERTRES) 
     height = GetDeviceCaps_(hDC,#VERTSIZE)
     LP_PageWidth = GetDeviceCaps_(hDC,#HORZSIZE)
     dpmmy = VerRes / height   
     LP_temp_fontsize=Int(LP_Title_Fontsize * dpmmy / 3.6) 
     StopDrawing()     
   EndIf
   ;
   LoadFont(1,LP_Title_Font,LP_temp_fontsize,LP_temp_fontstyle)
   StartDrawing(PrinterOutput())  
   DrawingFont(FontID(1))
   LP_Drawing_Active=#True
   LP_SETCOLOR()
   LP_test$="X"
   LP_CharHeight=TextHeight(LP_test$)
   LP_CharWidth=TextWidth(LP_test$)
   LP_Calc_Chars_Line()

EndProcedure

;set up the printing font for thwe title
;uses font id 1
Procedure LP_Setfont_Text()
  
   If LP_Drawing_Active   ; StartDrawing() is active
      StopDrawing()
   EndIf
   
   If Not LP_Printing_Active   
     MessageRequester("LPRINT ERROR","setting text font call before LP_START_PRINTING",4112) ; 4112 = on top with error symbol
     End
   EndIf
   
   LP_temp_fontstyle=0
   If LP_Text_Font_Bold=#True : LP_temp_fontstyle=LP_temp_fontstyle | #PB_Font_Bold : EndIf
   If LP_Text_Font_Italic=#True : LP_temp_fontstyle=LP_temp_fontstyle | #PB_Font_Italic : EndIf
   If LP_Text_Font_Underline=#True : LP_temp_fontstyle=LP_temp_fontstyle | #PB_Font_Underline : EndIf

   If IsFont(1)
     FreeFont(1)
   EndIf
   ;
   ; code by Maddin for setting the fontsize from points to YSize 
   ; the factor on the fontsize line was originally 3.8
   ; the result is a fair approximation...
   If LP_Text_Fontsize
     hDC = StartDrawing(PrinterOutput()) 
     VerRes = GetDeviceCaps_(hDC,#VERTRES) 
     height = GetDeviceCaps_(hDC,#VERTSIZE)
     LP_PageWidth = GetDeviceCaps_(hDC,#HORZSIZE)
     dpmmy = VerRes / height   
     LP_temp_fontsize=Int(LP_Text_Fontsize * dpmmy / 3.6) 
     StopDrawing()     
   EndIf
   ;
   LoadFont(1,LP_Text_Font,LP_temp_fontsize,LP_temp_fontstyle)
   StartDrawing(PrinterOutput())  
   DrawingFont(FontID(1))
   LP_Drawing_Active=#True
   LP_SETCOLOR()
   LP_test$="X"
   LP_CharHeight=TextHeight(LP_test$)
   LP_CharWidth=TextWidth(LP_test$)
   If LP_PageNumber
     LP_PageHeight=PrinterPageHeight() - 3 * LP_CharHeight
   Else
     LP_PageHeight=PrinterPageHeight() - LP_CharHeight
   EndIf
   LP_Calc_Chars_Line()

EndProcedure


Procedure LP_NewLine()
  If LP_Drawing_Active=#False
    MessageRequester("LPRINT ERROR","newline not possible before LP_START_PRINTING",4112) ; 4112 = on top with error symbol
    End
  EndIf
  LP_ypixels=LP_ypixels+LP_CharHeight   ; shift the location of the ypixels coordinate to the next line
  LP_LineCh_Index=1                     ; position of character cursor on line 
  LP_xpixels=LP_LMargin
EndProcedure

;begin printjob
;set paramter to 0 to use default printer otherwise requester is displayed
;returns non 0 if printing can proceed
Procedure.l LP_START_PRINTING(LP_usedialog=1)
   If Not (LP_usedialog = 0 Or LP_usedialog = 1)
     MessageRequester("LPRINT ERROR","LP_START_PRINTING parameter must be 0 or 1",4112) 
     End
   EndIf
   If LP_Drawing_Active
     MessageRequester("LPRINT ERROR","LP_START_PRINTING called while already started",4112) 
     LP_END_PRINTING()
     End
   EndIf
   If LP_usedialog
     If Not PrintRequester()
       MessageRequester("LPRINT ERROR","no printer specified",4112) 
       End
     EndIf
   Else
     If Not DefaultPrinter()
       MessageRequester("LPRINT ERROR","default printer not found",4112) 
       End
     EndIf
   EndIf  
   If LP_Title_Name =""
     LP_temp=Random(8999)+1000
     LP_filename$=Str(LP_temp)+".TMP"
   Else
     LP_filename$=LP_Title_Name+".TMP"
   EndIf
   If Not StartPrinting(LP_filename$)  ; initialize printer and job
     MessageRequester("LPRINT ERROR","printing could not be started",4112) 
     End 
   EndIf
   ; LP_SETFONT_TEXT - set printing to the text font and initialize several variables
   LP_Printing_Active=#True
   LP_Setfont_Text()
   LP_xpixels=0
   LP_ypixels=0
   LP_LMargin=17*PrinterPageWidth()/LP_PageWidth  ; left margin set to 17mm
   LP_RMargin=17*PrinterPageWidth()/LP_PageWidth  ; right margin set to 17mm

   If LP_Title_Name<>""  ; print page title if LP_Title_Name not empty
     LP_Print_Title()
   Else
     LP_NewLine()
   EndIf
   LP_PageBreak=#True
   
EndProcedure

; prints the text with no line feed after printing; checks for full line and full page
Procedure LPRINT(LP_prns$="")
  
  If LP_Drawing_Active=#False
    MessageRequester("LPRINT ERROR","LPRINT not possible before LP_START_PRINTING",4112) 
    End
  EndIf
  
  If Not LP_Title_Printing
    LP_Setfont_Text()
  EndIf
  
  If Len(LP_prns$)=0 : ProcedureReturn : EndIf
  LP_PageBreak=#False
  
  LP_prns_index=1
  
  Repeat
    LP_NewLine_Flag=#False
    LP_LineCharsRemaining = LP_LineOfChars-LP_LineCh_Index+1  
    
    LP_xpixels=LP_LMargin+(LP_LineCh_Index-1)*LP_CharWidth
    
    LP_temp$=Mid(LP_prns$,LP_prns_index,Len(LP_prns$))            ; fill LP_temp$ With the text
    If Len(LP_temp$)>=LP_LineCharsRemaining                       ; if it's too long or fills the line
      LP_temp$=Mid(LP_prns$,LP_prns_index,LP_LineCharsRemaining)  ; fill LP_temp$ with the amount of characters remaining
      LP_NewLine_Flag=#True  
    EndIf
   
    DrawText(LP_xpixels,LP_ypixels,LP_temp$) ; print the text
       
    If LP_NewLine_Flag
      If (LP_ypixels+LP_CharHeight)>LP_PageHeight      ; check for new page
        LP_NEWPAGE()
      Else
        LP_NewLine()
      EndIf
    Else  
      LP_LineCh_Index=LP_LineCh_Index+Len(LP_temp$)
    EndIf
    
   LP_prns_index=LP_prns_index+Len(LP_temp$)
  Until LP_prns_index>Len(LP_prns$)
   
 EndProcedure
 
 ;prints the text with automatic line feed and check for new page 
 Procedure LPRINTN(LP_prns$="")
   If LP_Drawing_Active=#False
    MessageRequester("LPRINT ERROR","LPRINTN not possible before LP_START_PRINTING",4112) 
    End
  EndIf
  LP_Setfont_Text()
  LP_PageBreak=#False  ; resetting of the switch
  LP_Newline_Flag = #False  ; to prevent another newline after a full line in LPRINT
  LPRINT(LP_prns$)
  If Not LP_Newline_Flag
    If (LP_ypixels+LP_CharHeight)>LP_PageHeight      ; check for new page
      LP_NEWPAGE()
    Else
      LP_NewLine()
    EndIf  
  Else
    LP_Newline_Flag=#False
  EndIf
 EndProcedure
 
; print the contents of a file as ASCII characters
Procedure LPRINTF(LP_FileToPrint.s="")
  dir$=GetCurrentDirectory()
  If LP_FileToPrint=""
    LP_FileToPrint = OpenFileRequester("Please select a file to print", dir$, "All files (*.*)|*.*", 0)
    If LP_FileToPrint=""
      MessageRequester("LPRINT WARNING","no file chosen to print",4144) ; 4144 = on top with exclamation mark
      ProcedureReturn 0
    EndIf
  EndIf
  If FileSize(LP_FileToPrint) = 0
    MessageRequester("LPRINT WARNING","file to print is empty",4144)
    ProcedureReturn 0
  ElseIf FileSize(LP_FileToPrint) = -1
    MessageRequester("LPRINT WARNING","file to print not found",4144) 
    ProcedureReturn 0
  ElseIf FileSize(LP_FileToPrint) = -2
    MessageRequester("LPRINT WARNING","file to print is a directory",4144) 
    ProcedureReturn 0
  EndIf
  ; file is OK
  If ReadFile(1, LP_FileToPrint)
    If OpenFile(1, LP_FileToPrint)
      While Eof(1) = #False
        LPRINTN(ReadString(1, #PB_Ascii))
      Wend
      CloseFile(1)
    EndIf
  EndIf
  
  ProcedureReturn 1
EndProcedure
 
 Procedure LP_Print_Title()
   
  If LP_Drawing_Active=#False
    MessageRequester("LPRINT ERROR","print title not possible before LP_START_PRINTING",4112) 
    End
  EndIf
  
  LP_NewLine() 
  LP_Setfont_Title()
  LP_Title_Printing=#True
  For i=1 To 0.5*(LP_LineOfChars-Len(LP_Title_Name))  
     LPRINT(" ")
  Next i
  LPRINT(LP_Title_Name)
  LP_Title_Printing=#False
  LP_Setfont_Text()
  LP_NewLine()
  LP_NewLine()
  LP_NewLine()
  
EndProcedure

Procedure LP_Print_Page_Number()
  
  If LP_Drawing_Active=#False
    MessageRequester("LPRINT ERROR","print page number not possible before LP_START_PRINTING",4112) 
    End
  EndIf
  
  LP_xpixels=LP_LMargin
  LP_ypixels=LP_PageHeight 

  LP_Setfont_Text()

  LP_nr$=LP_PageNumber_Prefix+Str(LP_PageNumber)
  LP_temp=Len(LP_nr$)
  LP_NewLine()
  For i=1 To 0.5*(LP_LineOfChars-LP_temp)  
    LPRINT(" ")
  Next i
  LPRINT(lp_nr$)
  LP_NewLine()
  LP_PageNumber+1
  
EndProcedure

Procedure LP_NEWPAGE()
  If LP_Drawing_Active=#False
    MessageRequester("LPRINT ERROR","newpage not possible before LP_START_PRINTING",4112) 
    End
  EndIf
  
  LP_Setfont_Text()

  If LP_PageNumber
    LP_Print_Page_Number()
  EndIf
  NewPrinterPage()
  LP_xpixels=0
  LP_ypixels=0
  If LP_Title_Name<>""
    LP_Print_Title()
  Else
    LP_NewLine()
  EndIf
  LP_PageBreak=#True
EndProcedure

Procedure LP_TAB(x)
  
  If LP_Drawing_Active=#False
    MessageRequester("LPRINT ERROR","cannot set TAB before LP_START_PRINTING",4112) 
    End
  EndIf
  
  LP_Setfont_Text()

  If x<1
    MessageRequester("LPRINT ERROR","TAB setting < 1",4112) 
    LP_END_PRINTING()
    End
  EndIf
  LP_Calc_Chars_Line()
  If x>LP_LineOfChars
    MessageRequester("LPRINT ERROR","TAB setting "+Str(x)+" > max ("+Str(LP_LineOfChars)+")" ,4112) 
    LP_END_PRINTING()
    End
  EndIf
  If x<LP_LineCh_Index
    MessageRequester("LPRINT ERROR","TAB setting "+Str(x)+" < current printing position "+Str(LP_LineCh_Index),4112) 
    LP_END_PRINTING()
    End
  EndIf
  LP_LineCh_Index=x
  
EndProcedure

Procedure LP_SET_WIDTH(x)
  
  If LP_Drawing_Active=#False
    MessageRequester("LPRINT ERROR","cannot set page width before LP_START_PRINTING",4112) 
    End
  EndIf
  If x < 1
    MessageRequester("LPRINT ERROR","page width setting < 1",4112) 
    LP_END_PRINTING()
    End
  EndIf
  If x < 10
    MessageRequester("LPRINT WARNING","page width setting very small",4144) ; 4144 = on top with exclamation mark
  EndIf
  If x>LP_PageWidth
    MessageRequester("LPRINT ERROR","page width setting > max page width size",4112) 
    LP_END_PRINTING()
    End
  EndIf
  
  LP_LMargin=(LP_PageWidth-x)/2  ; result in mm
  LP_LMargin = LP_LMargin * (PrinterPageWidth()/LP_PageWidth)  ; converted to pixels
  LP_RMargin=LP_LMargin
  
EndProcedure

;
; code copied from the PureBasic forum (coded by Shardik) (some small adding and deleting of code by me)
; coded for the default printer, this function also works on a printer selected with the PrintRequester, 
; except if the layout option in the PrintRequester is manually changed...
Procedure LP_Set_Printer_Orientation(x.s)
  
  Protected BufferSize.I
  Protected BytesRetrieved.I
  Protected *DEVMODEBuffer.DEVMODE
  Protected *DEVMODEBufferCopy.DEVMODE
  Protected PRINTER_DEFAULTSStructure.PRINTER_DEFAULTS
  Protected *PRINTER_INFO_2Buffer.PRINTER_INFO_2
  Protected *PRINTER_INFO_2BufferCopy.PRINTER_INFO_2
  Protected PrinterHandle.l
  Protected Result.i
  Protected ErrorMsg.S
  Protected ModeFlag.I
  Protected NewPageOrientation.i
  Protected OldPageOrientation.i
  Protected PageOrientation.i
;
; 
  If LP_Drawing_Active=#True
    MessageRequester("LPRINT ERROR","LP_Set_Printer_Orientation after LP_START_PRINTING",4112) 
    LP_END_PRINTING()
    End
  EndIf
  
  If x="L"
    PageOrientation=#DMORIENT_LANDSCAPE
  ElseIf x="P"
    PageOrientation=#DMORIENT_PORTRAIT
  Else
    MessageRequester("LPRINT ERROR","incorrect page-orientation parameter",4112) 
    End
  EndIf
    
  ; get the name of the default printer - this "old" code still works with Windows 8.1 
  PrinterName.s = Space(260)
  GetPrivateProfileString_("WINDOWS","DEVICE","", @PrinterName, 260, "Win.Ini")
  PrinterName = StringField(Printername, 1,",")
  ;
  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)

  ; ----- Change page orientation in copy of DEVMODE structure

  OldPageOrientation = *DEVMODEBufferCopy\dmOrientation
  If Not LP_Original_PageOrientation
    LP_Original_PageOrientation=OldPageOrientation
  EndIf
  If OldPageOrientation = PageOrientation  ; if there is to be no change
    result=#True
    Goto CleanUp
  EndIf
  *DEVMODEBufferCopy\dmOrientation = PageOrientation

  *DEVMODEBufferCopy\dmFields = #DM_ORIENTATION 

  ; ----- 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

; ----- 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("LPRINT ERROR IN ORIENTATION SETTING", ErrorMsg, #MB_ICONERROR)
    End
  EndIf
  
  
EndProcedure


;Finish printing
Procedure LP_END_PRINTING()
  If LP_Drawing_Active=#True
    If LP_PageNumber
      LP_Print_Page_Number()
    EndIf
    StopDrawing()
    StopPrinting()
    If IsFont(1)
       FreeFont(1)
    EndIf
    LP_Drawing_Active=#False
    
    If LP_Original_PageOrientation  ; if the orientation was changed
      If LP_Original_PageOrientation = #DMORIENT_LANDSCAPE
        LP_Set_Printer_Orientation("L")
      ElseIf LP_Original_PageOrientation = #DMORIENT_PORTRAIT
        LP_Set_Printer_Orientation("P")
      EndIf
    EndIf
    LP_Original_PageOrientation=0
    LP_PageNumber=0
    LP_Title_Name=""
    LP_Printing_Active=#False
  Else
    MessageRequester("LPRINT ERROR", "LP_END_PRINTING called with no LP_START_PRINTING", 4112)
    End
  EndIf
EndProcedure
 
; set the starting page number and the page title (=the job name for the printer)
; 1st param=0 --> no page number ; 2nd param="" --> no page title
Procedure LP_SET_PAGE_PREFS(LP_Nr=0, LP_Title.s="", LP_PageOrientation.s="")
  If LP_Drawing_Active=#True
    MessageRequester("LPRINT ERROR", "page prefs to be set *before* LP_START_PRINTING", 4112)
    LP_END_PRINTING()
    End
  EndIf
  LP_PageNumber=LP_Nr
  LP_Title_Name=LP_Title 
  If LP_PageOrientation = "L"
    LP_Set_Printer_Orientation("L")
  ElseIf LP_PageOrientation = "P"
    LP_Set_Printer_Orientation("P")
  EndIf  
EndProcedure
;======================================================================================================================================
;========================= END OF LPRINT INCLUDE ======================================================================================
;======================================================================================================================================
;
Last edited by Ferdinand on Mon Mar 16, 2015 10:28 am, edited 1 time in total.
User avatar
Ferdinand
New User
New User
Posts: 9
Joined: Tue Mar 10, 2015 1:43 pm
Location: Netherlands
Contact:

Re: LPRINT_plus

Post by Ferdinand »

No feedback yet ?
Anyway, I have added another example of the use of LPRINT_plus:
a program that can be configured as a tool in the PureBasic editor to print the source code of a program in the editor
see the webpage http://home.kpn.nl/fschinkel/purebasic
User avatar
blueb
Addict
Addict
Posts: 1111
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: LPRINT_plus

Post by blueb »

Thanks Ferdinand :D

Tried both examples and everything seems to work well.

It's nice to have the source code, so that if PB changes in the future, I'm
able to modify if necessary.

Now to go and play with this new toy!

NOTE: Because you've included the source... I'd place it in the "Tricks 'n' Tips" forum
where you might get more views.

blueb

PS - Win 8.1 64-bit and PureBasic 5.31 (x86)
- It was too lonely at the top.

System : PB 6.21(x64) and Win 11 Pro (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: LPRINT_plus

Post by Kwai chang caine »

Works fine here...i have now 5 pages in landscape mode of a big database of records in my hands :D
Thanks to have sharing the code 8)
ImageThe happiness is a road...
Not a destination
Post Reply