AutoHotkey Community

It is currently May 26th, 2012, 10:02 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 11 posts ] 
Author Message
PostPosted: September 28th, 2009, 8:46 am 
Offline

Joined: October 1st, 2005, 9:55 pm
Posts: 775
Location: Texas, USA
Introduction
This is a simple WYSIWYG print function for the HiEdit control.

Important: Minor modifications must be made to the function or to the parent script before the function will operate correctly. See the Issue/Considerations section for more information.


HE_Print()
Key features:
  • WYSIWYG printing. The exact content of the HiEdit control -- line numbers bar, font, font size, and color -- is formatted and sent to the printer.
  • Margins. The user/developer determines the page margins. If undefined, margins are set to 0.5 inches (12.7 mm).
  • Print All, Page Range, or Selection. The user can print all pages or a selected range of pages. If the user selects text from the HiEdit control before the function is called, the "Selection" option in the Print dialog is enabled and is automatically selected. If this option is not unselected, only the selected text will be printed.
Requirements
If using the line numbers bar workaround (see the Issues/Considerations section for more information) or if you would rather not comment out references to the HE_LineNumbersBar function, the HiEdit Library is required.


The Code
Code:
;******************
;*                *
;*    HE_Print    *
;*                *
;******************
;
;
;   Description
;   ===========
;   Simple WYSIWYG print function for the HiEdit control.
;
;
;
;   Parameters
;   ==========
;
;       Name            Description
;       ----            -----------
;       p_hEdit         Handle to the HiEdit control.
;
;       p_Owner         Handle to the owner window.  [Optional]
;
;
;       p_MarginLeft    Page margins based upon the locale system of
;       p_MarginTop     measurement -- English or Metric. [Optional]  If
;       p_MarginRight   English, the margin is measured in thousandths of
;       p_MarginRight   inches.  If metric, the margin is measured in hundredths
;       p_MarginBottom  of millimeters.
;                       
;                       English example: To get a 0.5 inch margin (12.7 mm), set
;                       the margin to 500.
;
;                       Metric example: To get a 25.40 mm margin (1 inch English
;                       equivalent), set the margin to 2540.
;
;
;
;   Return Codes
;   ============
;   {None}
;
;
;
;   Credit
;   ======
;   Some of the ideas/code for this function was extracted from the source code
;   for the HiEditor demo program ("Print" procedure) and from the Notepad2
;   source code ("Print.cpp").
;
;
;
;   Programming and Usage Notes
;   ===========================
;   xxxxx
;   
;   
;-------------------------------------------------------------------------------
HE_Print(p_hEdit
        ,p_Owner=""
        ,p_MarginLeft=""
        ,p_MarginTop=""
        ,p_MarginRight=""
        ,p_MarginBottom="")
    {
    ;[====================]
    ;[  Global variables  ]
    ;[====================]
    Global $LineNumbersBar
                ;-- This global variable is set to TRUE if the line numbers bar
                ;   is showing, otherwise it is FALSE
          ,hDevMode
          ,hDevNames


    ;[====================]
    ;[  Static variables  ]
    ;[====================]
    Static PD_ALLPAGES          :=0x0
          ,PD_SELECTION         :=0x1
          ,PD_PAGENUMS          :=0x2
          ,PD_NOSELECTION       :=0x4
          ,PD_NOPAGENUMS        :=0x8
          ,PD_RETURNDC          :=0x100
          ,PD_RETURNDEFAULT     :=0x400
          ,PD_ENABLEPRINTHOOK   :=0x1000    ;-- Not used (for now)
          ,PD_USEDEVMODECOPIES  :=0x40000   ;-- Same as PD_USEDEVMODECOPIESANDCOLLATE
          ,PD_DISABLEPRINTTOFILE:=0x80000
          ,PD_HIDEPRINTTOFILE   :=0x100000

          ,LOCALE_USER_DEFAULT  :=0x400
          ,LOCALE_IMEASURE      :=0xD
          ,LOCALE_RETURN_NUMBER :=0x20000000

          ,MM_TEXT              :=0x1
          ,HORZRES              :=0x8
          ,VERTRES              :=0xA
          ,LOGPIXELSX           :=0x58
          ,LOGPIXELSY           :=0x5A
          ,PHYSICALWIDTH        :=0x6E
          ,PHYSICALHEIGHT       :=0x6F
          ,PHYSICALOFFSETX      :=0x70
          ,PHYSICALOFFSETY      :=0x71

          ,WM_USER              :=0x400 ;-- 1024

          ,EM_EXGETSEL          :=1076  ;-- WM_USER+52
          ,EM_FORMATRANGE       :=1081  ;-- WM_uSER+57
          ,EM_SETTARGETDEVICE   :=1096  ;-- WM_USER+72
          ,WM_GETTEXTLENGTH     :=0xE


    ;[==============]
    ;[  Initialize  ]
    ;[==============]
    SplitPath A_ScriptName,,,,l_ScriptName


    ;-- Get locale system of measurement (0=Metric, 1=English)
    VarSetCapacity(lpLCData,4,0)
    DllCall("GetLocaleInfo"
        ,"UInt",LOCALE_USER_DEFAULT
        ,"UInt",LOCALE_IMEASURE|LOCALE_RETURN_NUMBER
        ,"UInt",&lpLCData
        ,"UInt",4)
   
    l_LOCALE_IMEASURE:=NumGet(lpLCData,0,"Unit")
    if l_LOCALE_IMEASURE=0      ;-- 0=HiMetric (hundredths of millimeters)
        l_LocaleUnits:=2540
     else                       ;-- 1=HiEnglish (thousandths of inches)
        l_LocaleUnits:=1000


    ;[==============]
    ;[  Parameters  ]
    ;[==============]
    if p_MarginLeft is not Integer
        p_MarginLeft:=l_LocaleUnits/2   ;-- (0.5 inch or 12.7 mm)

    if p_MarginTop is not Integer
        p_MarginTop:=l_LocaleUnits/2

    if p_MarginRight is not Integer
        p_MarginRight:=l_LocaleUnits/2

    if p_MarginBottom is not Integer
        p_MarginBottom:=l_LocaleUnits/2


    ;[================]
    ;[  Prep to call  ]
    ;[    PrintDlg    ]
    ;[================]
    ;-- Define/Populate the PRINTDLG structure
    VarSetCapacity(PRINTDLG_Structure,66,0)
    NumPut(66,PRINTDLG_Structure,0,"UInt")                  ;-- lStructSize
   
    if p_Owner is Integer
        Numput(p_Owner,PRINTDLG_Structure,4,"UInt")         ;-- hwndOwner

    if hDevMode is Integer
        NumPut(hDevMode,PRINTDLG_Structure,8,"UInt")        ;-- hDevMode

    if hDevNames is Integer
        NumPut(hDevNames,PRINTDLG_Structure,12,"UInt")      ;-- hDevMode


    ;-- Collect start/End select positions
    VarSetCapacity(CHARRANGE_Structure,8,0)
    SendMessage EM_EXGETSEL,0,&CHARRANGE_Structure,,ahk_id %p_hEdit%
    l_StartSelPos:=NumGet(CHARRANGE_Structure,0,"Int")      ;-- cpMin
    l_EndSelPos  :=NumGet(CHARRANGE_Structure,4,"Int")      ;-- cpMax
        ;-- Programming note: The HE_GetSel function is not used here so that
        ;   this function can be used independent of the HiEdit library.  This
        ;   will probably be changed in the future.


    ;-- Determine/Set Flags
    l_Flags:=PD_ALLPAGES|PD_RETURNDC|PD_USEDEVMODECOPIES
    if (l_StartSelPos=l_EndSelPos)
        l_Flags |= PD_NOSELECTION
     else
        l_Flags |= PD_SELECTION

    NumPut(l_Flags,PRINTDLG_Structure,20,"UInt")            ;-- Flags


    ;-- Page and copies
    NumPut(1 ,PRINTDLG_Structure,24,"UShort")               ;-- nFromPage
    NumPut(1 ,PRINTDLG_Structure,26,"UShort")               ;-- nToPage
    NumPut(1 ,PRINTDLG_Structure,28,"UShort")               ;-- nMinPage
    NumPut(-1,PRINTDLG_Structure,30,"UShort")               ;-- nMaxPage
    NumPut(1 ,PRINTDLG_Structure,32,"UShort")               ;-- nCopies
        ;-- Note: Use -1 to specify the maximum page number (65535).
        ;
        ;   Programming note:  The values that are loaded to these fields are
        ;   critical.  The Print dialog will not display (returns an error) if
        ;   unexpected values are loaded to one or more of these fields.


    ;[================]
    ;[  Print dialog  ]
    ;[================]
    ;-- Open the Print dialog.  Bounce if the user cancels.
    if not DllCall("comdlg32\PrintDlgA","UInt",&PRINTDLG_Structure)
        return

    hDevMode:=NumGet(PRINTDLG_Structure,8,"UInt")
        ;-- Handle to a global memory object that contains a DEVMODE structure

    hDevNames:=NumGet(PRINTDLG_Structure,12,"UInt")
        ;-- Handle to a movable global memory object that contains a DEVNAMES
        ;   structure.


    ;-- Free global structures created by PrintDlg
    ;
    ;   Programming note:  This function assumes that the user-selected printer
    ;   settings will be retained in-between print requests.  If this behaviour
    ;   is not desired, the global memory objects created by the PrintDlg
    ;   function can be released immediately by uncommenting the following code.
    ;   However, if this behavior is desired, the global memory objects should
    ;   be released before the script is terminated.  Copy the following code
    ;   (uncommented of course) to the appropriate "Exit" routine in your
    ;   script.
    ;
;;;;;    if hDevMode
;;;;;        {
;;;;;        DllCall("GlobalFree","UInt",hDevMode)
;;;;;        hDevMode:=0
;;;;;        }
;;;;;   
;;;;;    if hDevNames
;;;;;        {
;;;;;        DllCall("GlobalFree","UInt",hDevNames)
;;;;;        hDevNames:=0
;;;;;        }



    ;-- Get the printer device context.  Bounce if not defined.
    l_hDC:=NumGet(PRINTDLG_Structure,16,"UInt")             ;-- hDC
    if not l_hDC
        {
        outputdebug,
           (ltrim join`s
            Function: %A_ThisFunc% - Printer device context (hDC) not defined.
           )

        return
        }


    ;[====================]
    ;[  Prepare to print  ]
    ;[====================]
    ;-- Collect Flags
    l_Flags:=NumGet(PRINTDLG_Structure,20,"UInt")           ;-- Flags


    ;-- Determine From/To Page
    if l_Flags & PD_PAGENUMS
        {
        l_FromPage:=NumGet(PRINTDLG_Structure,24,"UShort")  ;-- nFromPage
        l_ToPage  :=NumGet(PRINTDLG_Structure,26,"UShort")  ;-- nToPage
        }
     else
        {
        l_FromPage:=1
        l_ToPage  :=65535
        }


    ;-- Collect printer statistics
    l_HORZRES:=DllCall("GetDeviceCaps","UInt",l_hDC,"UInt",HORZRES)
    l_VERTRES:=DllCall("GetDeviceCaps","UInt",l_hDC,"UInt",VERTRES)
        ;-- Width and height, in pixels, of the printable area of the page

    l_LOGPIXELSX:=DllCall("GetDeviceCaps","UInt",l_hDC,"UInt",LOGPIXELSX)
    l_LOGPIXELSY:=DllCall("GetDeviceCaps","UInt",l_hDC,"UInt",LOGPIXELSY)
        ;-- Number of pixels per logical inch along the page width and height

    l_PHYSICALWIDTH :=DllCall("GetDeviceCaps","UInt",l_hDC,"UInt",PHYSICALWIDTH)
    l_PHYSICALHEIGHT:=DllCall("GetDeviceCaps","UInt",l_hDC,"UInt",PHYSICALHEIGHT)
        ;-- The width and height of the physical page, in device units. For
        ;   example, a printer set to print at 600 dpi on 8.5" x 11" paper
        ;   has a physical width value of 5100 device units. Note that the
        ;   physical page is almost always greater than the printable area of
        ;   the page, and never smaller.

    l_PHYSICALOFFSETX:=DllCall("GetDeviceCaps","UInt",l_hDC,"UInt",PHYSICALOFFSETX)
    l_PHYSICALOFFSETY:=DllCall("GetDeviceCaps","UInt",l_hDC,"UInt",PHYSICALOFFSETY)
        ;-- The distance from the left/right edge (PHYSICALOFFSETX) and the
        ;   top/bottom edge (PHYSICALOFFSETY) of the physical page to the edge
        ;   of the printable area, in device units. For example, a printer set
        ;   to print at 600 dpi on 8.5-by-11-inch paper, that cannot print on
        ;   the leftmost 0.25-inch of paper, has a horizontal physical offset of
        ;   150 device units.


    ;-- Define/Populate the FORMATRANGE structure
    VarSetCapacity(FORMATRANGE_Structure,48,0)
    NumPut(l_hDC,FORMATRANGE_Structure,0,"UInt")            ;-- hdc
    NumPut(l_hDC,FORMATRANGE_Structure,4,"UInt")            ;-- hdcTarget


   ;-- Define FORMATRANGE.rcPage
    ;
    ;   rcPage is the entire area of a page on the rendering device, measured in
    ;   twips (1/20 point or 1/1440 of an inch)
    ;
    ;   Note: rc defines the maximum printable area which does not include the
    ;   printer's margins (the unprintable areas at the edges of the page).  The
    ;   unprintable areas are represented by PHYSICALOFFSETX and
    ;   PHYSICALOFFSETY.
    ;
    NumPut(0,FORMATRANGE_Structure,24,"UInt")               ;-- rcPage.Left
    NumPut(0,FORMATRANGE_Structure,28,"UInt")               ;-- rcPage.Top

    l_rcPage_Right:=Round((l_HORZRES/l_LOGPIXELSX)*1440)
    NumPut(l_rcPage_Right,FORMATRANGE_Structure,32,"UInt")  ;-- rcPage.Right

    l_rcPage_Bottom:=Round((l_VERTRES/l_LOGPIXELSY)*1440)
    NumPut(l_rcPage_Bottom,FORMATRANGE_Structure,36,"UInt") ;-- rcPage.Bottom


   ;-- Define FORMATRANGE.rc
    ;
    ;   rc is the area to render to (rcPage - margins), measured in twips (1/20
    ;   point or 1/1440 of an inch).
    ;
    ;   If the user-defined margins are smaller than the printer's margins (the
    ;   unprintable areas at the edges of each page), the user margins are set
    ;   to the printer's margins.
    ;
    ;   In addition, the user-defined margins must be adjusted to account for
    ;   the printer's margins.  For example: If the user requests a 3/4 inch
    ;   (19.05 mm) left margin but the printer's left margin is 1/4 inch
    ;   (6.35 mm), rc.Left is set to 720 twips (1/2 inch or 12.7 mm).
    ;
    ;-- Left
    if (l_PHYSICALOFFSETX/l_LOGPIXELSX>p_MarginLeft/l_LocaleUnits)
        p_MarginLeft:=Round((l_PHYSICALOFFSETX/l_LOGPIXELSX)*l_LocaleUnits)

    l_rc_Left:=Round(((p_MarginLeft/l_LocaleUnits)*1440)-((l_PHYSICALOFFSETX/l_LOGPIXELSX)*1440))
    NumPut(l_rc_Left,FORMATRANGE_Structure,8,"UInt")        ;-- rc.Left


    ;-- Top
    if (l_PHYSICALOFFSETY/l_LOGPIXELSY>p_MarginTop/l_LocaleUnits)
        p_MarginTop:=Round((l_PHYSICALOFFSETY/l_LOGPIXELSY)*l_LocaleUnits)

    l_rc_Top:=Round(((p_MarginTop/l_LocaleUnits)*1440)-((l_PHYSICALOFFSETY/l_LOGPIXELSY)*1440))
    NumPut(l_rc_Top,FORMATRANGE_Structure,12,"UInt")        ;-- rc.Top


    ;-- Right
    if (l_PHYSICALOFFSETX/l_LOGPIXELSX>p_MarginRight/l_LocaleUnits)
        p_MarginRight:=Round((l_PHYSICALOFFSETX/l_LOGPIXELSX)*l_LocaleUnits)

    l_rc_Right:=l_rcPage_Right-Round(((p_MarginRight/l_LocaleUnits)*1440)-((l_PHYSICALOFFSETX/l_LOGPIXELSX)*1440))
    NumPut(l_rc_Right,FORMATRANGE_Structure,16,"UInt")      ;-- rc.Right


    ;-- Bottom
    if (l_PHYSICALOFFSETY/l_LOGPIXELSY>p_MarginBottom/l_LocaleUnits)
        p_MarginBottom:=Round((l_PHYSICALOFFSETY/l_LOGPIXELSY)*l_LocaleUnits)

    l_rc_Bottom:=l_rcPage_Bottom-Round(((p_MarginBottom/l_LocaleUnits)*1440)-((l_PHYSICALOFFSETY/l_LOGPIXELSY)*1440))
    NumPut(l_rc_Bottom,FORMATRANGE_Structure,20,"UInt")     ;-- rc.Bottom


    ;-- Determine print range.
    ;
    ;   If "Selection" option is chosen, use selected text, otherwise use the
    ;   entire document.
    ;
    if l_Flags & PD_SELECTION
        {
        l_StartPrintPos:=l_StartSelPos
        l_EndPrintPos  :=l_EndSelPos
        }
     else
        {
        l_StartPrintPos:=0
        l_EndPrintPos  :=-1     ;-- (-1=Select All)
        }

    Numput(l_StartPrintPos,FORMATRANGE_Structure,40)        ;-- cr.cpMin
    NumPut(l_EndPrintPos  ,FORMATRANGE_Structure,44)        ;-- cr.cpMax


    ;-- Define/Populate the DOCINFO structure
    VarSetCapacity(DOCINFO_Structure,20,0)
    NumPut(20           ,DOCINFO_Structure,0)               ;-- cbSize
    NumPut(&l_ScriptName,DOCINFO_Structure,4)               ;-- lpszDocName
    NumPut(0            ,DOCINFO_Structure,8)               ;-- lpszOutput
        ;-- Programming note: All other DOCINFO_Structure fields intentionally
        ;   left as null.


    ;-- Determine l_MaxPrintIndex
    if l_Flags & PD_SELECTION
        l_MaxPrintIndex:=l_EndSelPos
     else
        {
        SendMessage WM_GETTEXTLENGTH,0,0,,ahk_id %p_hEdit%
        l_MaxPrintIndex:=ErrorLevel
            ;-- Programming note: HE_GetTextLength is not used here so that this
            ;   function can be used independent of the HiEdit library.  This
            ;   will probably be changed in the future.
        }


    ;-- Set LineNumbersBar to max size
    ;
    ;   Programming note:  This step is necessary because the LineNumbersBar
    ;   does not render correctly past the first couple of pages if the
    ;   "autosize" option is used.  A bug perhaps, but this workaround is
    ;   acceptable and the fixed size may even be desirable.
    ;
    ;   If you don't use the line numbers bar or you don't want to make any
    ;   changes to the line numbers bar, you can comment out this code.
    ;
    if $LineNumbersBar
        HE_LineNumbersBar(p_hEdit,"automaxsize")


   ;-- Be sure that the printer device context is in text mode
    DllCall("SetMapMode","UInt",l_hDC,"UInt",MM_TEXT)


    ;[=============]
    ;[  Print it!  ]
    ;[=============]
    ;-- Start a print job.  Bounce if there is a problem.
    l_PrintJob:=DllCall("StartDoc","UInt",l_hDC,"UInt",&DOCINFO_Structure,"Int")
    if l_PrintJob<=0
        {
        outputdebug Function: %A_ThisFunc% - DLLCall of "StartDoc" failed.
        return
        }


    ;-- Print page loop
    l_Page:=0
    l_PrintIndex:=0
    While (l_PrintIndex<l_MaxPrintIndex)
        {
        l_Page++


        ;-- Are we done yet?
        if (l_Page>l_ToPage)
            break


        if l_Page between %l_FromPage% and %l_ToPage%
            {
            ;-- StartPage function.  Break if there is a problem.
            if DllCall("StartPage","UInt",l_hDC,"Int")<=0
                {
                outputdebug,
                   (ltrim join`s
                    Function: %A_ThisFunc% - DLLCall of "StartPage" failed.
                   )

                break
                }
            }


        ;-- Format or measure page
        if l_Page between %l_FromPage% and %l_ToPage%
            l_Render:=true
         else
            l_Render:=false

        SendMessage EM_FORMATRANGE,l_Render,&FORMATRANGE_Structure,,ahk_id %p_hEdit%
        outputdebug ErrorLevel from EM_FORMATRANGE=%ErrorLevel%
        l_PrintIndex:=ErrorLevel


        if l_Page between %l_FromPage% and %l_ToPage%
            {
            ;-- EndPage function.  Break if there is a problem.
            if DllCall("EndPage","UInt",l_hDC,"Int")<=0
                {
                outputdebug,
                   (ltrim join`s
                    Function: %A_ThisFunc% - DLLCall of "EndPage" failed.
                   )

                break
                }
            }


        ;-- Update FORMATRANGE_Structure for the next page
        Numput(l_PrintIndex ,FORMATRANGE_Structure,40)      ;-- cr.cpMin
        NumPut(l_EndPrintPos,FORMATRANGE_Structure,44)      ;-- cr.cpMax
        }


    ;-- End the print job
    DllCall("EndDoc","UInt",l_hDC)


    ;-- Delete the printer device context
    DllCall("DeleteDC","UInt",l_hDC)


    ;-- Reset control (free cached information)
    SendMessage EM_FORMATRANGE,0,0,,ahk_id %p_hEdit%


    ;-- Reset the LineNumbersBar
    ;
    ;   Programming note: If you don't use the line numbers bar or you don't
    ;   want to make any changes to the line numbers bar, you can comment out
    ;   this code.
    ;
    if $LineNumbersBar
        HE_LineNumbersBar(p_hEdit,"autosize")


    ;-- Return to sender
    return
    }


Issues/Considerations
  • Preview release. This is the preview release of this function. The documentation is incomplete and there may residual debug code lying around. If there is any interest, these deficiencies will be corrected in future releases.
  • Custom mod 1: Global Memory Objects. The PrintDlg WinAPI function creates and/or reuses two global memory objects. These objects can be released within the function (not recommended) or released just before the script is terminated (better). If these objects are released within the function, changes to the printer settings (printer, orientation, etc.) are lost and the user sees the defaults every time the function is called. See the "Programming Note" comments in the "Print dialog" section of the script for instructions on what changes need to be made.
  • Custom mod 2: Line numbers bar. The line numbers bar does not render correctly past the first couple of pages if the "autosize" option is used. A bug perhaps, but the workaround is acceptable and the fixed size may even be desirable.

    Instructions: If you don't use the line numbers bar or if you want to leave the line numbers bar as is, do nothing and/or comment out the code that makes changes to the line numbers bar. However, if you use the "autosize" option of the line numbers bar, set the $LineNumbersBar global variable to TRUE before calling the function. The line numbers bar will be set to "automaxsize" before printing and then set back to "autosize" after printing. This workaround is temporary until either the bug get fixed or until a better solution is found.
  • Long lines. Line wrap is currently not an option of the HiEdit control so if a line is too long, it will truncated when printed. There are a couple of tricks to make sure that long lines are not truncated:

    1. Landscape. Before clicking on the "Print" button on the Print dialog, click on the "Preferences" button and change the orientation to Landscape (if it's not already the default).
    2. Font size. If the lines are still too long, reduce the size of the font before printing. Reset back to the desired size after printing.
  • Limited testing. This function has been tested on one computer (Windows XP SP3) and on one printer (HP LaserJet 5P). The function should work in all regions but I don't have enough resources to test it for all situations.


Final Thoughts
I hope that someone finds this useful.

---------------------------------------------------------------------------
Release Notes

v0.1
(Preview)
Original release.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 9:24 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Cool 8)

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 11:17 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
AWESOME, as always !

I tested it and it rly looks great.

I added link to this function on HiEdit page.

Quote:
Long lines. Line wrap is currently not an option of the HiEdit control so if a line is too long, it will truncated when printed. There are a couple of tricks to make sure that long lines are not truncated:

Perhaps a fix like this:
- take a text from HiEdit.
- Fix the text (add new line after 80 chars), i.e. create your own wrapped text.
- Insert new tab, put the text, print it, delete tab.

The only work is actually Wrap(txt) function which will fix the text.
The benefits are pretty much the same as internal word wrap, when priting is in question.


Idea
- It would be cool to specify the keywords file and color scheme for printing. So, once you activate print, silently there could be created another HiEdit with printing setup and that hiedit could be printed. Why? Because many people may want to print on white paper no matter what you see in control. I keep it black for instance and all pages were black and slow to print because of that. Or some people may want oposite behavior to always print on green with specific fonts etc... Now, if I had option to set printing scheme of HiEdit ....

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 29th, 2009, 6:04 am 
Offline

Joined: October 1st, 2005, 9:55 pm
Posts: 775
Location: Texas, USA
majkinetor wrote:
I tested it and it rly looks great.

Thanks for testing it. I wasn't sure the function was going to work on other printers. I have two other printers but they don't count because they are both sitting in the garage collecting dust and one of them is a dot-matrix printer.


majkinetor wrote:
Quote:
Long lines. Line wrap is currently not an option of the HiEdit control so if a line is too long, it will truncated when printed. There are a couple of tricks to make sure that long lines are not truncated:

Perhaps a fix like this:
- take a text from HiEdit.
- Fix the text (add new line after 80 chars), i.e. create your own wrapped text.
- Insert new tab, put the text, print it, delete tab.

The only work is actually Wrap(txt) function which will fix the text.
The benefits are pretty much the same as internal word wrap, when priting is in question.

The benefits are clear but the techniques for adding this feature may be out a scope for a "simple WYSIWYG" print function. My primary objection is that this solution destroys the integrity of line numbers.

This might be something that works better as a pre- and post- processing print routine. The pre- routine would prepare the contents for printing (create temporary tab (or create new HiEdit control) and formatting the text). The post- routine would clean up what the pre-routine created.

akyprian recently added the "line wrap" option to the HiEdit wish list. I'm wishing it gets added sooner rather than later so that we don't have to deal with this feature gap.


majkinetor wrote:
Idea
- It would be cool to specify the keywords file and color scheme for printing. So, once you activate print, silently there could be created another HiEdit with printing setup and that hiedit could be printed. Why? Because many people may want to print on white paper no matter what you see in control. I keep it black for instance and all pages were black and slow to print because of that. Or some people may want oposite behavior to always print on green with specific fonts etc... Now, if I had option to set printing scheme of HiEdit ....

This doesn't really fit into the scope of the project but it should be an easy change and I'm all for doing anything to keep from wasting toner/ink. Black/Colored backgrounds cost a fortune to print.

The feature would require two additional parameters. One parameter for the path to the "printing" keywords file and the other parameter for the path to the original keywords file. I suspect there will be some flickering when the control sets/resets the keywords file. I'll have to give it a try to see what happens.

Changing anything else for printing (font, font size, etc.) would probably fall out of scope for this function. As with the line-wrap printing problem/solution, a pre- and post- routine might make the most sense. Before printing, change the control to what you want it to look like for printing (font, font size, etc). After printing, change it back.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 30th, 2009, 1:27 am 
Offline

Joined: October 1st, 2005, 9:55 pm
Posts: 775
Location: Texas, USA
majkinetor wrote:
Idea
- It would be cool to specify the keywords file and color scheme for printing. So, once you activate print, silently there could be created another HiEdit with printing setup and that hiedit could be printed. Why? Because many people may want to print on white paper no matter what you see in control. I keep it black for instance and all pages were black and slow to print because of that. Or some people may want oposite behavior to always print on green with specific fonts etc... Now, if I had option to set printing scheme of HiEdit ....

You eluded to it in your reply but it wasn't until I started to look into it that I discovered that changing the look and feel of the HiEdit object is significantly more involved than just changing the Keywords.hes file. Obviously, it is very do-able but I'm just wondering if these kind of changes should be done outside of a generic print routine. Let me pour some brain juice on it.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 2nd, 2009, 10:22 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Since you are covering this topic now, tell me, can we use the same thing to print any control ?

With such code in question I am willing to add print dialog to the Dlg module.

About HiEdit appeareance, there are 3 things that need to be done - set colors, set font and set keyword file. All could be done as a Theme function similar to the way colors are passed to the SetColors function. Theme could just receive 2 more parameters: font and path to the keyword file. Then you could accept theme string as parameter for printing, and before actuall printing set the theme via function call. In that case, your current work would require 1 extra code line and 1 more parameter.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 3rd, 2009, 6:23 am 
Offline

Joined: October 1st, 2005, 9:55 pm
Posts: 775
Location: Texas, USA
majkinetor wrote:
Since you are covering this topic now, tell me, can we use the same thing to print any control ?

Preface: I am not an expert on this topic. I barely scratched together enough code to get this control to print. Also, by "other controls", I assume you're talking about the Edit control.

To answer your question, the answer is Yes and No. The function contains the core elements of what is necessary to print almost anything -- The print dialog, starting/ending the print job, starting/ending the page, etc. What is missing for other controls is the code to actually format/print the content of the control.

This function uses the EM_FORMATRANGE message to format the content of the HiEdit control for printing. Most controls don't support this message. In fact, the only other control that supports this message (that I know of) is the rich edit control. In theory, this function could be modified to work with rich edit controls. I spent 5 minutes trying to get it work but I lost interest because I don't use any rich edit controls in my stuff.

In theory, it should be fairly simple to replace the EM_FORMATRANGE message with the necessary commands and/or messages to print the contents of other controls. I've just never had to need to do it myself (yet).


majkinetor wrote:
With such code in question I am willing to add print dialog to the Dlg module.

Adding the PrintDlg and PrintDlgEx (Windows 2000+) functions to the Dlg library is very do-able but there are a couple of considerations.

1) These functions create two global memory objects. These objects can be released within the function but any changes made by the user will be lost when the function is called again. Not releasing these memory objects until just before the script is terminated is best but the developer must be instructed to do it. Now that I think about it, a Dlg function to free these memory objects may be the best way of dealing with this. I haven't thought this through but there may be no way to do this without using a couple of global variables and I know how you feel about global variables...

2) The printer device context should be deleted after ending the print job. I'm not sure what happens (if anything) if the developer does not delete it. This is probably just a documentation issue. I suppose the Dlg function that releases the global memory objects could also delete the printer device context. A separate Dlg function could also work.


majkinetor wrote:
About HiEdit appeareance, there are 3 things that need to be done - set colors, set font and set keyword file. All could be done as a Theme function similar to the way colors are passed to the SetColors function. Theme could just receive 2 more parameters: font and path to the keyword file. Then you could accept theme string as parameter for printing, and before actuall printing set the theme via function call. In that case, your current work would require 1 extra code line and 1 more parameter.

Thanks for the info. I'll take a look/see when I get some time.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2010, 10:31 pm 
Offline

Joined: July 25th, 2010, 11:36 pm
Posts: 154
jballi, I was working with HE_Print and I ended up making a change to one of your flags. From:
Quote:
if l_Flags & PD_PAGENUMS
To:
Code:
if l_Flags| PD_PAGENUMS
The default PrintDlg "All" selection was causing the l_ToPage to be set @ 65535. If "Pages" was selected, it worked correctly.[/quote]

_________________
“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2010, 5:45 am 
Offline

Joined: October 1st, 2005, 9:55 pm
Posts: 775
Location: Texas, USA
nothere wrote:
The default PrintDlg "All" selection was causing the l_ToPage to be set @ 65535. If "Pages" was selected, it worked correctly.

Actually, the problem you described is exactly how it's supposed to work.

"if l_Flags & PD_PAGENUMS" is just a test to see if the "Pages" option in the "Page Range" section of the print dialog has been selected. If the "Pages" option has been selected, the user-determined page number or page range is used. If the "Pages" option has not been selected, it means that the default "All" option is used. When the default "All" option is used, the print range is set to the minimum (1) and to the maximum (65535) to ensure that the entire document is printed.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2010, 1:02 pm 
Offline

Joined: July 25th, 2010, 11:36 pm
Posts: 154
ok, maybe I made a wrong assumption. I adapted it to a genericc RichEdit and when I accepted the default (All), it was printing 65535; did I mess up?

_________________
“No other God have I but Thee; born in a manger, died on a tree.” Martin Luther


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2010, 6:56 pm 
Offline

Joined: October 1st, 2005, 9:55 pm
Posts: 775
Location: Texas, USA
nothere wrote:
I adapted it to a genericc RichEdit and when I accepted the default (All), it was printing 65535; did I mess up?

I'm sorry, I don't know what "printing 65535" means. If you mean only printing page 65535 or printing the literal "65535" then yes, there is likely a code conversion error. Possibly a typo. Otherwise, I'm at a loss.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Apollo, JamixZol and 7 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group