SlideShare a Scribd company logo
WPTools 6
          GUIDE




              15.07.2009

Copyright 2005 - 2009 by WPCubed GmbH
         created by Julian Ziersch
I     WPTools Version 6



Table of Contents
         Foreword                                                                                                                                                                     0

  Part I What is WPTools?                                                                                                                                                            1

 Part II WPTools 6 new features                                                                                                                                                      3

 Part III WPTools Version 6                                                                                                                                                          5

 Part IV License                                                                                                                                                                     7

 Part V Technical Notes                                                                                                                                                              8

 Part VI PDF Products                                                                                                                                                                9

Part VII Guide                                                                                                                                                                    11
      1 Localization - change Language in Dialogs
          ................................................................................................................................... 14
      2 Programming Overview/QuickStart
          ................................................................................................................................... 18
                Modify the look and feel of the editor
                          ......................................................................................................................................................... 18
                Change current w riting mode
                          ......................................................................................................................................................... 19
                Move the ......................................................................................................................................................... 19
                          Cursor
                Change Page Size and Page margins
                          ......................................................................................................................................................... 19
                Insert Text
                          ......................................................................................................................................................... 19
                Mail Merge (replace fields w ith data)
                          ......................................................................................................................................................... 19
                Input TextObjects (i.e. page numbers)
                          ......................................................................................................................................................... 19
                Create an ......................................................................................................................................................... 19
                           ow n toolbar
                Save and load HTML
                          ......................................................................................................................................................... 19
                Get and set the text "as string"
                          ......................................................................................................................................................... 20
      3 Data Structures
          ................................................................................................................................... 20
      4 WYSIWYG
         ................................................................................................................................... 25
      5 Mail-merge and forms
          ................................................................................................................................... 27
                Create Field
                           ......................................................................................................................................................... 28
                    I
                    nputM  ergeField
                                  .................................................................................................................................................. 28
                    I
                    nputE ditField.................................................................................................................................................. 29
                    ReplaceTokens .................................................................................................................................................. 29
                    Low Level     .................................................................................................................................................. 30
                Customize Field Display
                           ......................................................................................................................................................... 31
                Update Field (Insert Text from Database)
                           ......................................................................................................................................................... 32
                    Start Merge process
                                  .................................................................................................................................................. 32
                    E vent OnMailMergeGetText
                                  .................................................................................................................................................. 33
                        TWP MnsertTextContents
                              M I ........................................................................................................................................... 33
                               procedure Clear...................................................................................................................................... 34
                               procedure Abort...................................................................................................................................... 34
                               procedure LoadTextFromStream(s: TStream)
                                              ...................................................................................................................................... 34
                               procedure LoadTextFromFile(const FileName: string)
                                              ...................................................................................................................................... 34
                               function LoadImageFromFile(const FileName: string; w : Integer = 0;
                               h: Integer...................................................................................................................................... 34
                                               = 0): Boolean;




                                                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Contents                        II

                                       property DataCollection: TWP
                                                      ...................................................................................................................................... 34
                                                                                     RTFDataCollection
                                       property DataBlock: TWP
                                                      ...................................................................................................................................... 35
                                                                              RTFDataBlock
                                       property MergeAttr: TWPStoredCharAttrInterface
                                                      ...................................................................................................................................... 35
                                       property MergeP TP
                                                      ...................................................................................................................................... 35
                                                                  ar: aragraph
                                       property MergeP os: Integer
                                                      ...................................................................................................................................... 35
                                                                  arP
                                       property Obj: TObject
                                                      ...................................................................................................................................... 35
                                       property CodeP ...................................................................................................................................... 35
                                                                 age: Integer
                                       property StringValue: AnsiString
                                                      ...................................................................................................................................... 36
                                       property WideStringValue: WideString
                                                      ...................................................................................................................................... 36
                                       property OldText: string
                                                      ...................................................................................................................................... 36
                                       property OldFormattedText: string
                                                      ...................................................................................................................................... 36
                                       property OldIsP...................................................................................................................................... 36
                                                                lain: Boolean
                                       property CurrentObject: TWP
                                                      ...................................................................................................................................... 36
                                                                                      Object
                                       property CurrentTxtObject: TWP
                                                      ...................................................................................................................................... 36
                                                                                          TextObj
                                       property Options: TWP
                                                      ...................................................................................................................................... 36
                                                                           MailMergeContinueOptions
                                       property Name: string
                                                      ...................................................................................................................................... 37
                                       property FieldnameP
                                                      ...................................................................................................................................... 37
                                                                        art: string
                                       property DatasetnamePart: string
                                                      ...................................................................................................................................... 37
                                       property Command: string
                                                      ...................................................................................................................................... 37
                                       property StartInspObject: TWP
                                                      ...................................................................................................................................... 37
                                                                                        TextObj
                                       property E nspObject: TWP
                                                      ...................................................................................................................................... 37
                                                       ndI                            TextObj
                                       property DisplayName: string
                                                      ...................................................................................................................................... 37
                                       property Format: Integer
                                                      ...................................................................................................................................... 37
                                       property Modified: Boolean
                                                      ...................................................................................................................................... 38
                                       property Hyperlink: string
                                                      ...................................................................................................................................... 38
                                       property HyperlinkName: string
                                                      ...................................................................................................................................... 38
                                       property I...................................................................................................................................... 38
                                                      sNull: TWP nsertTextContentsNull
                                                                      MMI
                                       property ReplaceMode: TWP nsertTextContentsReplaceMode
                                                      ...................................................................................................................................... 38
                                                                                    MMI
                             FieldLocate: Modify Field Name or Contents
                                          .................................................................................................................................................. 38
                             Use TWP .................................................................................................................................................. 39
                                       M DataP
                                          M           rovider
                         FastAppendText: Create text w ith multiple letters
                                   ......................................................................................................................................................... 39
                             E xample: FastAppendText
                                          .................................................................................................................................................. 39
                             Create Sections w ith FastAppendText
                                          .................................................................................................................................................. 40
                             Create Lists .................................................................................................................................................. 40
                             Save created text
                                          .................................................................................................................................................. 40
                         Hide empty paragraphs
                                   ......................................................................................................................................................... 40
                         Forms/Edit Fields
                                   ......................................................................................................................................................... 41
                         Create ComboBox
                                   ......................................................................................................................................................... 43
               6 Tasks
                   ................................................................................................................................... 45
                         Mini Editor ......................................................................................................................................................... 45
                              Save to HTML / Load from HTML
                                            .................................................................................................................................................. 47
                         How to use the "Default Editor"
                                     ......................................................................................................................................................... 47
                         Toolbar and Action Classes
                                     ......................................................................................................................................................... 49
                         Change Behaviour and Appearance of Editor
                                     ......................................................................................................................................................... 51
                              Layoutmodes   .................................................................................................................................................. 51
                              Hover E .................................................................................................................................................. 54
                                        ffects
                              EditOptions.................................................................................................................................................. 56
                              View Options  .................................................................................................................................................. 58
                              Format Options.................................................................................................................................................. 59
                              HideTableBorders
                                            .................................................................................................................................................. 61
                         Header and Footer
                                     ......................................................................................................................................................... 61
                         Create Sections
                                     ......................................................................................................................................................... 66
                              Full implementation - show s how to w ork w ith sections
                                            .................................................................................................................................................. 67
                              Use utility .................................................................................................................................................. 69
                                            procedure AppendAsSection




© 2004-2008 WPCubed GmbH - Munich, Germany
III     WPTools Version 6

                     Use strings in WPTOOLS format w ith the <new section/> tag
                                   .................................................................................................................................................. 69
                     Append section w ith individual footer (or header)
                                   .................................................................................................................................................. 69
                Use WPTools w ith TBX (Toolbar2000 Extension)
                            ......................................................................................................................................................... 70
                Set Attributes in code (unit WPCreateDemoText)
                            ......................................................................................................................................................... 74
                Tables ......................................................................................................................................................... 78
                     Set w idth .................................................................................................................................................. 79
                                   in inch of a certain column
                     Work w ith.................................................................................................................................................. 81
                                    % w idth
                Create Table in Code
                            ......................................................................................................................................................... 81
                Work w ith Styles and Stylesheets (in code)
                            ......................................................................................................................................................... 86
                Numbering   ......................................................................................................................................................... 93
                Hyperlinks  ......................................................................................................................................................... 96
                Bookmarks   ......................................................................................................................................................... 98
                XML editor mode
                          ......................................................................................................................................................... 100
                Printing - how to set printer properties
                          ......................................................................................................................................................... 103
                Superprint: Print Booklets and Labels
                          ......................................................................................................................................................... 104
                Print Labels (TWPSuperPrint)
                          ......................................................................................................................................................... 107
                Print/Edit......................................................................................................................................................... 110
                           elements of TWPRTFDataCollection
                Create Table from Database
                          ......................................................................................................................................................... 112
                Print Watermarks
                          ......................................................................................................................................................... 115
                Use "External Pages"
                          ......................................................................................................................................................... 120
                Images ......................................................................................................................................................... 123
                     Provide a Graphic Popup Menu
                                 .................................................................................................................................................. 125
                     Linked I .................................................................................................................................................. 127
                              mages
                     Technical Information
                                 .................................................................................................................................................. 127
                TWPTextObj w ith custom draw event
                          ......................................................................................................................................................... 128
                Working ......................................................................................................................................................... 130
                           w ith multiple threads
                Create Text Paths
                          ......................................................................................................................................................... 131
                Syntax Highlighting
                          ......................................................................................................................................................... 133
                     TWP SynE ighlight
                                 .................................................................................................................................................. 134
                                 ditH
                     TWP  CustomSyntax (added to WP
                                 .................................................................................................................................................. 134
                                                                        Tools 6)
                     TWP LSyntax
                         XM .................................................................................................................................................. 135
                     TWP LR
                         XM .................................................................................................................................................. 136
                                  TFSyntax
                     TWP  FieldSyntax
                                 .................................................................................................................................................. 136
                     TWP  FieldBandSyntax
                                 .................................................................................................................................................. 136
                Auto capitalisation
                          ......................................................................................................................................................... 136
                Search&Replace Text
                          ......................................................................................................................................................... 137
                CPChar, CPMoveNext, etc.
                          ......................................................................................................................................................... 140
                Share Styles betw een TWPRichText
                          ......................................................................................................................................................... 141
                Multiple Editors for the Same Text
                          ......................................................................................................................................................... 142
                     Use TWP.................................................................................................................................................. 143
                                RTFStorage
                     Create Multi View in Code
                                 .................................................................................................................................................. 144
                Work w ith sub paragragraphs
                          ......................................................................................................................................................... 144
      7 BCB Notes
         ................................................................................................................................... 147
                Example: Create dynamic TWPCustomRTFEdit
                       ......................................................................................................................................................... 148
                Example: Create image object and insert
                       ......................................................................................................................................................... 149
      8 Label Priniting
         ................................................................................................................................... 149
                LabelDef......................................................................................................................................................... 149
                    Vertical .................................................................................................................................................. 151
                    UnitI nch.................................................................................................................................................. 151
                        sI
                    Top        .................................................................................................................................................. 151
                    StartNr .................................................................................................................................................. 151
                    SheetWidth .................................................................................................................................................. 151
                    SheetHeight.................................................................................................................................................. 152
                    Row Count  .................................................................................................................................................. 152




                                                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Contents                        IV

                              R ight      .................................................................................................................................................. 152
                              P adding .................................................................................................................................................. 152
                              N e
                                am        .................................................................................................................................................. 152
                              Lef t       .................................................................................................................................................. 153
                              LabelWidth  .................................................................................................................................................. 153
                              LabelHeight .................................................................................................................................................. 153
                              Horizontal  .................................................................................................................................................. 153
                              Colum .................................................................................................................................................. 153
                                      nCount
                              Caption .................................................................................................................................................. 153
                              Bottom .................................................................................................................................................. 154
                              AsText .................................................................................................................................................. 154
                              Active .................................................................................................................................................. 154
                          Example ......................................................................................................................................................... 154
                                     Project
                              I
                              nitialization
                                          .................................................................................................................................................. 155
                              After changing sheet size and margins
                                          .................................................................................................................................................. 155
                              Change of column count or row count
                                          .................................................................................................................................................. 156
                              Change of label w idth and height
                                          .................................................................................................................................................. 156
                              ReadP .................................................................................................................................................. 156
                                       rops and StoreP          rops
               9 HTTP Interface
                  ................................................................................................................................... 157
                          Form Setup ......................................................................................................................................................... 158
                          Unit Initialization
                                     ......................................................................................................................................................... 159
                          User Action and History Management
                                     ......................................................................................................................................................... 160
                          Load Method......................................................................................................................................................... 160
                          Webbrow ser w ith WPTools
                                     ......................................................................................................................................................... 162
                          Source View......................................................................................................................................................... 162
              10 MIME Import / Export
                  ................................................................................................................................... 163
                          Reader / ......................................................................................................................................................... 164
                                   Writer
                          Demo ......................................................................................................................................................... 164
              11 PDF export with wPDF
                  ................................................................................................................................... 165
                          Export to......................................................................................................................................................... 166
                                    PDF
                          Export using dialog
                                   ......................................................................................................................................................... 167
                          Export using PaintRTFPage()
                                   ......................................................................................................................................................... 167
                          Create edit / memo fields
                                   ......................................................................................................................................................... 169
                          Create a ......................................................................................................................................................... 169
                                   check box field
                          Create embedded data objects
                                   ......................................................................................................................................................... 170
              12 Adding Spellcheck
                  ................................................................................................................................... 171
                          Use WPSpell
                                 ......................................................................................................................................................... 172
              13 WPReporter Addon
                  ................................................................................................................................... 174
                          Comparison to "usual" reporting
                                   ......................................................................................................................................................... 175
                          Calculation in Text and Tables
                                   ......................................................................................................................................................... 176
                          Reporting w ith WPReporter
                                   ......................................................................................................................................................... 178
                          WPReporter - step by step
                                   ......................................................................................................................................................... 181
                          WPReporter Events
                                   ......................................................................................................................................................... 188
                          Convert text into template
                                   ......................................................................................................................................................... 190
                          Reporter......................................................................................................................................................... 192
                                    and Bookmarks
                          Token to......................................................................................................................................................... 192
                                    Template Conversion
                              General Syntax - Fields
                                          .................................................................................................................................................. 193
                              Syntax Highlighting
                                          .................................................................................................................................................. 194
                              Bands .................................................................................................................................................. 195
                              Groups .................................................................................................................................................. 195
                              Parameters for Fields
                                          .................................................................................................................................................. 196
                              Parameters for Bands and Groups
                                          .................................................................................................................................................. 197




© 2004-2008 WPCubed GmbH - Munich, Germany
V      WPTools Version 6

                          Example Template
                                  .................................................................................................................................................. 197
      14 WPPremium Addon
          ................................................................................................................................... 199
                  Text boxes
                          ......................................................................................................................................................... 200
                  Footnotes
                          ......................................................................................................................................................... 201
                  Columns ......................................................................................................................................................... 201
      15 Trouble Shooting
          ................................................................................................................................... 202

Part VIII Reference                                                                                                                                                             202
       1 Reader and Writer
          ................................................................................................................................... 203
       2 TParagraph API
          ................................................................................................................................... 204
                  TParagraph Properties
                          ......................................................................................................................................................... 204
                  TParagraph Methods
                          ......................................................................................................................................................... 207
                  AppendParCopy
                          ......................................................................................................................................................... 214
       3 TWPRTFDataCursor
          ................................................................................................................................... 215
                  Drop-Markers
                           ......................................................................................................................................................... 215
                  Attribute......................................................................................................................................................... 217
                            Interfaces
       4 Manage Style Properties
          ................................................................................................................................... 223
                  List of 'A' methods
                            ......................................................................................................................................................... 224
                  ASet/GetBorder
                            ......................................................................................................................................................... 226
       5 WPAT_codes
          ................................................................................................................................... 227
                  Character Attributes
                           ......................................................................................................................................................... 227
                  Paragraph Attributes
                           ......................................................................................................................................................... 229
                  Numbering Attributes
                           ......................................................................................................................................................... 230
                  Border Attributes
                           ......................................................................................................................................................... 231
                  Table Size and Position
                           ......................................................................................................................................................... 233

 Part IX Notes for Upgraders                                                                                                                                                    234
       1 Updated Rendering and Formatting
          ................................................................................................................................... 236
       2 Changed Unit Names
          ................................................................................................................................... 236
       3 Changed Classes
          ................................................................................................................................... 237
       4 Changed Pointers
          ................................................................................................................................... 237
       5 Changed GUI elements
          ................................................................................................................................... 238
       6 New Border Handling
          ................................................................................................................................... 239
       7 Changed Style Handling
          ................................................................................................................................... 240
       8 BackgroundImage
          ................................................................................................................................... 240

 Part X Release Notes - WPTools 6                                                                                                                                               240

 Part XI Release Notes - WPTools 5                                                                                                                                              243

           Index                                                                                                                                                                 261




                                                                                                   © 2004-2008 WPCubed GmbH - Munich, Germany
What is WPTools?        1



1        What is WPTools?

         WPTools is a word processing component for Borland Delphi and C++Builder. It loads
         and saves RTF files. Its RTF implementation is one of the most complete on the
         component market (header/footer, paragraph styles, optional footnote support, table
         header rows).

         The "premium" edition also does columns, text boxes and footnotes.

         But it does not only serve to edit text, it is a powerful toolset for mass mailing and,
         optional, RTF reports.

         If you need a text component for Microsoft Access(TM), VisualFox PRO(TM), VisualBasic
         (TM) or .NET please use our new word processing component TextDynamic. This
         component has been esspecially created for .NET. It offers the same word porcessing
         features as WPTools Version 6 does. The concept of the programming API is similar. The
         .NET version does not use an OCX but an assembly written in C#, but an OCX is also
         included at no extra charge.
         Info: www.textdynamic.com

         If you need word processing or text conversion features (RTF to PDF, HTML to PDF, RTF
         to HTML) on a server (ASP) or with .NET or as ActiveX please check out our product
         RTF2PDF / TextDynamic Server. It now includes the same powerful API as used by
         TextDynamic.

         The History
         The first version of our product was released on the Delphi market in January 1996. Over
         the years it has evolved further to become what you now see. First of all, HTML and
         WYSIWYG support was added, later we also added the page layout view and fast
         zooming. At the beginning of 2004 version 4.22 was released - it was the last release of a
         WPTools version which was still partially based on the RTF Engine created in 1996.

         During 2003 and 2004 the WPCubed GmbH, managed by Julian Ziersch, developed a
         new word processing engine. This new engine was constructed to provide solutions for
         the wide variety of demands which were raised over the last 8 years and addresses
         issues which could not be solved within the framework of the old WPTools engine.

         WPTools has been quite successful over the last 8 years and was used in a multitude of
         projects, both large and small. It is the only text editor which was developed in native
         Delphi and which supports WYSIWYG page layout view (with WYSIWYG header and
         footer), including support for tab stops. The competition continues to struggle to achieve
         the standard set by WPTools, thus demonstrating that the original concept was very
         good. So why was this rewrite necessary?

         In-depth modifications were required to add support for new features, such as nested
         tables. Plus, potential .NET compliancy made it necessary to remove pointer aritmetic
         completely. This had been very important in 1996 to enhance performace and because
         the compiler did not support arrays with variable lengths. Furthermore, some parts of the
         programming interface had become redundant over the years and last, but not least, CSS
         and XML development brought new ideas to word processing, which could only be
         implemented in a complete re-write.

         WPTools 4 had heaps of functionality, but a great deal of it was developed in an ad-hoc



© 2004-2008 WPCubed GmbH - Munich, Germany
2    WPTools Version 6


    manner - a problem arose and we provided a solution. But the various solutions provided
    did not necessarily gel consistently into an integrated framework and the planned
    architecture of the engine.

    In the end we decided it would be a good idea to take advantage of the opportunity to
    develop a new RTF-Engine to fulfill the needs which had arisen within a structured
    environment.

    The new RTF-Engine was first used for WPTools 5. WPTools 6 is build upon the stable
    WPTools 5 kernel, but introduces several interesting new features. We also optimized the
    engine to improve load and save times. WPTools 5 is still serviced but new features will
    go exclusively into WPTools 6. The migration from WPTools 5 to WPTools 6 is made as
    easy as possible.


    What does WPTools Version 6 do?
    a) Word processing (WYSIWYG, page layout view, headers + footers, tab stops,
       paragraph styles, UNICODE).
    b) Special text editing tasks - most importantly, editing one text stream with multiple
       editors which can be on different forms.
    c) Reporting - WPTools has the ability to dynamically create and display text during
       page formatting. This makes it possible to display calculated sums in dynamic table
       footers. Because the display changes after each reformat, this is an ideal solution for
       creating invoices since the report is completely editable!
    d) Preview - The developer can insert pages from any source (owner drawn) into the
       displayed pages. This way it is possible to mix these pages with RTF pages and
       preview and print them all at once. It is also possible to have an editable text, followed
       by a report created by the specialized reporting engine and preview everything in the
       same editor!
    e) Spread sheet - WPTools has incredibly powerful and fast table support. It is fast
       enough to hold thousands of rows!
    f) Mail merge - It is possible to merge in text, plain or formatted and also images.
    g) HTML editing - WPTools supports additive paragraph attributes which makes it
       perfect for this task. In contrast to other solutions which completely import or export
       the HTML properties, the form of the imported HTML text remains intact.
    h) Automatic text creation. The new TableAdd function is very easy to use but still very
       powerful. As we prove in our "ThreadSave" demo the text creation can take place in
       sub threads.
    i) new: Integrated Label printing.
    j) new: Alternative formatting routine to display web pages.
    k) new: MIME support (based on Synapse).
    l) new: integrated HTML and XML syntax highlighting.
    m) new: automatic HTTP download (based on Synapse)
    n) new: PREMIUM version only: Application Server Mode
    o) new: better Clipboard control and security
    p) improved section support
    q) other additions to API and various code optimation.
    r) Optimized GUI - it is possible to use a marquee effect in the window




                                                         © 2004-2008 WPCubed GmbH - Munich, Germany
WPTools 6 new features          3



2        WPTools 6 new features
         WPTools 6 includes many improvements to the editor and general working experience. It has an
         enhanced API.
         But it is also compatible to WPTools 5 and we tried to make the upgrade as smooth as possible.

         This are the most notable new features:

         1) Application-Server-Mode

         WPTools 6 introduces a feature which is called "Application-Server-Mode". This is only available
         when you have the PREMIUM version. This mode is activated when true is assigned to the global
         boolean variable WPAppServerMode. When this mode is activated the editor does not use the
         double buffered output anymore. While this can cause some flickering the network traffic is reduced
         when the application runs on an application server, such as Citrix.

         Please note, effective with WPTools 6 software which was written for application servers
         (such as clinic software) may only be distributed when a TEAM or SITE license of WPTools
         was acquired.

         2) Integrated Label Printing

         When activated the integrated label printing shows multiple labels on one virtual sheet of paper. The
         cursor can move from label to label freely. The user can so edit the labels, add new or delete
         unwanted labels before the complete sheet is printed. This is a very unique and versatile feature.

         3) Additions to the PDF export with wPDF V3

         Create embedded data objects
         Create edit / memo fields
         Create a check box field

         Also the creation of PDF tags was enhanced. So now hints to paragraph styles will be also
         exported.

         4) Additional Control over Clipboard Actions

         a) properties to select the format
         b) added security

         5) Added section API
         + WPRichText1.ActiveSection
         + WPRichText1.InputSection
         + TWPPagePropDlg has new method ExecuteEx. Use it to change current page size or Section
          WPPagePropDlg1.ExecuteEx(WPRichText1.ActiveSection);

         6) Load over HTTP connections (requires Synapse)

         7) Load and save MIME encoded HTML with embedded images (requires Synapse)

         8) Integrated XML syntax highlighting

         9) WPReporter: Token to Template conversion with syntax highlighting

         10) Scroll with middle mouse button




© 2004-2008 WPCubed GmbH - Munich, Germany
4    WPTools Version 6




    11) Premium Edition: Now Column Balancing is now supported




    12) draw gradient effect in background of editor

    13) XML editor mode




            here w e use a style sheet to auto format the embedded texts, in this case the style sheet
                     Lemma{font-family:'Courier New';font-weight:bold;color:red}
                     Entsprechung{font-family:'Tahoma';font-size:13.00pt;}

    14) new Insert Symbol Dialog




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
WPTools Version 6        5



3        WPTools Version 6
         WPTools Version 6 has an entirely new RTF Engine, compared to WPTools 1 to 4. This
         makes it much easier to work with the paragraph text and offers an object-oriented
         approach whenever such an approach is beneficial.

         Please read chapter "Release notes", "Data Structures" and "Quick Start".

         The new data model supports a separation between data and editing logic. This makes it
         possible to attach multiple editors to one text object in order to view different parts of the
         same text. This feature can be used to create a split view of the same text or, even more
         interesting, to link different editors to specific pages. This feature can also be used to edit
         text paths in DTP applications.

         The result is a suite of components with a combination of features you will not find
         available in any other single component package.

         New concepts found in WPTools Version 6 include:
         · storage of character attributes in a special record which is assigned to the character
           which uses these particular attributes. This makes it easy to copy characters and
           assign new attributes. Other products use start and end tags to store character
           attributes with the danger of inconsistency if a tag 'gets lost'. Since WPTools caches
           the attributes, it does not consume a lot memory for them!
         · paragraph storage in a linked list with sub-elements (children) - this reflects the
           document structure of HTML and makes it possible to support HTML/CSS editing.
         · inherited attributes - in WPTools paragraph and character attributes can be added and
           removed. If an attribute is not defined the 'default' or 'inherited' value is used instead.

         For application designers WPTools Version 6 supports
         · different types of multiple page layout which can be displayed quickly
         · fast zooming
         · the possibility of editing ONE text in TWO (or more) windows (split-screen)
         · effective property dialogs (NEW: The dialogs shade 'undefined' values)
         · integrated localization
         · and all important action classes are included.

         For word processing WPTools Version 6 includes
         · a vast number of paragraph and character attributes for text (numbering, alignment,
           indents, spacing - the usual RTF features, but also color and style for various
           underlines, different border styles, background colors)
         · strong table support - including the ability to nest tables (table within a table) and
           merging of table columns and table rows, with support for page breaks within table rows
         · Repeated table header and footer rows
         · pictures with text flow on one or (new!) both sides
         · powerful support for headers and footers
         · extensive support for paragraph styles
         · improved support for tab stops - including support for leading signs (.......1.00).
         · insertion of foreign pages - i.e. pages which are painted by an owner-provided function.
           These pages appear in the text, but cannot be accessed with the cursor
         · WYSIWYG
         · and different layout modes - so powerful that the preview dialog now uses a standard



© 2004-2008 WPCubed GmbH - Munich, Germany
6    WPTools Version 6


      editor which is switched to read only. It still allows thumbnails and side-by-side page
      layout views!
    · Support for "sections" - have different page sizes in one document.
    · new in V6: Clickable Section marker and dialog

    For HTML/CSS editing WPTools Version 6 enables
    · loading of HTML/CSS files
    · saving of HTML/CSS files
    · and powerful CSS support - the word processing engine supports inherited attributes
      and nested tables and paragraphs.
    · new in V6: Alternative formatting routine to display web pages.
    · new in V6: Ready to use unit to load over HTTP connection (based on Synapse)
    · new in V6: MIME support to read *.MSG / *.EML / *.MHT (based on Synapse).
    · new in V6: Integrated HTML and XML syntax highlighting.


    For developers WPTools Version 6 is an improvement because it
    · is not bloatware - in fact WPTools V5 is smaller than WPTools 4!
    · offers effective memory management. It also supports many more paragraph and
      character attributes without consuming more memory than the previous version (under
      the same OS).
    · is safe for multi-threaded applications
    · allows the addition of new paragraph attributes
    · makes it possible to insert 'external' or 'owner drawn' pages into a document
    · offers support of most RTF features in HTML/CSS file format and vice versa. (Notable
      exception: Tab stops cannot be coded into HTML/CSS.)
    · makes it possible to share styles and other properties (color palette, font table) between
      texts. This makes it easier to work with two synchronized RTF texts.
    · allows linking of editors to text paths (the text is never copied between these editors).
    · provides support for Delphi 5, 6, 7 and 2005(Win32), 2006, 2007
    · provides support for C++Builder 5 and 6, C++Builder 2006
    · provides an effective storage format which produces the minimum amount of RTF and
      HTML/CSS code possible.
    · optionally: Support for FastReport 3 & 4 (supports stretching)
    · optionally: Support for ReportBuilder 9 & 10 (supports stretching)
    · optionally: Support for QuickReport 4

    Optional in WPTools PREMIUM:
    · editing and printing of footnotes (WYSIWYG!)
    · text boxes (movable boxes with RTF text. Anchor is in text body)
    · support for columns (newspaper layout).
    · Application Server Mode - this mode activates text rendering which does not utilize a
      double buffer. This makes it possible to minimize the network traffic.

    Other products in WPTools family:
    · WPSpell - spell checking highly integrated into the WPTools environment
    · wPDF - perfect and fast PDF creation, not only from WPTools since it also does
      conversion of metafiles. Supports PDF/A.
    · WPViewPDF - display and print the PDF files not only created by wPDF but also
      several competing products.



                                                         © 2004-2008 WPCubed GmbH - Munich, Germany
WPTools Version 6       7




         We hope that you are as satisfied with WPTools Version 6 as we are and that the
         improvement in your product is worth the effort which may be required for the upgrade to
         this new version. WPTools Version 6 was built to be the most powerful word processor
         available on the component market. In addition, it also works as a HTML editor, offering
         convenient word processing features, while still working as closely to the HTML document
         model as possible.




4        License
         1. NO ROYALTIES F EXE-PROJECTS
                          OR

         IF YOU ARE REGISTERED YOU HAVE THE RIGHT TO DISTRIBUTE PROGRAMS (EXE-FILES) YOU HAVE
         CREATED WITH THE HELP OF WORD PROCESSING TOOLS ROYALTY-FREE. YOU MAY NOT
         DISTRIBUTE MODULES WHICH MAY BE USED BY OTHER (ALSO NOT "INHOUSE") DEVELOPERS
         (SUCH AS COMMANDLINE TOOLS, VBX, OCX, VCL, DLL, VCL OR ACTIVE-X) WITHOUT WRITTEN
         PERMISSION. THE LICENSE DOES NOT INCLUDE THE PRODUCTION OF ACTIVE-X MODULES FOR
         THE USE WITHIN THE INTERNET.

         THE SOFTWARE SUPPLIED MAY BE USED BY ONE PERSON ON AS MANY COMPUTER SYSTEMS AS
         THAT PERSON USES.

         GROUP PROGRAMMING PROJECTS MAKING USE OF THIS SOFTWARE MUST PURCHASE A COPY OF
         THE SOFTWARE FOR EACH MEMBER OF THE GROUP. THIS DOES *ALSO* APPLY WHEN "ONLY ONE"
         PERSON IN THE GROUP IS DEVELOPING WITH WPTOOLS!

         CONTACT JULIAN ZIERSCH FOR VOLUME DISCOUNTS AND SITE LICENSING AGREEMENTS.

         Note: the distribution license requires:

         If WPTools is used in a project which is developed by a group of developers, all members
         of this group must have a WPTools development license!

         In case only one developer works with WPTools but there are others in the project who
         work with other development systems, those other developers still need a WPTools license
         since the work of the first developer is a "Module" for the others.

         Please note, effective with WPTools 6 software which was written for application servers
         (such as clinic software) may only be distributed when a TEAM or SITE license of WPTools
         was acquired.

         If this condition is not met, the product may not be distributed. If developers join the
         project, new licenses are required. This license model makes it possible for us to provide
         and support a product as powerful and versatile as WPTools.

         2. THE LICENSE DOES NOT ALLOW PRODUCTION OF MODULES, DLLS, ActiveX OR COMMAND LINE
         UTILITIES

         UPON REGISTRATION OF THE STANDARD VERSION YOU WILL RECEIVE 70% OF THE SOURCE FILES
         FOR VERSION 5.x. YOU MAY ALTER THEM BUT YOU MAY NOT DISTRIBUTE THEM TO ANY OTHER
         PERSON WHO HAS NOT REGISTERED! YOU MAY NOT DISTRIBUTE WPTOOLS-DCU FILES OR DELPHI/
         BCB DESIGNING PACKAGES EITHER. IT IS NOT ALLOWED TO USE WPTOOLS IN COMMAND LINE
         UTILITIES, SUCH AS TOOLS WHICH DESIGNED TO ONLY RENDER RTF OR HTML - EXCEPT FOR
         INHOUSE USE. THE USE IN A GENERAL "VIEWER" APPLICATION WOULD BE AGAINST THIS LICENSE.




© 2004-2008 WPCubed GmbH - Munich, Germany
8    WPTools Version 6


        IF YOU NEED THE COMPLETE SOURCE PLEASE PURCHASE THE PRO OR PREMIUM VERSION!

        3. NO REVERSEENGINEERING

        YOU MAY NOT REVERSE ENGINEER, DECOMPILE, OR DISASSEMBLE THE PRODUCT UNLESS
        ALLOWED BY APPLICABLE LAW. THE PROVISION OF SOURCE CODE DOES NOT CONSTITUTE A
        TRANSFER OF ANY LEGAL RIGHTS TO SUCH CODE, AND RESALE OR DISTRIBUTION OF ALL OR ANY
        PORTION OF ALL SOURCE CODE AND INTELLECTUAL PROPERTY WILL BE PROSECUTED.

        THIS COMPONENT IS LICENSED FOR USE WITH DELPHI OR C++BUILDER WIN32 ONLY - THE
        SOURCE MAY NOT BE ALTERED TO BUILD .NET TOOLS OR TOOLS FOR OTHER COMPILERS OR
        OPERATION SYSTEMS.

        THE WPTOOLS STANDARD AND STANDARD-PRO VERSION DOES NOT INCLUDE THE RIGHT TO
        EXTEND IT TO SUPPORT COLUMNS, TEXTBOXES OR THE PRINTING OF FOOTNOTES. THIS IS
        RESERVED TO THE "PREMIUM" EDITION. THE SAME IS TRUE FOR TEXT BOXES BASED ON OUR
        LAYER TECHNOLOGY.
        THE DISTRIBUTION LICENSE FOR CREATED APPLICATION(S) REQUIRE THIS LICENSE AGREEMENT
        TO BE RESPECTED!

        4. YOU MAY NOT RENT, LEASE, OR LEND THIS SOFTWARE COMPONENT.

        ONCE AN APPLICATION WHICH USES THIS LIBRARY WAS DISTRIBUTED, THE LICENSE MUST STAY
        WITH THE COMPANY WHICH HOLDS THE DISTRIBUTION RIGHT TO THE DISTRIBUTED APPLICATION.

        5. LIABILITY LIMITATION

        THE DOCUMENTATION AND THE VCL ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
        EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
        MERCHANTABILITY AND/OR SUITABILITY FOR A PARTICULAR PURPOSE. THE USER ASSUMES THE
        ENTIRE RISK OF ANY DAMAGE CAUSED BY THIS SOFTWARE.
        THIS INCLUDES DAMAGE BECAUSE OF INFRINGEMENT OF ANY PATENTS.

        IN NO EVENT SHALL JULIAN ZIERSCH OR WPCUBED GMBH BE LIABLE FOR DAMAGE OF ANY KIND,
        LOSS OF DATA, LOSS OF PROFITS, INTERRUPTION OF BUSINESS OR OTHER PECUNIARY LOSSES
        ARISING DIRECTLY OR INDIRECTLY FROM THE USE OF THE PROGRAM. ANY LIABILITY OF THE
        SELLER WILL BE EXCLUSIVELY LIMITED TO REPLACEMENT OF THE PRODUCT OR REFUND OF
        PURCHASE PRICE.

        GOOD DATA PROCESSING PROCEDURE DICTATES THAT ALL PROGRAMS BE THOROUGHLY TESTED
        WITH NON CRITICAL DATA BEFORE THEY CAN BE RELIED UPON.

        4. COPYRIGHT MESSAGEREQUIRED

        IF YOUR PROGRAM HAS AN "ABOUT BOX" THE FOLLWING CREDIT SHOULD BE DISPLAYED IN IT:
        "WPTools (C) Julian Ziersch" or "WPTools (C) WPCubed GmbH"




5       Technical Notes
        WPTools Version 6 supports Delphi 5,6,7 and 2005, 2006 (Win 32) and Delphi 2007. It
        also supports Borland C++ Builder 5 and 6 and C++Builder 2006.

        Delphi 3 and 4 are not supported since the code requires modern language features,
        such as method overloading.




                                                           © 2004-2008 WPCubed GmbH - Munich, Germany
Technical Notes     9




           If you need a text component for Microsoft Access(TM), VisualFox PRO(TM),
           VisualBasic(TM) or .NET please use our new word processing component
           TextDynamic. Info: www.textdynamic.com.

           For ASP and ASP.NET we have RTF2PDF / TextDynamic Server. This
           component includes most of the prowerful interface methods TextDynamic has.
           Please check out our demo webserver at http://www.rtf-net.com/


         The code uses pointers only in very few functions - mainly to optimize the performance.
         The reader and writer classes do not use static buffers.

         The use of global variables has been limited. The most important ones are stored in the
         TWPToolsEnviroment object. By creating several instances of this class it is possible to
         create a threadsave application. (See demo ThreadSave)

         WPTools Version 6 has been designed for modern PCs.
         The Text rendering engine requires an up-to-date graphics adapter. We recommend a
         CPU with at least 500Mhz.

         The Memory consumption has been highly optimized. It is equal or less than with
         WPTools 4.

         The general text editing functionality require Windows 98 or later. Unicode support was
         tested with XP only - special word wrap rules for unicode text have not been implemented,
         such as Japanese rules. Support for RTL languages is limited (experimental).

         For questions about WPTools Version 6 please use our web based forum:

          Discussion
          FAQ: Questions when upgrading
          FAQ: General

         You will find the Release notes at the end of this manual.

6        PDF Products
         WPCubed GmbH also markets this PDF products:

         wPDF:
         Powerful and versatile PDF creator for Delphi and C++Builder.
         It supports WPTools (see "PDF export with wPDF") and the most important
         Delphi reporting engines. Also converts metafiles into PDF data.

         New Features in wPDF Version 3
         · Support for standard brush styles (hatching)
         · TransparentBitBlt
         · Automatic reuse of the same image data. This way, when you export a
           document which often uses a logo the PDF file will be significantly smaller!
         · Creation of PDF/A complient PDF files (with added meta data and PDF




© 2004-2008 WPCubed GmbH - Munich, Germany
10    WPTools Version 6


       tagging when you use it with WPTools)
     · Support of CID fonts (known as "unicode" support)
     · Binary Data embedding: You can store the document source which was
       used to create a PDF file within this PDF file. When you use WPTools for the
       PDF creation you can store the RTF source document inside of the created
       PDF data, the user only has to click on an icon to extract this document.
       This can be a great feature if you use it to embed programming examples
       within your programming manual!

     WPViewPDF:
     To view, print and manipulate PDF files right in your Application our product
     WPViewPDF Version 2 may be interesting for you. It is not only usable with .
     NET and as ActiveX, but also in Delphi and C++Builder.

     This component was created to view PDF files which were created using the
     wPDF engine, but it is also capable of viewing PDF files created with other
     windows based engines which utilize TrueType(tm) fonts. In contrast to many
     competing solutions WPViewPDF is very fast. You can also use WPViewPDF to
     convert PDF to EMF and to convert PDF to JPEG.


     New Features in WPViewPDF
     Version 2
     · now with bookmark tree
     · now text selection and copy to
       clipboard is supported
     · auto scrolling (use middle mouse
       key).
     · Optionally high quality font
       rendering of embedded Type1
       and TTF subset fonts

     WPViewPDF PLUS:

     With the PLUS license you can save the PDF information from WPViewPDF
     which makes it a versatile pdf conversion software. This means you can load
     in multiple PDF files and save all pages into a new PDF file (=pdf merge, edit
     pdf).
     Certain pages can be marked to be deleted, they will not be displayed by
     WPViewPDF. When you save the PDF file this pages will be removed. It is also
     possible to set new security properties (apply, remove encryption) and set
     property strings int this pdf conversion tool. The WPViewPDF Demo has the
     PLUS features enabled, but when a new file is created a red cube will be
     printed on all pages.

     With the "PLUS" version it is possible to add text and vector graphics to
     certain pages of a PDF file (pdf stamping). Any text will be converted to
     vectors - this allows it to use special fonts. The graphics will be already visible
     in the viewer before the PDF data has been updated!




                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
PDF Products       11


         NEW: it is also possible to read and modify Acro Form field in PDF files!

         WPViewPDF: merge, split, stamp, encrypt, decrypt PDF files!




7        Guide
         In this chapter we collected introduction texts to important tasks which can be solved with WPTools.
         We recommend to also review the HLP file since it contains a structured list of all classes,
         properties and methods. It also contains 'Categories' which are a big help. In chapter 'Tasks' we
         will explain how to create the first small editor, how to use mail merge, how attach a
         generic toolbar using actions and much more. There is also an introduction to WPReporter
         .

         Please check out the demos which are described in this chapter:
          Mini Editor - shows how to create a small, yet powerful editor
          Create Table in Code - demos the most effective way to create tables in code
          TBX Demo - how to use WPTools with TBX, the toolbar 2000 extension
          GridMode - how to create tables dynamically from a database
          DynAssign TWPRTFDataCollection (create MDI app without MDI windows)
          ParStyle - this demo shows how to work with the CSS like paragraph styles
          Localization - how to localize (translate) the dialogs and messages.

         Also see the Programming Overview .

         QuickStart




© 2004-2008 WPCubed GmbH - Munich, Germany
12    WPTools Version 6


     After having dropped the TWPRichText you can click right to use the QuickConfig dialog:




                                                   [the WPTools Propery Dialog]




                                                             © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   13




© 2004-2008 WPCubed GmbH - Munich, Germany
14    WPTools Version 6



       Loading and Saving

       To load text into the editor You can use the functions LoadFromFile, LoadFromStream and also the
       properties AsString and SelectionAsString (the latter inserts the text). To move the cursor before the
       insertion or after the load modify the property CPPosition.

       To save the text You can use the functions SaveToFile, SaveToStream and AsANSIString. The
       function AsANSIString is useful to convert the text into a data string of a given format, i.e.
       AsANSIString('HTML') will create a string with HTML tags.

       If the load and save functions ask for a second string parameter this is a "format string" - please read
       more here http://www.wpcubed.com/manuals/formatstrings.htm

       In our web based forum we have posted several FAQ topics and articles.

       The article "Compose an e-mail in HTML format / Save image to HTML" shows how to create a
       HTML e-mail.

       The WPRichText component implements several functions which open a dialog box: Load, Save,
       SaveAs, InsertGraphicDialog and Insert.




7.1    Localization - change Language in Dialogs
       For anyone wanting to work with inch units, please add the following line in your code (for example,
       in the FormCreate event).

       GlobalValueUnit := euInch;

       WPTools Version 6 supports the localization of the texts which are used for filters and error
       messages and also the localization of the provided property dialogs.

       Steps to update the dialog language in WPTools 5 and 6:

       We start with a simple form:




       Now w e add the component TWPLanguageControl to the form




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      15




         A double click opens the XML editor.

         Here we can load (and merge in) the language files which are provided under DemosTasks
         Localization. Close the form with File/OK




         Please note that the properties Active, AutoLOadString and AutoSaveStrings are not
         supported in WPTools 5 or WPTools 6.

         Here we need to create a COM interface like this:

         Add the units WPUtil and WPActnStr to the uses clause.

         To active use this code in the OnCreate event of the form:

         procedure TForm1.FormCreate(Sender: TObject);
         begin
           WPLangInterface := TWPLocalizationInterface.Create(WPLanguageControl1);
           WPLanguageControl1.GlobalLanguage := 'DE';
           WPLocalizeLoadForms := TRUE;
           WPTools_LoadVCLStrings;
           WPTools_LoadActionStrings;
         end;




© 2004-2008 WPCubed GmbH - Munich, Germany
16    WPTools Version 6


     In the OnDestroy event add this:

     procedure TForm1.FormDestroy(Sender: TObject);
     begin
       WPLangInterface.Free;
     end;

     Done: We have hints in German:




     And Dialogs, too:




     To change the language at runtime use code like this:

       WPLanguageControl1.GlobalLanguage := 'DE';
       WPLocalizeLoadForms := TRUE;




                                                        © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       17


           WPTools_LoadVCLStrings;    // from unit WPUtil
           WPTools_LoadActionStrings; // from unit WPActnStr



         You need to create the TWPLanguageControl and the Interface
         on the Form which is created first in the project.
         If necessary You can put it into a Datamoduel.

         How does the localization work?

         In WPTools Version 6 we are using a localization interface which is defined as:

           IWPLocalizationInterface = interface
             ['{A12EF1F7-E592-4483-855F-67E28332AFC5}' ]
         // This method can be used to save the menu items and captions
            on a certain form. I f you use the TWPLocalizeForm class you don't need
            to care about that. }
             procedure SaveForm(
                const Name: string;
                Form: TWinControl;
                Menus, Captions, Hints: Boolean);
         // Load all Components on a certain TForm. }
             procedure LoadForm(
                const Name: string;
                Form: TWinControl;
                Menus, Captions, Hints: Boolean);
         // This method saves a string list under a certain name. The string list has to
         use
            the syntax NAME=xxxn }
             procedure SaveStrings(
                const Name: string;
                Entries: TStrings;
                Charset: Integer);
         // Loads back the string(s) saved with WPLangSaveStrings }
             function LoadStrings(
                const Name: string;
                Entries: TStrings;
                var Charset: Integer): Boolean;
         // Method to save a certain string. To save multiple strings use
         WPLangSaveStrings
             procedure SaveString(
                const Name, Text: string;
                Charset: Integer);
         // Loads back a string saved with WPLangSaveString
             function LoadString(
                const Name: string;
                var Text: string;
                var Charset: Integer): Boolean;
           end;

         This interface is implemented by the TWPLanguageControl. The TWPLocalizeForm (implemented in
         unit WPUtil, it is the anchestor of all localizable dialogs) automatically uses this interface through
         the instance of the TWPLocalizationInterface class which must be created by your code:
         WPLangInterface := TWPLocalizationInterface.Create(WPLanguageControl1);




© 2004-2008 WPCubed GmbH - Munich, Germany
18    WPTools Version 6



7.2     Programming Overview/QuickStart
        This topic should help you to find the correct procedures and properties in the reference manual
        when you start programming with WPTools. Please note that the reference defines categories.
        When you found one property you can browse the list of topics in the same category (link to list of
        all categories).

        Also see:
        Mini Editor                                        Hyperlinks
        Save to HTML / Load from HTML                      Hover Effects
        Localization/Translation                           Bookmarks
        Mailmerge and forms                                Printing - how to set printer properties
        Create Field                                       Superprint: Print Booklets and Labels
        Merge: Change Field Text/Read Field Text           Print Labels (TWPSuperPrint)
        Merge: Insert/Modify Image                         Print/Edit elements of TWPRTFDataCollection
        Modify Field Name or Contents                      Create Table from Database
        Create text with multiple letters                  Print Watermarks
        Hide empty paragraphs                              Use "External Pages"
        Forms/Edit Fields                                  Images
        Create ComboBox                                    Provide a Graphic Popup Menu
        How to use the "Default Editor"                    Linked Images
        Toolbar and Action Classes                         Technical Information
        Localization                                       TWPTextObj with custom draw event
        Layoutmodes                                        Working with multiple threads
        Header and Footer                                  Create Text Paths
        Create Sections                                    Syntax Highlighting
        Use WPTools5 with TBX (Toolbar2000 Extension)      Search&Replace Text
        Set Attributes in code (unit WPCreateDemoText)     CPChar, CPMoveNext, etc.
        Tables                                             PDF export with wPDF
        Set width in inch of a certain column              Multiple Editors for the Same Text
        Work with % width                                  Use TWPRTFStorage
        Create Table in Code                               Create Multi View in Code
        Work with Styles and Stylesheets (in code)         Work with sub paragragraphs
        Numbering




7.2.1   Modify the look and feel of the editor
        Please use the properties ViewOptions, EditOptions and EditOptionsEx.

        The properties FormatOptions and FormatIOptionsEx change how the formatting routine works, they
        have a significant influence on how the text appears.

        Please also see the Layout Catagory.

        To change the language (for localization, translation) please see demo "Lozalisation".




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       19


7.2.2    Change current writing mode
         See property WPRichText.CurrAttr, here you can set attributes such as Bold, Italic etc. using
         AddStyle and DeleteStyle. CurrAttr also controls the paragraph attributes (Alignment) indents and
         spacing. CurrAttr will change the current writing mode or the selected text - if text is selected. See
         this FAQ if you want to implement ShortCuts, such a Ctr+B = bold. WPTools Version 6 also has
         more specialized attribute interfaces. They can be used to only change the current attribute, only the
         selected text, the attributes of the text which was found by "Finder" or the attributes of merged text.
         (Attribute Interface Category)

7.2.3    Move the Cursor
         Please use the CP.. properties. CPPosition is the current character position, assign 0 to go to the
         start, MaxInt to go to the end. Also procedure MovePosition is very useful. When the user changes
         the cursor position the event OnChangeCursorPos is triggered.



7.2.4    Change Page Size and Page margins
         Modify WPRichText.Header. The properties with "default" in their name are the values which will be
         applied by Clear, the others are the current values. Method SetPageWH can be used to set several
         values at once, the values which should not be changed can be passed as -1

7.2.5    Insert Text
         Use the method InputString() to insert text at cursor position. The char codes #13 will create a new
         paragraph, #12 a new page. To create a table use TableAdd (). Also see the chapter Set Attributes In
         Code.

7.2.6    Mail Merge (replace fields with data)
         This is done by once procedure, MergeText and the event OnMailMergeGetText. If you have a text
         with fields marked with special characters (<name>) use method ReplaceTokens. Otherwise crate
         fields with method InputMergeField . Note, that mail merge fields are embedded into two instances of
         the TWPTextObj class. This FAQ shows how to work with images. Note: If you need to print (or
         export to PDF) the text right after the merge process you need to call ReformatAll(false, true)!

7.2.7    Input TextObjects (i.e. page numbers)
         This objects can be create with InputTextField(type) and InputTextFieldName(name). All text objects
         can show custom text which is define by event OnTextObjectGetTextEx. Custom text objects will
         usually display the text assigned to their property Params.

7.2.8    Create an own toolbar
         If you decide to not use the toolbar we provide please open unit WPCtrRich.PAS and check out
         method OnToolBarIconSelection. This method is executed for all toolbar button clicks and WPTools
         actions. You can see how things are done. You can also call this method from "outside".

7.2.9    Save and load HTML
         HTML is autotected when using the LoadFromFile or LoadFromStream methods. Images must be
         directly linked to local files. Otherwise the image must be loaded in the event OnRequestHTTPImage
         . (This event is also execoted for images in RTF files which have not been embedded but just linked.)
         Also see this FAQ and the info about format strings.




© 2004-2008 WPCubed GmbH - Munich, Germany
20     WPTools Version 6


7.2.10 Get and set the text "as string"
        Use the property AsString - you can use SelectionAsString to read only the selected text. You can
        also assign text - the property SelectionAsString will insert the text at the cursor position. The
        function AsANSIString will work like property AsString but you can specify the format string,
        optionally only save the selection. Also see the load & save category.


7.3     Data Structures
        Here is a general description of the architecture and concept of the RTF engine, for your reference.

          Please read this carefully! This knowledge is necessary for you to understand WPTools
                                                 Version 6.

         Note: the separation between edit/display and data-objects make some elegant solutions
            possible - ie. create MDI editor without using MDI windows! (See demo DynAssign )

        Since not all details are listed here, please look for further information on the classes written in bold
        in the online help (reference).

        In the WPTools RTF-Engine (we always refer to the 'RTF-Engine', however this does not mean that
        the engine is limited to the Rich-Text, *.RTF), a text is split up into several parts. The main parts are
        stored in two objects which are linked together:

        a) RTF Data is stored in the TWPRTFDataCollection(see: Multiple Editors for the Same Text)
        b) RTF properties, such as paragraph or number styles, are stored in the TWPRTFProps object.
        (see: Share Styles between TWPRichText)




                                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       21




            Note: This concept allows multiple TWPRTFDataCollection objects to share the same
            TWPRTFProps object. Thus, they share the same attribute identifier (such as index values for
            colors). If you use this feature you can simply copy texts parts between RTFData objects or
            compare text.

         The TWPRTFDataCollectionalso hosts the text cursor (TWPRTFDataCursor) and a few
         parameters which are shared by the RTF editors (TWPRTFDataCollectionEngineParams). This
         means that even if you have several editors using one TWPRTFDataCollection there is only one
         cursor which is the same for all editors attached. The cursor object also controls text selection and
         changing properties of the selected text (SelectedTextAttr : TWPSelectedTextAttrInterface or the)




© 2004-2008 WPCubed GmbH - Munich, Germany
22    WPTools Version 6


     current writing mode (CurrentCharAttr : TWPCursorCharAttrInterface). It also contains the CPAttr (
     TWPTAttrEmulator) interface which changes the attribute at the cursor position. (Please see last
     inheritance chart and "Character Attributes" below)

     The TWPRTFDataCollection is home to the TWPRTFDataBlock collection items. Such an item
     contains the text which is displayed. The text body and the header or footer texts are all different
     collection items. When a new text is loaded, it is first loaded into a new TWPRtfDataBlock and, if
     everything is all right, then inserted into the body. The editor can display any of the RTFDataBlocks,
     or even display several at once.

     The TWPRTFDataBlock contains the text within a nested list of TParagraph objects. The
     TParagraphobjects are linked using the references NextPar/PrevPar and for nested dependencies,
     ChildPar/ParentPar references.

     Note: WPTools 4 only supported linking in one level using next/prev pointers. The new TParagraph
     object contains functions to emulate these pointers. Using this function it is still very easy to create
     a loop which checks all paragraphs in a text. The first paragraph is referenced by the property
     FirstPar.

     The TParagraph class inherits the complete functionality of the TWPTextStyle class which contains
     the code to maintain attributes and tab stops. The TWPTextStyle class is also used by other
     classes which need this functionality.




     How does TParagraph store the text?

     The text is separated into characters, character attributes and objects. Each of these elements is
     stored in its own dynamic array. For the characters an array of WideChar is used, the character
     attributes are stored in an array of cardinal (double word) values. When objects are used, you can
     read the TWPTextObject for a certain position in the paragraph using the array ObjectRef. The count
     of elements is stored in the variable CharCount.

     Note:
     The TParagraph class has several functions to insert and delete text and objects.

     In the instance that it is part of a table, TParagraph also has functions to find other parts of the same
     table (rows, cells or the parent table object). The memory architecture of a table is very similar to the
     system used by HTML:




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     23




         (All rows of a table and all cells of one row are connected using NextPar/PrevPar, the levels are
         created using ChildPar/ParentPar.)

         There are also useful properties which provide reference to the parent row or the parent table of a
         cell, or, for cells which are in a nested table (= table in a table cell), to get the first level
         ("ParentParent") row or table.

         To copy the first row of a table after the current row you can use this simple code:
             current_row.NextPar := current_table.RowFirst.Duplicate(true, true);

         In this code the first row is duplicated and inserted into the chain of rows by assigning it to the
         NextPar property. Duplicate() needs two parameters, the first enables the copying of the text
         (othwise only the properties are copied) the second enables the copying of the children, in case of a
         table row this are the cells.

         Paragraph Attributes:

         WPTools Version 6 supports many different paragraph, table and border attributes. These attributes
         are identified by a code, the WPAT_code. (The constants all start with WPAT_). It is important to
         remember that not all property ids make sense in all TParagraph objects, for example a table row
         cannot use the column width property. Some properties override each other (WPAT_ColWidth
         override WPAT_ColWidth_PC) and some are reserved for future versions. To read a, attribute you
         can use the method TParagraph.AGet( code, value ). 'Value' is passed as var parameter (by
         reference) and is only modified if that property was defined by this TParagraph or TWPTextStyle. In
         case the property was defined the function AGet returns true, otherwise false. Alternatively you can
         use the function AGetDef( code, default_value ). Here the value of the property is returned if defined,
         otherwise the provided default value. There are more 'A' methods, to delete a property (ADel), to read
         the properties of the paragraph or the style it uses (AGetInherited), to read and set a color value
         (AGetColor, ASetColor). Please see the TParagraph reference in the HLP file.

         Important: The method TWPTextStyle.AGet(WPAT_code : Integer; var Value : Integer) is a
         functions which returns a boolean value. The return code is false if the property with the id
         WPAT_code was not defined. In this case the variable "Value" will not be modified! Please make
         sure you initialized the variable Value!

         Tabstops:
         Tabstops are not stored as WPAT_ properties. They are accessed through several methods, such
         as TabstopAdd, TabstopMove or TabstopGet. (See reference)

         Character Attributes:

         As stated character attributes are stored in just one double byte value. You may ask, 'How can this
         work?' Particularly since WPTools Version 6 supports 15 different character attributes with multiple
         settings possible for each of these.

         WPTools Version 6 does not save the attributes directly in this CharAttr value. It only saves an
         index there. This is then used to retrieve the actual attributes from a global attribute cache.




© 2004-2008 WPCubed GmbH - Munich, Germany
24     WPTools Version 6


     We find this concept ideal - other text editors use start/end tags to store character attributes, others
     even split up the text into elements which are using the same combination of attribute styles. In both
     cases it is extremely difficult to 'apply' a certain attribute to text. Our concept makes it possible to
     simply set a number value and the style is changed.
     If styles have to be updated, the interface classes, such as TWPAbstractCharAttrInterface, make
     it easy to create and use the index values.

     WPRichText1.AttrHelper.Clear;
     WPRichText1.AttrHelper.SetFontName(
                                      'Courier New') ;
     WPRichText1.AttrHelper.SetColor(clGreen);
     WPRichText1.ActiveParagraph.SetText(
           'Some green text',
           WPRichText1.AttrHelper.CharAttr);
     WPRichText1.DelayedReformat;

     Explanation: AttrHelper is an obj ect of class TWPStoredCharAttrInterface. It calculates "CharAttr" index
     values. 'Clear' will delete all attributes - the CharAttr index will be 0. SetFontName and SetColor are used to
     define new character attribute. Reading the property CharAttr (inside the call to the TParagraph method
     SetText) will create a new CharAttr index which is used for the text. The calculated CharAttr can be used at
     different places for text which should look the same. It will become invalid when the document is cleared
     by TWPRichText.Clear. Read more...

     Inheritance Charts:

     TWPRichText, the RTF memo and TWPRTFEnginePaint, the RTF Engine (used by the
     TWPRichText as object 'Memo', the TWPRichTextLabel inherits from it)




     Please note that we now use format strings to pass properties to the reader and writer classes.
     Example: WPRichText1.AsANSIString('RTF-onlybody') creates a string in RTF format which
     contains only the body text.




                                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide        25




         To update TParagraph and TWPTextStyle objects you will have to use the "A" methods (ASet,
         AGet) - the interface classes are only used to either change the current writing mode or the
         attributes of multiple paragraphs and characters (such as selected text).




         All classes which change the attribute of certain elements inherit from
         TWPAbstractCharAttrInterface. In cases where it makes sense the classes are also able to change
         paragraph attributes as well. The only exception is TWPAttrEmulator, which does not work like the
         other interfaces since it is mainly used to offer compatibility to the WPRichText.CPAttr pointer in
         WPTools 4.


7.4      WYSIWYG

         The word WYSIYWG abbreviates What You See Is What You Get - which means that the printed
         output of an application which supports WYSIWYG will match the screen output it displayed before.
         WPTools Version 6 will always work in WYSIWYG mode, this means the printed output will
         always match the output you saw in the editor. Making this work is actually a quite complicated
         task and the editing engine has to be well prepared for it. The concept of WPTools5 was created
         from ground up to allow several WYSIWG modes:

         a) Default: render for best screen and best printing quality
         b) Render for optimal printing quality
         c) Render for optimal screen quality - print quality can be low




© 2004-2008 WPCubed GmbH - Munich, Germany
26    WPTools Version 6


     Usually you do not have to change anything - but we recommend to add a switch to the application
     to activate mode (b) - simply execute TWPRichText1.Memo.RTFData.UpdateReformatMode(true)             .
     Now the RTF-Engine will use the current printer to measure the fonts. For special printer fonts this
     can make a big difference for the output quality.

     To work with mode (c) you can simply set the flag wpfAlwaysFormatWithScreenRes in the property
     FormatOptions of the TWPRichText.

     If you know that there is no printer available for the application, you can set the global boolean
     WPNoPrinterInstalled to true. This property is automatically initialized by using the windows
     EnumPrinters() API.

     Please note that the property WordWrap disables WYSIWYG. If this property is set to TRUE this
     means that the text is formatted to the width of the editor, not the paper size defined in the property
     Header or the section. When WordWrap is set to false, word wrapping is still performed, but not
     using the width of the editor but the defined page size. You can, of course, set WordWrap to false
     and still modify the page size dynamically (Header.PageWidth according to the size of the editor. In
     this case WYSIWYG printing is possible, but you probably need to set the flag PrintParameter.
     PrintOptions := [wpDoNotChangePrinterDefaults] - otherwise the printer will select a custom paper
     size.

     Upgrade note: There are no properties ScreenResMode and WYSIWYG in WPTools Version 6, they
     are not required anymore. Using the mode (a) mentioned above provides good print out quality
     without the need for a default printer - this solves the problems which used to occur in applications
     when not printer was available. If the current printer is changed the reformat of the text is not
     required.




     WPTools supports many different layout modes. It is possible to see the page with header and
     footers, several pages side by side, thumbnails, just the body text etc. Please read the chapter
     about LayoutModes.




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       27



7.5      Mail-merge and forms
         "Mail-merge" means the automatic update of data fields in any document.
         It can be used to do mass mailing or to create customizable database record views.

         Concept of mail-merge in WPTools:

         The text contains merge fields, on command "MergeText" the component locates all fields and
         triggers the event OnMailMergeGetText for each of it. This event is used to fill data into the field or
         read out the current contents. Please note, that this concept differs from the usual "search and
         replace" and is much more verstile and faster. With WPTools merge fields are not destroyed by the
         merge process, the field data can be exchanged as soon as it changes. So it is possible to scroll
         through a database with a merge letter being "attached". It is also possible to read out the contents
         of the merge field. So the document can be also used as data entry from. You can merge in
         standard ANSI text, formatted text and images. Formatted text may be encoded in HTML, RTF or
         the WPTOOLS format.
         Info: Mail merge templates can be converted to reporting templates which use the WPTools
         WPReporter addon.

         Three steps to create a working prototype of mail-merge in Your application:

         1) Add code to create a field (more...)

         procedure TForm1.Button1Click(Sender: TObject);
         begin
           WPRichText1.InputMergeField('NAME','Default-Name' ;
                                                           )
         end;

         2) Provide an event handler for the event OnMailMergGetText (more...)




         In the created handler please type some lines of code

         procedure TForm1.WPRichText1MailMergeGetText (Sender: TObject;
           const inspname: String; Contents: TWPMMInsertTextContents);
         begin
           i f inspname='NAME' then
               Contents.StringValue := 'Julian Ziersch'




© 2004-2008 WPCubed GmbH - Munich, Germany
28      WPTools Version 6


            else    Contents.StringValue := '<unknown>'
                                                      ;
          end;



          3) Launch mail merge with a different button (more...)

          procedure TForm1.Button2Click(Sender: TObject);
          begin
               WPRichText1.MergeText;
          end;



          Demo Projects

          Please check out the ThreadSave demo to learn how to use mail merge in a thread. There is also
          the demo project DemosTasksMailM4 which shows how to work with a database and merge
          multiple records.

7.5.1     Create Field
          InputMergeField - create a merge field
          InputEditField - create a form field
          ReplaceTokens - convert tokens into fields
          Low Level - create a field in a TParagraph object

7.5.1.1   InputMergeField
          To create a field use the procedure InputMergeField

          function InputMergeField(
                const FieldName: string;
                const DisplayText: string = ' ';
                Command: string = ' ';
                Format: Integer = 0;
                DisplayChar: Char = # 0 //<-- obsolete parameter!
                ): TWPTextObj;

          The parameters are:
              FieldName = the name of the field. Will be stored in TWPTextObj.Name
              DisplayText = the text which will be placed inside the field. Will be stored in TWPTextObj.
              Params. Can be modified in the editor.
              Command = any text which will be stored in TWPTextObj.Source
              Format = any integer which will be stored in TWPTextOnj.IParam
              DisplayChar should be not used anymore.

          The result of this function is a reference to the TWPTextObj which marks the start of the field.

          Please note, a merge field always consists of two object, a start and an end object. Only the start
          object contains the properties of the field.

          WPTextObj instances can be deleted and restored at any time by the editor. It is not recommended
          to save the references in a list. To fill a list with reference to field objects you can use the procedure
          FieldGetList at any time. You can also use the 'Code' API with field objects - for example the
          procedure CodeListTags. (See reference, HLP)




                                                                       © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       29


7.5.1.2   InputEditField
          WPTools Version 6 also supports 'form fields'. They work like merge fields but if you use a special
          mode in property ProtectedProp the complete text can be protected, only the text inside this form
          fields can be edited.

          To create such a fields use the Method InputEditField.

          More about forms ...

7.5.1.3   ReplaceTokens
          ReplaceTokens(const opening, closing: string; FieldPreText: string = ''): Integer;

          This method (and its sister ReplaceTokensInAllTexts) updates the text and converts
          tokens such as <NAME> into the respective field. The start and end character
          sequence is variable, you have to pass it to the function: ReplaceTokens('< '>
                                                                                      ', ');

          The third param eter is the text which will be used to create the field nam You can
                                                                                     e.
          use it to create fields such as "CUSTOMER. NAME" by using 'CUSTOMER.' as param   eter
          FieldPreText.

          ReplaceTokensInAllTexts does not only work in the current text but in all, header and
          footer texts.

          Both function return the count of replacements.

          Tip: WPTools 6 with the WPReporter addon also supports "Token to Template
          Conversion".

          If you use the token to tem plate conversion you can edit the mail-merge/reporting
          tem plate with an editor such as MS Word.

          The tem plate is loaded into TWPRichText. In this control the template can be further
          edited with the additional convenience of syntax highlighting and on dem  and
          converted into a "true" reporting template. In case no bands are used, this technique
          can be also used to create m mail erge tem plates. (WPTools' Reporting is backward
          com patible to m m
                           ail erge)

          Example:




© 2004-2008 WPCubed GmbH - Munich, Germany
30     WPTools Version 6




7.5.1.4   Low Level
          If you work with TParagraph references You maybe want to create fields using low
          level routines.

          There are two possibilities.

          a) Use TParagraph.AppendNewObject

          var starto, endo : TWPTextObj;
              par : TParagraph;
          begin
            par := WPRichText1.ActiveParagraph;

            starto := par.AppendNewObject(wpobjMergeField, true, false); // Start Object
            par.Append('Julian Ziersch'); // Displayed Text
            endo := par.AppendNewObject(wpobjMergeField, true, true); // End Object
            // Link both objects together
            endo.SetTag(starto.NewTag);
            // Set Name of field
            starto.Name := 'DB_NAME';

            // Reformat and display
            WPRichText1.ReformatAll(false, true);
          end;

          b) Use TParagraph.AppendNewObjectPair

          var fieldo : TWPTextObj;
              par : TParagraph;
          begin
            par := WPRichText1.ActiveParagraph;

            fieldo := par.AppendNewObjectPair(wpobjMergeField, 'Julian Ziersch') ;
            fieldo.Name := 'DB_NAME';
            // Reformat and display
            WPRichText1.ReformatAll(false, true);
          end;




                                                          © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       31


         Using method (a) You can initialize the field with formatted text by subsequently adding text and
         changing the current writing mode between the text parts.


7.5.2    Customize Field Display
         The merge fields always use a start and an end marker. The markers use internally the TWPTextObj
         class. The start marker stores the name of the field in the 'name' property. The ObjType property of
         both, the start and the end marker is both set to wpobjMergeField.

         By default this objects are displayed like in this image:




         The display of the markers is optional. Please set the property WPRichText.InsertPointTextAttr.
         Hidden = true to hide the field markers. WPRichText.InsertPointTextAttr.Hidden should be set to
         true when the document is printed. To permanently delete the fields (and keep the text) use the
         procedure.DeleteFields.

         This method will toggle display depending on the state of a check box:

         procedure TForm1.ShowFieldsClick(Sender: TObject);
         begin
           i f ShowFields.Checked then
           begin
               wprichtext1.InsertPointAttr.hidden:=false;
               wprichtext1.automatictextattr.BackgroundColor := clYellow;
               wprichtext1.automatictextattr.UseBackgroundColor := TRUE;
           end else
           begin
               wprichtext1.InsertPointAttr.hidden:=true;
               wprichtext1.automatictextattr.UseBackgroundColor := FALSE;
           end;
           wprichtext1.ReformatAll(false, true);
         end;

         It is also possible to show a different text in a different color.

         The text is defined by the public (not published) properties CodeOpeningText and CodeClosingText.
         The variables %N, %S, %Y and %P can be used. The color can be changed with property
         CodeTextColor.

           WPRichText1.InsertPointAttr.CodeOpeningText := ' [% N= ';
           // % N inserts the TWPTextObj.Name property
           // %S inserts the TWPTextObj.Source property
           // %Y inserts the TWPTextObj.StyleName property - only useful for span styles
           // %P inserts the TWPTextObj.Params property
           WPRichText1.InsertPointAttr.CodeClosingText := ']';
           WPRichText1.InsertPointAttr.CodeTextColor := clBlue;

         This is how the field is displayed now:




© 2004-2008 WPCubed GmbH - Munich, Germany
32      WPTools Version 6




          Display Fieldnames only:

          WPTools 6 also allows to hide the embedded text and the fieldmarker and display just a small box
          with the field marker:




          This mode is controlled by property ShowMergeFieldNames The value TRUE will show the boxes
                                                                         .
          while the value FALSE will enabled the default display (with the field markers visible or not).




7.5.3     Update Field (Insert Text from Database)
          The mail merge process activates some or all all fields one after the other and calls an event to let
          the code fill in text and images in each of it.

7.5.3.1   Start Merge process
          The mail merge is started by the method

           MergeText(const FieldName: string = ''; AllTexts: Boolean = FALSE).

          Both parameters are optional. If you need to merge only the text the cursor is located in (header,
          footer ..) use procedure MergeActiveText;

          Example:
          MergeText( ',true) - merge the fields in all areas, headers and footers
                   '

          MergeText('A*', true) - merge the fields whith names starting with "A" in all areas, headers and
          footers

          MergeText('A*', 'name', true) - merge the fields whith names starting with "A" and
          Source='name' in all areas, headers and footers

          Important:
          If you need to print (or export to PDF) the text right after the merge process you need to call
          ReformatAll(false, true)!

          If you need to merge the fields only in a header or footer text use the MailMerge procedure of any
          TWPRTFDataBlock.You will have to pass the OnMailMergeGetText procedure described below as




                                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       33


          callback.

          Example   :
          Merge fields only in all header texts:

          for i:=0 t o WPRichText1.HeaderFooter.Count-1 d o
          i f (WPRichText1.HeaderFooter[i].Kind=wpIsHeader and
                                                           )      // only header
              not (WPRichText1.HeaderFooter[i].IsEmpty) then      // and not empty
              WPRichText1.HeaderFooter[i].MergeText(
              WPRichText1,                     // object used as 'Sender', can be also
          datasource ...
              WPRichText1MailMergeGetText,     // event handler (see below)
              false,                           // readonly, we want to modify
              '', nil, nil );                  // optional to restrict merge range


7.5.3.2   Event OnMailMergeGetText
          This event is used to modify a field. It can also be used to enumerate fields and also to reads the
          properties of the field or the embedded text.

          The event OnMailMergeGetText receives the following parameters:
          Sender: TObject - this is a reference to the parent editor
          const inspname: String - the name of the field
          Contents: TWPMMInsertTextContents - this is the most important parameter. It provides You with
          an interface to evaluate and manipulate the field and the embedded text.

          In the easiest case You can use one line of code to assign text to a field:

              procedure TForm1.DoMailMergGetTexte(
                 Sender: TObject; const inspname: string;
                 Contents: TWPMMInsertTextContents);
              begin
                Contents.StringValue := DataSet.FieldByName(inspname).AsString;
              end;

          This code will read the contents of a given field and use it as the embedded text of a field. If the field
          contains HTML or RTF formatted text the text will be inserted as formatted text.

          If you need to modify the character attributes (such as font name, font style and color) of the field
          inside this event, please use the interface MergeAttr.

              Attention: Do NOT call ReformatAll,
                         do not move the cursor position,
                         do not change InsertPointTextAttr.Hidden inside this event!

          Example: Display a checkbox:

             Contents.MergeAttr.SetFontName
             if data=true then
                   Contents.StringValue := #254 // þ
             else Contents.StringValue := #168; // ¨

7.5.3.2.1 TWP nsertTextContents
             MMI

          The TWPMMInsertTextContents is used as a parameter 'Contents' in the event
          OnMailMergeGetText. You can replace a string by simply assign a string to StringValue.

          To Modify the attribute of the inserted text (i.e. the font name or style) change the




© 2004-2008 WPCubed GmbH - Munich, Germany
34       WPTools Version 6


                 property 'MergeAttr'.

            You can modify the paragraph the start of the field is located. This paragraph is accessible through
            MergePar.

            Upgrade Note: The parameter 'c' is not supported anymore.

            But please note that you can use the common programming interface to insert text and objects.

            Note: When the event is called the the whole field is selected.

7.5.3.2.1.1 procedure Clear

            Clears the contents of this object.

7.5.3.2.1.2 procedure Abort

            Notifies the merge routine to abort the process.

7.5.3.2.1.3 procedure LoadTextFromStream(s: TStream)

            Load text from a stream.

7.5.3.2.1.4 procedure LoadTextFromFile(const FileName: string)

            Load text from a file.

7.5.3.2.1.5 function LoadImageFromFile(const FileName: string; w : Integer = 0; h: Integer = 0): Boolean;

            Load an image into this field. This methods have been added to WPTools 6.

            If You specify the width and height (twips values) the image will be scaled, keeping the original
            aspect ratio.

            You can pass negative values for w and h to preserve the width and height of the image currently
            embedded in the field.

            If currently no image is in the field, w and h will be used as absolute values.

              if inspname='IMAGE_A' then
              begin
               Contents.LoadImageFromFile('c:a.jpg', -1440, -1440);
              end;


            Also available is
            function LoadImageFromStream(const ImageData: TStream; FileExt: string; w: Integer = 0;
            h: Integer = 0): Boolean;

            It expects the data in a stream object and the file extension which defines the contents of the
            stream. For example ".JPG" if it is JPEG data.

7.5.3.2.1.6 property DataCollection: TWPRTFDataCollection

            This is the current RTFDataCollection




                                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       35


7.5.3.2.1.7 property DataBlock: TWPRTFDataBlock

           The is the DataBlock which hosts the current paragraph

7.5.3.2.1.8 property MergeAttr: TWPStoredCharAttrInterface

           This interface allows it to modify the attributes of the text which is about to be inserted.

           You can use the methods of the AttributeInterfaces.

           Example:
           Contents.MergeAttr.SetColor(clRed);

           The object 'MergeAttr' is initialized with the character properties of the start object of the mailmerge
           field. If you want to use the first character of the merged text (this is the visible field name or the field
           data) You can use this code in the the OnMailMergeGetText event:

              Contents.MergeAttr.CharAttr :=
                  Contents.MergePar.CharAttr[
                     Contents.MergeParPos+1] ;

           This code assigns the character attribute of the character which follows the the mergefield start code
           (= the merge text).

           You can, for example, change the font name:
           Contents.MergeAttr.SetFontName(...);

           This can be very useful if you need to display checkboxes in the fields. In this case simply
           assigne the desired wingdings characters code to StringValue.

           Contents.MergeAttr.SetFontName
           i f data=true then
                    Contents.StringValue := #254 // þ
           else Contents.StringValue := #168; // ¨




7.5.3.2.1.9 property MergePar: TParagraph

           MergePar is the paragraph the merged field starts within. MergeParPos is its position.

7.5.3.2.1.10 property MergeParPos: Integer

           MergePar is the paragraph the merged field starts within. MergeParPos is its position.

7.5.3.2.1.11 property Obj: TObject

           If an object of type TWPObject is assigned to this value, the new object is inserted into the text.
           This can be used to merge images. (Example... More easy to use is LoadImageFromFile and
                                                           )
           LoadImageFromStream ..

7.5.3.2.1.12 property CodePage: Integer

           This CodePage, if <> 0, the value will be used to convert the string value to the internal
           representation.




© 2004-2008 WPCubed GmbH - Munich, Germany
36       WPTools Version 6


7.5.3.2.1.13 property StringValue: AnsiString

           This is the result string as ANSI string. You can use the property CodePage to specify which code
           page should be used to convert it to the intern UNICODE representation. Please also see
           WideStringValue.

           You can also assign formatted text in RTF, HTML or WPTOOLS format to StringValue.

           If you merge in RTF text and the inserted text starts with a table you will see an empty line. This
           "empty" line is used to store the field marker which is not automatically deleted by the merge
           process. If it is not required to repeat the merge process or to read out modified text you can let the
           Merge procedure delete the field marker. Simply set the flag mmDeleteThisFieldin the property
           Contents.Options. This flag can be also very useful if the merged text contains field markers on its
           own which have to be processed in a second run!

7.5.3.2.1.14 property WideStringValue: WideString

           This is the result string as unicode string. If you need to insert formatted text (RTF, HTML) please
           use StringValue.

7.5.3.2.1.15 property OldText: string

           This is the current text inside the field.

7.5.3.2.1.16 property OldFormattedText: string

           This is the current text inside the field including formatting tags.

7.5.3.2.1.17 property OldIsPlain: Boolean

           This value is true if the "OldText" does not use different character attributes.


7.5.3.2.1.18 property CurrentObject: TWPObject

           This is a reference to the object currently INSIDE the field. It can be used to update a graphic
           container.

7.5.3.2.1.19 property CurrentTxtObject: TWPTextObj

           This is a reference to the object currently INSIDE the field. It can be used to update a graphic
           container.

7.5.3.2.1.20 property Options: TWPMailMergeContinueOptions

           This SET contains flags which change the way the data is inserted and how the method proceeds.


              mmStopNow, aborts the merge process
              mmMergeTrim, // WPTools 6: removes leading and trailing spaces from the replacement string.
           (Not used for formatted text)
              mmUseFirstLoadedParProps, // When loading RTF or HTML we also assign the paragraph props
           of the first loaded paragraph (WPT6: Use /setattr in Extras)
              mmUseFirstLoadedParPropsAuto, // use mmUseFirstLoadedParProps if the field is the first NON
           SPACE sign in the paragraph
              mmUseFirst_AlsoBorders, // refines "mmUseFirstLoadedParProps" to copy also the border and
           padding properties
              mmIgnoreNewParAttr, // If we are loaded in RTF or HTML string then paragraph attributes are




                                                                         © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       37


           preserved (WPT6: Use /keepattr in Extras)
              mmIgnoreNewCharAttr, // If we are loaded in RTF or HTML string then character attributes are
           preserved
              mmIgnoreLoadedFonts, // When loading RTF ignore the Fonts
              mmIgnoreLoadedFontSize, // When loading RTF ignore the Font sizes
              mmIgnoreLoadedFontStyles, // When loading RTF ignore bold/italic and underline
              mmMergeAsRTF,
              mmMergeAsHTML,
              mmMergeAsWPTOOLS,
              mmSkipSpacesBehind, // not used yet
              mmInsertObject,
              mmDeleteEmptyParagraph, // not used yet
              mmDeleteUntilFieldEnd, // not used yet
              mmDeleteThisField, //Delete the field markers! (WPT6: Use /remove in Extras)
              mmDontUseLoadedParTabs, // When loading RTF optionally IGNORE the tabs
              mmDontUseLoadedParStyle // When loading ignore the style

              , mmMergeTrimSpaces //WPTools 6: remove double spaces between words, can be combined
           with mmMergeTrim (Not used for formatted text)


7.5.3.2.1.21 property Name: string

           This is the field name.

7.5.3.2.1.22 property FieldnamePart: string

           This is the part of the string NAME after the character '.', converted to uppercase characters. If there
           is no '.', 'Name' will be returned.

7.5.3.2.1.23 property DatasetnamePart: string

           This is the part of the string 'NAME' before the character '.', converted to uppercase characters. If
           there is no '.' DatasetnamePart will be empty.

7.5.3.2.1.24 property Command: string

           This is the command - it is placed in the "Source" property of the field object.

7.5.3.2.1.25 property StartInspObject: TWPTextObj

           The reference to the starting merge field object.

7.5.3.2.1.26 property EndInspObject: TWPTextObj

           The reference to the closing merge field object.

7.5.3.2.1.27 property DisplayName: string

           Reserved

7.5.3.2.1.28 property Format: Integer

           Reserved




© 2004-2008 WPCubed GmbH - Munich, Germany
38       WPTools Version 6


7.5.3.2.1.29 property Modified: Boolean

            This value is true if a value has been assigned to StringValue or Obj.

7.5.3.2.1.30 property Hyperlink: string

            If this property is not empty, a hyperlink with this URL and the name "HyperlinkName" will be
            created.

7.5.3.2.1.31 property HyperlinkName: string

            The name of the hyperlink with the URL "Hyperlink".

7.5.3.2.1.32 property IsNull: TWPMMInsertTextContentsNull

            This property is only used for reporting in WPTools 6.

            This new property can be used to provide the WPReporter engine with additional information about a
            field. This is esspecially useful when a field is used for a condition. The standard value is
            wpFieldDefault - here the contents will be evaluated using the StringValue and Modified properties.

               wpFieldDefault, // Preset when reading field data
               wpFieldIsUnknown, // Preset when conditions are checked (?...=...)
               wpFieldIsNull, // If this is set any value will be ignored!
               wpFieldIsZero, // Should be set if an integer or float value = 0
               wpFieldIsDefined // Should be set if field is defined

7.5.3.2.1.33 property ReplaceMode: TWPMMInsertTextContentsReplaceMode

            wpconNoChange,
            wpconStringValue,
            wpconWideStringValue,
            wpconObject,
            wpconStream

7.5.3.3     FieldLocate: Modify Field Name or Contents
            The powerful function named FieldLocate can be used as alternative to the MergeText/
            OnMailMergeGetText double. It is used to locate certain fields.

            This code will enumerate a certain group of fields and update their contents.

                obj := nil;
                FromStart := TRUE;
                repeat
                   obj := WPRichText1.FieldLocate('A*B', ' ',
                              FromStart,
                            [wplocGlobalSearch,wplocDontMoveCursor]);
                   i f obj<>nil then
                      obj.Embeddedtext := 'Test';
                   FromStart := FALSE;
                until obj = nil;

            An alternative method to enumerate the fields is the function FieldGetList. It will fill a list (an
            instance of the TWPTextObjList class) with references of fields. This list can be used to change the
            names of the fields and also to read or change the contents (EmbeddedText).

            The property FieldAtCP can be used to retrieve a reference to the active field at the current cursor
            position. Please use this function with care since the backward search for the open object can be




                                                                        © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       39


          slow, esspecially if no field can be found. CPObj is faster, it returns any TWPTextObj directly at the
          current cursor position (= at the current text insertion point - do not confuse with mouse-cursor).

7.5.3.4   Use TWPMMDataProvider
          This component can be used to automatically attach a mail merge template to a data set. The
          property NextDataProvider can be used to build a chain of data provider.

          The event OnGetDataSet can be used to locate the correct dataset for a given field. (i.e. evaluate
          Contents.DataSetNamePart)

          Fieldsnames which are listed in the list BMPFields are expected to be pictures, the fields in
          RTFFields are expected to contain formatting tags.

          If a field is of type TGraphicField, automatically the contained image will be inserted. Here the flag
          wpmmPreserveObjectSize can be used in property "Options" to load the image into the current
          container (if there is one).

          Info: The data merging is performed by

          procedure TWPMMDataProvider.DoMergeGetText(Sender: TObject;
           const fieldname: string;
           Contents: TWPMMInsertTextContents);

          found in unit wpdbrich.pas. We recommend to read it.



7.5.4     FastAppendText: Create text with multiple letters
          Sometimes you need to create a longer text which contains copies of the same template filled with
          different data.

          You can use a second TWPRichText object "AllRTFText" to receive the text of all the single letters.

          Then You can use code like this to loop through the complete database, merge each record and
          append the result to AllRTFText. The first time the text is copied using "AsString" to make sure the
          page format and the header and footers are copied too. Later records use FastAppendText.


7.5.4.1   Example: FastAppendText
          var i : Integer;

             Table1.DisableControls;
             try
             Table1.First;
             i := 0;
             AllRTFText.BeginUpdate;
             AllRTFText.Clear;
             while not Table1.EOF d o
             begin
                WPRichText1.MergeText;

                 i f i=0 then // FIRST RUN
                 begin
                     AllRTFText.AsString := WPRichText1.AsString;
                     AllRTFText.CPPosition := MaxInt; // to end
                 end
                 else i f i>0 then // SUBSEQUENT RUNS




© 2004-2008 WPCubed GmbH - Munich, Germany
40     WPTools Version 6


                begin
                   AllRTFText.FastAppendText(WPRichText1,true, [wpCreateNewPage );
                                                                              ]
                end;
                Application.ProcessMessages;
                Table1.Next;
                inc(i);
             end;
             finally
               AllRTFText.EndUpdate;
               AllRTFText.ReformatAll(true, true);
               Table1.EnableControls;
             end;


7.5.4.2   Create Sections with FastAppendText
          The above code simply copies the text to the destination. It will be one large text without sections.
          To create sections please add the marked lines in red. We use the section property
          wpsec_ResetOutlineNums to make sure each section uses its own outline numbering.

             var Section : TWPRTFSectionProps;

             try
             Table1.First;
          ...
                   // Need page break
                   Section := AllRTFText.FastAppendText(WPRichText1,true,
          [wpCreateNewPage]);
                   Section.Select := [wpsec_ResetOutlineNums, wpsec_ResetPageNumber];
                end;
          ...
             end;
             finally
          ...
             end;


7.5.4.3   Create Lists
          You can use the flag wpCombineTableIfPossibleto create a large table from a template which
          consists only of a single table with fields. If this flag is not used, for each run one table will be
          created in the destination editor.

          If the flag wpReuseLastPar was used, empty lines in the destination will be avoided.

          Both flags were added to WPTools 6.

7.5.4.4   Save created text
          To save the text use Dest.SaveToFile or Dest.SaveAs;

          When you save the resulting text you can use the following writer options in the format string to
          create better RTF code:
           -nonumberprops:        Write the numbers as text
           -nomergefields:        Do not save the fields, only the contents

7.5.5     Hide empty paragraphs

          After the mail merge procedure it is possible that some paragraphs are completely empty, except for
          the remaining fields and maybe space and tab chars.




                                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       41


         a) Using the function
           DeleteParWithEmptyFields
         this paragraphs can be deleted. This function internally uses the function DeleteParWithCondition.

         The function DeleteParWithCondition works only with paragraphs and tables in the first level (not
         nested tables). Tables rows which do only contain cells with can be deleted will be deleted as well. If
         all rows in a table have been deleted that table will be deleted, too.
         Inside a table cell all child paragraphs of that cell (if any) are individually checked. If those child
         paragraphs trigger the 'condition' to true, they will be deleted. If the main cell paragraph trigger the
         condition to true it will be cleared. The cell will only be deleted if all sibling cells have to be deleted,
         too. (the complete row)

         b) You can also temporarily hide paragraphs which do only contain empty fields and spaces.

         To do so use the event BeforeInitializeParwith this code:

           i f par.HasObjects(false,[wpobjMergeField]) and
               not par.IsNonSpace([wpobjMergeField]) then
                  include(par.prop, paprHidden)
           else exclude(par.prop, paprHidden);



         c) Delete leading or trailing spaces

            function DeleteLeadingSpace(EmptyFieldsToo: Boolean; InFirstPar : Boolean =
         TRUE): Boolean;
            function DeleteTrailingSpace(EmptyFieldsToo: Boolean): Boolean;

         Both functions will stop at the first table they find. They will delete the text (and optionally empty
         fields) from the start or from the end of the text.

7.5.6    Forms/Edit Fields

         WPTools can be also used to create forms. These are sepecial texts which are generally protected.
         The user may only edit the text in specially marked areas. We call this areas 'Edit Fields':




         Edit fields work like mail merge fields. The only difference is that the objects use the mode flag
         "wpobjWithinEditable". When saved to RTF a formfield instead of a field tag is written.



© 2004-2008 WPCubed GmbH - Munich, Germany
42    WPTools Version 6



     To create a field use procedure
       InputEditField(const FieldName: string;
            DisplayText: string = ' ';
            PlaceCaret: Boolean = FALSE;
            Command: string = ' '; // will be written to TWPTextObj.Source
            Format: Integer = 0 // will be written to TWPTextObj.IParam
       ): TWPTextObj;

     All procedures which work with mail merge fields will work for the edit fields, too. Like with mail
     merge fields the presentation of the start and end markers is controlled by the property
     InsertPointAttr. The text within the markers is controlled by AutomaticTextAttr.

     The editor for the example above had been set up with:

      DataEdit.ProtectedProp := [ppAllExceptForEditFields];
      DataEdit.EditOptionsEx := [wpTABMovesToNextEditField,wpRepaintOnFieldMove];
      DataEdit.InsertPointAttr.Hidden := FALSE;
      DataEdit.InsertPointAttr.CodeTextColor := $E0FFE0;
      DataEdit.InsertPointAttr.CodeOpeningText := '[';
      DataEdit.InsertPointAttr.CodeClosingText := ']';

     The most important property change is ProtectedProp := [ppAllExceptForEditFields]. This makes it
     impossible for the cursor to move anywhere else than within edit field tags.

     To make it possible to highlight the current field (yellow background) the property
     UseOnGetAttrColorEvent and the event OnGetAttributeColor has been used:

      DataEdit.AutomaticTextAttr.UseOnGetAttrColorEvent := TRUE;

      procedure TWPEdTest.DataEditGetAttributeColor(Sender: TObject;
       var CharStyle: TCharacterAttr; par: TParagraph; posinpar: Integer);
      var obj : TWPTextObj;
      begin
       obj := DataEdit.CodeInsideOf(par,posinpar,wpobjMergeField);
       i f obj = DataEdit.FieldAtCP then
       begin
           CharStyle.BackgroundColor := $A0FFFF;
           CharStyle.UseBackgroundColor := TRUE;
       end;
      end;

     Edit fields can be read out using procedure MailMerge and event OnMailMergeGetText:

     // Read the data which is currently displayed in the editor
     procedure TWPEdTest.ReadData;
     begin
        FReadingData := TRUE; // global boolean to change behaviour
        DataEdit.MergeText;
     end;

     // Write back the data
     procedure TWPEdTest.WriteData;
     begin
        FReadingData := FALSE;
        DataEdit.MergeText;
     end;

     // This reads and writes the data fro the database 'Table1'
     procedure TWPEdTest.DataEditMailMergeGetText(Sender: TObject;
       const inspname: String; Contents: TWPMMInsertTextContents);




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide          43


         begin
              i f FReadingData then
                     Table1.FieldByName(inspname).AsString := Contents.OldText
              else Contents.StringValue := Table1.FieldByName(inspname).AsString;
           end;
         end;

         This code can be used to move to a certain field. If the cusror is within a field with that name the
         next field will be located and selected.

         procedure TWPEdTest.MoveToField(fieldname : String) ;
         begin
            fieldname := SelectField2.Text;
            // If this is the current move on ...
            i f DataEdit.CurrentEditField=fieldname then
                  DataEdit.MoveToNextField(false);
            // Try from here
            i f DataEdit.MoveToField(fieldname,false) then
                DataEdit.SelectFieldAtCP(false, true)
            // or from start
            else i f DataEdit.MoveToField(fieldname,true) then
                DataEdit.SelectFieldAtCP(false, true);
            DataEdit.SetFocus;
         end;



7.5.7    Create ComboBox
         Now we show how to create a pick list for a merge field:




         We use a panel with a speed button to display the drop down button. This panel is moved to the
         correct location in the MouseMove event. A timer is used to hide this panel if it is not required
         anymore. The picklist itself is a listbox, also placed on the form. It would be better to display this list
         on a seperate form located over the mainform but we wanted to make this example as simple as
         possible.

         The name of the current field (for which the picklist is displayed) is stored in the string variable
         CurrField.

         The MouseMove event handler for the editor. It sets 'CurrField'

         procedure TWPEdTest.DataEditMouseMove(Sender: TObject; Shift: TShiftState;
           X, Y: Integer);




© 2004-2008 WPCubed GmbH - Munich, Germany
44    WPTools Version 6


     var fieldobj, fieldobjend : TWPTextObj;     px, py : Integer;
     begin
       fieldobjend := nil;
       fieldobj := DataEdit.CodeInsideOf(x, y, wpobjMergeField);
       i f (fieldobj <> nil) and ((CompareText(fieldobj.Name,'name') =0) o r
                                   (CompareText(fieldobj.Name,'company' =0)) then
                                                                       )
       begin
           fieldobjend := fieldobj.EndTag;
           i f fieldobjend<>nil then
           begin
               DataEdit.GetParXYBaselineScreen(fieldobjend.ParentPar, fieldobjend.
     ParentPosInPar, px, py ) ;
               PickPanel.Left := px - PickPanel.Width div 2;
               PickPanel.Top := DataEdit.Top + py - MulDiv(PickPanel.Height,4,5) ;
               CurrField := fieldobj.Name;
           end;
       end;
       i f fieldobjend=nil then
              HidePickPanelTimer.Enabled := TRUE // we hide it 500ms delayed
       else
       begin
           PickPanel.Visible := true;
           HidePickPanelTimer.Enabled := FALSE;
       end;
     end;

     The timer HidePickPanelTimer disables the button

     procedure TWPEdTest.HidePickPanelTimerTimer(Sender: TObject);
     begin
       HidePickPanelTimer.Enabled := FALSE;
       PickPanel.Visible := false;
     end;

     The OnExit event of the listbox (it is called when the listbox looses the focus)is used to hide the
     listbox when the user clicks on the editor:

     procedure TWPEdTest.PicklistExit(Sender: TObject);
     begin
       Picklist.Visible := FALSE;
     end;

     A click on the speedbutton display the listbox:

     procedure TWPEdTest.PickDropClick(Sender: TObject);
     begin
       Picklist.Left := PickPanel.Left + PickPanel.Width - Picklist.Width;

       i f CompareText(CurrField,'name') =0 then
             Picklist.Items.Assign(PicName.Lines)
       else i f CompareText(CurrField,'company' =0 then
                                                )
           Picklist.Items.Assign(PicCompany.Lines)
       else Picklist.Items.Clear;

       i f PickPanel.Top>EditTab.Height-100 then
       begin
          Picklist.Height := PickPanel.Top -2 0;
          i f Picklist.Height>150 then Picklist.Height := 150;
          Picklist.Top     := PickPanel.Top - Picklist.Height;
       end else
       begin
          Picklist.Top := PickPanel.Top + PickPanel.Height;
          Picklist.Height := EditTab.Height - Picklist.Top-2 0;




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Guide        45


              i f Picklist.Height>150 then Picklist.Height := 150;
           end;
           Picklist.Visible := TRUE;
           Picklist.SetFocus;
         end;

         Last but not least - a click in the listbox should update the current field. We use the function [b]
         CodeListTags[/b] to find all the field with a given name and simply update the property
         EmbeddedText     .

         procedure TWPEdTest.PicklistClick(Sender: TObject);
         var objlst : TWPTextObjList;
              i : Integer;
              s : string;
         begin
            i f Picklist.ItemIndex>=0 then
                  s := Picklist.Items[Picklist.ItemIndex]
            else exit;
            objlst := DataEdit.CodeListTags(wpobjMergeField,CurrField, true);
            try
               for i:=0 t o objlst.Count-1 d o
                 objlst[i].EmbeddedText := s;
            finally
               objlst.Free;
               DataEdit.ReformatAll(false, true);
            end;
            DataEdit.Setfocus; // also hides Picklist!
         end;

         You can download the complete example here
         http://www.wpcubed.com/ftp/ex/EditFieldDemo.zip



7.6      Tasks
7.6.1    Mini Editor

         With WPTools Version 6 you can create extremely compact editor applications which still do not
         miss any functionality the end user might expect - such as support for headers and footers,
         WYSIWYG, scaling, tables etc.

         When you need a really compact editor we suggest to create objects of the class
         TWPCustomRtfEdit (defined in unit WPCTRMemo) in code. This way you can also attach two
         editors to the same TWPRTFDataCollection to create an editor with split screen support.

         Our demo uses 4 variables defined inside the form interface:

           TWPMiniEd = class(TForm)
           ...
           public
             WPRichText1, WPRichText2 : TWPCustomRtfEdit;
             RTFData : TWPRTFDataCollection;
             RTFDataProps : TWPRTFProps;
           end;

         We also added a splitter, a graphic popup menu and a main menu. At runtime the demo looks like
         this screen shot:




© 2004-2008 WPCubed GmbH - Munich, Germany
46    WPTools Version 6




     The editor objects are created and connected in code inside of the OnCreate event of the form:

     procedure TWPMiniEd.FormCreate(Sender: TObject);
     begin
         RTFData := TWPRTFDataCollection.Create(TWPRTFDataBlock);
         RTFDataProps := TWPRTFProps.Create;
         RTFData.RTFProps := RTFDataProps;

         WPRichText1 := TWPCustomRtfEdit.Create(Self);
         WPRichText1.Parent := Self;
         WPRichText1.Align := alClient;
         WPRichText1.TabStop := FALSE;
         WPRichText1.AcceptFiles := TRUE;
         WPRichText1.Memo.SetRTFDataOrProps(RTFData,nil) ;

         WPRichText2 := TWPCustomRtfEdit.Create(Self);
         WPRichText2.Memo.SetRTFDataOrProps(RTFData,nil) ;
         WPRichText2.Parent := Self;
         WPRichText2.Align := alBottom;
         WPRichText2.Height := 100;
         Splitter1.Top := 0;

     We now assign the graphic popup menu. This menu is automatically used as contect menu for
     image objects.

         WPRichText1.GraphicPopupMenu := GraphicPopupMenu;
         WPRichText2.GraphicPopupMenu := GraphicPopupMenu;

     Now we add the text to the body. The HTML format makes it easy to add some formatting.

         WPRichText1.AsString := '<div align=left><font face="verdana" size=2>WPTools
     Demo</font></div>';

     We also want to show a header text with page numbering. We also use HTML with the WPTools
     addition tag <pagenr/>.

         WPRichText1.HeaderFooter.Get(wpIsHeader,
           wpraOnAllPages).RTFText.AsString :=
            '<div align=right><font face="verdana">www.WPTOOLS.de - Page <pagenr/></
     font></div><hr>';




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       47



                 WPRichText2.SetZoomMode(-2 0) ;
          end;

          At last we use the SetZoomMode procedure to select a certain layout and zoom mode. The
          SetZoomMode makes it easy to modify several properties of the editor all at once. Since it only
          requires one integer parameter it can be used in menus or actions which are using the 'Tag' property
          to store the parameter for SetZoomMode.


          Hint: The TWPCustomRtfEdit can also be used in a thread save context, for example to
          create documents using mailmerge in a thread save context. Please check out the demo "
          ThreadSave "




7.6.1.1   Save to HTML / Load from HTML
          WPTools will create a HTML file if you save to a file with extension HTML or HTM.
          To get the HTML code as a string use WPRichText1.AsANSIString('HTML');

          'HTML' is a "format string" - please read more about this option strings here.

          If your text containes embedded images you will need to save them to a file during the creation of
          the HTML code.

          This FAQ shows how to do it: http://wpcubed.com/forum/viewtopic.php?t=1167

          This FAQ shows how to load from HTML and include images: http://wpcubed.com/forum/viewtopic.
          php?t=1498

7.6.2     How to use the "Default Editor"
          Can you create a full blown word processing application in one minute?

          Yes, with WPTools Version 6 you can.

          A) The is the complete program code in Delphi:

          program UseDefEditor;

          uses
            Forms, WPDefEditor;

          {$R *.res}

          begin
            Application.Initialize;
            Application.CreateForm(TWPToolsEditor,WPToolsEditor);
            Application.Run;
          end.

          All you need is to use the included default editor, this is the editor which is also used by the IDE to
          edit the text which is contained in WPTools objects.
          It uses a form (defined in unit WPDefEditor) and a data module which contains the main menu and
          the actions. Of course, you can edit both files but you can modify them at runtime.



© 2004-2008 WPCubed GmbH - Munich, Germany
48    WPTools Version 6


     The data module with the actions will be also a great help if you need to create an editor inplace, not
     using the provided default editor form!

     Please copy both units and accompanied DFM files to a save place if you intend to modify
     them. Otherwise they will be replaced by the WPTools setup.




     B) Even easier to use is the component TWPDefaultActions. Place this component on your form -
     also create a toolbar (using the TWPToolPanel - you can use Copy&Paste from unit wpDefEditor),
     and add a TWPRuler. Now you only have to create a link to the TWPRichText in the
     ControlledMemos collection of the TWPDefaultActions component.
     Using the OnInit event of the TWPDefaultActions component you can modify the menu.
     Please see the HLP file (=reference) for more information.

     You can also use the default editor within a MDI project:

     // This event for auto free !
     procedure TWPMdiDemo.WPDefEditorFormClose(Sender: TObject; var Action: TCloseAction);
     begin
        Action := caFree;
     end;

     // Create a new wptools default editor as MDI child




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       49


         procedure TWPMdiDemo.NewEditorClick(Sender: TObject);
         var
           lForm : TWPToolsEditor;
         begin
           WPIsMDIApp := true; // Make the Toolbar MDI compatible
           lForm := TWPToolsEditor.Create(nil) ;
           lForm.FormStyle := fsMDIChild;
           lForm.OnClose := WPDefEditorFormClose;
         end;




7.6.3    Toolbar and Action Classes
         WPTools contains a complete set of component to quickly build a user interface.
         You can use the ready-to-use TWPToolbar to create an editor within 5 seconds, or you can use the
         action classes and your own choice of tool buttons to let the user change the attributes of the text.

         a) Toolbar Components

         The tool-bar components (TWPToolBar and TWPToolPanel) can be attached to any TWPRichText
         component using its property WPToolBar. If you have more than one use the propety WPToolBar.
         NextToolBar to connect to the next toolbar in the chain. When the TWPToolBar is used on a MDI
         child window you need to set the global variable WPIsMDIApp := true;



                 TWPToolBar

         This components makes it easy to start a new program which uses a TWPRichText component.
         You only have to activate some flags in the object inspector and the TWPToolBar will display action
         and status buttons and some combo boxes to select the font or color of the text in the
         TWPRichText control.
                 TWPToolPanel

         Contrary to the toolbar, which creates and positions the buttons automatically, with the tool-panel
         component you have to drop the buttons in place. This gives you more freedom in the design of the
         user interface.
                 TWPComboBox

         This components can be used together with a TWPToolPanel or TWPToolCtrl. It can control the font,
         font size or colors of the text - to select the mode use the property ComboBoxStyle.
                 TWPToolButton

         This components can be used together with a TWPToolPanel. It can control the fonts styles or
         execute certain actions like 'Print', 'Load' or 'Save'. If you use the TWPToolBar you don't need the
         TWPComboBox or TWPToolButton control since the buttons and combo boxes are created by the
         TWPToolBar object.

         b) Work with Actions


                 TActionList

         Actions objects are uses to connect menu items and buttons to a certain procedure of the
         TWPRichText editor.



© 2004-2008 WPCubed GmbH - Munich, Germany
50    WPTools Version 6



     The TActionList which contains the action objects must be specified in the ActionList property of the
     TWPRichText component.

     To add an action to a ActionList please open its editor (double click) and select 'new standard
     action'

     Tip: In case you find out that certain hot keys do not work please check the short cuts
     defined in action lists or menus. It is possible that a shortcut is consumed somewhere else.

     Assigning an action to a menu item always overrides the image index of this element. So please
     specify the image index values in the actions and not in the menu items. The image list must be
     assigned to both, the action list and the toolbar!

     Please also see "Use WPTools with TBX" (TBX / DevExpressBars)

     Work with TWPComboBox

     The TWPToolCtrl component is not included in WPTools Version 6. If you want to use the
     TWPComboBox control which can display a list of fonts, colors or styles, You need to create a links
     using the TWPToolsCustomEditContolAction action class.

     This action class is created in the ActionList and its property AttachedControl is set to the
     TWPComboBox instance you need to attach. The property AttachedControlStyle to select the
     functionality is not used for TWPComboBox - they have their own property ComboboxStyle for the
     same purpose.

     Create shortcuts, such as Ctrl+I to activate/deactivate ITALIC:

     To do this You can use the event OnKeyPress.

     procedure TForm1.WPRichText1KeyPress(Sender: TObject;
       var Key: Char);
       procedure ToggleStyle(sty : TOneWrtStyle);
       begin
           i f sty i n WPRichText1.CurrAttr.Style then
                 WPRichText1.CurrAttr.DeleteStyle([sty])
           else WPRichText1.CurrAttr.AddStyle([sty]);
           WPRichText1.SetFocusValues(true);
       end;
     begin
       i f Key=Char(Integer('B') -6 4) then // Ctrl + B
       begin
           ToggleStyle(afsBold);
           Key := # 0;
       end else
       i f Key=Char(Integer('I') -6 4) then // Ctrl + I
       begin
           ToggleStyle(afsItalic);
           Key := # 0;
       end else
       i f Key=Char(Integer('U') -6 4) then // Ctrl + U
       begin
           ToggleStyle(afsUnderline);
           Key := # 0;
       end;
     end;




                                                               © 2004-2008 WPCubed GmbH - Munich, Germany
Guide         51


          Note

          Please do not use actions if you want to execute certain methods of the TWPRichText component
          from your own code. You can call the procedure directly (i.e. WPRichText1.Save) or change text
          attributes using CurrAttr (i.e. WPRichText1.CurrAttr.AddStyle[afsBold]).




7.6.4     Change Behaviour and Appearance of Editor

          Please see:
             Localization
             Layoutmodes
             Hover Effects
             EditOptions
             ViewOptions
             HideTableBorders




7.6.4.1   Layoutmodes
          The different layout modes are probably one of the most exciting feature in WPTools Version 6. You
          will hardly find a component which offers this kind of versatility in a text editing tool.

          Different layout modes are mainly activated in property LayoutMode
          - but also the properties PageColumns, AutoZoom, Zooming, ViewOptions and OnPageGapGetText
          are important for the display of the text.

          If you are using our multiview technology (multiple editors show one text), each editor can use
          different settings for the mentioned properties. So it is possible that one editor displays the
          thumbnails while a different editor shows the text in 'normal' mode!

          Changing the layout modes is also extremely fast, usually the already formatted pages are
          rearranged on the virtual desktop!

          Please note that the TWPPreview component also inherits from the usual editor component. So it
          has the same properties. But it also introduces the property SinglePageMode. If this property is true,
          unlike the default display of all pages in a row, only one row of pages will be displayed. BTW - if you
          are using the TWPPreview or TWPPreviewDlg you are already using the multiview technology.

          Possible values of the property LayoutModes are:

          wplayNormal : Only show the text area without margins - do not paint background color.

          wpWordWrapView: Display like wplayNormal - used when the word wrap is set to the editor box.

          wplayShowManualPageBreaks like wpNormal but draws a dashed line for page breaks
                                  -

          wplayPageGap- display the text similar to wplayNormal with a bar iin between

          wplayExtendedPageGap works like wplayPageGap but does not suppress the left and right
                              -



© 2004-2008 WPCubed GmbH - Munich, Germany
52    WPTools Version 6


     margin.

               wplayPageGap example:




               The display of the page numbers ("--- 1") is activated using the ViewOption
               wpShowPageNRinGap . You can use the event OnGetPageGapText to display a different
               text.

     wplayShrinkedLayout- show PageLayout without header and footer (reduces page height!)

     wplayLayout - show PageLayout but do not paint header and footer.

     wplayFullLayout - show PageLayout with header and footer.

     wpDualPageView- display 2 pages side by side. A similar effect can be accieved by setting the
     property "PageColumns" to 2 but wpDualPageView makes sure the 2 pages are handled as 1 by the
     auto zoom function.
     The DualPage view expects the first page to be ouside and the 2nd and 3rd to be side by side. If the
     property WPRichText.Memo.DualPageViewAlternate is true the first page is displayed side by side
     with the second.

     wpThumbNailView- display thumb nails of the pages, optionally with display of the page numbers
     in little boxes. This is activated by ViewOption wpShowPageNRinGap.




     property ViewOptions
     The following values are possible:




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       53



         wpShowGridlines- draw a gray line for table borders which would mbe otherwise invisible

         wpDisableHotStyles - disable the hot styles (or hover styles) which can be activated for hyperlinks
         or fields.


         wpShowCR - show a         symbol at the end of a paragraph

         wpShowFF - displays         at the end of a paragraph when the next paragraph starts on a new page

         wpShowNL - displays an arrow for a new line

         wpShowSPC- shows a dot for the code #32 (SPACE)

         wpShowHardSPC- shows a dot for the code #160 (non breaking space)

         wpShowTAB - show an arrow in the place of tabstops (suppressed if fillsigs are active)

         wpShowParCalcNames- Display the names assigned using property WPAT_PAR_NAME

         wpShowParCalcCommands- Display the formulas assigned to paragraphs and cells.

         wpShowParNames Display the names assigned using property TParagraph.Name
                      -

         wpNoEndOfDocumentLine - display a line at the end of the document if not in pagegap mode.
         Ignore the typo 'No'.

         wpHideSelection- Always hides the selection

         wpHideSelectionNonFocussed - hides thenselection when editor does not have the focus

         wpShowPageNRinGap- displays a number or any other text provided by event
         OnPageGapGetText either at the right border or in a box under the page

         wpDrawFineUnderlines- always draw thin underlines

         wpDontGrayHeaderFooterInLayout- do not shaed the header and footer texts

         wpInfiniteTextArea- makes it possible to show a text as if it is infinite. This can be used for a
         scroller control, for example to show news or credits. To scroll change the property TopOffset in a
         timer event.

         wpDontPaintPageFrame- with page layout modes, do not draw a frame around the page

         wpCenterPaintPages- center the page horizontally in the window. This is useful for preview
         windows.

         wpDrawPageMarginLines draw dotted lines at the page margins.
                              -

         wpDontDrawSectionMarker- do not draw the arrow which shows where a new section starts.

         wpDrawHeaderFooterLines- draw gray lines around header/footer areas.

         wpUseOwnDoubleBuffer - Usually a shared double buffer is used for all editors to limit the memory
         use - unless thumbnailmode has been activated or this flag is active.




© 2004-2008 WPCubed GmbH - Munich, Germany
54     WPTools Version 6




          wpDontDisplayScrollPageHint - Do not display this default page number hint when pressing the
          scrollbar handle. The hint can be modified by changing the global string variable WPPageHintStr.
          The default is ' %d / %d '.



          property AutoZoom
          The following values are possible:

          wpAutoZoomOff - use the value of property Zooming to change the aspect ratio of the text display

          wpAutoZoomWidth - automatically adjust the aspect ratio to make room for the complete width of
          the page

          wpAutoZoomFullPage - automatically adjust the aspect ratio to make room for the complete size
          of the page

          wpAutoZoomAdjustColumnCount - automatically adjust the property PageColumns to show as
          many pages side by side as fit into the window. Usually the property Zooming should be set to a
          small value, for example 30.

          wpAutoZoomAsManyAsPossibleInRow - show as many pages side by side but allow a different
          count of pages each row. You can see the effect in the lower editor in the section demo. This mode
          should be also combined with a small zooming value.

          Please note that the property CurrentZooming can be read to get the current aspect ratio as a
          floating point multiplicator.

7.6.4.2   Hover Effects


          Certain text can change the attributes when the mouse is moved over it. In addition a hint window
          can be displayed. This is useful for mail merge fields and hyperlinks.

          All text which support this kind of interaction can also use global style and color definitions set up in
          these properties:

          i)    property   HyperlinkTextAttr: TCharacterAttrTags;
                property   BookmarkTextAttr: TCharacterAttrTags;
                property   SPANObjectTextAttr: TCharacterAttrTags;
                property   AutomaticTextAttr: TCharacterAttr;

          ii)   property ProtectedTextAttr: TCharacterAttr;
                property HiddenTextAttr: TCharacterAttr;

          iii) property FieldObjectTextAttr: TCharacterAttr ;
               property InsertPointAttr: TCharacterAttrTags;

          The group i) defines attributes for texts which is wrapped in TWPTextObj instances of the following




                                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       55


         types: wpobjHyperlink, wpobjBookmark, wpobjSPANStyle and wpobjMergeField (= merged text).

         The two prioperties in group ii) affects text which uses the character style afsProtected and
         afsHidden.

         In group iii) FieldObjectTextAttr changes the appearance of wpobjTextObject objects (with the
         exception of objects with the name 'PAGE', 'NUMPAGES', 'SYMBOL'.
         InsertPointAttr changes the way wpobjMergeField objects are displayed and can be used to hide
         those objects.

         The TCharacterAttr class contains various properties to change the color of the "special" text, to
         add or remove underlines and to set the underline color.

         To display hint windows two events can be used:

         a) the OnActivateHint event

         This event is triggered when the mouse is moved over special text which uses the property
         OnHintEventIsActive set to true in the respective TCharacterAttr property. Since there is no
         OnDeactivateHint event we suggest to use a timer to hide the window. In contrast to property
         "HotStyleIsActive" the property "OnHintEventIsActive" does not force a repaint of the text window!

         a) the OnActivatingHotStyle event

         This event is triggered when the mouse is moved over special text which uses the property
         HotStyleIsActive set to true in the respective TCharacterAttr property.

         This code can be used to show a hint window with information about merged text. HotStyleIsActive
         must be set to TRUE in property AutomaticTextAttr:

         procedure TForm1.WPRichText1ActivatingHotStyle(Sender: TObject;
           par: TParagraph; posinpar: Integer);
         var p : TPoint;
         begin
           i f par <> nil then
           begin
               FHintForm.Caption := (Sender a s TWPCustomRTFEdit).FieldGetNameInPar(par,
         posinpar);                p := TWPCustomRTFEdit(Sender).GetPointFromParLin(par,
         posinpar);
               i f p.x > TWPCustomRTFEdit(Sender).Width then p.x := TWPCustomRTFEdit(Sender).
         Width;
               p := TWPCustomRTFEdit(Sender).ClientToScreen(p);
               FHintForm.Left := p.x;
               FHintForm.Top := p.y;
               FHintForm.Show;
           end;
         end;

         The hint form is hidden in event OnDeactivateHotStyle

         procedure TForm1.WPRichText1DeactivateHotStyle(Sender: TObject);
         begin
            FHintForm.Hide;
         end;

         If you need to use OnClick events for certain texts use the event OnClickHotText and the property
         ClickableCode. See previous chapter for more information.




© 2004-2008 WPCubed GmbH - Munich, Germany
56     WPTools Version 6




7.6.4.3   EditOptions
          The properties EditOptions and EditOptionsEx control how the editor works. They are also used to
          disable certain actions, such as table resizing.

          TWPEditOptions = set of
             (wpTableResizing, // Mobve left right indent }
             wpTableOneCellResizing, // always only one cell, can be switched with CTRL key
             wpTableColumnResizing, // change column width
             wpTableRowResizing, // Change height of row. Also see EditOptionEx:
          wpTableRowResizingWithCTRL
             wpClearAttrOnStyleChange, //ON: clear the redundant properties when the style name is
          changed.
             wpNoAutoWordSelection, // don't select complete words (like Word)
             wpObjectMoving, // move images (ObjType=wpobjImage)
             wpObjectResizingWidth, // the width of objects can be changed
             wpObjectResizingHeight, // the height of objects can be changed
             wpObjectResizingKeepRatio, // the width/height of objects can be changed
             wpObjectSelecting, // objects can be selected
             wpObjectDeletion, // objects can be deleted (only used for TWPObject)
             wpNoAutoScroll, // Switch off the new Auto Scroll Feature
             // obsolete! wpFieldObjectsAsGraphicObjects, { work with TWPOFieldObject as if they were
          TWPOGraphics }
             wpSpreadsheetCursorMovement, { Cursor up/down in Rows }
             wpAutoInsertRow, { wpAutoInsertRow, TAB in last cell. Must be combined with
          wpSpreadsheetCursorMovement }
             wpNoEditOutsideTable, { to simulate spreadsheet - V5 ok }
             wpBreakTableOnReturnInRow, { V5: instead of inserting a row break up the table }
             wpActivateUndo, { activate UNDO }
             wpActivateUndoHotkey, { activate ALT + Backspace - requires wpAllowUndo set too }
             wpActivateRedo, { makes backup of complete text ! }
             wpActivateRedoHotkey, { makes backup of complete text ! }
             wpAlwaysInsert, { don't switch to overwrite }
             // wpDeactivateCharsetSwitching,
             wpMoveCPOnPageUpDown, { Move Cursor on Page up or Down code - V5 ok }
             wpAutoDetectHyperlinks, // Create a hyperlink after 'www.' was typed
             wpNoHorzScrolling, //V5=ok
             wpNoVertScrolling, //V5=ok
             // wpNoAutomaticHangingBulletsAndNumbers, - see FormatOption!
             // wpMDIDragAndDrop,
             // wpDontDeleteExtraSpace,
             // wpUseHyphenation, -> Moved to FormatOptions!
             wpDontSelectCompleteField, // Selections will always wrap the complete merge field
             wpSelectCompleteFieldAlsoWhenInside, // When selection inside of field also complete field is
          selected
             wpStreamUndoOperation, // saves also additional info like bands, objects ..
             //is default: wpToolBarDisableDifferentFontsInSelections, // Sets Size,Color, Font to blank is not
          = in a selection
             wpTabToEditFields, // not used.
            // wpAllowEditHeaderFooter
             wpSelectPageOnDblClick, //V5=ok
             // Used by TWPRichText only:
             wpAllowCreateTableInTable // - the create table button allows nested tables
              // Don't allow selection at all
             );



                                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       57




         TWPEditOptionsEx = set of
             (
             wpDisableSelection, // The user cannot select text (see ViewOptions to hide selection)
             wpDisableCaret, // The caret (insertion point marker at cursor position) is not displayed
             wpDisableGetFocus, // The editor will never receive the focus
             wpDisableEditOfNonBodyDataBlocks, // in Pagelayout mode other DataBlocks (header, footer)
         cannot
             // be selected for edtiting with a click of the mouse
             wpAllowCursorInRow, // the cursor can be placed in row end marker to create a new row with
         return
             wpTextObjectMoving, // move text objects (ObjType=wpobjTextObj)
             wpTextObjectSelecting, // By defualt allow selectiong of text objects
             wpNoAutoWordStartEndFieldSelection, // Normally a complete field is selected
             // when the cursor is moved over the start or end of a mail merge field.
             // unless wpNoAutoWordSelection is used. Also see EditOption:
         wpSelectCompleteFieldAlsoWhenInside
             // Note: wpNoAutoWordStartEndFieldSelection only applies to selection with mouse!
             wpDisableAutoCharsetSelection, // If true the charset is not retrieved by
             // checking the current keyboard layout when the user types
             wpIgnoreSingleCellSelection, // No cell selection by pointing in bottom left corner
             wpTABMovesToNextEditField, // used with forms
             wpDblClickCreateHeaderFooter, // Double click in Margin creates header/footer for all pages
             // Use 'OnClickCreateHeaderFooter' event to modify 'range'
             wpRepaintOnFieldMove, // When the cursor moves to a different field
             // the form is repainted. This is important if you use code to
             // highlight the current field. (using event: OnGetAttributeColor)
             wpKeepCellsWhenCombiningCells, // use the HTML way to combine cells horizontally
             wpAllowSplitOfCombinedCellsOnly, // use the HTML way to split cells, dont allow split if not
         combined
             wpDontClearStylesInNew, // If defined Action 'New' will not clear the defined styles
             wpDontResetPagesizeInNew, // If defined clearing the text will not set up the default page size
             wpSetDefaultAttrInNew, // If defined "New" will preset the writing attributes to the default
             wpAllowDrawDropBetweenTextBlocks, // Allow drag & drop between header and body
             wpDisableFastInitOnTyping, // Disable the improved typing performance in large paragraphs
             wpDontTriggerPopupInContextEvent, // Changes the time the event OnMouseDownWord is
         triggered (old behaviour)
             wpAlwaysColWidthPC, // Changine column width sets percentage colwidth in cells
             wpDisableXPosLineUpDown, // Disable the code which triues to keep cursor at same X position in
         Line up/down
             wpDontInitSelTextAttrWithDefaultFont, // SelltextAttr will not report the default attr for undefined
             wpDontSelectCellOnSpreadsheetMovement, // when tabbing throgh a table dont select the cell
             wpScrollLineWise, // When using line up&down do not move by 1/3 screen but only by the height
         of a line
             wpZoomWithMouseWheel, // Press Ctrl + use Mouse Wheel to zoom in and out
             wpTableRowResizingWithCTRL, // Resize rows when also CTRL is pressed
             wpDontUseNumberIndents // when using Inc/Dec Outline Level ignore the indents defined in
         number styles
          wpAutoCaptitalize // WPTools 6: Auto capitalize sentence starts
             );




© 2004-2008 WPCubed GmbH - Munich, Germany
58     WPTools Version 6


7.6.4.4   ViewOptions
          The properties ViewOptions and ViewOptionsEx (added in WPTools 6) control how the text is
          displayed.

           TWPViewOptions = set of
            (
            wpShowGridlines, // display gray lines around cells
            wpDisableHotStyles, // disable the hover styles (See HyperlinkTextAttr for example)
            wpShowCR, // Show Paragraph symbol
            wpShowCRButNotInCells,
            wpShowFF,
            wpShowNL,
            wpShowSPC,
            wpShowHardSPC,
            wpShowTAB,
            wpShowParCalcNames, // Display the names assigned using property WPAT_PAR_NAME
            wpShowParCalcCommands, // Display the formulas
            wpShowParNames, // Display the names assigned using property TParagraph.Name

             wpNoEndOfDocumentLine, // If enabled a line will be displayed in normal mode at the bottom.
          (Ignore the "no")
             wpHideSelection, // Selection possible but not displayed
             wpHideSelectionNonFocussed, // selection not displayed when not focussed
             wpHideSelectionNonFocussedAndInactive, // Selection not displayed if not active (not connected
          to toolbar)
             wpTraditionalMisspellMarkers, // Draw "Word like" curly underlines
             wpDisableMisspellMarkers, // Do not draw curly underlines
             wpShowPageNRinGap,
             wpDrawFineUnderlines,
             wpDontGrayHeaderFooterInLayout,
             wpInfiniteTextArea,
             wpDontPaintPageFrame, // Do not draw the rectangle around page
             wpCenterPaintPages,
             wpUseOwnDoubleBuffer, // Usually a shared double buffer is used
             // - unless thumbnailmode has been activated or this flag is active
             wpDrawPageMarginLines,
             wpDontDrawSectionMarker,
             wpDrawHeaderFooterLines, // Display gray lines around header and footer
             wpDontDisplayScrollPageHint,
             wpDontDrawObjectAnchors // Dont draw the anchor lines for movable objects
          }

          WPTools 6 adds

            TWPViewOptionsEx = set of
            (
               // Unless wpDontDrawObjectAnchors was used for select objects the anchor will be drawn
               // with this option the anchor will be always drawn at the position of the anchor character
            wpAlwaysDrawImageAnchors,
            wpAlwaysDrawTextboxAnchors,
            wpAutoThumbnailMode, // when in thumbnail mode, page numbers are automatically displayed
            wpDisableAllSpecialAttributes, // disable, hyperlink, field ... color and underlines
            wpDisableCharacterStyles, // disable the character styles defined with RTF CS tag
            wpDisableColorInTableOfContents // TableOfContents will be all black, like in MS Word
            );




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      59




7.6.4.5   Format Options
          WPTools 6 uses the properties

          FormatOptions
          FormatOptionsEx
          and FormatOptionsEx2

          to change, how the text is formatted. If changed for one RTF-Engine all other RTF-Engines which
          use the same RTFData object will be affected, too.

          You need to call ReformatAll(true,true) to update the text.

          TWPFormatOptions = set of (
              // This flags change the display of tables
              wpDisableAutosizeTables, // - we suggest to enable this flag. Otherwise tables
              wpNoMinimumCellPadding, // Do not add a one pixel padding to all cells
              wpfDontBreakTables, // do not break tables at all. Also see wpKeepTogetherAdjac
              wpfDontBreakTableRows, // do not break table rows
              wpDontClipCells, // do not clip cells if absolute row heights are used
              wpfIgnoreMinimumRowheight, // Do not use the row height property
              wpfIgnoreMaximumRowheight, // Do not use the row maximum height property
              wpTableRowIndicator, // must be combined with EditOptionsEx : AllowCursorInRow
              // -------------------------------------------------------------------------
              // This flags conmtrol the layout
              wpfIgnoreKeep, // The WPAT_ParKeep property is ignored (do not break par)
              wpfIgnoreKeepN, // The WPAT_ParKeepN property is ignored (do not break adjacent
              wpfKeepOutlineWithNext, // Text which uses the WPAT_ParIsOutline property is ke
              wpfAvoidWidows, // Avoid single lines on old page
              wpfAvoidOrphans, // Avoid single lines on new page
              wpfCenterOnPageVert, // Center text on all pages
              wpfHangingIndentWithTab, // V5: first tab in paragraph jumps to indent first (t
              // the left indent will be handled as first tabstop not only if the tab is the
              // first character but also if the text before the tab fits into the first inde
              wpfDontTabToIndentFirst, // V5: The oposite to wpfHangingIndentWithTab
              wpJustifySoftLinebreaks, // Justify n
              wpJustifyHardLinebreaks, // Justify r
              wpUseHyphenation, // Use soft hyphens in the text (inserted with Ctrl + '-')
              wpFooterMinimumDistanceToText, // The footer texts start after the body text (W
              // -------------------------------------------------------------------------
              // This flags control the display of codes.
              // IMPORTANT: You need to call ReformatAll(true,true) after you have changed th
              wpShowBookmarkCodes, // display bookmark tags
              wpShowHyperlinkCodes, // display hyperlinks tags
              wpShowSPANCodes, // display SPAN tags
              wpShowInvisibleText, // show text which would be otherwise hidden
              // -------------------------------------------------------------------------
              // Experimental flags
              wpfHideEmptyParElements, // reserved: Can be used when editing HTML files with
              wpfXMLOutlineMode, // Debugging mode: Show paragraph tree similar XML in IE
              wpWriteRightToLeft, // activate RTL writing
              wpAutoWriteRightToLeft, // reserved for future




© 2004-2008 WPCubed GmbH - Munich, Germany
60   WPTools Version 6


       // -------------------------------------------------------------------------
       // Troubleshooting flags
       wpUseAbsoluteFontHeight, // Calculate the height of the text using the font siz
       wpfAlwaysFormatWithScreenRes, // .. even if RM600 is defined in WPCtrMemo
       wpDisableSpeedReformat, // format only the current page and the next page on re
       wpDontAdjustFloatingImagePosition // do not adjust image position to keep it on
       // note that it is not possible to click on an image which is outside of the pa
       );

     TWPFormatOptionsEx = set of (
       // -------------------------------------------------------------------------
       wpDontAddExternalFontLeading, // When measuring the font height don't add the
       // value defined for a font: Metrics.tmExternalLeading. This improves compatibi
       // Alternatively set global variable WPDoNotAddExternalFontLeading := TRUE to
       // activate this mode for all editors!
       // -------------------------------------------------------------------------
       // Layout flags
       wpfKeepTablesInTextArea, // If defined avoid that table go into right margin
       wpKeepTogetherAlwaysNewPage, // if wpfDontBreakTables is used a table which is
       wpKeepTogetherAdjacentTables, // When tables are not seperated by paragraphs th
       wpDontUseTablePadding, // Do not read the padding of cells from table
       wpfIgnoreVertAlignment, // Switches off the vertical alignment
       wpfKeepNUsesParImages, // When using KeepN paragraph aligned images will be
       // kept on same page as their anchor paragraph. (changes the value calculated b
       // Note: Images which use the wrap mode wpwrUseWholeLine will always be checked
       wpDontIgnoreSpacebeforeOnTopOfPage, // switch "Word" mode off
       // -------------------------------------------------------------------------
       // Limit the use of inherited attributes
       wpDontUseRowPadding, // Do not read the padding of cells from table row
       wpDontUseBorderPadding, // Do not use the border width to calculate padding
       wpDontInheritCellAttr, // Dont inherit cell attributes from table row and table
       wpDontUseSPANStyles, // Do not use the stalyes of hyperlink and SPAN objects .
       // -------------------------------------------------------------------------
       // modify the way the editor works
       wpAlwaysContinueBorderAfterCR, // Paragraph.SplitAt (= ENTER key in editor) wil
      // the new paragraph if the split position is at the end
       wpNoDefaultParStyles, // Disable default paragraph style handling (So you can h
      // it yoursel in the OnInitializePar event)!
       wpfAutoRestartSimpleNumbering, // Reset a numbering level after a line which wa
       wpfNestedNumberingInTableCells, // Each table cell uses its individual NumberLe
      // this only affects numbering which does not use outlines
       wpfSimpleNumberingPriorityOverOutlines, // When outlines (numberlevel>0) are us
       // numbered paragraphs the simple numbering will continue AFTER the outlines. (
       wpfNoAutoDecTabInTable, // Do not automatically align to only decimal tabstop i
       wpfNoTableHeaderRows, // Ignore table header
       wpfNoTableFooterRows, // Ignore table footer
       wpfDisableJustifiedText, // Format Justified text as if it was Left Aligned
       // -------------------------------------------------------------------------
       // Experimental Flags
       wpAllow_WPAT_NoWrap, // If active don't wrap par marked with WPAT_NoWrap
       wpfMixRTLText, // If a paragraph which uses the paprRightToLeft attribute the
       // western text is not reordered
       wpfStoreWPObjectsInRTFDataProps, // unless this flag is used the TWPObjects wil




                                            © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       61


               // be stored in the TWPRTFDataCollection and not in the TWPRTFDataProps
               // -------------------------------------------------------------------------
               // Activate User CharStyle
               wpCharEffectIsUserAttribute, // Currently the character attribute WPAT_CharEffe
               // It can be used to store custom information. If the flag wpCharEffectIsUserAt
               // the RTF engine will ignore this property.
               wpfIgnoreTrailingEmptyParAtFooter, // Empty paragraphs are ignored at´the foote
               wpfDontHideParAboveNestedTable, // allow empty paragraph before a nested table
               wpfDontCombineDifferentStylePars, // DeleteParagraphEnd will not merge paragrap
               // Can be selectively set for certain paragarphs using WPAT_ParFlags flag WPFLG
               wpfNumberingControlledByStyles, // Only supported by WPT format!
               wpfSectionsRestartFootnoteNumbers,
               wpfDontIgnoreKeepNInTable, // unless this flag is set the KeepN in table rows i
               wpfDontIgnoreEmptyHeader
               );

            //:: New HTML formatting routine added to WPTools V6
            TWPWebPageFormat = set of (
                 wpFormatAsWebpage,
                 wpNoMinimumWidth,
                wpNoMinimumHeight); // + formats


            TWPFormatOptionsEx2 = set of
              (
              wpfSectionsRestartPageNumbers // All pages restart their numbering
              , wpfUseKerning // initialize the text and also adjust kerning according to fon
              , wpfCodeObjectAsXMLTags // visualize the code objects as XML tags
              , wpDisableBalancedColumns // dont use the new column balancing
              , wpfCodeObjectCheckParStyles // code objects format the contained text accordi
              );

7.6.4.6   HideTableBorders
          This property has been added to WPTools 6 to allow hiding of table borders.

          Possible values are:

          wpDontHide,
          wpHideOnScreen,
          wpHideOnPrinter,
          wpHideAlways

7.6.5     Header and Footer
          WPTools provides powerful support for headers and footers.
          You can create a header or footer which is valid for all pages or header and footers for the first, the
          odd and the even pages.

          In WPTools Version 6 ist is also possible to start a new section in the text. This section can then
          have its own set of header and footer and also, optionally, a different page size or different margins.


          Example: Create a Footer with the text "PAGE # of ##"

          var par : TParagraph;




© 2004-2008 WPCubed GmbH - Munich, Germany
62    WPTools Version 6


          txtplain : Cardinal;
     begin
       par:=WPRichText1.HeaderFooter.Get(wpFooter,wpraOnAllPages).FirstPar;
       WPRichText1.WritingAttr.Clear;
       WPRichText1.WritingAttr.SetFontName('Courier New') ;
       WPRichText1.WritingAttr.SetFontSize(900); // 9pt
       txtplain := WPRichText1.WritingAttr.CharAttr;
       par.ClearText;
       par.ASet(WPAT_Alignment, Integer(paralRight));
       par.Insert(0,'Page ',txtplain);
       par.InsertNewObject(maxint, wpobjTextObject, false, false,txtplain).Name :=
     WPTextFieldNames[wpoPageNumber];
       par.Insert(maxint,' of ',txtplain);
       par.InsertNewObject(maxint, wpobjTextObject, false, false,txtplain).Name :=
     WPTextFieldNames[wpoNumPages];
     end;

     Please note that the property 'FirstPar' will always create a paragraph if the text block was empty.

     "Manage Header and Footer", a useful dialog

     WPTools comes with a useful form in unit WPManHeadFoot to work with header and footer.




     This form makes it easy to navigate to a certain header or footer. It can be edited, copied or deleted.
     The two buttons switch between the page layout mode and the normal layout mode. If the user
     clicks on a header or footer which is currently not visible, the text cannot be edited in page layout
     mode, so the dialog will automatically select the normal mode.

     To use this form add the unit to the uses clause and create a global variable:

     ManHeadFoot : TWPManageHeaderFooter;

     Now, to show the form in a non-modal:

       i f ManHeadFoot=nil then
           ManHeadFoot := TWPManageHeaderFooter.Create(Self);
       ManHeadFoot.WPRichText := WPRichText1;
       ManHeadFoot.Show;




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       63


         We recommend to check out the source of this dialog since it also contains good example code.


         Properties TWPRichText.WorkOnText and TWPRTFDataBlock.WorkOnText

         This property selects the text which is currently edited. All commands will operate on the selected
         text part. Only ‚Load' and ‚Save' will automatically select the body.

         Possible values for 'WorkOnText' are
           wpIsBody
           wpIsHeader
           wpIsFooter

         If you need to select the special text for a certain 'range' you the property HeaderFooterTextRange.
         (type TWPPagePropertyRange).
           WPRichText1.HeaderFooterTextRange := wpraOnOddPages;
           WPRichText1.WokOnText := wpIsHeader;

         Now all the procedures work with the header for odd pages. You can execute mailmerge
         "MergeText", add number fields "InputTextFieldName('PAGE')" or inserts texts "InputString'Hello
         World')".

         If you have a reference to a certain TWPRTFDataBlock - for example provided by WPRichText1.
         HeaderFooter.Get - you can also set the boolean property WorkOnText of this element to TRUE to
         select it for editing!
             WPRichText1.HeaderFooter.Get(wpIsHeader,wpraOnFirstPage,' ').WorkOnText := TRUE;
             WPRichText1.InputString('WPTools Documentation') ;
             WPRichText1.WorkOnText := wpIsBody;

         Please note that you will only see the selected text exclusively in the 'normal' LayoutMode.
         Otherwise the cursor simply moves to the header or footer region.

         Notes
         a) Please note, the above puts the cursor into a certain header/footer text. It does not change which
         header or footer is currently displayed on the page. If you need to modify the way header and footer
         are selected for the display in page layout mode use the OnGetSpecialTextevent.

         This event handler selects the ALL PAGES header or footer for all pages, also first, odd and even no
         matter what other header or footer are there:

         procedure TForm1.WPRichText1GetSpecialText(Sender: TObject;
           par: TParagraph; PosInPar, PageNr: Integer; Kind: TWPPagePropertyKind;
           var IsLastPage, UseThis: Boolean; var SpecialText: TWPRTFDataBlock);
         begin
           // We use 'Get' to find the header or footer
           SpecialText := WPRichtext1.HeaderFooter.Get(Kind, wpraOnAllPages, ' ') ;
           // Only then the variable is actually used
           UseThis := TRUE;
         end;

         b) It is important to note that if the PrintHeaderFooter sub-property is set to wprNever, the headers
         and footers will not be displayed on screen either.
         Also, you can choose if the headers and footers will be displayed in grayed form by setting the
         wpDontGrayHeaderFooter sub-property of the ViewOptions property to false.

         c) The header and footer can be printed in the top/bottom margin area or in the text area. It is up to
         you what you like better, both possibilities are used by standard word processors. This behavior is
         controlled by the sub-property PrintHeaderFooterInPageMargins in property HeaderHeader. In the




© 2004-2008 WPCubed GmbH - Munich, Germany
64    WPTools Version 6


     property Header you can also modify the values for the margins and page and the default values that
     should be set when the buffer was cleared.


     Copy all header and footer from one editor to another:

     var i : Integer;
     begin
       for i:=0 t o WPRichText1.HeaderFooter.Count-1 d o
       i f WPRichText1.HeaderFooter[i].Kind i n [wpIsHeader, wpIsFooter] then
       WPRichText2.HeaderFooter.Get(WPRichText1.HeaderFooter[i].Kind,
          WPRichText1.HeaderFooter[i].Range, ' ').RtfText.AsString :=
             WPRichText1.HeaderFooter[i].RTFtext.AsString;
     end;



     Collection HeaderFooter : TWPRTFDataCollection

     The headers and footers (and also the body and optional texts) are stored in the runtime collection
     property TWPRichText.HeaderFooter.

     This collection manages a list of instances of the class TWPRTFDataBlock. Each instance holds
     one 'special' text. This text can be used as a header or a footer within the selected range.

       TWPRTFDataBlock = class(TCollectionItem)
       ...
       published
         property Name: string
         property UsedForSectionID
         property Range: TWPPagePropertyRange
         property Kind: TWPPagePropertyKind
         property RtfText: TWPRTFDataContents
       end;

       TWPPagePropertyRange =
         (wpraOnAllPages, wpraOnOddPages, wpraOnEvenPages, wpraOnFirstPage,
         // these Modes are not compatible to the RTF Standard !
         // They have priority !!!!
         wpraOnLastPage, wpraNotOnFirstAndLastPages,
         wpraNamed, wpraIgnored);

       TWPPagePropertyKind = (wpIsBody, wpIsHeader, wpIsFooter,
           wpIsFootnote,        // The last 4 are for internal use only
           wpIsLoadedBody,
           wpIsDeleted,
           wpIsOwnerSelected);



       TWPRTFDataContents = class(TPersistent)
       public
         constructor Create(Source: TWPRTFDataBlock);
         procedure LoadFromStream(Stream: TStream); virtual ;
         procedure SaveToStream(Stream: TStream); virtual ;
         property AsString: string read GetAsString write SetAsString;
         procedure Assign(Source: TPersistent); override;
         property Format: string read FFormat write FFormat;
       end;

     To change the text you can load the text from a stream using Item.RtfText.LoadFromStream or you
     can simply set or read the property AsString! This string can also be in HTML or WPTOOLS format!




                                                               © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       65


         The RTFDataCollection provides this functions to find certain header or footer entries. You can of
         course enumerate all the items using the Items[] array.

                  function Find(Kind: TWPPagePropertyKind; Range: TWPPagePropertyRange;

                  const Name: string = '*'; UsedForSectionID: Integer = 0): TWPRTFDataBlock;

                  procedure DeleteTexts(UsedForSectionID: Integer); overload;

                  procedure DeleteTexts(Kind: TWPPagePropertyKind; UsedForSectionID: Integer);
                  overload;

                  procedure DeleteRTFData(RTFData: TWPRTFDataBlock);

                  procedure DeleteText(Kind: TWPPagePropertyKind; Range: TWPPagePropertyRange;
                  UsedForSectionID: Integer = 0) ;



         We suggest to use this code to add a new header:

                  WPRichText1.HeaderFooter. Get(
                      wpIsHeader,
                      wpraOnAllPages,
                      ' ').RtfText.AsString
                       := WPEditor.AsString; // any other TWPRichText which is used to edit
                  the header
         -or-
                    WPRichText1.HeaderFooter.Get(
                         wpIsHeader,
                         wpraOnAllPages, ' ').RtfText.LoadFromStream( filestream1 );

         C++Builder:
         WPRichText1->HeaderFooter->Get(wpIsHeader,wpraOnAllPages,
                                                               " ")->RtfText->AsString;



         Event: OnGetSpecialText

         This event receives this parameters:

                Sender: TObject;
                par: TParagraph;
                PosInPar: Integer;
                PageNr: Integer;
                Kind: TWPPagePropertyKind;
                var IsLastPage: Boolean;
                var UseThis: Boolean;
                var SpecialText: TWPRTFDataBlock

         You can set UseThis to true to let the RTF Engine use as header or footer whatever item you have
         choosen in 'SpecialText'. To switch off the header or footer set this parameter to nil:

           SpecialText := nil;
           i f PageNr=1 then
                 UseThis := TRUE
           else UseThis := FALSE;




© 2004-2008 WPCubed GmbH - Munich, Germany
66     WPTools Version 6


7.6.6   Create Sections

        Sections make it possible to use many different header and footer texts and different page sizes in
        one document.


        The editor will display an arrow           in the left margin where a new section starts.

        The following code can be used to create a new section:

        var sectionprops : TWPRTFSectionProps;
        begin
          // New Page
          WPRichText1.InputString(#12);
          // New section properties
          sectionprops := WPRichText1.ActiveParagraph.StartNewSection;
          // Now we can do something with sectionprops
          ...
        end;

        Each section is defined by an instance of TWPRTFSectionProps. The property WPRichText.Header
        which stores the default page size for the whole document is consequently implemented using a
        class which inherits from TWPRTFSectionProps.

        Usually all instances of TWPRTFSectionProps use the property value defined in the master section
        property (WPRichText.Header). If certain attribute should be unique for a section the property
        Selected must be set accordingly.

          sectionprops.Select := [wpsec_PageSize];
          sectionprops.Landscape := TRUE;

        The following flags exist   in property Select:
          wpsec_PageSize             --> Overwrite PageWidth, PageHeight and Landscape
          wpsec_Margins              --> Top, left and other margins
          wpsec_TabDefault           --> Change deftabstop property
          wpsec_PageMirror           --> change the marginmirror property

        Note: The "speed reformat" feature of WPTools Version 6 does not work well with different page
        sizes yet. So please switch this feature off using WPAll.FormatOptions :=
        [wpDisableSpeedReformat];

        It is also possible to select that certain header or footer texts should be only used for one section.
        This is done by the property TWPRTFDDataBlock.UsedForSectionID. If this property is changed to
        sectionprops.SectionID the text block will be only used for that special section.




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Guide        67


          The demo AppendAsSection shows how texts from different editors (WP1,WP2, WP3) can be
          appended to create one multi section document in the editor WPALL:




          The 3 buttons use 3 different approaches:

          1.) Full implementation - shows how to work with sections
          2.) Use utility procedure AppendAsSection - same functionality as 1)
          3.) Use strings in WPTOOLS format with the <newsection/> tag.




          4) Append section with individual footer (or header)




7.6.6.1   Full implementation - shows how to work with sections
          DELPHI CODE
          procedure TWPALL.AppendClick(Sender: TObject);
             procedure AppendText(Source : TWPRTFDataCollection);
             var sectionprops : TWPRTFSectionProps ;
                  i   : Integer;
                  textblock : TWPRTFDataBlock;
             begin
               // Create a new Page if required
               i f WPAll.IsEmpty then
                     WPAll.CheckHasBody
               else WPAll.InputString(#12) ;
               // Create new section properties
               sectionprops := WPALL.HeaderFooter.AddSectionProps;
               // Assign the default page size




© 2004-2008 WPCubed GmbH - Munich, Germany
68       WPTools Version 6


          sectionprops.Assign(Source.Header);
          sectionprops.Select := [wpsec_PageSize,wpsec_Margins];
          // Copy all header + footer into certain section
          for i:=0 t o Source.Count-1 d o
             i f Source[i].Kind i n [wpHeader, wpFooter] then
             begin
                textblock := WPALL.HeaderFooter.Append(
                  Source[i].Kind,
                  Source[i].Range,
                  Source[i].Name) ;
                textblock.UsedForSectionID := sectionprops.SectionID;
                textblock.RtfText.Assign(Source[i].RTFText);
             end;
          // The current paragraph starts this section
          WPAll.ActiveParagraph.SectionID := sectionprops.SectionID;
          include(WPAll.ActiveParagraph.prop,paprNewSection);
          // Copy the text as part of a certain section
          WPAll.CPPosition := MaxInt;
          WPAll.SelectionAsString := Source.AsANSIString('WPTOOLS' ;)
        end;
     begin
       WPAll.Clear;
       AppendText(WP1.HeaderFooter);
       AppendText(WP2.HeaderFooter);
       AppendText(WP3.HeaderFooter);
     end;

     C++BUILDER Example:
     This code appends the text from a different editor to "WPRichText1" as a new section

     void __fastcall TWPALL::AppendNewSection TWPRTFDataCollection * Source)
                                            (
     {
       TWPRTFSectionProps * sectionprops;
       TWPRTFDataBlock * textblock ;
       int i;

         // Create a new Page if required
         i f (this->WPRichText1->IsEmpty())
         this->WPRichText1->CheckHasBody();
         else this->WPRichText1->InputString(
                                            "f",0);

         // Create new section properties
         sectionprops = this->WPRichText1->HeaderFooter->AddSectionProps();

         // Assign the default page size
         sectionprops->Assign(Source->Header);

         //sectionprops->Select = [wpsec_PageSize,wpsec_Margins];
         sectionprops->Select << wpsec_PageSize << wpsec_Margins ;

         // Copy all header + footer into certain section
         for (i=0; i < Source->Count; i++ )
     {
         TWPRTFDataBlock * src = Source->Items[i] ;
         i f ( src->Kind == wpHeader || src->Kind == wpFooter )
                {
                textblock = this->WPRichText1->HeaderFooter->Append(
                Source->Items[i]->Kind ,
                Source->Items[i]->Range ,
                Source->Items[i]->Name );
                textblock->UsedForSectionID = sectionprops->SectionID;
                textblock->RtfText->Assign(Source->Items[i]->RtfText);




                                                             © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      69


                    }
              }//for()

              // The current paragraph starts this section
              this->WPRichText1->ActiveParagraph->SectionID = sectionprops->SectionID;

              //include(WPAll->ActiveParagraph->prop,paprNewSection);
              this->WPRichText1->ActiveParagraph->prop << paprNewSection ;

              // Copy the text as part of a certain section
              this->WPRichText1->CPPosition = MaxInt;
              this->WPRichText1->SelectionAsString = Source->AsANSIString("WPTOOLS"
                                                                                  );
          }


7.6.6.2   Use utility procedure AppendAsSection
          procedure TWPALL.Append2Click(Sender: TObject);
          begin
            WPAll.HeaderFooter.AppendAsSection(WP1.HeaderFooter);
            WPAll.HeaderFooter.AppendAsSection(WP2.HeaderFooter);
            WPAll.HeaderFooter.AppendAsSection(WP3.HeaderFooter);
          end;


7.6.6.3   Use strings in WPTOOLS format with the <newsection/> tag
          This technique allows it to create a multi section text by simply appending strings or streams
          without loading the text into an editor. This shows how versatile the WPTOOLS format can be used:

          procedure TWPALL.AppendWithStringsClick(Sender: TObject);
          begin
            WPAll.AsString := '<newsection/>' + WP1.AsANSIString('WPTOOLS')
             +'<newsection/>' + WP2.AsANSIString('WPTOOLS')
             +'<newsection/>' + WP3.AsANSIString('WPTOOLS' ;
                                                          )
            // Using <newsection pagebreak=0/> no page break will be inserted
          end;


7.6.6.4   Append section with individual footer (or header)
          You can use WPRichText1.ActiveParagraph.StartNewSection to add a new section property object
          to the current paragraph. The return object will be an object of class TWPRTFSectionProps. In
          property 'Select' you can change which properties should be used for this section.

          Using WPRichText1.HeaderFooter.Append you can append a new RTFDataBlock to be used as
          footer. 'Get' cannot be used, since this will reuse an existing RTFDataBlock.

          procedure TForm1.PortraitLandscapeClick(Sender: TObject);
          var sect : TWPRTFSectionProps;
              footer : TWPRTFDataBlock;
          begin
            WPRichText1.CPPosition := MaxInt;
            Inc(c);
            // start a section
            sect := WPRichText1.ActiveParagraph.StartNewSection;
            sect.Select := [wpsec_PageSize]; // 1. (in this order!)
            sect.Landscape := Sender = Landscape; // 2.

               // Now new page and some text
               WPRichText1.InputString(#12+#32+IntToStr(c)+#13);




© 2004-2008 WPCubed GmbH - Munich, Germany
70    WPTools Version 6


             // also add special header+footer for this section
             footer := WPRichText1.HeaderFooter.Append(wpIsFooter,wpraOnAllPages,''
        );
             footer.UsedForSectionID := sect.SectionID;

             WPRichText1.ActiveText := footer;
             WPRichText1.InputString('Section ' + IntToStr(c) + #9);
             WPRichText1.InputTextFieldName('PAGE');

          WPRichText1.ActiveParagraph.TabstopAdd(
             sect.PageWidth-sect.LeftMargin-sect.RightMargin,
             tkRight,
             tkUnderline );
          // select body again
          WPRichText1.ActiveText := WPRichText1.BodyText;
        end;

        Since WPTools V6 You can also use this API:

        function InputSection(Select: TWPRTFSectionPropsSelect = [wpsec_PageSize, wpsec_Margins]): TWPR
        It returns a new section object.

        This property can be used to retrieve the current section object:

        function ActiveSection: TWPRTFSectionProps;


7.6.7   Use WPTools with TBX (Toolbar2000 Extension)
        Toolbar2000 is a component by Jordan Russel to build a modern GUI.
        It can be extended with TBX, written by Alex A. Denisov.
        You can download and order ToolBar2000 and TBX 2.1 from
        www.g32.org and www.jrsoftware.org . For additional TBX themes check out www.rmklever.com .

        It is easy to create an impressive word processing application using this 2 products and of course,
        WPTools Version 6.

        INFO: Using the WPTools Version 6 Demo VCL You cannot activate the support for TBX combos
        using the define USETBX. Therefore the demo does not install the TBX demo proj ect.

        Note, there is also experimental support for DevExpressBars - use compiler define: USE XP E
                                                                                              E R SSBARS

        1) Please activate the define USETBX in file WPINC.INC or, better, in your project options.

        This modifies the compilation of the units wpruler and wpaction. Please make sure you do a 'compile
        all' after the change.

        2) Create a toolbar (see Toolbar2000 and TBX manual)

        Example:




        3) Now you can bring life to the tool items

        a) For the buttons, such as 'bold'




                                                                   © 2004-2008 WPCubed GmbH - Munich, Germany
Guide         71



         Create a TActionlist on the form. Assign it to the property 'Actionlist' of the editor component,
         TWPRichText.
         In this action list you can create WPTools standard actions, such as TWPABold




         This new actions can be assigned to the 'Action' property of menu items and button elements. Now
         they will automatically work with the attached TWPRichText.

         b) To activate the color drop downs more code is requires.

         If you use 3 drop downs for text color, highlight color and paragraph background color use the tags
         1, 2 and 3.
         Depending on the tags the drawing and OnChange code can be behave differently.

         This code is used in the OnDrawImage event of the button itself.

         procedure TForm1.bColorButtonDrawImage(Item: TTBCustomItem;
           Viewer: TTBItemViewer; Canvas: TCanvas; ImageRect: TRect;
           ImageOffset: TPoint; StateFlags: Integer);
         var
           DC: HDC;
           Color: TColor;
           ColorInd: Integer;
         begin
           DC := Canvas.Handle;
           ColorInd := -1;
           i f not Boolean(StateFlags and ISF_DISABLED) then
           begin
              case Item.Tag o f
                 1: ColorInd := WPRichText1.CurrAttr.GetColorEx(WPAT_CharColor);
                 2: ColorInd := WPRichText1.CurrAttr.GetColorEx(WPAT_CharBGColor);
                 3: ColorInd := WPRichText1.CurrAttr.GetColorEx(WPAT_FGColor);
              else ColorInd := -1;
              end;
              OffsetRect(ImageRect, ImageOffset.X, ImageOffset.Y);
              ImageRect.Top := ImageRect.Bottom - 4;
              i f ColorInd >= 0 then
              begin
                 Color := WPRichText1.CurrAttr.NrToColor(ColorInd);
                 Canvas.Brush.Color := Color;
                 Canvas.FillRect(ImageRect);
              end
              else
              begin
                 FrameRectEx(DC, ImageRect, clBtnShadow, True);
                 DitherRect(DC, ImageRect, clBtnFace, clBtnShadow);
              end;
           end;
         end;




© 2004-2008 WPCubed GmbH - Munich, Germany
72    WPTools Version 6



     Each of the buttons has as subitems (which are used for the dropdown) and ColorPalette.
     We assigned the tags 1,2 and 3 to this 3 color palettes as well and use the same OnChange code.

     procedure TForm1.TBXColorPalette1Change(Sender: TObject);
     var aColor: Integer;
     begin
       aColor := (Sender a s TTBXColorPalette).Color;
       case (Sender a s TTBXColorPalette).Tag o f
          1: WPRichText1.CurrAttr.Color :=
            WPRichText1.CurrAttr.ColorToNr(aColor, true);
          2: WPRichText1.CurrAttr.BKColor :=
            WPRichText1.CurrAttr.ColorToNr(aColor, true);
          3: WPRichText1.CurrAttr.ParColor :=
            WPRichText1.CurrAttr.ColorToNr(aColor, true);
       end;
     end;

     This was already sufficient to make all three color buttons work.

     c) to bring life to the drop down combos, such as the font selection, you only need to use the
     special WPTools' pseudo actions (TWPToolsCustomEditContolAction) which have to be added to
     the action list as well.

     After such an action has been created in category 'WPT_COMBOS', you can select the style in
     property 'AttachedControlStyle' and the list box in property 'AttachedControl'.
     The first time the drop down will be used it will be initialized and the events to modify the attached
     editor will be set. Please note that the combo box styles cbsColor, cbsBKColor, cbsParColor are
     not supported by TWPToolsCustomEditContolAction. The style cbsStandard is the neutral value.




     Note: The TWPToolsCustomEditContolAction can be also used to attach TWPComboBox elements.
     In this case 'AttachedControlStyle' has to be set to cbsStandard.

     Now you can create the horizontal and if required, also the vertical ruler:




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       73




         You only need to attach the ruler controls to the the property WPRuler and VertRuler of the
         TWPRichText Control.
         If you are using a vertical ruler disable the flag wpNoVertRulerAttached in WPRuler.Options.


         How to use the predefined dialogs?

         Please drop one of the dialog components on the form:




         Then set the property 'EditBox' to point to the editor which should be used.

         Using a call to the method 'Execute' the dialog can be opend:




         (Screenshot of the Border dialog. When this dialog is opend all properties are set to 'undefined': the
         user can change any of the elements and leave the other unchanged)




© 2004-2008 WPCubed GmbH - Munich, Germany
74    WPTools Version 6


7.6.8   Set Attributes in code (unit WPCreateDemoText)
        WPTools can be perfectly used to create text and tables in code. This text can be saved in RTF or
        WPTOOLS format, printed and (with wPDF) exported to PDF.

        In unit WPCreateDemoText you will find a procedure which creates text with different character and
        paragraph attributes. We have included this procedure in this chapter and inserted screenshots of
        the output which is created by each part of the code.

        The procedure starts with the variable declaration. Most important is par: TParagraph which is used
        as reference to the current paragraph while the text is created. Each new paragraph (or table) is
        created after this paragraph and the reference is changed to this new object.

        cha: TWPStoredCharAttrInterface is used to create character attribute index values which are then
        used in par.SetText and par.Append methods.


        procedure CreateDemoText(RTFMemo : TWPCustomRtfEdit; Mode : TWPCreateDemoText);
        var par: TParagraph; // The current paragraph or table
          row, cell: TParagraph; // the current rows and cells
          cha: TWPStoredCharAttrInterface;
          HeadlineA, TextA, RedTextA: Cardinal;




          procedure CreateEmptyPar;
          begin
            par := par.AppendNewPar(true);
            par.LoadedCharAttr := TextA; // Default attribute for empty paragraphs
          end;
        begin




          cha := RTFMemo.AttrHelper;
          cha.Clear;
          cha.SetFontName('Times New Roman') ;
          cha.SetFontSize(1 2) ;
          HeadlineA := cha.CharAttr;

          cha.Clear;
          cha.SetFontName('Arial' ;
                                 )
          cha.SetFontSize(1 1) ;
          TextA := cha.CharAttr;

          cha.SetColor(clRed);
          RedTextA := cha.CharAttr;




          i f Mode=wpNewText then // Clear and set page size and margins
          begin




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide    75


           RTFMemo.Clear;

           RTFMemo.Header.SetPageWH(
             WPCentimeterToTwips(1 5) ,
             WPCentimeterToTwips(2 9.7) ,
             WPCentimeterToTwips(1.5) ,
             WPCentimeterToTwips(1.5) ,
             WPCentimeterToTwips(1.5) ,
             WPCentimeterToTwips(1.5)
             );
           RTFMemo.CheckHasBody;
           par := RTFMemo.FirstPar;
           end
           else i f Mode=wpInsertText then // insert at current position
           begin
             par := RTFMemo.InsertPar;
           end
           else i f Mode=wpAppendText then // append at end of text
           begin
             par := RTFMemo.ActiveText.LastPar;
             CreateEmptyPar;
           end;




           // Set the text of the first paragraph
           par.SetText('A paragraph with a green background:', HeadlineA);

           // append a new, clean paragraph and set attributes
           par := par.AppendNewPar(true);
           par.ASetColor(WPAT_BGColor, clGreen);
           par.ASet(WPAT_ShadingValue, 3 0) ;
           par.SetText('This is 30 % green', TextA);

           CreateEmptyPar;

           Please see reference for supported WPAT_ codes.




           par := par.AppendNewPar(true);
           par.SetText('A paragraph with a red background and borders:', HeadlineA);
           // append a new, clean paragraph and set attributes
           par := par.AppendNewPar(true);
           // Indents
           par.ASet(WPAT_IndentLeft, WPCentimeterToTwips(2));
           par.ASet(WPAT_IndentRight, WPCentimeterToTwips(2));
           // Border
           par.ASet(WPAT_BorderFlags,
             WPBRD_DRAW_Left + WPBRD_DRAW_Right + WPBRD_DRAW_Top + WPBRD_DRAW_Bottom); // =
         WPBRD_DRAW_All4
           par.ASet(WPAT_BorderWidth, WPCentimeterToTwips(0.0 5)); // 0,5 mm




© 2004-2008 WPCubed GmbH - Munich, Germany
76    WPTools Version 6


      par.ASetColor(WPAT_BGColor, clRed);
      par.ASet(WPAT_ShadingValue, 5 0) ;
      par.SetText('This is 50 % red, indented', TextA);
      CreateEmptyPar;




      par := par.AppendNewPar(true);
      par.SetText('A paragraph with colored borders and spacing', HeadlineA);
      par := par.AppendNewPar(true);
      par.ASet(WPAT_SpaceBefore, WPCentimeterToTwips(0.1)); // 1 mm padding
      par.ASet(WPAT_SpaceAfter, WPCentimeterToTwips(0.1)); // 1 mm padding
      par.ASet(WPAT_IndentLeft, WPCentimeterToTwips(0.1)); // 1 mm padding
      par.ASet(WPAT_SpaceBefore, WPCentimeterToTwips(0.1)); // 1 mm padding

      par.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4); // all lines
      par.ASet(WPAT_BorderWidth, WPCentimeterToTwips(0.0 5)); // 0,5 mm
      par.ASetColor(WPAT_BorderColorL, clRed); // Left
      par.ASetColor(WPAT_BorderColorT, clGreen); // Top
      par.ASetColor(WPAT_BorderColorR, clBlue); // Right
      par.ASetColor(WPAT_BorderColorB, clYellow); // Bottom
      par.SetText('Red, Green, Blue, Yellow', TextA);
      CreateEmptyPar;




      par := par.AppendNewPar(true);
      par.SetText('A paragraph with tabstops', HeadlineA);
      par := par.AppendNewPar(true);
      par.TabstopAdd(WPCentimeterToTwips(3), tkLeft);
      par.TabstopAdd(WPCentimeterToTwips(9), tkRight, tkDots);
      par.TabstopAdd(WPCentimeterToTwips(1 2), tkRight, tkNoFill);

      par.Append('START' RedTextA);
                         ,
      par.Append(# 9 + 'from' + # 9 + 'to' + # 9, TextA);
      par.Append('END', RedTextA);
      CreateEmptyPar;




      // CREATE A HORIZONTAL LINE
      CreateEmptyPar;
      with par.AppendNewObject(wpobjHorizontalLine) d o
      begin
        IParam := clGreen;
        // Width := WPCentimeterToTwips(10);
        CParam := -WPCentimeterToTwips(1) ;
      end;
      CreateEmptyPar;

     horizontal lines can use the follow ing parameters:
     Width: w idth in tw ips, if 0 the printable area is used




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   77


          CParam:the offset to the margins of the printable area. Native values are possible
          IParam:the color as RGB value
          Height: the height in tw ips

          Note: AppendNew Object() and AppendNew ObjectPair() can also be used to create hyperlinks .




           par := par.AppendNewPar(true);
           par.SetText('A table with colored borders', HeadlineA);

           par := par.AppendNewTable; // a new table
           par.ASet(WPAT_BoxWidth, WPCentimeterToTwips(9)); // 9 cm wide
           par.ASet(WPAT_BoxMarginLeft, WPCentimeterToTwips(2)); // 2 cm from left margin

           row := par.AppendNewRow(true); // the first row
           row.ASet(WPAT_PaddingAll, WPCentimeterToTwips(0.2));                          // 2 mm padding

           cell := row.AppendNewCell;
           pacell.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4); // all lines
           cell.ASet(WPAT_BorderWidth, WPCentimeterToTwips(0.0 5)); // 0,5 mm
           cell.ASetColor(WPAT_BorderColorL, clRed); // Left
           cell.ASetColor(WPAT_BorderColorT, clGreen); // Top
           cell.ASetColor(WPAT_BorderColorR, clBlue); // Right
           cell.ASetColor(WPAT_BorderColorB, clYellow); // Bottom
           cell.SetText('Cell A', RedTextA);
           cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(3)); // 3 cm wide

           cell := cell.AppendNewCell(false); // new cell, same colors
           cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(3)); // 3 cm wide
           cell.SetText('Cell B', RedTextA);

           cell := cell.AppendNewCell(false); // new cell, same colors
           cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(3)); // 3 cm wide
           cell.SetText('Line 1', TextA);
           cell.AppendNewPar(true).SetText('Line 2',TextA);

           // and a second row
           row := row.AppendNewRow(true); // the first row
           cell := row.AppendNewCell;
           cell.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4);
           cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(9));
           cell.SetText('second cell', HeadlineA);




           RTFMemo.DelayedReformat;
         end;




© 2004-2008 WPCubed GmbH - Munich, Germany
78    WPTools Version 6


7.6.9   Tables

        WPTools Version 6 tables are very powerful:




        A table is handled like a paragraph object which contains multiple paragraphs as children. These
        are the rows. In turn, the rows contain multiple paragraphs which are the cells. Each cell paragraph
        can contain multiple paragraphs which are either text lines or tables:




        This makes WPTools tables very similar to HTML tables:

        <table>
          <tr>
            <td>Cell   1 in Row 1</td>
            <td>Cell   2 in Row 1</td></tr>
          <tr>
            <td>Cell   1 in Row 2</td>
            <td>Cell   2 in Row 2</td></tr></table>

        One possibility to create a table is to use the CreateTable API function:

          var aCell : TParagraph;

          with WPRichText1.Memo.DisplayedText.CreateTable(nil) d o
          begin
            ASet(WPAT_BorderFlags, WPBRD_DRAW_All4);
            with CreateRow(nil, true) d o
            begin
              InputCell.SetText('Cell 1') ;
              InputCell.SetText('Cell 2') ;
              EndRow(ThisRowStyle)
            end;
            with CreateRow(nil, true) d o
            begin
              InputCell.SetText('Cell 3') ;
              aCell := InputCell;
              with aCell d o
              begin
                 // You could create more text ort a sub table ...




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       79


                 end;
                 EndRow(ThisRowStyle)
              end;
            end;

          The table is created using the 'CreateTable' function of the TWPRTFDataBlock object. The parameter
          for this function is the paragraph after which the new table should be created. You can use 'nil' to
          create a table at the end of the document. The resulting value of this function is the TParagraph
          object which will contain all new rows. Use the CreateRow function of this paragraph to create a new
          row. The resulting value of the CreateRow function is a TWPTableRowStyle object, which serves as
          the default style for all cells created and also provides the function to create new cells. This object is
          deallocated by 'EndRow'.

          The other possibility is to use the API TableAdd() with a callback function to initialize the table
          cells. This is usually the more powerfull way to do it. Please see next chapter for various examples.




7.6.9.1   Set width in inch of a certain column


          Note: The function TParagraph._IsWidth_tw returns the current width of a cell in twips. Please note
          that this function requires the text to be formatted.

          Example 1)

          In this example we do not only set the width of a certain column but adjust the width of the parent
          table to fit in all columns:

          var cellwidth_tw, newwidth_tw : Integer; // Twip Values!
              par, cell, row : TParagraph;
          begin
              // cellwidth_tw := WPValueEdit1.Value; // Use a WPValueEdit to enter the
          number
              cellwidth_tw := WPInchToTwips(2.5) // use a fixed INCH value

               row := WPRichText1.TableRow;
               cell := WPRichText1.ActiveParagraph.Cell;
               i f (row=nil) o r (cell=nil) then
                   ShowMessage('Please position the cursor in a cell!')
               else
               begin
                   // Calculate current width of all columns
                   newwidth_tw := 0;
                   par := row.ChildPar; // this are the cells in this row
                   while par<>nil d o
                   begin
                      i f par=cell then inc(newwidth_tw, cellwidth_tw )
                      else inc( newwidth_tw, par._IsWidthTw );
                      par := par.NextPar; // Sibling cell !
                   end;
                   // Make sure we do not use % values !
                   row.ParentTable.FixAllCellWidths(0) ;
                   // Assign TWIPS value to THIS column
                   cell.ASetColumn (WPAT_COLWIDTH, cellwidth_tw);
                   // And set the table width to fit all coluns
                   row.ParentTable.ASet(WPAT_BoxWidth, newwidth_tw);
                   // Reformat
                   WPRichText1.DelayedReformat;




© 2004-2008 WPCubed GmbH - Munich, Germany
80    WPTools Version 6


            end;
     end;

     Example 2)

     This extended example creates an array of TWPValueEdit controls in a scrollbox to let the user see
     and adjust the width of each individual column:




     // This is the UpdateGrid procedure
     procedure TForm1.UpdateWidthGridClick(Sender: TObject);
     var i: Integer;
       cell, row: TParagraph;
       ctrl: TWPValueEdit;
     begin
         // Empty the scrollbox
       for i := ScrollBox1.ControlCount - 1 downto 0 d o
         with ScrollBox1.Controls[i] d o
         begin
           Parent := nil;
           Free;
         end;

          // Fill the scrollbox
       row := WPRichText1.TableRow;
       cell := WPRichText1.ActiveParagraph.Cell;
       i f (row = nil) o r (cell = nil) then
          ShowMessage('Please position the cursor in a cell!')
       else
       begin
            // Make sure we do not use % values !
          row.ParentTable.FixAllCellWidths(0) ;
            // Create ColCount edits:
          for i := 0 t o row.ColCount - 1 d o
          begin
            ctrl := TWPValueEdit.Create(ScrollBox1);
            ctrl.Left := i * 8 0;
            ctrl.Width := 7 8;
            ctrl.Parent := ScrollBox1;
            ctrl.Tag := i; // ColNr
            ctrl.UnitType := euInch; // euCm for Centimeters
            ctrl.Value := row.Cols[i]._IsWidthTw;
            ctrl.OnChange := CellValueEditChange;
          end;
       end;
     end;

     // OnChange event handler for each TWPValueEdit in array
     procedure TForm1.CellValueEditChange(Sender: TObject);
     var i, w: Integer;
       cell: TParagraph;
     begin
       i f WPRichText1.TableRow <> nil then
          cell := WPRichText1.TableRow.Cols[(Sender a s TWPValueEdit).Tag]
       else cell := nil;




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   81


            i f cell <> nil then
            begin
            // Calculate sum of all width
               w := 0;
               for i := 0 t o ScrollBox1.ControlCount - 1 d o
                 inc(w, TWPValueEdit(ScrollBox1.Controls[i]).Value);
            // and apply to table

               cell.ParentTable.ASet(WPAT_BoxWidth, w);
            // and apply to column
               cell.ASetColumn(WPAT_COLWIDTH, (Sender a s TWPValueEdit).Value);
            // Reformat
               WPRichText1.DelayedReformat;
            end;
          end;


7.6.9.2   Work with % width


          WPTools Version 6 also has the ability to use % values for column widths. The procedure
          WPRichText1.TableMakeCellWidthPC         converts all tables in the document to measure the column
          width in %.

          If the flag wpAlwaysColWidthPC was set in property EditOptionsEx this procedure is executed
          after a file was loaded and after each change to the column width using the mouse.

          The % column widtn is stored as property WPAT_ColWidthPC as %*100.

            // Set the width in 5, example 10%
            WPRichText1.ActivePar.ASetColumn(WPAT_COLWIDTH_PC, 1000) ;
            // Delete the fixed width since it has priority
            WPRichText1.ActivePar.ADelColumn(WPAT_ColWidth);
            // Reformat the text
            WPRichText1.DelayedReformat;



7.6.10 Create Table in Code
          Very often you will have to create a table, for example a calculation.

          This can be done best using the TableAdd procedure. This procedure requires only a few
          parameters, such as row cont and column count but can also work with a callback procedure which
          is executed for each created cell.

          Since the callback procedure receives information about the current column and row number it is
          easy to apply special properties to certain cells or preset the contents of the created cell.

            Note: You can also use the Rows[r].Cols[c] arrays as described in the second
            part of this chapter but then you have to take care that you work with the correct
            row index. Using this arrays is probably also a little slower.

            Please see reference for supported WPAT_ codes.

          a) Use TableAdd() with a callback function

          This code will append a new table to the end of the text:

            WPRichText1.TableAdd(7,7,
               [wptblActivateBorders,wptblAppendTableAtEnd],nil, InvoiceDemoCell);




© 2004-2008 WPCubed GmbH - Munich, Germany
82     WPTools Version 6




     This is a screen shot of the created table:




     The callback procedure InvoiceDemoCell is implemented like this

     procedure TWPTableCalc.InvoiceDemoCell(RowNr, ColNr: Integer; par: TParagraph);
     const prods : array[1. .5] o f string =
      ( 'Cool', 'Master' 'Hummer' 'High Performace', 'Better' );
                        ,           ,
     begin
       // Set the widths of the rows
       case ColNr o f
            1 : par.ASet(WPAT_COLWIDTH_PC, 500); // % * 100 !
            2 : par.ASet(WPAT_COLWIDTH_PC, 2500) ;
            else
            begin
               par.ASet(WPAT_COLWIDTH_PC, 1400) ;
               par.ASet(WPAT_Alignment, Integer(paralRight));
            end;
       end;

       // Set the text and the cell names and commands

       i f RowNr=1 then // Header Row ------------------------------
       begin
           case ColNr o f
             1 : ;
             2 : par.SetText('Product' ; )
             3 : par.SetText('Price' ;
                                     )
             4 : par.SetText('Amount' ;)
             5 : par.SetText('net') ;
             6 : par.SetText('+VAT') ;
             7 : par.SetText('total' ;
                                     )
           end;
           par.ASetColor(WPAT_FGColor, $A0A0A0 ;
                                               )
           par.ASet(WPAT_ParProtected,1) ;
           par.ASet(WPAT_Alignment, Integer(paralCenter));
       end else
       i f RowNr=7 then // Footer Row ------------------------------
       begin
           par.ADel(WPAT_BorderWidth); // Delete the border width for ALL linese
           par.ASet(WPAT_BorderWidthT, 4 0); // ANd set the top line to 40 twips
           par.ASetAdd( WPAT_BorderFlags, WPBRD_DRAW_Top); // Add a flag!
           // par.ParentRow.ASet(WPAT_BoxMinHeight, WPCentimeterToTwips(1.5));
           par.ASet(WPAT_SpaceBefore, WPCentimeterToTwips(0.3));
           par.ASet(WPAT_SpaceAfter, WPCentimeterToTwips(0.3));
           par.ASet(WPAT_ParProtected,1) ;
           case ColNr o f
             1 : ;
             2 : ;




                                                             © 2004-2008 WPCubed GmbH - Munich, Germany
Guide    83


                 3 : ;
                 4 : ;
                 5 : begin
                       par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_NET' ;
                                                                     )
                     end;
                 6 : begin
                        par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_VAT' ;
                                                                       )
                     end;
                 7 : begin
                        par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_TOTAL' ;
                                                                         )
                        par.ASetCharStyle(true, WPSTY_BOLD);
                     end;
               end;

           end else // Data Rows ------------------------------
           begin
              case ColNr o f
                 1 : begin
                        par.SetText(IntToStr(RowNr-1));
                        par.ASet(WPAT_ParProtected,1) ;
                     end;
                 2 : par.SetText(prods[RowNr-1]);
                 3 : par.SetText(IntToStr(Random(1000) +1));
                 4 : par.SetText(IntToStr(Random(3) +1));
                 5 : begin
                       par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)*left(1)' ;
                                                                             )
                       par.ASetStringProp(WPAT_PAR_NAME, 'PAR_NET' ;
                                                                  )
                       par.ASet(WPAT_ParProtected,1) ;
                     end;
                 6 : begin
                        par.ASetStringProp(WPAT_PAR_COMMAND, 'left(1)*0.16' ;
                                                                          )
                        par.ASetStringProp(WPAT_PAR_NAME, 'PAR_VAT' ;
                                                                    )
                        par.ASet(WPAT_ParProtected,1) ;
                     end;
                 7 : begin
                        par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)+left(1)' ;
                                                                               )
                        par.ASetStringProp(WPAT_PAR_NAME, 'PAR_TOTAL' ;
                                                                      )
                        par.ASet(WPAT_ParProtected,1) ;
                     end;
               end;
           end;
         end;

         Note: The commands
                            par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)+left(1)' ;
                                                                                 )
                            par.ASetStringProp(WPAT_PAR_NAME, 'PAR_TOTAL' ;
                                                                         )
         are only usable with WPTools Bundle. They are used to add calculation to a table.


         b) Use TableAdd() and the Rows[] and Cols[] arrays

         This example appends 2 rows to the current table (a new table is created if necessary) and loads an
         image in the second cell of the first row.

         Screen shot of the created table. (Only the first row is visible.)




© 2004-2008 WPCubed GmbH - Munich, Germany
84    WPTools Version 6




     procedure TForm1.CreateTableWithImageClick(Sender: TObject);
     var tbl: TParagraph;
       obj: TWPTextObj;
       img: TWPOImage;
       imagefilename: string;
       rowoffset : Integer;
     begin
      // Select the image from file or use a local image
       imagefilename := ' ';
       i f SelectImageFile.Checked then
       begin
          i f OpenPictureDialog1.Execute then
             imagefilename := OpenPictureDialog1.FileName
          else exit;
       end;

      // Create the image object
       img := TWPOImage.Create(WPRichText1); // uses WPObj_Image
       try
         i f imagefilename = ' ' then img.Picture.Assign(Image2.Picture)
         else img.LoadFromFile(imagefilename);
       except
         img.Free; // We cannot load this image
         raise;
       end;

       // This code is required if we do *not* use the wptblAppendTableAtEnd option.
       // since than an existing table is enlarged
       tbl := WPRichText1.Table;
       i f tbl<>nil then
       begin
           rowoffset := tbl.RowCount;
           WPRichText1.ActiveParagraph := tbl.LastChild.ColFirst;
       end
       else rowoffset := 0;

      // Create the table and after that modify the cells
      // makes sure a new table is created at the end!
       tbl := WPRichText1.TableAdd(2, 1, [wptblActivateBorders],nil, nil) ;

       // Set text of first column
       tbl.Rows[rowoffset+0].Cols[ 0].SetText(imagefilename);

      // Create the TWPTextObj (which is the reference to image)
       obj := tbl.Rows[rowoffset+0].Cols[1].AppendNewObject(wpobjImage, false, false, 0
     );
       obj.ObjRef := img;
       obj.Frame := [wpframeFine];

      // Set the size of the image
       obj.Width := img.ContentsWidth * 2;
       obj.Height := img.ContentsHeight * 2;




                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       85



           // Empty row, no borders - move cursor to first cell
           WPRichText1.ActiveParagraph := tbl.ColFirst;
           tbl := WPRichText1.TableAdd(2, 1, [], nil, nil) ;
           WPRichText1.ActiveParagraph := tbl.ColFirst;

          // Format and display changed text
           WPRichText1.Refresh;
         end;

         c) Create a table with a header and footer row which are repeated on each page




         This feature is controlled by the flags paprIsFooter and paprIsHeader in the property TParagraph.par.
         The property must be set in the row paragraph which is the parent paragraph of a cell. The API
         TableAdd does this for you.

         We suggest to use this feature with the flag wpfDontBreakTableRows in FormatOptions.
         In any case please set the property wpDisableSpeedReformat.

         Example code:

         procedure TForm1.CreateTableCellCallBackHF(RowNr, ColNr: Integer; par:
         TParagraph);
         begin
           i f RowNr = - 1 then // THIS CELL IS IN THE HEADER




© 2004-2008 WPCubed GmbH - Munich, Germany
86     WPTools Version 6


          begin
             par.ASetColor(WPAT_BGColor, clBtnFace);
             i f ColNr = 1 then par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5) )
             else par.SetText('HEADER' ;
                                       )
          end
          else i f RowNr = - 2 then // THIS CELL IS IN THE FOOTER
          begin
             par.ASetColor(WPAT_BGColor, clBtnFace);
             i f ColNr = 1 then par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5) )
             else par.SetText('FOOTER' ;
                                       )
          end else
          begin
             i f (RowNr and 1) = 0 then par.ASetColor(WPAT_BGColor, clYellow);
             i f ColNr = 1 then
             begin
                par.ASetColor(WPAT_BGColor, clBtnFace);
                par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5));
                par.SetText(IntToStr(RowNr));
             end else
             begin
                par.SetText(IntToStr(FCellNr));
                inc(FCellNr);
             end;
          end;
        end;

        procedure TForm1.CreateTableWithHeaderFooterClick(Sender: TObject);
        begin
          WPRichText1.Clear;
          FRowCount := 200; // count of rows, excluding header and footer!
          WPRichText1.FormatOptions := [wpDisableSpeedReformat wpfDontBreakTableRows ;
                                                              ,                    ]
          WPRichText1.TableAdd (
             4, FRowCount,
             [wptblActivateBorders,wptblCreateHeaderRow,wptblCreateFooterRow nil,
                                                                            ],
             CreateTableCellCallBackHF;
                                      )
          WPRichText1.Refresh;
        end;




7.6.11 Work with Styles and Stylesheets (in code)
        WPTools Version 6 has powerful possibilities to work with text styles.

        This one is one of the most important chapters of this manual since it explains how the styles -
        which are the heart of WPTools Version 6 - can be used and controlled.

        1) What is a 'style'?

        A text style is a collection of text attributes which are used for a certain text unless the text itself
        overrides the attributes. So if you have a style which defines two properties, the font name and the
        font size and assign it to some text this text will be displayed in the select font in the selected size.
        If the text was created to use the font size, ie. 10, this font size will be used and not the font size
        defined in the style.
        Please note that borders can not be be defined in styles.

        Text styles usually have names, for example 'Headline' or 'Normal'. Using the names you can select
        a style from the list of styles and assign it to a paragraph. This assignment usually does not modify




                                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       87


         the attributes of the text. (NOTE A)

         2) The demo project (Demos/Tasks/ParStyle):




         This demo shows different ways to deal with the styles. You can play with the default attribute and
         the properties of one if the styles (FIRST) and immediately see the effect.

         3) The default attribute

         This attribute (or elements of it) will be used for all the text which does not have an attribute ion its
         own.

         In this demo we initialize the default attribute using:

           WPRichText1.DefaultAttr.SetFontName(ComboBox1.Text);
           WPRichText1.DefaultAttr.SetFontSize(WPValueEdit2.Value / 2 0) ;

         While the demo is running you can change the defined values and immediately see the effect. So all
         the paragraph styles (FIRST and SECOND) set their own font size - changing the default will not
         change the display. But if you are changing the font name, you will see the change not only in the
         first line but also in the 3rd line:




© 2004-2008 WPCubed GmbH - Munich, Germany
88     WPTools Version 6



     So how is text created which only uses the default attribute?

       par := WPRichText1.ActiveText.AppendPar;
       par.SetText('1) This line uses no style - It uses WPRichText1.DefaultAttr !') ;

     But in general, when you write text into the editor and no specific font was selected - that entry will
     be 'undefined' and the default will be used.

     4) Creating a paragraph style

     In this demo we create a style (sty : TWPTextStyle;) like this:

       sty := WPRichText1.ParStyles.AddStyle('FIRST' ;
                                                    )

     and then assign properties using the ASet methods:

       sty.ASetAddCharStyle(WPSTY_BOLD);
       sty.ASetFontName('Verdana' ;
                                 )
       sty.ASet(WPAT_CharFontSize, 1 3 * 100) ;

       Please see reference for supported WPAT_ codes.

     Many customers have asked why the styles do not have properties, such as sty.FontName? The
     reason for this is that using functions to read and write the properties we can support the
     <undefined> state. This means that if a font name was not set in a style we can react on that (by
     using the inherited font name). In general are the ASet... methods used to write a property while the
     AGet function are used to read it. They usually require a var parameter which will be changed. The
     result value of an AGet function is TRUE if the property was defined, otherwise it is FALSE. There is
     also the AGetDef() function which returns the property value itself, if it was not found it returns the
     default which was passed as parameter. (Read more about ASet)

     To use the paragraph style we can set the name
       par.ABaseStyleName := 'FIRST';

     or the style:
       par.ABaseStyle := sty;

     Important: Only the attributes which are not overridden in the paragraph or the character
     attributes whill be retrieved from the attached style.

     This code will simply attach a style, it will not modify any properties of the paragraph or the text in
     this paragraph. So it is possible that the text does not use certain attributes of the style since they
     are overridden.

     a) To remove the attributes which are defined by a style you can use the method SetStyle which
     can be used with a style number, a style name or the reference to an item of the ParStyles
     collection. Two optional parameters control if the paragraph attributes and/or the character attributes
     should be adjusted to make all style attributes visible.   par.SetStyle( 'FIRST' , true,
     true);

     b) If you are working with selected text, you can use the procedure SelectedTextAttr.ClearAttr(false,
     true) to remove all styles from the selected text, only the paragraph styles will be used.

     You can also use SelectedTextAttr.ClearAttrOverride - this will remove the attributes which are used
     in the paragraph styles. So the attributes which are not override attributes will be preserved, the
     attributes which will otherwise hide the paragraph style attributes will be removed.




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       89



         5) Saving and loading

         Save and restore style sheet in WPCSS format

         // Save:
            Memo1.Text := WPRichText1.ParStyles.GetWPCSS;
         //or
            WPRichText1.ParStyles.SaveToFile('c:stylesheet.wpcss' ;
                                                                 )
         // Load:
            WPRichText1.ParStyles.SetWPCSS(Memo1.Text);
            WPRichText1.ReformatAll(true,true);
         //or
            WPRichText1.ParStyles.LoadFromFile('c:stylesheet.wpcss' ;
                                                                    )
            WPRichText1.ReformatAll(true,true);

         Save and restore style sheet in CSS format (WPTools 6 only)

         You can save the paragraphs to a string using

          a_string := WPRichText1.SaveCSSheet;

         And load it using

           WPRichText1.LoadCSSheet( a_string );

         6) Creating embedded SPAN objects (Line 3)

         Especially to provide strong HTML support WPTools Version 6 can work with embedded SPAN
         styles. This are special objects which are embedded into the text. They are always used in pairs,
         one opening and one closing. The opening object can select a style and the closing object selects
         the previous settings again.

         If you are working with RTF you should not use SPAN objects.

         In this demo we create the objects right in the TParagraph object. If you need a less abstract way to
         work with the objects please check out the 'Code' procedures implemented in TWPRichText. They
         make it easy to create the objects, for example wrap selected text into a pair of SPAN tags.

           par := WPRichText1.ActiveText.AppendPar;
           pos := par.Insert(0, '3) SECOND STYLE - except for ',0) ;
           spanobj_open := par.InsertNewObject pos,wpobjSPANStyle, true, false) ;
                                               (
           spanobj_open.StyleName := 'FIRST';
           inc(pos);
           pos := par.Insert(pos, '<SPAN "FIRST">',0) ;
           spanobj_close := par.InsertNewObject(pos,wpobjSPANStyle, true, true) ;
           spanobj_close.SetTag(spanobj_open.NewTag); //<-- tags are used to link start
         with end!
           inc(pos);
           pos := par.Insert(pos, ' - END',0) ;
           par.ABaseStyleName := 'SECOND';

         The variables spanobj _open and spanobj _close are of type TWPTextObj. They are created by
         InsertNewObject which requires four parameters:
           index: Integer;
           objtype TWPTextObjType;
                  :
           HasClosing IsClosing Boolean
                     ,        :

         Please note how the value for 'IsClosing' is alternated the the demo source code. "pos" is an integer




© 2004-2008 WPCubed GmbH - Munich, Germany
90     WPTools Version 6


     value which is the index into the paragraph. The insert() function always returns the position after the
     inserted text, so pos is always incremented.

     Please note, that for each open SPAN object the closing object must be on the same paragraph. If
     you need a linebreak you can use the code Char(10) to create a soft line break.

     Usually SPAN objects are not visible. They can be made visible using the flag
     wpShowSPANCodes in property Formatoptions. The display is controlled by property
     SPANObjectTextAttr, the text can be changed using SPANObjectTextAttr.CodeOpeningText and
     SPANObjectTextAttr.CodeClosingText (%Y inserts the StyleName).


     7) Working with the Character Attributes (Line 4)

     In this demo we wanted to show how to use the low level methods. You can of course also create
     text using the procedure InputString and modify the current writing mode using the interface 'CurrAttr'
     - the demo GridMode uses the InputString technology. But this demo creates the text a bit
     differently. Please don't read on if you find this confusing. Using the AttrHelper interface ist
     usually much easier.

     First we need a buffer for our character attributes:
       ca : TWPCharAttr;

     Then we create the paragraph:
       par := WPRichText1.ActiveText.AppendPar;

     The buffer is initialized with
       FillChar(ca, SizeOf(ca), 0);
     If you are using Delphi 8 you can define another emptyca : TWPCharAttr and assign it to clear ca.

     Now we fill the paragraph by appending text.

       pos := par.Insert(0,'4) DEFAULT "FIRST" ',0) ;
       par.RTFProps.AttrInterface.SetCharStyles(ca, WPSTY_ITALIC, WPSTY_ITALIC);
       par.RTFProps.AttrInterface.SetFontSize(ca, 1 2) ;
       pos := par.Insert(pos,'12ptITALIC ',ca);

     "pos" is an integer value which is the index into the paragraph. The insert() function always returns
     the position after the inserted text, so pos is always incremented.

     The lines with par.RTFProps.AttrInterface.... used to modify ca - which in the end will be
                                                 are
     used as parameter to insert().

     AttrInterface is an object of class TWPCharAttrInterface. This class is not used to store attributes
     but to modify buffer variables of type TWPCharAttr!

     8) The complete source of the "Init Text" procedure

     var par: TParagraph;
       sty: TWPTextStyle;
       pos: Integer;
       spanobj_open, spanobj_close: TWPTextObj;
       ca: TWPCharAttr;
     begin
       WPRichText1.DefaultAttr.SetFontName(ComboBox1.Text);
       WPRichText1.DefaultAttr.SetFontSize(WPValueEdit2.Value / 2 0) ;

       WPRichText1.Clear;




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide    91


           // Set BODY
           WPRichText1.ActiveText := WPRichText1.BodyText;
           // ---------------------------------------------------- FIRST LINE -----------
           // We use the DefaultAttr ----------------------------------------------------
           par := WPRichText1.ActiveText.AppendPar;
           par.SetText('1) This line uses no style - It uses WPRichText1.DefaultAttr !') ;
           // ---------------------------------------------------- SECOND LINE ----------
           // We use the default Style for the complete paragraph -----------------------
           // Creates Style
           sty := WPRichText1.ParStyles.AddStyle('FIRST' ;
                                                         )
           // Create Paragraph
           par := WPRichText1.ActiveText.AppendPar;
           par.SetText('2) This line uses the FIRST style') ;
           // Assign Style
           par.ABaseStyle := sty;
           // Set Props
           sty.ASetAddCharStyle(WPSTY_BOLD);
           sty.ASetFontName('Verdana' ;
                                     )
           sty.ASet(WPAT_CharFontSize, 1 3 * 100) ;
           // ---------------------------------------------------- THIRD LINE -----------
           // We embedd a SPAN style ----------------------------------------------------
           // Creates Style
           sty := WPRichText1.ParStyles.AddStyle('SECOND' ;)
           // Set Props
           sty.ASetAddCharStyle(WPSTY_ITALIC);
           sty.ASet(WPAT_CharFontSize, 1 0 * 100) ;
           // Create Paragraph
           par := WPRichText1.ActiveText.AppendPar;
           pos := par.Insert(0, '3) SECOND STYLE - except for ', 0) ;
           spanobj_open := par.InsertNewObject(pos, wpobjSPANStyle, true, false);
           spanobj_open.StyleName := 'FIRST' ;
           inc(pos);
           pos := par.Insert(pos, '<SPAN "FIRST">', 0) ;
           spanobj_close := par.InsertNewObject(pos, wpobjSPANStyle, true, true);
           spanobj_close.SetTag(spanobj_open.NewTag); //<-- tags are used to link start
         with end!
           inc(pos);
           par.Insert(pos, ' - END', 0) ;
           par.ABaseStyleName := 'SECOND' ;
           // ----------------------------------------------------- 4th LINE ------------
           // We use character attributes -----------------------------------------------
           // 'ca' is used as buffer to create a char attribute
           par := WPRichText1.ActiveText.AppendPar;

           FillChar(ca, SizeOf(ca), 0) ;
           pos := par.Insert(0, '4) DEFAULT "FIRST" ', 0) ;
           par.RTFProps.AttrInterface.SetCharStyles(ca, WPSTY_ITALIC, WPSTY_ITALIC);
           par.RTFProps.AttrInterface.SetFontSize(ca, 1 2) ;
           pos := par.Insert(pos, '12ptITALIC ', ca);

           FillChar(ca, SizeOf(ca), 0) ;
           par.RTFProps.AttrInterface.SetFontName(ca, 'Courier New') ;
           par.RTFProps.AttrInterface.SetFontSize(ca, 1 0) ;
           par.RTFProps.AttrInterface.SetColor(ca, clGreen);
           pos := par.Insert(pos, '10ptGreenCourier ', ca);

           FillChar(ca, SizeOf(ca), 0) ;
           par.RTFProps.AttrInterface.SetColor(ca, clBlue);
           par.Insert(pos, 'blue text', ca);

           // Assign the FIRST Style
           par.ABaseStyleName := 'FIRST';




© 2004-2008 WPCubed GmbH - Munich, Germany
92    WPTools Version 6



       // ----------------------------------------------------- last LINE --------
       // We use a character style -----------------------------------------------
       // 'ca' is used as buffer to create a char attribute
       par := WPRichText1.ActiveText.AppendPar;

       FillChar(ca, SizeOf(ca), 0) ;
       pos := par.Insert(0, '5) default ', 0) ;
       par.RTFProps.AttrInterface.SetCharStyleSheet(ca,
                par.RTFProps.ParStyles.GetID('FIRST'));
       pos := par.Insert(pos, 'with chararacter-style FIRST', ca);
       par.Insert(pos, ' default (RTF does not preserve character styles)', 0) ;
     end;

     9) Working with CSS

     CSS means Cascading Style Sheet and is used to store any kind of paragraph and character
     attributes in HTML files. WPTools Version 6 was created keeping in mind the philosophy of both,
     CSS and RTF to provide the developer the best of both worlds.


     [>>] WPTools' TWPTextStyle class has the ability to dump its properties (to be exact: only the
     properties supported by CSS) as a CSS string:

     var sty : TWPTextStyle;
     begin
        sty := WPRichText1.ParStyles.FindTextStyle('FIRST' ;
                                                          )
        i f sty<>nil then
            CSS1.text := sty.AGet_CSS(true,false,true);
     end;

     [<<] To load a CSS string back into a TWPTextStyle you can use the TWPCSSParserStyleWP
     which is implemented in unit WPIOCSS:

     var sty : TWPTextStyle;
          parser : TWPCSSParserStyleWP;
     begin
        sty := WPRichText1.ParStyles.FindTextStyle('FIRST' ;
                                                           )
        i f sty<>nil then
        begin
            parser := TWPCSSParserStyleWP.Create;
            try
               parser.AsString := CSS1.text;
               parser.ApplyToStyle(sty);
               WPRichText1.ReformatAll(true); // Initialize all because we changed the
     font
               WPRichText1.Repaint;
            finally
               parser.Free;
            end;
        end;
     end;

     Please note that the TParagraph inherits from TWPTextStyle - so the above techniques can
     be also used for any paragraph object!

     10) Working with WPCSS

     WPTools can work with string representation of property settings. Theses are called WPCSS strings
     due to their similarity to CSS.




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       93



         To read a WPCSS string use

         function TWPTextStyle.AGetWPSS(
               Names,
               CharAttr,
               TabAttr: Boolean;
               OnlyUsePTag: Boolean = FALSE;
               Abbreviated: Boolean = FALSE): AnsiString;

         To write it use

         procedure TWPTextStyle.ASetWPSS(
               const WPCSSString: AnsiString;
               Merge: Boolean = false;
               Abbreviated: Boolean = FALSE);

         If OnlyUsePTag is set to TRUE no style names are written. You should not use this feature if you
         want to store the created string. It will be invalid the next time the text is created.

         If Abbreviated is TRUE the short form for the property names will be used.




7.6.12 Numbering
         In WPTools Version 6 you can create paragraphs with bullets, simple numbering our outline
         numbering.

         The numbering is always controlled by the collection NumberStyles which is accessible by
         TWPRichText.NumberStyles.

         Each entry in this collection has a unique ID which is selected in each numbered paragraph using
         the WPAT_NumberStyle property. In case of outline numbering this style id only needs to select one
         style from the correct group. The engine will then use the outline level (WPAT_NumberLevel) to
         select the style within the same group.

         If a paragraph uses a paragraph style the NumberStyle defined in this style (if any) has priority. The
         number level of a paragraph has priority over the number level defined by a paragraph style!

         Please note: The properties WPAT_NumberMode, NumberTEXTB, NumberTEXTA etc should NOT
         be used for paragraphs or paragraph styles. They are only handled by the styles which are part of
         NumberStyles collection.

         Example: Initialize the NumberStyles to use legal numbering 1, 1.1, 1.2 ...



© 2004-2008 WPCubed GmbH - Munich, Germany
94    WPTools Version 6



     var
       i: Integer;
     begin
       i f WPRichText1 <> nil then
          for i := 1 t o 9 d o
            with WPRichText1.NumberStyles.AddOutlineStyle(1, i) d o
            begin
              Style := wp_1;
              TextB := ' ';
              TextA := '.';
              Font := ' ';
              Indent := 360 * i;
              UsePrev := TRUE;
            end;
          WPRichText1.Refresh;
     end;

     Example using 'SelectedTextAttr': Assign simple 1,2,3 numbering to the selected text:

     var ind : Integer;
     begin
       ind := 360;
       WPRichText1.SelectAll;
       WPRichText1.SelectedTextAttr.ASet(
          WPAT_NumberStyle,
          WPRichText1.NumberStyles.AddNumberStyle(
            wp_1, // possible values: wp_bullet, wp_circle,
                   // wp_1, wp_lg_i, wp_i, wp_lg_a, wp_a,
            Before1.Text,
            After1.Text,
            ' ', // Font, important for bullets
            ind, // default indent
            0, // Fontsize or default
            false, // = legal numbering
            0, // group, 1 for outline numbering
            0 // level in group 1..10
          ));
     end;

     If the selected numbering style is an outline style, you can use ASet(WPAT_NumberLevel, level) to
     select the style within this level.

     This example will apply the level one of the default outline group to either the current paragraph or
     the selected text if any selection has been made.

     var sty : TWPRTFNumberingStyle;
     begin
       // Locate level 1 in default outline group
                                                          1
       sty := WPRichText1.NumberStyles.FindNumberStyle(-1,);
       // and assign the ID to the current paragraph or the selected
       // paragraphs
       WPRichText1.ASet(WPAT_NumberSTYLE, sty.I D) ;
       WPRichText1.ASet(WPAT_NumberLEVEL, 1) ;
       WPRichText1.Refresh;
     end;

     Like the paragraph styles the elements in "NumberStyles" have a property 'TextStyle'. This is a
     standard TWPTextStyle instance which holds the attributes for the numbering level. You can use it
     to set additional properties, such as the font color for the numbers.




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       95


         Example using 'CurrAttr': Assign simple 1,2,3 numbering to the selected text:

         var ind : Integer;
         begin
           ind := 360;
           WPRichText1.SelectAll;
           WPRichText1.CurrAttr.BeginUpdate;
           WPRichText1.CurrAttr.IndentLeft := ind;
           WPRichText1.CurrAttr.IndentFirst:= -ind;
           WPRichText1.CurrAttr.SetNumberStyle(
              Before1.Text, After1.Text, ' ', wp_1, ind );
           WPRichText1.CurrAttr.EndUpdate;
           WPRichText1.HideSelection;
         end;



         Example using 'CurrAttr': Create several outline levels in the text

         var cp : Integer; i,l,m : Integer;
         begin
           cp := WPRichText1.TextCursor.DropMarker;
           // Remove numbers and indent
           WPRichText1.SelectAll;
           WPRichText1.CurrAttr.BeginUpdate;
           WPRichText1.CurrAttr.NumberStyle := 0;
           WPRichText1.CurrAttr.IndentLeft := 0;
           WPRichText1.CurrAttr.EndUpdate;
           WPRichText1.HideSelection;
           i := 0;
           l := 1;
           m := 1;
           // Move down and apply Outline Mode
           WPRichText1.CPPosition := 0;
           repeat
              WPRichText1.CurrAttr.BeginUpdate;
              WPRichText1.CurrAttr.OutlineLevel := l;
              WPRichText1.CurrAttr.IndentLeft := l * 360;
              WPRichText1.CurrAttr.IndentFirst := -360;
              WPRichText1.CurrAttr.EndUpdate;
              inc(i);
              i f i=3 then
              begin
                 l := l+m;
                 i f (l=4) o r (l=1) then m := -m;
                 i := 0;
              end;
           until not WPRichText1.CPMoveDownPar;
         end;

         Note about CurrAttr: This is an interface which was introduced in WPTools 3. It is still supported and
         implemented in unit WPCTRRich. If you do not want to link unit WPCTRRich you cannot use
         CurrAttr. For new code we suggest to use ActiveParagraph, ASet or SelectTextAttr methods.




© 2004-2008 WPCubed GmbH - Munich, Germany
96     WPTools Version 6


7.6.13 Hyperlinks

       Certain texts can be interactive in WPTools - this means the text can be automatically highlighted
       when the mouse is moved over it (hover or "hot" effect) or an event can be triggered when the user
       clicks on it.

       The standard interactive texts are hyperlinks.

       Hyperlinks in WPTools Version 6 start with a hyperlink start tag <a> and end with a closing tag </a>
       . All these tags are represented by TWPTextObj instances. (These tags can be made visible
       using the 'FormatOptions'!) To read the hyperlinks URL use obj.Source, to modify the visible text
       change obj.EmbeddedText!

       This code can be used to create a hyperlink:

       WPRichText1.InputHyperlink(
                                'WPTOOLS'
                                        ,'BOOK1' .
                                                )

       Since hyperlinks are marked with paired TWPTextObj instances it is also possible to create those
       tags directly by code. This is very useful if you are creating the text using the low level paragraph
       procedures:

       var par : TParagraph;
            link_tag : TWPTextObj;
       begin
        par := WPRichText1.ActiveText.AppendNewPar();
        par.Append('This is a link: ');                             // Some Text
        // Create a link
        link_tag := par.AppendNewObjectPairwpobjHyperlink,'WPCubed GmbH');
                                           (
        link_tag.Source := 'http://www.wpcubed.com';
        // to display:
        WPRichText1.Refresh;
       end;

          Note: The above code uses the function AppendNewObjectPair´. This function internally executes code
          similar to this example:
          startobj := par.AppendNewObject wpobjHyperlink,true,false); // Opening
                                          (
          par.Append('WPCubed GmbH');          // some text
          endobj   := par.AppendNewObject(wpobjHyperlink,true,true);   // Closing
          endobj.SetTag(startobj.NewTag);      // Link Opening<->Closing
          startobj.Source := 'http://www.wpcubed.com';                 // The URL



       Hyperlink tags can have a style attached. This style can be a paragraph style:

       startobj.StyleName := ParStyleName; // set a reference to a paragraph style

       If no style name was specified the list of paragraph styles will be searched for a style with the name
       "A".

       Alternatively the style can be defined directly in the TWPTextObj instance:

        startobj.MakeStyle(true);
        startobj.Style.ASet(WPAT_CharFontSize, 2200);     // create a large font
        startobj.Style.ASetColor(WPAT_CharColor, clRed); // as red text
        startobj.Style.ASetColor(WPAT_CharBGColor, clYellow); // on yellow background
        startobj.Style.ASetFontName('Courier New') ;

       Please note that these style definitions have a lower priority than the text attributes defined for the




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       97


         enclosed characters (this are the attributes which have been assigned to the text) and the attributes
         defined in the property AutomaticTextAttr. They are only loaded and saved in the WPTOOLS format,
         not in RTF format.

         React on the click on hyperlinked text: Event OnClickHotText

         procedure TForm1.WPRichText1HyperLinkEvent(Sender: TObject; text,
           url: String; IgnoredNumber: Integer);
         begin
           i f Pos('http:',url)>0 then
              ShellExecute(Handle, 'open', PChar(url), ' ', ' ', SW_SHOW ) ;
         end;

         This event is executed after a dounble click on hyperlinked text. It will be triggered after a single
         click if the property 'OneClickHyperlink' has been set to true.

         React on the click on hyperlinked text: Event OnClickHotText

         procedure TForm1.WPRichText1ClickHotText(Sender: TObject; par: TParagraph;
           posinpar, X, Y: Integer; Button: TMouseButton; Shift: TShiftState;
           TxtObj: TWPTextObj);
         begin
           i f TxtObj.ObjType=wpobjHyperlink then
           begin
              WPRichText1.BookmarkMoveTo(TxtObj.Source);
           end;
         end;

         this bookmark was created with WPRichText1.BookmarkInput('BOOK1');

         Which types of text objects are clickable is always controlled by property ClickableCodes. This
         means the event can be also created for text which has been wrapped by merge fileds,
         bookmarks or span codes. The event OnClickHotText is always triggered by a single click.

         Please note that in WPTools Version 6 hyperlinks are not represented by text with a certain
         attribute (asfHyperlink) followed by hidden text (afsHidden) as it was in WPTools 4 and
         before!


         How to display visited hyperlinks in a different color:

         We use the property
         WPRichText1.HyperlinkTextAttr.UseOnGetAttrColorEvent := TRUE;

         and a string list:
         FVisitedHyperlinks := TStringList.Create;

         In the hyperlink event we add URLs to the stringlist to know later if the link was already clicked:

         procedure TForm1.WPRichText1HyperLinkEvent(Sender: TObject; text,
           url: string; IgnoredNumber: Integer);
         begin
           FVisitedHyperlinks.Add(url);
           i f Pos('www', url) > 0 then
              ShellExecute(Handle, 'open', PChar(url), ' ', ' ', WM_SHOWWINDOW);
         end;

         Now we can use the OnGetAttributeColor event to modify the special text attribute 'on the fly':

         procedure TForm1.WPRichText1GetAttributeColor(Sender: TObject;




© 2004-2008 WPCubed GmbH - Munich, Germany
98    WPTools Version 6


         var CharStyle: TCharacterAttr; par: TParagraph; posinpar: Integer);
       var txtobj : TWPTextObj;
       begin
         txtobj := WPRichText1.CodeInsideOf(par,posinpar,wpobjHyperlink);
         i f txtobj<>nil then
         begin
             i f FVisitedHyperlinks.IndexOf(txtobj.Source)>=0 then
                   CharStyle.TextColor := clGreen;
         end;
       end;

       The reference CharStyle: TCharacterAttr which is passed to the event is a reference to a copy of
       the HyperlinkTextAttr property object. We can modify it without any sideffect to the other links in the
       text. But please do not modify the reference, just the properties of this object!

       This technique can be also used for other 'special texts' - but the property UseOnGetAttrColorEvent
       must be always set to true to activate the feature.




7.6.14 Bookmarks
       The bookmarks of WPTools Version 6 are very powerful. They can be nested and several functions
       make it easy to work with the marks.

       It is possible tio hide the bookmarks or to sow them. When they are displayed it is even possible to
       display themy through owner drawn code as in this example:




       This code creates a book mark

         WPRichText1.BookmarkInput(
                                  'BM' + IntToStr(bm),true);

       The following functions deal with bookmarks

       //:: finds and selects a Bookmark
           function BookmarkSelect(const Name: string; OnlyText: Boolean): Boolean;
           //:: locates a bookmark and and moves Cursor
           function BookmarkMoveTo(const Name: string): Boolean;
           //:: locates a bookmark and and moves Cursor. Start at the current position
           function BookmarkMoveToNext(const Name: string): Boolean; // locates and moves
       Cursor to next ..
           //:: locates and returns position (or -1 iof not found)
           function BookmarkFind(const Name: string): Integer;
           {:: Creates a bookmark. If text is currently selected the selected text
              will be put iside of the new bookmark markers }
           function BookmarkInput(const Name: string; PlaceCursorBetweenTags: Boolean =
       FALSE):TWPTextObj;
           procedure BookmarkDeleteAllMarkers;
           {:: Deletes the bookmark markers with the given name. This procedure
           searches through all blocks of the current text }
           procedure BookmarkDeleteMarkers(const Name: string) ;
           procedure BookmarkDelete(const Name: string; Marks, Text: Boolean);




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      99


             function BookmarkDeleteInPar(const NameStart: string; par: TParagraph):
         Boolean;
             procedure BookmarkGetList(list: TStrings; FromAllBlock: Boolean = FALSE);
         overload;
             procedure BookmarkGetList(list: TWPTextObjList; FromAllBlock: Boolean =
         FALSE); overload;

             {:: This functions checks if the text at the given position is locate
             inside of a bookmark.<br>
             To check if there is a bookmark object under the mouse
             cursor use CodeAtXY(X,Y,Code)! }
             function BookmarkAtXY(x, y: Integer; var Bookmark: TWPTextObj): Boolean;
             {:: This functions checks if the cursor is inside of a bookmark.<br>
             To check for a text object, such a bookmark object at the cursor position
             use CPAttr.GetObject }
             function BookmarkAtCP: TWPTextObj;
             function BookmarkFirstInPar(par: TParagraph): string;
             function BookmarkAtParLin(par: TParagraph; pos_i n_par: Integer): TWPTextObj;
             function BookmarkForceInPar(par: TParagraph; const frmstr: string): string; / /
         reserved

         Example:

         This code in the event handler for OnTextObjGetTextEx is used to paint the bookmarks in the
         image above:

         procedure TForm1.WPRichText1TextObjGetTextEx(RefCanvas: TCanvas;
           TXTObject: TWPTextObj; var PrintString: WideString; var WidthInPix,
           HeightInPix: Integer; var PaintObject: TWPTextObj; Xres, YRes: Integer);
         begin
           i f not ShowBookmarkCodes.Checked then exit;
           i f TXTObject.ObjType=wpobjBookmark then
           begin
               // If you set PaintObject to anything <> nil PrintString will be ignored!
               // Here you can initialize an event for an owner draw object
               PaintObject := TXTObject;
               PaintObject.OnPaint := OnPaintObject;
               WidthInPix := RefCanvas.TextWidth(TXTObject.Name+'<'+#32) ;
           end;
         end;

         procedure TForm1.OnPaintObject(Sender : TWPTextObj;
              OutCanvas : TCanvas;
              XRes, YRes : Integer;
              X, Y, W, H, BASE: Integer );
         var s : string;
         begin
              OutCanvas.Rectangle(x,y,x+w,y+h);
              OutCanvas.MoveTo(x+w,y+1) ;
              OutCanvas.LineTo(x+w,y+h);
              OutCanvas.LineTo(x+1,y+h);
              i f wpobjIsClosing i n Sender.Mode then
                  s := '>' + Sender.Name
              else s := Sender.Name + '<';
              OutCanvas.TextOut(x+2,y+BASE,s);
         end;

         Sometimes you will need to replace the text which is wrapped within bookmarks. This can be
         useful to process mailmerge forms which used to be processed using a word processor and OLE.

         The following code is fast and effective:




© 2004-2008 WPCubed GmbH - Munich, Germany
100    WPTools Version 6


        procedure TForm1.ReplBookmarksClick(Sender: TObject);
        var
          allbm : TWPTextObjList;
          i : Integer;
        begin
           allbm := WPRichText1.CodeListTags(wpobjBookmark,'*ALL*' ,true);
           try
             for i:=0 t o allbm.Count-1 d o
             i f allbm[i].Name='sum' then // check the name!
             begin
                // simply assign text. You can even create new paragraphs
                // with #13 or #13+#10 sequences.
                allbm[i].EmbeddedText :=
                   '$134.39'+#13#10
                  +'$180.00'+#13#10
                  +'$200.00'+#13#10+'$272.00';
             end;
           finally
             allbm.Free;
           end;
           WPRichText1.ReformatAll(false,true);
        end;




7.6.15 XML editor mode
        WPTools 6 supports a special XML editing mode.

        A loaded XML text will be displayed as:




        for this the XMLTAGS reader must be used.

         WPRichText1.LoadFromFile( filename , true, 'XMLTAGS-utf8' );

        and the FormatOptions initialized as follows:
          WPRichText1.FormatOptions := WPRichText1.FormatOptions + [wpShowSPANCode
          WPRichText1.FormatOptionsEx2 := WPRichText1.FormatOptionsEx2 + [wpfCodeO

        wpfCodeObjectAsXMLTags creates the tag boxes shown above.
        wpfCodeObjectCheckParStyles makes the editor look up paragraph styles which have
        the same name as the tags which include the text. In this case the paragraph style
        collection uses the CSS definition



                                                         © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      101




                           Lemma{font-family:'Courier New';font-weight:bold;color:red}
                           Entsprechung{font-family:'Tahoma';font-size:13.00pt;}

         which was assigned to the editor using:

              WPRichText1.LoadCSSheet( css_string );

         ... but there is more ...

         in case You have the WPTools 6 Premium edition, You can also work with XML schemas.

         from the tags in the XML schema it is possible to create a popup menu with items, which can be
         inserted at a certain position in the editor.

         To make this easy the premium edition includes the unit WPXMLSchema which implements the
         class TWPXMLSchmema.

         You need to create it like this:

         procedure TForm1.FormCreate(Sender: TObject);
         begin
           Schema := TWPXMLSchmema.Create(Self);
           Schema.OnPopupMenuClick := DoPopupMenuClick;
         end;

         procedure TForm1.FormDestroy(Sender: TObject);
         begin
           Schema.Free;
         end;

         DoPopupMenuClick is a method which should handle the click event on one popup menu item.

         procedure TForm1.DoPopupMenuClick(fMenu: TXMLMenuItem; fXMLSchema: TWPXMLSchmema; fXMLTag: TWPX
         var men: TXMLMenuItem;
         begin
           men := fMenu.XMLParent;
           while men <> nil d o
           begin
              WPRichText1.InputCode(wpobjCode, men.XMLTag.nameparam, ' ', [wpinpWrapSelectedText, wpinpNew
              men := men.XMLParent;
           end;
           WPRichText1.InputCode(wpobjCode, fXMLTag.nameparam, ' ', [wpinpWrapSelectedText, wpinpNewParag
           WPRichText1.SetFocus;
         end;



         The popup menu object is created on the form and assigned to the WPRichText PopupMenu
         property. Then in event PopupMenu1Popup this code is placed:

         var bb: Boolean;

         procedure TForm1.PopupMenu1Popup(Sender: TObject);
         var a: TWPXMLSchemaTag; pt: TPoint;
         begin
           i f not bb then
           try
              bb := true;
              PopupMenu1.Items.Clear;




© 2004-2008 WPCubed GmbH - Munich, Germany
102    WPTools Version 6


           a := Schema.LocateContext(
              WPRichText1.ActivePar,
              WPRichText1.ActivePosInPar);
           i f a <> nil then
              a.FillPopupMenu(PopupMenu1, 0) ;
           WPRichText1.GetParXYBaselineScreen(WPRichText1.ActivePar,
              WPRichText1.ActivePosInPar, pt.x, pt.y);
           pt := WPRichText1.ClientToScreen(pt);
           PopupMenu1.Popup(PopupMenu1.PopupPoint.X, pt.y + 4) ;
        finally
           bb := false;
        end;
      end;

      Of course the menu can be also created a bit differently or other items can be added.

      In action the popup menu can look like this:

      1) press the context menu key on the keyboard:




      2) select the item and press enter




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       103


7.6.16 Printing - how to set printer properties
         WPTools Version 6 provides you with the possibility to easily change important printer options (such
         as paper tray) using an easy to use property PrintParameter.
         During the printing the "PrintParameter" are evaluated and applied to the DEVMODE structure which
         is used by the printer driver. There is also the event OnSetupPrinterEvent to let you change the
         DEVMODE structure yourself. This feature can be disabled using the flag
         wpDoNotChangePrinterDefaults in property PrintParameter.PrintOptions.

         The demo 'PrinterSet' shows how to:
         · change the orientation of a certain page
         · activate duplex mode (requires support of the printer!)
         · display the available paper trays
         · change the paper tray for the first and the rest of the pages
         · print the document
         · use BeginPrint/EndPrint to print the contents of two different editors into one printer cue - with a
           continuous page numbering.




         You can use the TWPRichText method Print to print the complete document or PrintPages to print a
         range of documents. If you first call BeginPrint(title, pagenumber) a new printing cue is opened.
         For best results it is necessary to provide this function with the number of the first page. This
         number is 0 based. (This is necessary since the printer properties for the first page must be set
         before Printer.BeginDoc is executed)

         If you print from different editors please make sure that the text in all this editors is formatted. If an
         editor is not visible call ReformatAll! To get the correct page numbering assign the total page count
         to WPRichText.Enviroment.CombinedPrintPageCount You will also need to set the flag
                                                                        .
         wpUsePrintPageNumberin the property PrintParameter.PrintOption of the editor which started the
         printing cue. The value of this -first- property will automatically be used by all the editors which are




© 2004-2008 WPCubed GmbH - Munich, Germany
104     WPTools Version 6


        printing into the same printing cue.
        When printing is finished don't forget to call EndPrint!

        Notes:
        · The property Printer.PageNumber is not updated as usual.
        · We recommend to add a possibility (i.e. INI entry) to your application to make it possible for the
          end user to set wpDoNotChangePrinterDefaults.
        · WPTools Version 6 selects the paper from the list of the available papers of this printer. Only if the
          paper is not found (by comparing the size) 'custom' is used. The list of papers is updated at
          printime, property PageDefs is not used. So it is possible to change the printer (using Printer.
          PrinterIndex) at any time!
        · Please also see the chapter about WYSIWYG
        · You will need to temporarily hide mail-merge markers using the propertry InsertPointTextAttr.
          Hidden if this flag is not true anyways.




7.6.17 Superprint: Print Booklets and Labels
        We've added a new component, TWPSuperPrint, that allows you to centrally manage a variety
        a WPTools printing features. Should you wish to, you also have the option of bypassing the
        Print Console, and controlling these aspects directly within your code, hidden from the user.

        This component includes the ability to control:
            · true "booklet-style" printing – the component has been optimized to automatically control
                "two up" (two pages per sheet) booklet printing
            · printing of labels (automatically tiled across the page! See other demo)
            · include a background image, selected via a subdirectory browser
            · tiling or stretching of the included background image
            · placement of the background image either vertically or horizontally centered, left, right,
                top, or bottom, and combinations of those (e.g., vertically centered and horizontally
                centered, horizontally centered on the bottom, etc.)

        As mentioned, almost all the power and flexibility of the TWPSuperPrint component can be
        centrally controlled from within a dialog box-type form.

        Please check out the LabelPrint demo to learn how to add simple label printing to your
        application.




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      105


         For an example of this, see the "SuperPrint" example off of DemosTasks. Please feel free to use
         as much of that code as you wish (or the entire Print Console itself) in your own application.




         The demo is written to be as generic as possible. Should you wish to customize the code, check
         out the assignments in FormCreate event (e.g., the EditBox and Preview properties), and tailor
         them to fit your particular case. Please note that the controls on the right hand side of the form
         could be easily copied and pasted into a different application.

         To print a test booklet, simply select File / Print, everything is already set up in the demo. Out
         comes the pages, and correctly ordered! Optionally, if you have the product wPDF, also a PDF
         file can be created.

         For the sake of simplicity, from here on we'll refer to the TWPSuperPrint component as
         WPSuperPrint1, or SuperPrint.

                                               Booklet Printing
         Let's talk about the booklet printing feature of this component.

         This is driven by a single procedure, WPSuperPrint1.SetTwoUpBooklet (). When called with
         first parameter set to true, and then the printed page width and height in twips, a number of
         adjustments required to print in a booklet format are made behind the scenes - so that you (or
         the person running the application) don't have to. They include:




© 2004-2008 WPCubed GmbH - Munich, Germany
106    WPTools Version 6


          ·   setting the printer into Landscape
          ·   controls whether the page passed to it for printing is printed on the left or right half of the
              page
          ·   internally adjusts the page dimensions so that two pages can be printed on a sheet (more
              on this coming up)
          ·   sets the orientation of the TWPRichText component referred to by WPSuperPrint1.
              EditBox to Portrait (well, more accurately, it sets Landscape to False)
          ·   sets WPSuperPrint1's Columns property to 2, and its Rows property to 1
          ·   sets WPSuperPrint1's Mode property to wpprPageColRows. This tells it how to
              calculate the page height and width
          ·   sets all of WPSuperPrint1's margins (left, right, top, and bottom) to 0, since we already
              have the margins in the text

      Note: be sure to set TwoUpBooklet to True p rior to executing a Printer.BeginDoc statement.
      If you don't, SuperPrint's code that automatically changes the printer's Orientation to Landscape
      will have no effect.

      One very important part of booklet printing is to determine the order that pages are sent to the
      printer. If we use as an example for this discussion a 12 page document, the pages would be
      ordered like this:




      The first sheet contains the highest and lowest numbered page. The second sheet contains the
      second highest and lowest numbered pages.

      Notice how on the first sheet, the even numbered page is positioned on the left half and the odd
      numbered page on the right . However, the second sheet reverses that – the odd page is on left,
      the even page on the right. WPSuperPrint1 automatically handles the left / right positioning,
      whichever is appropriate to the current sheet.

      Your code is responsible for supplying SuperPrint with the page number to print.
      WPSuperPrint1's OnCalcPageNumber should point to your procedure that calculates the page
      number ordering. For example:

       WPSuperPrint1.OnCalcPageNumber := DoCalcPage

      The DoCalcPage procedure in the SuperPrint demo is a good example of how to calculate the
      page numbers. As written, it will work with documents any number of pages.

      Another important part to using the TWPSuperPrint component is its Paint procedure. The




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       107


         demo's StartPrint procedure is a good example of setting up the call to WPSuperPrint1's Paint
         procedure, and the parameters passed to it.

         A word about the call to RestoreValues in StartPrint. As mentioned above, SuperPrint internally
         adjusts page dimensions and orientation to print in booklet format. Therefore, you should store
         those properties somewhere (see the Demo's FormCreate event handler) so they can be
         restored after printing. And they should be saved p rior to setting WPSuperPrint1's
         TwoUpBooklet property True. In the demo, that's what RestoreValues is about. And although
         the code to store the values is in FormCreate, that code could just as easily have been moved to
         the top of StartPrint.

         Hint: By using a printer capable of supporting 11 inch x 17 inch paper, you can produce
         booklets with a page dimension of 8.5 inches by 11 inches (since the paper's orientation is
         switched to Landscape behind the scenes)!

                                                      Labels
         To print labels, first, create the label (from within the TWPRichText component you assigned to
         the WPSuperPrint1.EditBox property), or import one into there. Then (in no particular order)

             ·   set TwoUpBooklet to False
             ·   include the line: WPSuperPrint1.Mode := wpprLabels
                 (where WPSuperPrint1 is the TWPSuperPrint component), or add a checkbox that you
                 use to assign/unassign the Mode property
             ·   set Columns to the number of labels you want across the page
             ·   set Rows to how many rows of labels you want across the page
             ·   set Copies to the product of Rows * Columns

         That's all you have to do to print labels!


7.6.18 Print Labels (TWPSuperPrint)
         We added an easy to understand demo which shows how to use the TWPSuperPrint component to
         add label printing to your application.

         Note: Please also see the new integrated label printing feature which was added to
         WPTools 6!

         The demo code has been created in a way which makes it easy to use it in your application.

         This is a screenshot of the main dialog - Page 1:




© 2004-2008 WPCubed GmbH - Munich, Germany
108    WPTools Version 6




      This is a screenshot of the main dialog - Page 2:




      The code also implements loading and saving of the label definitions into one XML file which will be
      stored in the application root path.

      The format used inside this XML file is:

      <?xml version="1.0" encoding="windows-1250"?>




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     109


         <Labels>
            <Def Name="2*5_on_Din_A4">
                <TopMargin>238</TopMargin>
                <LeftMargin>238</LeftMargin>
                <RightMargin>238</RightMargin>
                <BottomMargin>238</BottomMargin>
                <HorzMargin>0</HorzMargin>
                <VertMargin>0</VertMargin>
                <ColCount>2</ColCount>
                <RowCount>5</RowCount>
                <PageWidth>11906</PageWidth>
                <PageHeight>16838</PageHeight>
            </Def>



         Note: The horizontal and vertical Margins are the small gaps BETWEEN labels - they are not the
         "pitch".

         To use this form you only have to create and show it.
         To load the first lines of the text into the label use the procedure LoadAddress.

         Example:

         procedure TForm1.Button1Click(Sender: TObject);
         begin
              WPLabelForm.LoadAddress( WPRichText1 );
              WPLabelForm.Show;
         end;

         On the form the user can select a font, change the text and change the label definition.

         If any of values, such as the count of columns, is changed, this procedure is executed:

         procedure TWPLabelForm.ColCountChange(Sender: TObject);
         begin
           i f FLocked then exit;
           WPSuperPrint1.PageWidth := PageWidth.Value;
           WPSuperPrint1.PageHeight := PageHeight.Value;

           WPSuperPrint1.Rows := RowCount.IntValue;
           WPSuperPrint1.Columns := ColCount.IntValue;
           WPSuperPrint1.MarginTop := TopMargin.Value;
           WPSuperPrint1.MarginLeft := LeftMargin.Value;
           WPSuperPrint1.MarginRight := RightMargin.Value;
           WPSuperPrint1.MarginBottom := BottomMargin.Value;
           WPSuperPrint1.InbetweenHorz := HorzMargin.Value;
           WPSuperPrint1.InbetweenVert := VertMargin.Value;

           WPSuperPrint1.LabelStartRow := StartRow.Value;
           WPSuperPrint1.LabelStartColumn := StartCol.Value;
           WPSuperPrint1.Copies := Copies.Value;

           WPRichText1.Header.SetPageWH(
              WPSuperPrint1.Width,
              WPSuperPrint1.Height,
              0, 0, 0, 0) ;
           WPRichText1.ReformatAll;
         end;

         It sets the properties of the SuperPrint component. After that the properties Width and Height which




© 2004-2008 WPCubed GmbH - Munich, Germany
110     WPTools Version 6


        reflect the current label size are applied to the TWPRichText - it holds the text of the label and is
        used for the printing process.

        The printing is started with this code:

        procedure TWPLabelForm.Button1Click(Sender: TObject);
        begin
          Printer.Title := 'Label' ;
          Printer.BeginDoc;
          WPSuperPrint1.Paint(
             Printer.Canvas,
             -GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX), // Offset in pixels
             -GetDeviceCaps(Printer.Handle, PHYSICALOFFSETy), // Offset in pixels
             GetDeviceCaps(Printer.Handle, LOGPIXELSY) / 1440, // Multiplicator for
        Parameters (twips->Canvas)
             [wpDoNotScalePage]); // Options
          Printer.EndDoc;
        end;

        It uses the Paint procedure of the SuperPrint component to render one page to the printer canvas.
        The physical offsets are passed as negative values to make sure the positions are acurate. Of
        course this offsets can be used to adjust the printing.

7.6.19 Print/Edit elements of TWPRTFDataCollection

        The demo DynAssignRTFData shows how to use the TWPPaintEngine to paint elements stored in
        a TWPRTFDataCollection on any Canvas. It also shows how to dynamically assign the RTFData
        object to an editor - so the editor can edit any of the elements in the collection!




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   111




         This code is used to assign the text which should be edited:

         procedure TWPDynRTFData.DynDataListDblClick(Sender: TObject);
         begin
              // Remove link to this RTF Data Object
              WPRichText1.RemoveRTFData;
              // And add link to this one
              WPRichText1.SetRTFData(
                DynDataList.Items.Objects[DynDataList.ItemIndex]
                    a s TWPRTFDataCollection);
              // Make sure the new text is shown
              WPRichText1.SetFocus;
         end;

         The boxes are painted using TWPPaintEngine components which have been created in code in
         "FormCreate".

         To change the RTFData which they are using this code is used after Drag&Drop:
           paint1.RTFData :=
              DynDataList.Items.Objects[DynDataList.ItemIndex]
                   a s TWPRTFDataCollection;




© 2004-2008 WPCubed GmbH - Munich, Germany
112     WPTools Version 6


7.6.20 Create Table from Database
        WPTools possibilities to create text and tables in code are extraordinary powerful.

        We created an example (DemosGridMode) which loads a BDE database and creates a table with
        all the rows. Optionally blobs can be loaded using the TParagraph.LoadFromStream method - this
        will preserve the formatting.
        The demo also shows how to change the background color using the ASetColor procedure.
        Optionally rows can be splitted on several pages (RowBreak) and, if you want to test the
        performance, the same data can be imported 100 times.




        This screen shot was taken after the well known BIOLIFE database was loaded - 100 times.
        This created 2800 rows and images on 400 pages in only 2.8 seconds! (P-M 1.6 GHZ)



        This is the main routine of the demo.
        It first cleares the text and sets the page size. Then a footer is created to show the page number.
        After that a new table paragraph is created (table) which will then host all rows.

        Please note that the CreateRow function creates an object of the class TWPTableRowStyle. This
        class inherits from TWPTextStyle (so does class TParagraph!) and is used as template for all cells
        which are created. So when you make changes to rowstyle, the new properties will be applied to all
        cells which are created afterwards using InputCell.
        The rowstyle object is deleted when the row is completed with EndRow.


        procedure TForm1.LoadFromDataSet(Data: TDataSet; aName: string; LoadBlobAsANSI:
        Boolean);
        var i, a, a_max, RowNr: Integer;
          table, cell, row: TParagraph;
          b: Boolean;
          obj: TWPTextObj;
          wpobj: TWPObject;
          bit: TBitmap;
          rowstyle: TWPTableRowStyle;
          tim: Cardinal;




                                                                         © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   113


           stream: TStream;
         begin
           WPRichText1.Clear;
           Caption := 'loading... - press ESCAPE to abort';
           tim := GetTickCount;
           try

              WPRichText1.EditOptions := [];

           // Set Page Size
             WPRichText1.Header.PageSize := wp_DinA4;
             WPRichText1.Header.LeftMargin := WPCentimeterToTwips(2) ;
             WPRichText1.Header.RightMargin := WPCentimeterToTwips(1) ;
             WPRichText1.Header.TopMargin := WPCentimeterToTwips(1.5) ;
             WPRichText1.Header.BottomMargin := WPCentimeterToTwips(1.5) ;
             WPRichText1.Header.Landscape := TRUE;
             // WPRichText1.WordWrap := TRUE;

              // Create Footer
              WPRichText1.ActiveText := WPRichText1.HeaderFooter.Get(
                     wpIsFooter, wpraOnAllPages);
              WPRichText1.InputString(aName + # 9) ;
              WPRichText1.InputTextField(wpoPageNumber);
              WPRichText1.ASet(WPAT_BorderFlags, WPBRD_DRAW_Top);
              WPRichText1.SetTabPos(MaxInt, tkRight);

               // Switch to BODY
              WPRichText1.ActiveText := WPRichText1.BodyText;

              RowNr := 0;

              i f StressTest.Checked then
              begin a_max := 100;
                 ProgressBar1.Visible := TRUE;
              end else
              begin
                 a_max := 1;
                 ProgressBar1.Visible := FALSE;
              end;

              // Boolean to alternate the background
              b := FALSE;

              // Add all rows to this table
              table := WPRichText1.ActiveText.CreateTable
                                                        (nil);

              table.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4);

              // now create the rows, a_max is used for stresstest
              for a := 1 t o a_max d o
              begin
                ProgressBar1.Position := a;
                ProgressBar1.Update;

              // Start at the beginning of database
                Data.First;

              // Repeat for all data rows
                repeat
                  inc(RowNr);
                  rowstyle := table.CreateRow(nil, true);
                  i f rowstyle <> nil then




© 2004-2008 WPCubed GmbH - Munich, Germany
114    WPTools Version 6


             begin
               b := not b;
               rowstyle.ASetColor(WPAT_BGColor, clBlue);
               rowstyle.ASet(WPAT_ShadingValue, 3 0) ;

             // Create first Column with numbers
               cell := rowstyle.InputCell;
               cell.ASet(WPAT_BorderFlags, WPBRD_DRAW_Right);
               cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1));
               cell.SetText(IntToStr(RowNr));

             // Make sure every other row is *not* shaded:
               i f b then
               begin
                  rowstyle.ADel(WPAT_BGColor);
                  rowstyle.ADel(WPAT_ShadingValue);
               end;
               rowstyle.ASet(WPAT_IndentRight, 7 2) ;

                 for i := 0 t o Data.Fields.Count - 1 d o
                 begin
                   cell := rowstyle.InputCell;
                   i f Data.Fields[i] i s TGraphicField then
                   begin
                      bit := TBitmap.Create;
                      bit.Assign(Data.Fields[i]);
                      wpobj := TWPOImage.CreateImage (WPRichText1.Memo.RTFData, bit);
                      obj := TWPTextObj.Create;
                      cell.Insert(0, obj);
                      obj.ObjRef := wpobj;
                      obj._SetObjType(1 2); // = TWPTextObjType.wpobjImage
                      obj.Width := wpobj.ContentsWidth div 3;
                      obj.Height := wpobj.ContentsHeight div 3;
                      bit.Free;
                   end
                   else i f Data.Fields[i] i s TBlobField then
                   begin
                      i f LoadBlobAsANSI then
                      begin
                   // The simple method which loads text into one paragraph
                         cell.ASet(WPAT_CharFontSize, 600) ;
                         cell.SetText(Copy(Data.Fields[i].AsString, 1, 400) + '...') ;
                      end else
                      begin
                   // the "difficult" method which also loads formatted text
                         stream := TBlobStream.Create(Data.Fields[i] a s TBlobField,
      bmRead);
                      try
                         cell.LoadFromStream stream,
                                             (
                            'AUTO', ' ', [wploadpar_ClearShading]);
                      finally
                         stream.Free;
                      end;
                    end;
                  end
                  else cell.SetText(Data.Fields[i].AsString);
                  cell.ASet(WPAT_BorderFlags, WPBRD_DRAW_Bottom);
               end;
             // Create the cells
               row := table.EndRow(rowstyle);
               i f not RowBreak.Checked then
                  row.ASet(WPAT_ParKeep, 1) ;




                                                        © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      115


                  // Allow ESCAPE
                    i f (GetAsyncKeyState(VK_ESCAPE) shr 1 5) <> 0 then
                    begin
                       i f MessageBox(Handle, 'Abort loading of data ?', 'ESCAPE',
                          MB_YESNO) = IDYES then exit;
                    end;
                  end;

                  Data.Next;
                until Data.EOF;
              end; // for a

           finally
              WPRichText1.Refresh;
              Caption := Format('WPTools5: Created %d rows in %.02f sec', [RowNr,
         (GetTickCount - tim) / 1000]);
           end;
         end;




7.6.21 Print Watermarks
         Watermarks are drawings which are printed before the actual contents of a page is printed.

         In WPTools Version 6 Watermarks have to be printed inside the event handler for
         OnPaintWatermark   .

         This event gets this parameters:

         Sender            a reference to the TWPRichText component which tiggered the event
         RTFEngine         is the RTF Engine (= TWPRichText.Memo)
         toCanvas          the drawing canvas for the output. During printtime this is the printer canvas.
         PageRect          the bounding rectangle of the page. During printime the Top,Left coordinate is set
                           to the negative physical offset to make it easy to print at exact positions.
         PaintPageNr       the number of the page, 0 based
          RTFPageNr        0 or the number of the text page which is printed later over the watermark. You
                           can access the definition object (class TWPVirtPage) of this page by reading
                           RTFEngine.DisplayedText.Pages[RTFPageNr - 1].
         WaterMarkRef      reserved
         XRes and YRes     define the current resolution. This is very important to convert real coordinates into
                           coordinates on the virtual paper. You can use this functions to convert CM into
                           pixles. The result value has to be added to PageRect.Left or PageRect.Top.

                              function   XP(cm: Double): Integer;
                              begin
                                Result   := MulDiv(WPCentimeterToTwips(cm), Xres, 1440) ;
                              end;
                              function   YP(cm: Double): Integer;
                              begin
                                Result   := MulDiv(WPCentimeterToTwips(cm), Yres, 1440) ;
                              end;

         CurrentZoom       specifies the zooming the editor uses, at printtime it is 1
         PaintMode         the paint mode which is currently used. By checking for 'wppInPaintDesktop' you
                           can write code which is not active at print time.




© 2004-2008 WPCubed GmbH - Munich, Germany
116     WPTools Version 6


      Example:

      You can print the contents of one editor to the background of a different editor: (demo WaterM3)

      procedure TWPLetterHeadEdit.WPRichText1PaintWatermark(Sender: TObject;
        RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas; PageRect: TRect;
        PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject; XRes,
        YRes: Integer; CurrentZoom: Single; PaintMode: TWPPaintModes);
      begin
        // We are painting on a RTF-Engine surface so use the
        // PaintPageMode wpNoViewPortAPI since everything has been
        // set up already
        WPLetterhead.PaintPageOnCanvas(0,
           0, 0, 0, 0, toCanvas, [],
           XRes, YRes, -1, -1, [wpNoViewPortAPI );
                                               ]
      end;



      Other examples how Watermarks can be used (Project: DemosTasksWatermark)

      a) show a background pattern on the virtual paper - but do not print this pattern:

      var x,y : Integer;
           bit : TBitmap;
      begin
        i f wppInPaintDesktop i n PaintMode then
        begin
           x := PageRect.Left;
           bit := Image1.Picture.Bitmap;
           while x<PageRect.Right d o
           begin
            y := PageRect.Top;
            while y<PageRect.Bottom d o
            begin
              toCanvas.Draw(x,y,bit);
              inc(y, bit.Height);
            end;
            inc(x, bit.Width);
           end;
        end;
      end;



      b) Draw a 0.5 cm grid using light blue color, this grid is also printed

      var i,j : Integer;
      begin
          toCanvas.Pen.Width := 0;
          toCanvas.Pen.Color := $00FAD5AF ;
          toCanvas.Pen.Style := psSolid;
          for i:=1 t o 1000 d o
          begin
            j := PageRect.Left + MulDiv(WPCentimeterToTwips(0.5 * i), Xres, 1440) ;
            i f j>= PageRect.Right then break;
            toCanvas.MoveTo(j, PageRect.Top);
            toCanvas.LineTo(j, PageRect.Bottom);
          end;

           for i:=1 t o 1000 d o
           begin
             j := PageRect.Top + MulDiv(WPCentimeterToTwips(0.5 * i), Yres, 1440) ;
             i f j>= PageRect.Bottom then break;




                                                                   © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       117


                  toCanvas.MoveTo(PageRect.Left, j);
                  toCanvas.LineTo(PageRect.Right, j);
                end;
         end;



         c) Print a frame line around the text area

         (1) We are using the main page layout information:

         procedure TWaterM.WPRichText1PaintWatermark(Sender: TObject;
            RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas;
            PageRect: TRect; PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject;
            XRes, YRes: Integer;
            FCurrentZoom : Single;
            PaintMode: TWPPaintModes);
         var r: TRect;
         begin
           r.Left := PageRect.Left + MulDiv( RTFEngine.RTFData.Header .LeftMargin, XRes,
         1440);
           r.Top := PageRect.Top + MulDiv( RTFEngine.RTFData.Header.TopMargin, YRes, 1440
         );
           r.Right := PageRect.Right - MulDiv( RTFEngine.RTFData.Header.RightMargin, XRes,
         1440);
           r.Bottom := PageRect.Bottom - MulDiv( RTFEngine.RTFData.Header.BottomMargin,
         YRes, 1440);
           toCanvas.Pen.Color := clBtnShadow;
           toCanvas.Pen.Width := 0;
           toCanvas.Brush.Style := bsClear;
           toCanvas.Rectangle(r);
         end;

         (2) Now we are using the page layout information for the current page.

           i f RTFPageNr > 0 then
           begin
              r.Left := PageRect.Left + MulDiv(
                   RTFEngine.DisplayedText.Pages[ RTFPageNr            - 1].PageMarginLeft, XRes, 1440) ;
              r.Top := PageRect.Top + MulDiv(
                   RTFEngine.DisplayedText.Pages[RTFPageNr             - 1].PageMarginTop, YRes, 1440) ;
              r.Right := PageRect.Right - MulDiv(
                   RTFEngine.DisplayedText.Pages[RTFPageNr             - 1].PageMarginRight, XRes, 1440
         );
              r.Bottom := PageRect.Bottom - MulDiv(
                   RTFEngine.DisplayedText.Pages[RTFPageNr             - 1].PageMarginBottom, YRes, 1440
         );
              toCanvas.Pen.Color := clBtnShadow;
              toCanvas.Pen.Width := 0;
              toCanvas.Brush.Style := bsClear;
              toCanvas.Rectangle(r);
           end;

         Please note that the parameter RTFPageNr can be 0 if the page was inserted as "external page".

         d) Display a pre-printed form (such as a money transfer form) as part of the page.




© 2004-2008 WPCubed GmbH - Munich, Germany
118    WPTools Version 6




      This example requires to use the event OnMeasurePage as well. In this event we reserve space at
      the bottom of the first page:

      const PR_Form_Height = 1 0.5; // Form Height in CM
            PR_Form_Width = 1 5.0;

      procedure TForm1.WPRichText1MeasureTextPage(Sender: TObject;
        PageInfo: TWPMeasurePageParam);
      begin
        // We want to make sure the first page has a bottom margin which is
        // large enough for our form
        i f PageInfo.pagenr = 1 then
        begin
           PageInfo.marginbottom := WPCentimeterToTwips(PR_Form_Height);
           PageInfo.changed := TRUE;
        end;
      end;

      The PaintWatermark code only draws on the first page:

      procedure TForm1.WPRichText1PaintWatermark(Sender: TObject;
        RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas; PageRect: TRect;
        PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject; XRes,
        YRes: Integer; CurrentZoom: Single; PaintMode: TWPPaintModes);
        // ~~~~~~~~~~~~~~~~~~~~~ Convert CM values into pixel ~~~~~~~~~~~~~
        function XP(cm: Double): Integer;
        begin
          Result := MulDiv(WPCentimeterToTwips(cm), Xres, 1440) ;
        end;
        function YP(cm: Double): Integer;
        begin
          Result := MulDiv(WPCentimeterToTwips(cm), Yres, 1440) ;
        end;
        // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      var r, r2: TRect;
        off, w: Integer;




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   119


         begin
           i f PaintPageNr = 0 then
           begin
              r := PageRect;
              r.Top := r.Bottom - YP(PR_Form_Height);
              toCanvas.Pen.Color := clBlack;
              toCanvas.Pen.Style := psDash;
              toCanvas.MoveTo(r.Left, r.Top);
              toCanvas.LineTo(r.Right, r.Top);

              // Draw the form at the right bottom border
              r.Left := r.Right - XP(PR_Form_Width);

              // Draw line
              toCanvas.MoveTo(r.Left, r.Top);
              toCanvas.LineTo(r.Left, r.Bottom);

              // Draw the sizzors
              toCanvas.Font.Name := 'WingDings' ;
              toCanvas.Font.Height := -YP(0.5) ;
              toCanvas.TextOut( PageRect.Left + XP(0.7), r.Top-
                 toCanvas.TextHeight(#$22) div 2 , #$22 );

               // This is background of the form, we do not draw this when
               // we are printing!
              i f wppInPaintDesktop i n PaintMode then
              begin
                 r2 := r;
                 inc(r2.Left,XP(0.1));
                 inc(r2.Top,YP(0.1));
                 toCanvas.Brush.Color := clYellow;
                 toCanvas.FillRect(r2);
              end;

               // This are the form text
              toCanvas.Brush.Color := clWhite;
              toCanvas.Font.Name := 'Courier New';
              toCanvas.Font.Height := -YP(0.5) ;
              toCanvas.Font.Style := [fsBold];
              off := YP(0.1) ;

               // NAME
              r2.Left := r.Left + XP(1.0) ;
              r2.Top := r.Top + YP(2) ;
              r2.Right := r2.Left + XP(1 0) ;
              r2.Bottom := r2.Top + YP(0.7) ;
              toCanvas.FillRect(r2);
              toCanvas.TextOut(r2.Left + off, r2.Top + off, NameE.Text);

               // ADR
              r2.Left := r.Left + XP(1.0) ;
              r2.Top := r.Top + YP(5.5) ;
              r2.Right := r2.Left + XP(1 0) ;
              r2.Bottom := r2.Top + YP(0.7) ;
              toCanvas.FillRect(r2);
              toCanvas.TextOut(r2.Left + off, r2.Top + off, AdrE.Text);

               // COST, right aligned
              r2.Left := r.Left + XP(8.5) ;
              r2.Top := r.Top + YP(4.5) ;
              r2.Right := r2.Left + XP(5) ;
              r2.Bottom := r2.Top + YP(0.7) ;
              toCanvas.FillRect(r2);




© 2004-2008 WPCubed GmbH - Munich, Germany
120    WPTools Version 6


            w := toCanvas.TextWidth(CostE.Text);
            toCanvas.TextOut(r2.Right - off - w, r2.Top + off, CostE.Text);

             // For Debugging
             // Draw a Line at 10,10 CM
             i f DrawDebugCross.Checked then
             begin
                toCanvas.TextOut( PageRect.Left+XP(1 0), PageRect.Top, '10') ;
                toCanvas.TextOut( PageRect.Left, PageRect.Top+YP(1 0), '10') ;
                toCanvas.MoveTo( PageRect.Left, PageRect.Top + YP(1 0));
                toCanvas.LineTo( PageRect.Right, PageRect.Top + YP(1 0));
                toCanvas.MoveTo( PageRect.Left+XP(1 0), PageRect.Top);
                toCanvas.LineTo( PageRect.Left+XP(1 0), r.Top);
             end;
          end;
        end;




7.6.22 Use "External Pages"

        What are "external pages" ?

        This are pages which are displayed by WPTools Version 6 before, after or within the regular text. In
        page layout mode the page will be displayed as if it was a text page.

        Why do I need it ?

        If you want to display the output of your favourite report generator and text in a powerful preview
        component. For example if you need to create a big report which contains of several parts, text and
        graphical report data.
        This feature will also help a lot if you need to combine the ANSI text (such as logging data) with
        formatted text. Since the external pages are rendered through an event it is possible to work with
        thousands of them - there is no need to initialize the graphical data at the beginning.

        Why can't I use watermarks for this?

        Actually you can - and this would be the second best way to implement it. But with the use of
        "external pages" no empty pages have to be inserted into the text, no place holders are required.
        The formatted text stays completely unaltered.

        Can I save the document with the additional pages ?

        No, this is not possible. The data which has been added as "external pages" will not be saved or
        loaded. The editor will only load and save (and edit) the regular text.


        The installed (TasksExternalPages) demo creates a list with dummy data. This list is displayed at
        the beginning of the formatted text:




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide         121




         Methods to be used for external pages: (only in TWPRTFEnginePaint = WPRichText.Memo)

         Adds a reference 'ExternPageRef'. The returned TWPRTFExternPageRef contains variables to
         change the page size.

         function ExternPageRefAdd(
           mode: TWPRTFExternPageRefMode;
           PageNrX: Integer;
           Order: Integer;
           ExternPageRef: TObject;
           WatermarkRef: TObject): TWPRTFExternPageRef;

         procedure ExternPageRefClear - deletes all references and frees the data

         Events to be used with external pages:

         OnPaintExternPage (in TWPCustomRtfEdit and TWPRTFEnginePaint)

           Sender: TObject;
           RTFEngine: TWPRTFEnginePaint;
           prCanvas: TCanvas;
           xoff, yoff: Integer;
           r: TRect;
           PaintPageNr: Integer;
           ExternPageRef: TObject;
           DestXRes, DestYRes: Integer



         OnInitPage (only in TWPRTFEnginePaint = WPRichText.Memo)

             Sender: TObject; // The 'Parent' Object of the RTF - Engine, usually the
         TWPRichText
             RTFEngine: TWPRTFEnginePaint;




© 2004-2008 WPCubed GmbH - Munich, Germany
122    WPTools Version 6


          paintpagenr: Integer; // the number of the paint page (this is not the RTF
      page)
          rtfpagenr: Integer; // the RTF page which will be used if ExternPageRef stayes
      to be nil
          var ExternPageRef: TObject; // assign an object here to disable RTF text for
      this page
          var WatermarkRef: TObject; // assign data required to paint a watermark
          var PaperColor: TColor;
          var pagewidth, pageheight, marginleft, margintop, marginright, marginbottom:
      Integer) o f object;



      Example:

      procedure TWPExternalP.UpdateBtnClick(Sender: TObject);
      var s        : string;
          c,i      : Integer;
          x,y,th,h: Integer;
          pw, ph : Integer;
          PageNr : Integer;
          aPage    : TMetafile;
          aCanvas : TMetafileCanvas;
          procedure NewPage  ;
          begin
            i f aPage = nil then
            begin
                aPage := TMetafile.Create;
                aPage.Width := pw;
                aPage.Height := ph;
            end;
            i f aCanvas=nil then
            begin
               aCanvas := TMetafileCanvas.Create( aPage, 0) ;
               aCanvas.Font.Name := 'Arial';
               aCanvas.Font.Size := 1 1;
               h := ph - WPScreenPixelsPerInch;
               y := WPScreenPixelsPerInch div 2;
               th:= aCanvas.TextHeight('Ag') ;
               x := WPScreenPixelsPerInch div 2;
            end;

            PageCount.Caption := IntToStr(PageNr+1) + ' Extern Pages';
            PageCount.Update;
          end;
          procedure PostPage ;
          var PageRef : TWPRTFExternPageRef;
          begin
            FreeAndNil(aCanvas);
            i f aPage<>nil then
            begin
                // We add a page at a certain location. The data object we added
                // Is freed automatically unless we set in the
                // returned TWPRTFExternPageRef object the property DontFreeExternPage
                // to true
                PageRef := WPRichText1.Memo.ExternPageRefAdd(
                    wpAsPageX,
                    PageNr,
                    0,
                    aPage,
                    nil
                   );
                // This values are optional
                PageRef.PageWidth := MulDiv( pw, 1440, WPScreenPixelsPerInch);




                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       123


                    PageRef.PageHeight := MulDiv( ph, 1440, WPScreenPixelsPerInch);

                  inc(PageNr);
                  aPage := nil;
               end;
             end;
         begin
            c := StrToInt(ACount.Text); // The count of lines to be printed
            s := ALine.Text; // the format string
            aPage     := nil;
            aCanvas := nil;
            PageNr    := 0;
            WPRichText1.Memo.ExternPageRefClear;

             // The page size for the external page in pixels
             pw := MulDiv( WPRichText1.Header.PageWidth, WPScreenPixelsPerInch, 1440) ;
             ph := MulDiv( WPRichText1.Header.PageHeight, WPScreenPixelsPerInch, 1440) ;

             // Try it: The external pages will be landscape!
             // ph := MulDiv( WPRichText1.Header.PageWidth, WPScreenPixelsPerInch, 1440);
             // pw := MulDiv( WPRichText1.Header.PageHeight, WPScreenPixelsPerInch, 1440);



             // Now create the lines
             for i:=1 t o c d o
             begin
                i f y>h then PostPage;
                NewPage;
                aCanvas.TextOut(x,y,Format(s,[i,Random(1000000)]));
                inc(y,th);
             end;
             PostPage;

            WPRichText1.DelayedReformat;
         end;

         Since we use simple metafiles as data for the external pages the painting is very easy. Of course we
         could also use a string list or a custom object and so avoid the overhead of metafiles. If you know in
         advance the count of pages but do not want to load the data in the beginning, this is possible, too.
         The data can be initializes when it is used first in the event OnPaintExternPage.

         procedure TWPExternalP.WPRichText1PaintExternPage(Sender: TObject;
           RTFEngine: TWPRTFEnginePaint; prCanvas: TCanvas; xoff, yoff: Integer;
           r: TRect; PaintPageNr: Integer; ExternPageRef: TObject; DestXRes,
           DestYRes: Integer);
         begin
           prCanvas.StretchDraw( r, ExternPageRef a s TGraphic );
         end;


7.6.23 Images




© 2004-2008 WPCubed GmbH - Munich, Germany
124    WPTools Version 6


                                  (This screenshot shows text and a floating obj ect in WPTools Version
                                  6.)


      Insert a graphic:

      procedure TForm1.InsertGraphicClick(Sender: TObject);
      var txtobj: TWPTextObj;
      begin
        i f OpenDialog2.Execute and (WPRichText1.ActiveParagraph <> nil) then
        begin
           WPRichText1.SetFocus;
           txtobj := WPRichText1.Memo.RTFData.TextObjects.Insert(
              WPLoadObjectFromFile(
                  WPRichText1.Memo.RTFData,
                  OpenDialog2.FileName), 1440, 1440) ;
         // Code to change the graphic, for example change width and height ot the
      'PositionMode'
           i f txtobj <> nil then
           begin



           end;
           WPRichText1.Refresh;
        end;
      end;

      Note: If you need to work directly with a TParagraph you can use the method TParagraph.
      AppendNewObject to create a new TWPTextObj object. To the ObjRef property of this object you
      can assign the TWPObject instance created by WPLoadObjectFromFile. (See CreateTable demo)


      Modify selected object:

      procedure TForm1.ChangeObjectPositionAndWrapMode(Sender: TObject);
      begin
         i f WPRichText1.TextObjects.SelectedObj>nil then
                                                <
         begin
               WPRichText1.TextObjects.ChangePositionMode(
                    WPRichText1.TextObjects.SelectedObj,
               wpotPar, wpwrBoth);
         end;
      end;



      Load new image into object:

      procedure TForm1.Loadimage1Click(Sender: TObject);
      begin
        i f (WPRichText1.TextObjects.SelectedObj<>nil) and
             (OpenPictureDialog1.Execute) then
             begin
                WPRichText1.TextObjects.SelectedObj.LoadObjFromFile
                                                                 (
                   OpenPictureDialog1.FileName);
             end;
      end;



      Replace text with a graphic file

      var GSFile: string;




                                                             © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     125


              TextObject: TWPOImage; // from unit WPObj_Image
         begin
           GSFile := 'C:testfile.jpg'  ;
           i f FileExists(GSFile) then
              with WPRichText1 d o
              begin
                Finder.ToStart;
                while Finder.Next('<<Graphic-Signature>>' d o
                                                          )
                begin
                   TextObject := TWPOImage.Create(WPRichText1.Memo.RTFData); // !
                   TextObject.LoadFromFile(GSFile);
                   SetSelPosLen(Finder.FoundPosition, Finder.FoundLength);
                   TextObjects.Insert(TextObject);
                end;
              end;
         end;

         Alternative, using a graphic from an TImage object:

         WPRichText1.Finder.ToStart;
         while WPRichText1.Finder.Next('[sig]' d o
                                                )
         begin
           WPRichText1.CPPosition := WPRichText1.Finder.FoundPosition;
           WPRichText1.Finder.FoundText := ' ';
           WPRichText1.TextObjects.InsertCopy(Image1.Picture.Graphic);
         end;
         WPRichText1.DelayedReformat;



         Hint: It would be also possible to use modify WPRichText1.TextObjects.SelectedObj.Wrap and
         WPRichText1.TextObjects.SelectedObj.PositionMode directly but this change is not logged for
         undo.

7.6.23.1 Provide a Graphic Popup Menu


         Please insert this popup menu ito your form:

         object GraphicPopupMenu: TPopupMenu
           Left = 675
           Top = 443
           object ascharacter1: TMenuItem
             Tag = 1
             Caption = 'as character'
           end
           object reltoparautowrap1: TMenuItem
             Tag = 2
             Caption = 'rel. to par - auto wrap left or right'
           end
           object reltoparwrapleftandright1: TMenuItem
             Tag = 3
             Caption = 'rel to par - wrap left and right'
           end
           object reltopagenowrappng1: TMenuItem
             Tag = 4
             Caption = 'rel. to page - no wrappng'
           end
           object reltopagewrapleftandright1: TMenuItem
             Tag = 5
             Caption = 'rel. to page - wrap left and right'
           end
         end




© 2004-2008 WPCubed GmbH - Munich, Germany
126    WPTools Version 6


      Now select all items and create a one OnClick event for all menu items:

      In C++ Builder use this code:

      void __fastcall TForm1::GraphicOptionsClick(TObject *Sender)
      {
        i f (WPRichText1->SelectedObject)
        {
            switch ((((TComponent *)Sender)->Tag))
            {
                case 1: WPRichText1->SelectedObject->PositionMode = wpotChar;
                   break;
                case 2:
                    WPRichText1->SelectedObject->Wrap = wpwrAutomatic;
                    WPRichText1->SelectedObject->PositionMode = wpotPar;
                  break;
                case 3:
                    WPRichText1->SelectedObject->Wrap = wpwrBoth;
                    WPRichText1->SelectedObject->PositionMode = wpotPar;
                  break;
                case 4:
                    WPRichText1->SelectedObject->Wrap = wpwrNone;
                    WPRichText1->SelectedObject->PositionMode = wpotPage;
                  break;
                case 5:
                    WPRichText1->SelectedObject->Wrap = wpwrBoth;
                    WPRichText1->SelectedObject->PositionMode = wpotPage;
                  break;
              }
          }
      }

      In Delphi You can use this code:

      procedure TWPForm1.GraphicOptionsClick(Sender: TObject);
      begin
        i f (WPRichText1<>nil) and (WPRichText1.SelectedObject <> nil) then
           case (Sender a s TComponent).Tag o f
             1: WPRichText1.SelectedObject.PositionMode := wpotChar;
             2:
                begin
                  WPRichText1.SelectedObject.Wrap := wpwrAutomatic;
                  WPRichText1.SelectedObject.PositionMode := wpotPar;
                end;
             3:
                begin
                  WPRichText1.SelectedObject.Wrap := wpwrBoth;
                  WPRichText1.SelectedObject.PositionMode := wpotPar;
                end;
             4:
                begin
                  WPRichText1.SelectedObject.Wrap := wpwrNone;
                  WPRichText1.SelectedObject.PositionMode := wpotPage;
                end;
             5:
                begin
                  WPRichText1.SelectedObject.Wrap := wpwrBoth;
                  WPRichText1.SelectedObject.PositionMode := wpotPage;
                end;
           end;
      end;




                                                               © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      127


7.6.23.2 Linked Images
         Linked images use the string propetry StreamName to identify their contents. If this property is <>""
         the binary image data will not be saved in a document fromat which othewise allows embedding,
         such as RTF and WPT. To HTML images can only be saved if a "StreamName" is provided.

         The event OnHTTPRequestImage is used to load the image data for images placed in HTML code
         and also for linked images loaded in RTF or WPT format. This event should be used to load images
         from a database which are only referenced in the text blob.

         Please read the FAQ at
           http://wpcubed.com/forum/viewtopic.php?p=3287#3287

         The event OnPrepareImageforSavingcan be used to create image files (or database records) for
         images which are embedded.

         procedure TForm1.WPRichText1RequestHTTPImage(RTFData: TWPRTFDataCollection;
           Reader: TWPCustomTextReader; const LoadPath, URL: String;
           TextObject: TWPTextObj; var Ok: Boolean);
         var stream : TMemoryStream;
              loadurl : string;
         begin
           i f pos('http:',lowercase(URL))> then
                                           0
                loadurl := URL
           else loadurl := LoadPath + URL;

           stream := TMemoryStream.Create;
           try
              Panel2.Caption := URL;
              try
                 Application.ProcessMessages;
                 // this example uses INDY
                 IdHTTP1.Get(loadurl,stream);
              except
                 on e : Exception d o Panel2.Caption := URL + '-->' + e.Message;
              end;
              i f stream.Size>0 then
              try
                  TextObject.LoadObjFromStream(URL,stream);
              except
                  on e : Exception d o Panel2.Caption := URL + '-->' + e.Message ;
              end;
              ok := TRUE;
              i f ok then Panel2.Caption := ' ';
              Application.ProcessMessages;
           finally
              stream.Free;
           end;
         end;



7.6.23.3 Technical Information
         In previous versions of WPTools embedded objects were stored by using a list of references. A tag,
         which was required to identify a reference, was stored in the TAttr record which was used parallel to
         the character.

         WPTools Version 6 uses a similar method which is much more powerful and consumes less
         memory.

         Each paragraph can have a CharObjectIndex array. If no objects are used, this array is not allocated.




© 2004-2008 WPCubed GmbH - Munich, Germany
128     WPTools Version 6


        The items in this array are the index values +1 in the FWPTextObjs array of the same paragraph.

        If a character is an embedded object the entry in the corresponding CharObjectIndex item is set to
        value <> 0. (Using this double reference makes it quicker to test whether a character is an object or
        not.)

        To check if a character is an embedded object, please use the IsObject function of the TParagraph
        object.

7.6.24 TWPTextObj with custom draw event
        Instances of the TWPTextObj class with ObjType set to wpobjTextObj are used to display page
        numbers, time and similar fields. Unlike mail merge fields those objects are represented using just
        one character. So it is impossible to have a line wrap in the text.

        Normally the objects are painted using an internal routine, so for objects with the name 'PAGE' the
        current page number is inserted.

        The text objects are created using
         WPRichText1.InputTextFieldName    ('CHANGEME');

        To have a different text you can provide an event handler for the OnTextObjGetTextEx event:

        procedure TForm1.WPRichText1TextObjGetTextEx(RefCanvas: TCanvas;
          TXTObject: TWPTextObj; var PrintString: WideString; var WidthInPix,
          HeightInPix: Integer; var PaintObject: TWPTextObj; Xres, YRes: Integer);
        begin
          i f TXTObject.Name='CHANGEME' then
          begin
               PrintString := 'more...'
                                      ;
          end;
        end;

        This will display the text object with the text "more..." using the attributes defined for that object.

        It is very easy to create a different background color:

        procedure TForm1.WPRichText1TextObjGetTextEx(RefCanvas: TCanvas;
          TXTObject: TWPTextObj; var PrintString: WideString; var WidthInPix,
          HeightInPix: Integer; var PaintObject: TWPTextObj; Xres, YRes: Integer);
        begin
          i f TXTObject.Name='CHANGEME' then
          begin
               PrintString := 'more...';
               RefCanvas.Brush.Color := clYellow;
          end;
        end;

        Now, if you want to make that object clickable you can add an event handler to the
        OnTextObjectClick event:

        procedure TForm1.WPRichText1TextObjectClick(Sender: TWPCustomRtfEdit;
          pobj: TWPTextObj; obj: TWPObject; var ignore: Boolean);
        begin
          i f (pobj.ObjType=wpobjTextObject) and
              (pobj.Name='CHANGEME' then
                                   )
          begin
              // locate next data record or similar ...
              ShowMessage('Object was clicked!' + #13 + pobj.AGetWPSS );
          end;




                                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      129


         end;




         Usually text objects can not be selected like images. This feature can be activated in
         EditOptionsEx, flag wpTextObjectSelecting. If you need to avoid the selection for certain objects add
         an event handler for the event BeforeObjectSelection.

         procedure TForm1.WPRichText1BeforeObjectSelection(Sender: TObject;
           txtobj: TWPTextObj; var Ignore: Boolean);
         begin
            // We only want images to be selectable
            Ignore := txtobj.ObjType <> wpobjImage;
         end;

         But what if you want to display some kind of graphic instead of the text?
         Do not use the OnTextObjectPaint event for this - this event is used to draw embedded images only.
         Instead create an event handler for the objects own paint event:

         procedure TForm1.OnPaintMarker(Sender : TWPTextObj;
             OutCanvas : TCanvas; XRes, YRes : Integer; X, Y, W, H, BASE: Integer );

         Assign the address of this paint event to the property TXTObject.OnPaint in the event
         OnTextObjGetTextEx and don't forget to also specify a width. The width is only used if the variable
         PaintObject has been set since otherwise always the PrintString is evaluated.

         procedure TForm1.WPRichText1TextObjGetTextEx(RefCanvas: TCanvas;
           TXTObject: TWPTextObj; var PrintString: WideString; var WidthInPix,
           HeightInPix: Integer; var PaintObject: TWPTextObj; Xres, YRes: Integer);
         begin
           i f TXTObject.Name='CHANGEME' then
           begin
               WidthInPix := Xres div 5;
               TXTObject.OnPaint := OnPaintMarker;
               // This line is required:
               PaintObject := TXTObject;
           end;
         end;

         procedure TForm1.OnPaintMarker(Sender : TWPTextObj;
             OutCanvas : TCanvas;
             XRes, YRes : Integer;
             X, Y, W, H, BASE: Integer );
         var o : Integer;
         begin
               OutCanvas.Brush.Color := clYellow;
               OutCanvas.RoundRect(x,y,x+w,y+h,XRes div 1 0, YRes div 1 0) ;
               OutCanvas.Pen.Color := clRed;




© 2004-2008 WPCubed GmbH - Munich, Germany
130    WPTools Version 6


               o := XRes div 6 0;
               OutCanvas.Pen.Width := 0;
               OutCanvas.MoveTo(x + o*2, y + h        div   2) ;
               OutCanvas.LineTo(x + w - o*3, y        + h   div 2) ;
               OutCanvas.MoveTo(x + w - o * 6,        y +   h div 2 - o * 3) ;
               OutCanvas.LineTo(x + w - o*3, y        + h   div 2) ;
               OutCanvas.LineTo(x + w - o * 6,        y +   h div 2 + o * 3) ;
        end;

        The example above will create the yellow maker:




7.6.25 Working with multiple threads
        Unlike many other editor components WPTools Version 6 can work threadsavely. This makes sense
        if you use WPTools to create documents. Since WPTools can be used to create and print
        documents without any window handle being required You can use WPTools as a powerful engine to
        created electronic documents. This includes RTF documents, HTML documents and, with our
        product wPDF, also PDF documents.

        The demo 'ThreadSave' shows how to create a seperate task to do merge text. The merge template
        is sent from the main thread to the sub thread. Each subthread merges the text 100 times and
        saves each resulting file as RTF FILE:




        The constructor is the most important part of the thread class:

        constructor TWPToolsThread.Create(const SomeText, DirName, Text: string; Count:
        Integer);
        begin
          inherited Create(false);
          ForceDirectories(DirName);
          RichText := TWPCustomRtfEdit.CreateDynamic;
          {$IFNDEF NOENVIROMENT}
          Enviroment := TWPToolsEnviroment.Create(nil) ;




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       131


           Enviroment.Assign(GlobalWPToolsCustomEnviroment);
           RichText.Memo.RTFData.RTFProps.Enviroment := Enviroment;
           {$ENDIF}
           RichText.OnMailMergeGetText := DoMailMergeGetText;

           RichText.AsString := Text;
           FCount := Count;
           FSomeText := SomeText;
           FDirName := DirName;
         end;

         With this line the editor which is used for the process is created:
           RichText := TWPCustomRtfEdit.CreateDynamic;
         TWPCustomRtfEdit is defined in unit WPCTRMEMO - it is the basic editor class. This class does
         not contain all features TWPRichTExt has, cannot be attached to a TWPRuler or a TWPToolBar but
         contains all procedures which are required to create text and tables, insert images and to do mail
         merge.

         The optional code
           Enviroment := TWPToolsEnviroment.Create(nil);
           Enviroment.Assign(GlobalWPToolsCustomEnviroment);
           RichText.Memo.RTFData.RTFProps.Enviroment := Enviroment;
         is only required if you need threadsave printing or if you need to add different object and file format
         handling classes to the enviroment.

         Example C++Builder code to work with dynamic WPTools editor

             TWPCustomRtfEdit *wp2;
             wp2 = new TWPCustomRtfEdit();          // = CreateDynamic
             wp2->_MakeDynamic();

             wp2->InputString("Hello WorldrNext Line",0) ;

             // Insert the text into a differen editor
             WPRichText1->SelectionAsString = wp2->AsString;

             // If we need to print we need ReformatAll
             wp2->ReformatAll(false,false) ;
             wp2->PrintPages(1,1) ;

             // Delete the object
             delete wp2;

         Note: do not create editor windows which should work interactively using CreateDynamic !




7.6.26 Create Text Paths
         To create text paths simply use the TWPRTFStorage component.

         In its property 'Links' you have to create an item for each TWPRichText in the chain.




© 2004-2008 WPCubed GmbH - Munich, Germany
132     WPTools Version 6




      The following initialization is required:

      procedure TWPTextPathDemo.FormCreate(Sender: TObject);
      begin
       // All path objects need the window handle - otherwise we cannot
       // use our broadcasting system
       WPRichText1.HandleNeeded;
       WPRichText2.HandleNeeded;
       WPRichText3.HandleNeeded;
       WPRichText4.HandleNeeded;

       WPRichText1.InputString('This is a text path. Please create new pages with Ctrl
      +CR'+#13) ;
       WPRichText1.CPPosition := MaxInt;
       // Settings for all TWPRichText
       WPRichText1.EditBoxModes := [wpemLimitTextWidth,wpemLimitTextHeight];
       WPRichText1.EditOptions := [wpNoHorzScrolling,wpNoVertScrolling];

       WPRichText2.EditBoxModes := [wpemLimitTextWidth,wpemLimitTextHeight];
       WPRichText2.EditOptions := [wpNoHorzScrolling,wpNoVertScrolling];

       WPRichText3.EditBoxModes := [wpemLimitTextWidth,wpemLimitTextHeight];
       WPRichText3.EditOptions := [wpNoHorzScrolling,wpNoVertScrolling];

       WPRichText4.EditBoxModes := [wpemLimitTextWidth,wpemLimitTextHeight];
       WPRichText4.EditOptions := [wpNoHorzScrolling,wpNoVertScrolling];
      end;




                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   133



         In the BeforeEditBoxNeedFocus event we use this code:

         procedure TWPTextPathDemo.WPRichText1BeforeEditBoxNeedFocus(Sender: TObject;
           var Abort: Boolean);
         begin
           PageControl1.ActivePageIndex := 0;
         end;

         procedure TWPTextPathDemo.WPRichText3BeforeEditBoxNeedFocus(Sender: TObject;
           var Abort: Boolean);
         begin
           PageControl1.ActivePageIndex := 1;
         end;

         In the OnMouseDown event of the page control we remove the focus from the editors:

         procedure TWPTextPathDemo.PageControl1MouseDown(Sender: TObject;
           Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
         begin
           // The WPRichText must loose the focus - otherwise it is not possible
           // to switch to a different page
           PageControl1.SetFocus;
         end;




7.6.27 Syntax Highlighting

         Syntax highlighting is useful to avoid logical errors when the user is supposed
         to edit XML or HTML text in ANSI form or when she or he is editing
         programming code.

         WPTools 5 includes the class TWPSynEditHighlight which is used as interface
         to the syntax highlighters included in the open source project SynEdit. Since
         character attributes, such as "bold" and text color are permanently assigned
         to the text, it is not possible to deliberately choose text attributes for the
         text.

         WPTools 6 includes a new special syntax highlighting component which
         dynamically highlights the parts of the text which are detected to be "tokens".
         It is still possible to apply text attributes.

         Currently a syntax highlighter for XML and the special reporting and mail
         merge tokens are available.

         Syntax highlighers can apply character attributes to the text, or, and this is
         unique, work non destructive. Here the character attribute is calculated "on
         the fly", depending on the context.




© 2004-2008 WPCubed GmbH - Munich, Germany
134    WPTools Version 6


7.6.27.1 TWPSynEditHighlight


        The component TWPSynEditHighlight has been created to use the SynEdit (http://SynEdit.
        SourceForge.net) syntax highlighters (available for pascal, c++, java, SQL, XML and many many
        more) with WPTools Version 6.

        Please check out demo SynHighlight.




        TWPSynEditHighlight works in an optimized way - it updates the text attributes only when
        necessary and caches the text attribute ids. The relatively short sourcecode (WPSyntaxInterface) is
        really worth to be read.

7.6.27.2 TWPCustomSyntax (added to WPTools 6)
        This class, which is implemented in unit WPSyntaxHighlight implements a basics for a syntax
        highlighter.

        To apply syntax highlighting simply assign a TWPCustomSyntax instance to the property
        TWPRichText.CustomSyntax. The instance will be automatically freed by the editor.

        Example:

            uses WPSyntaxHighlight;

            HTMLText.CustomSyntax := TWPXMLSyntax.Create(nil);


        TWPCustomSyntax implements this interface:

        Initialize - receives a reference to the "Memo" object in a TWPRichText
            procedure Init(Engine: TWPRTFEngineBasis); override;

        Called for each paragraph at the start
          procedure StartPar(par: TParagraph); override;

        Called for each character. It has to update the variable FMode according to the syntax
          procedure NextChar(par: TParagraph; CPos: Integer); override;

        Called at the end of each paragraph
          procedure EndPar(par: TParagraph); override;




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      135


         Called before the complete text is processed
           procedure PreProcess(RTFData: TWPRTFDataBlock); override;

         Called after the complete text was processed
           procedure PostProcess(RTFData: TWPRTFDataBlock); override;

         Used to calculate the CharAttr index used at a certain position of a paragraph.
           function CalcAttr(attr: Cardinal; par: TParagraph): Cardinal; override;

         Reference to the RTFDataProps object
           property RTFProps: TWPRTFProps read FRTFProps;

7.6.27.3 TWPXMLSyntax
         The XML highlighter TWPXMLSyntax descends from TWPCustomSyntax.

         It is used to highlight XML and HTML code. It uses a fixed pitch fonts.

         It only overrides two methods:

         constructor TWPXMLSyntax.Create(aOwner: TComponent);
         begin
           inherited Create(aOwner);
           FReservedColor := clBlue;
         end;

         and NextChar which detects the meaning of certain parts of the text. The caller takes care that
         "FMode" is updated with the mode which was active when the previous paragraph ended.

         procedure TWPXMLSyntax.NextChar(par: TParagraph; CPos: Integer);
         var C: WideChar;
           function CC(i: Integer): WideChar;
           begin i f (CPos + i < 0) o r (CPos + i >= par.CharCount) then Result := # 0 else Result := par.C
         begin
           i f FRTFProps <> nil then
           begin
              C := par.CharItem[CPos];
              i f not (FMode i n [wpsynMLComment, wpsynComment, wpsynReserved, wpsynString]) then
              begin
                 i f (C = '&') then FMode := wpsynChar
                 else i f (C = '<') then
                 begin
                    i f (CC(1) = '!') and (CC(2) = '-') and (CC(3) = '-') then
                       FMode := wpsynMLComment
                    else FMode := wpsynReserved;
                 end;
                 i f C = '>' then Ferror := true;
              end
              else
              begin
                 i f (FMode = wpsynReserved) and (c = #32) then FMode := wpsynString
                 else i f (FMode = wpsynString) and (c = '>') then FMode := wpsynReserved;
                 i f C = '<' then Ferror := true;
              end;
              inherited NextChar(par, CPos);
              i f (FMode = wpsynMLComment) and (C = '>') and (CC(-1) = '-') then
                 FMode := wpsynNormal
              else i f (FMode = wpsynReserved) and (C = '>') then
                 FMode := wpsynNormal
              else i f (FMode = wpsynChar) and ((C = ';') o r (C = #32)) then
                 FMode := wpsynNormal;




© 2004-2008 WPCubed GmbH - Munich, Germany
136     WPTools Version 6


             Ferror := false;
          end;
        end;


7.6.27.4 TWPXMLRTFSyntax
        This class highlights XML tags in the text but does not apply permanent changes to the formatting.

7.6.27.5 TWPFieldSyntax
        This class highlights field tokens marked by certain strings. It does not apply permanent changes to
        the text.

        This class publishes the properties

        FieldStart and FieldEnd. They are initialized with '<<' and '>>'.

7.6.27.6 TWPFieldBandSyntax
        This class highlights field and band tokens marked by certain strings. It does not apply permanent
        changes to the text. It is inherited from TWPFieldSyntax.

        Band tokens start with the sign :, groups with #. Only groups may be nested.

        This class publishes the properties

        FieldStart and FieldEnd which are initialized with '<<' and '>>'.

        In addition to TWPFieldSyntax it also publishes BandChar and GroupChar which are initialized with
        ':' and '#'.




7.6.28 Auto capitalisation
        You can use the event BeforeInitializePar to update the current paragraph:

        procedure TForm1.WPRichText1BeforeInitializePar(Sender: TObject;
          RTFEngine: TWPRTFEngineBasis; RTFDataBlock: TWPRTFDataBlock;
          par: TParagraph);
        var pos_wstart, i : Integer; s : string;
        begin
          // Current paragraph
             // Current paragraph
          i f par = WPRichText1.ActivePar then
          begin
              i := WPRichText1.ActivePosInPar;
              // 1. Overread spaces to the left
              while (i>0) and par.IsSpace(i) d o dec(i);

              // 2. Overread a word
              pos_wstart := -1;
              i f not par.IsWordDelimiter(i) and (par.IsSpace(i+1)) then
              begin
                   while (i>=0) and not par.IsWordDelimiter(i) d o begin pos_wstart := i; dec(i); end;
                   // 3. Overread spaces
                   while (i>0) and par.IsSpace(i) d o dec(i);

                   // Now, if . ! ? or start of par uppercase it!
                   i f (pos_wstart>=0) and




                                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      137


                         ((i<=0) o r (par.CharItem[i]='.') o r
                                    (par.CharItem[i]='!') o r
                                    (par.CharItem[i]='?') )
                         // Check for abbreviation (simplified - only check a..z
                         and ((par.IsSpace(i-1) o r (par.CharItem[i]<>'.') o r
                                ((par.CharItem[i-1]>='a') and (par.CharItem[i-1]<='z'))))
                         then
                        begin
                             i f Integer(par.CharItem[pos_wstart])<256 then
                             begin
                                    s := AnsiUpperCase(Char(par.CharItem[pos_wstart]));
                                    i f s<>' ' then par.CharItem[pos_wstart] := WideChar(s[1]);
                             end
                             else par.CharItem[pos_wstart] := WideUpperCase(par.CharItem[pos_wstart])[1] ;
                        end;
              end;
           end;
         end;



         Note: WPTools 6 Feature:

         On popular demand the mode wpAutoCaptitalize has been added to property EditOptionsEx.

         If this mode is active the editor will automatically capitalize Words at the beginning of a sentence.



7.6.29 Search&Replace Text

         To search for text You can use the 'Finder'. The finder is a class which contains several properties
         to adjust how finding works. It is also able to find using a wildcard, but the found text always has to
         be in one paragraph.

         Overview TWPTextFinder:
         ds
         Method Clear - resets the attributes

         Method DropMarkerAtFoundPosition

         This function drops a cursor marker, see DropMarker. The optional parameter offset will be added to
         the 'position in paragraph'.

         Example - extract text in brackets [ ]:

           var startid, endid : Integer;

           with WPRichText1.Finder d o
           begin
             ToStart;
             while true d o
             begin
               i f not Next('[') then break;
               startid := DropMarkerAtFoundPosition(1) ;
               i f not WPRichText1.Finder.Next(']') then break;
               endid := DropMarkerAtFoundPosition(0) ;
               WPRichText1.TextCursor.SelectMarker(startid, endid);

                ShowMessage(WPRichText1.AsANSIString('ANSI', true));




© 2004-2008 WPCubed GmbH - Munich, Germany
138     WPTools Version 6


             WPRichText1.TextCursor.CollectAllMarker;
          end;
        end;

      Method FindAgain - uses the last search text

      Method MoveToFoundPositionEnd - moves cursor

      Method MoveToFoundPositionStart - moves cursor

      Method Next - searches a text - returns TRUE if successful.

      Method Prev - searches a text backwards - returns TRUE if successful.

      Method ReplaceAll - replaces text

      Method ReplaceAllW - replaces text using unicode strings

      Method SelectText - selects the text which was found

      Method SetFoundImage - replaces the found text with an image

      Property Position - current position where the search starts.

      Method ToEnd - current position - goto end

      Method ToStart - current position - goto start

      Property CaseSensitive - true or false

      Property CharAttr - If attributes have been defined in this property the attributes of the text which is
      found must contain this attributes. Please make sure you clear this property with CharAttr.Clear
      after your code has been processed!

      Property EndAtSpace
      This property restricts the wildcard search to stop when the next space or object is found. Also see
      EndAtWord.
      This example creates hyperlinks for all texts which start with http://:

        with WPRichText1.Finder d o
        begin
           ToStart;
           EndAtSpace := TRUE;
           while Next('http://*' d o
                                )
           begin
             SelectText;
             WPRichText1.InputHyperlink(FoundText);
           end;
        end;

      Property EndAtWord
      This property restricts the wildcard search to stop when the next word delimiter is found.

      Property Found
      This property is true after the Next found the text. It is not update by ReplaceAll. The method ToStart
      resets this value to FALSE.

      Property FoundLength - length of the found text




                                                                   © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   139



         Property FoundParagraph - the paragraph wher the text was found

         Property FoundPosInPar - the position where the text was found in 'FoundParagraph'

         Property FoundPosition - The absolute character positiuon of the found text. Can be used to initialize
         the property WPRichText.CPPosition. Better use MoveToFoundPositionStart.

         Property FoundText - Reads and replaces the found text with new text. (Dont' forget WPRichText.
         DelayedReformat).
         Please note that it is not possible to insert new paragraphs using this property. If you need to insert
         paragraphs or formatted text use SelectText and assign the new text to TWPRichText.
         SelectionAsString.

         Property FoundAttr
         Reads and changes the attributes of the found text..

         Property WholeWord - if true the found text must be within white spaces

         Property WildCard - the wild card character allowed in the search string, for example '*'

         Example: Replace the placeholder |NAME| with data using a bold font:

           WPRichText1.Finder.ToStart;
           while WPRichText1.Finder.Next('|NAME|' d o
                                                 )
           begin
              WPRichText1.Finder.FoundAttr.IncludeStyle(afsBold);
              WPRichText1.Finder.FoundText := 'Julian Ziersch';
           end;
           WPRichText1.DelayedReformat;

         Example: Convert Hyperlink:

         The "Finder" demo project shows how to create hyperlinks and how to replace colored words. It also
         includes some demo code to change the attribute of text depending on their current attributes - not
         using the finder but the 'CurrentCharAttr' interface.




              (Note: The display of the hyperlink objects has been enabled in the property FormatOptions)

           with WPRichText1.Finder d o
           begin
             ToStart;




© 2004-2008 WPCubed GmbH - Munich, Germany
140    WPTools Version 6


            EndAtSpace := TRUE;
            while Next('http://*' d o
                                  )
            begin
               SelectText;
               WPRichText1.InputHyperlink(FoundText);
            end;
            EndAtSpace := FALSE;
          end;
          WPRichText1.HideSelection;

        Example: Replace red words

        var Finder: TWPTextFinder;
        begin
          Finder := WPRichText1.Finder;
          Finder.Clear;
          Finder.ToStart;
          Finder.CharAttr.SetColor(clRed);
          Finder.EndAtWord := TRUE; // "WholeWord" does not work
          Finder.WildCard := '*';
          while Finder.Next('*') d o
          begin
             Finder.FoundText := 'Test';
             Finder.FoundAttr.SetColor(clBlack);
          end;
          Finder.CharAttr.Clear;
          WPRichText1.Refresh;
        end;




7.6.30 CPChar, CPMoveNext, etc.

        WPTools makes it easy for you to loop through all the characters to check for attributes, change
        attributes or extract or modify text. (Also read about the cursor class TWPRTFDataCursor )

        Example: Change color of bold text (from Finder demo)

          WPRichText1.AttrHelper.Clear;
          WPRichText1.AttrHelper.SetStyles([afsBold]);
          WPRichText1.CPPosition := 0;
          repeat
            i f WPRichText1.CurrentCharAttr.Contains(
               WPRichText1.AttrHelper) then
               WPRichText1.CurrentCharAttr.SetColor(clRed);
          until not WPRichText1.CPMoveNext;
          WPRichText1.Refresh;




        Example: Assign the bold attribute to the selected text

        var i : Integer;
        begin
           i := WPRichText1.SelLength;
           WPRichText1.CPPosition := WPRichText1.SelStart;
           while i>0 d o
           begin
             WPRichText1.CPAttr.BeginUpdate;
             WPRichText1.CPAttr.IncludeStyle(afsBold);




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      141


              // other changes ...
              WPRichText1.CPAttr.EndUpdate;
              i f not WPRichText1.CPMoveNext then break;
              Dec(i);
            end;
         end;

         Instead of this complicated code you can also use
           CurrAttr.AddStyle([afsBold])
         but the above let you decide for each character which style has to be set.


         Upgrade notes:

         CPChar and CPAttr cannot be used as pointers anymore.

         Instead CPChar is a property and CPAttr is an object with properties to manipulate the
         corresponding TAttr value.

7.6.31 Share Styles between TWPRichText
         Sometimes you need to copy text and objects quickly between several editors. If you copy
         paragraph, table or table rows you can avoid using clipboard like operations by copying the
         TParagraph objects directly.

         To make this can work it is important that all TWPRichText use the same internal font,
         color and style tables.

         So, the TWPRichText must use the same TWPRTFProps object.

         1) Only a few lines of code are required to initialize this prerequisite:

         a) add a variable of type

          WPGlobalRTFProps : TWPRTFProps;

         b) add the event OnInitializeRTFDataObject use code like this

         procedure TForm1.WPRichTextInitializeRTFDataObject(
           Sender: TObject; var RTFDataObject: TWPRTFDataCollection;
           var RTFPropsObject: TWPRTFProps);
         begin
           i f WPGlobalRTFProps=nil then
           begin
              WPGlobalRTFProps := TWPRTFProps.Create;
              WPGlobalRTFProps.Locked := true;
           end;
           RTFPropsObject := WPGlobalRTFProps;
         end;



         c) when the application closes you need to free the WPGlobalRTFProps object.

         2) Copy current paragraph to a different TWPRichText

         var par : TParagraph;

         par := WPRichText1.ActiveParagraph.CreateCopyList(true, WPRichText1.ActiveParagraph);
         WPRichText2.ActiveParagraph.NextPar := par;




© 2004-2008 WPCubed GmbH - Munich, Germany
142    WPTools Version 6


        WPRichText2.ReformatAll(false, true);

        3) Copy current table row to a table in a different TWPRichText


        var par, aTable : TParagraph;

        // Copy this row
           par := WPRichText1.TableRow;
           par := par.CreateCopyList(true, par);

        // Insert a row - if necessary create a surrounding table object
        // Insert after current row
              i f WPRichText2.TableRow<>nil then
                  WPRichText2.TableRow.NextPar := par
              else
              begin
                  // Create a new table
                  aTable := WPRichText2.ActiveParagraph.AppendNewTable(false);
                  // and insert the row
                  aTable.AppendChild(par);
              end;



7.6.32 Multiple Editors for the Same Text
        WPTools Version 6 allows the use of multiple editors which all work with the same text.

        This is also known as the split screen technique.

        Example:




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      143


7.6.32.1 Use TWPRTFStorage
         The component TWPRTFStorage is used to host the TWPRTFDataCollection for a number of
         attached editor component.

         So if you place several editors on a form you can create Create items in the 'Links' collection and
         set wpDisplayTextStreamin property DisplayMode.

         The property AllowMultiView must be set to TRUE in all editors.




© 2004-2008 WPCubed GmbH - Munich, Germany
144    WPTools Version 6


7.6.32.2 Create Multi View in Code
         You need an event handler for the event OnInitializeRTFDataObject of the TWPRichText object. This
         event is executed when the text data is needed the first time. In the event handler you assign a
         RTFDataCollection which has been created 'outside'. You will need two variables in the TForm class:

         TForm1 = class(TForm)
         ...
         public
           RTFData: TWPRTFDataCollection;
           RTFDataProps: TWPRTFProps
         end;

         The event handler now initializes the variables and assigns them to any TWPRichText which is using
         this event handler.

         procedure TForm1.OnInitRTFData(Sender: TObject;
           var RTFDataObject: TWPRTFDataCollection;
           var RTFPropsObject: TWPRTFProps);
         begin
           i f RTFData = nil then
           begin
              RTFData := TWPRTFDataCollection.Create(TWPRTFDataBlock);
              RTFDataProps := TWPRTFProps.Create;
              RTFData.RTFProps := RTFDataProps;
           end;
           RTFDataObject := RTFData;
         end;




7.6.33 Work with sub paragragraphs
         WPTools Version 6 stores the text in a paragraph tree. The paragraphs are connected using the
         property 'NextPar'. Some paragraph types require that contents paragraphs are stored on a deeper
         level, as children paragraphs. For example tables are created that way.

         You can use this feature to separate the text into different sections. (Don't mix up with the text
         sections described here)

         These sections can be useful if you need to use one editor to edit or display the text which is stored
         in different locations, for example different database fields or even database records. It is even
         thinkabele to use WPTools similar to a database grid!




                                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     145


         We created demo which showshow this can be done. You find this demo in the directory
         SubParagraphs.




         The demo shows how to use the paint line event to show the gray header bands. It also contains the
         code which moves the text from and to the main editor or the fields.

         This code is executed when '<<<<' is pressed:

         procedure TWPSubParDemo.LoadDataClick(Sender: TObject);
         var par: TParagraph;
           block: TWPRTFDataBlock;
           mem: TMemoryStream;
           s: string;
           charattr_for_ANSI: Cardinal;
         begin
           mem := TMemoryStream.Create;
           AllText.LockScreen;
           try
             AllText.Clear;
            // AFTER the clear we calculate our ANSI character property
             AllText.AttrHelper.Clear;
             AllText.AttrHelper.SetFontName('Courier New') ;
             AllText.AttrHelper.SetFontSize(1000) ;
             charattr_for_ANSI := AllText.AttrHelper.CharAttr;
            // and now create the text




© 2004-2008 WPCubed GmbH - Munich, Germany
146    WPTools Version 6


          AllText.CheckHasBody;
          block := AllText.ActiveText;
          par := block.FirstPar;
          par.ASet(WPAT_ParProtected, 1) ;
          par.Name := 'FieldA'  ;
          par.ParagraphType := wpIsXMLTopLevel;
          s := FieldA.Text;
         // SetAllText creates a sub paragraph when the first #13#10 is found!
          i f s <> ' ' then par.SetAllText #13 + #10 + s, charattr_for_ANSI); // The first
                                         (
      ANSI Text

          par.NextPar := TParagraph.Create(block);
          par := par.NextPar;
          par.ParagraphType := wpIsXMLTopLevel;
          par.ASet(WPAT_ParProtected, 1) ;
          par.Name := 'FieldB' ;
          par.ASet(WPAT_CharFontSize, 900) ;
          FieldB.SaveToStream(mem, 'WPTOOLS' ;
                                             )
          mem.Position := 0;
          par.LoadFromStream mem, 'AUTO', ' ', [wploadpar_AsChildrenPar
                             (                                        ]); // The
      formatted Text

           par.NextPar := TParagraph.Create(block);
           par := par.NextPar;
           par.ParagraphType := wpIsXMLTopLevel;
           par.ASet(WPAT_ParProtected, 1) ;
           par.Name := 'FieldC'  ;
           s := FieldC.Text;
           i f s <> ' ' then par.SetAllText(#13 + #10 + s, charattr_for_ANSI); // The last
      ANSI Text
        finally
           mem.Free;
           AllText.UnLockScreen(true);
        end;
      end;

      This code is executed when '>>>>' is pressed:

      procedure TWPSubParDemo.PostDataClick(Sender: TObject);
      var par, cpar: TParagraph;
        mem: TMemoryStream;
      begin
        par := AllText.FirstPar;
        while par <> nil d o
        begin
          i f par.ParagraphType = wpIsXMLTopLevel then
          begin
             i f par.Name = 'FieldA' then
             begin
                FieldA.Text := par.GetAllText(false, false);
             end
             else i f par.Name = 'FieldB' then
             begin
                FieldB.LockScreen;
                try
                 // This code uses AppendParCopy() to copy the text --------------------
                  FieldB.Clear;
                  cpar := par.ChildPar;
                  while cpar <> nil d o
                    FieldB.BodyText.AppendParCopy(cpar);
                  FieldB.CheckHasBody;

               // The code uses a stream to copy the text ----------------------------




                                                       © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      147


                    // this will be useful if you need to save to a blob field!
                    {mem := TMemoryStream.Create;
                     try
                        if par.SaveToStream mem, true, 'WPTOOLS') then
                                           (
                        begin
                          mem.Position := 0;
                          FieldB.LoadFromStream(mem, 'WPTOOLS', true);
                        end
                        else FieldB.Clear;
                     finally
                        mem.Free;
                     end;}
                   finally
                     FieldB.UnLockScreen(true);
                   end;
                end
                else i f par.Name = 'FieldC' then
                begin
                   FieldC.Text := par.GetAllText(false, false);
                end;
              end;
              par := par.NextPar; // do NOT use "next" here
           end;
         end;




7.7      BCB Notes

         Installation

         We added BPK files which can be compiled in C++Builder as packages. If there is a problem (Your
         setup is different than on the reference machine) you can install the file WPTools_Reg.PAS as a
         new component into a new package.

         You will have to add the vcl and vclx package - otherwise the message "filename.obj was not found"
         will be displayed.

         Please make sure the VCLJPG and DSNIDE packages are added. For database support VCLDB is
         also required. If you have BCB-Standard you can activate the switch NODB in the file WPINC.INC

         You will also need to make a change to the 'Option Source', the XML makefile for the package:

         When C++Builder compiles the RTFEngine it creates HPP files.




© 2004-2008 WPCubed GmbH - Munich, Germany
148    WPTools Version 6




        Programming

        In general you can use the same techniques in BCB as you use in Delphi

        But please note that the dot '.' usually has to be replaced by the arrow '->' to access any objects.

        Instead of Txx.Create you usually use new.

        Procedures can be called without () in Delphi, for C++ please always add ().

        Speciality: Instead of TWPCustomRTFEdit.CreateDynamic
                                                            use
        edit = new TWPCustomRTFEdit(nil);
        edit._MakeDynamic();

        Troubleshooting:

        If you get a linker error 'unresolved external' please make sure the WPTools units are found, but only
        one time (no duplicates), in the library and in the include path. Please deactivate the use of
        runtime packages.




7.7.1   Example: Create dynamic TWPCustomRTFEdit
           TWPCustomRtfEdit *DynRTFText;

           DynRTFText = new TWPCustomRtfEdit();
           DynRTFText->_MakeDynamic();

           DynRTFText->Clear();




                                                                   © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      149


             DynRTFText->Header->SetPageWH(WPCentimeterToTwips(2 1) ,
                                      WPCentimeterToTwips(29.7) ,
                                      WPCentimeterToTwips(2),     //left Margin
                                      WPCentimeterToTwips(2),     //right Margin
                                      WPCentimeterToTwips(2),     //top Margin
                                      WPCentimeterToTwips(2));       //Bottom Margin

             DynRTFText->CheckHasBody();
             DynRTFText->InputString("Some Textf") ;


7.7.2    Example: Create image object and insert
              TWPOImage *image = new TWPOImage(0) ;
              image->LoadFromFile( "logo.bmp" );

              //image->PositionMode = wpotPage;

              WPRichText1->TextObjects->Insert(image->CreateCopy(0), 0, 0, " ", " " );

              image->LoadFromFile( "logo1.bmp" );
              WPRichText1->TextObjects->Insert(image, 0, 0, " ", " " );


7.8      Label Priniting
         WPTools 6 introduces an exciting new feature. This is the integrated label design and printing. When
         label printing is activated, each logical page in the editor will be displayed and printed on an
         individual label. The user can freely edit the label sheet and mover the text cursor from label to label.
         This makes it very easy to preview the labels which are about to be printed and make last changes.

         The label printing is controlled by the interface WPRichText1.RTFData.LabelDef
                                                                                      .

         Note: This feature is much more versatile than label printing using the demo Print Labels
         (TWPSuperPrint) since here the preview is editable.




7.8.1    LabelDef
         Using the new property LabelDef which was added to WPTools 6 You can quickly print
         labels. It is also possible to preview the label sheets just like they would be printed. It
         is even possible to edit the text on the label sheets. You can also specify the label
         num  ber to start with. All param eters of a label can be specified, using centimeter or
         inch values, depending on UnitIsInch.

         A Label is either defined by the sheet size (width/height), colum count, rowcount and
                                                                          n
         the m argins (top, bottom ,left, right, horizontal and vertical)
         or, alternatively
         by the sheet size (width/height), the top, left, right and bottom margin and the
         specified label width and label height.




© 2004-2008 WPCubed GmbH - Munich, Germany
150    WPTools Version 6




      Overview:

      Active : Switch Label display on / off
      AsText : Retrieve and set the label definition as text
      Bottom : Bottom Margin
      Caption : Caption of the label, displayed over text
      ColumnCount : Count of columns
      Horizontal : Horizontal margin between columns
      LabelHeight : Size of a label, if you set it you cannot change vertical margin and row count
      LabelWidth : Size of a label, if you set it you cannot change horizontal margin and row count
      Left : Left Margin
      Name : Name of this label definition (encoded into "AsText")
      Padding : Padding inside of the label
      Right : Right Margin




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     151


          RowCount : Count of rows
          SheetHeight : Height of label sheet
          SheetWidth : Width of label sheet
          StartNr : Start nr for printing
          Top : Top Margin
          UnitIsInch : If true all floating point values are inch instead of CM
          Vertical : Margin between rows




7.8.1.1   Vertical

          Declaration
          Vertical : Single;

          Description
          The vertical margin between labels (in CM or inch).


7.8.1.2   UnitIsInch

          Declaration
          UnitIsInch : Boolean;

          Description
          If this value is true all floating point properties are interpreted as inch values,
          otherwise CM are expected.


7.8.1.3   Top

          Declaration
          Top : Single;

          Description
          The margin at the top of the label sheet.


7.8.1.4   StartNr

          Declaration
          StartNr : Integer;

          Description
          The num  ber of the label on first page to start with. This property is useful if you work
          with half full label sheets.


7.8.1.5   SheetWidth

          Declaration
          SheetWidth : Single;

          Description




© 2004-2008 WPCubed GmbH - Munich, Germany
152     WPTools Version 6


          The width of the label sheet (cm or Inch, depending on UnitIsInch).


7.8.1.6   SheetHeight

          Declaration
          SheetHeight : Single;

          Description
          The height of the label sheet (cm or Inch, depending on UnitIsInch).


7.8.1.7   RowCount

          Declaration
          RowCount : Integer;

          Description
          The count of labe rows.


7.8.1.8   Right

          Declaration
          Right : Single;

          Description
          The margin to the right of the label sheet.


7.8.1.9   Padding

          Declaration
          Padding : Single;

          Description
          The m argin between text and label borders on all sides of the label. If this property is
          0, the labels will be displayed in the preview as simple rectangles, if it is > a round
                                                                                         0
          rectangle will be drawn.


7.8.1.10 Name

          Declaration
          Name : String;

          Description
          The nam of the label. Will be saved with property AsText.
                  e




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     153


7.8.1.11 Left

         Declaration
         Left : Single;

         Description
         The margin on the left of the label sheet.


7.8.1.12 LabelWidth

         Declaration
         LabelWidth : Single;

         Description
         The width of the label. You can read this property to display the current width. If
         written, the properties ColumnCount and Horizontal are changed accordingly.


7.8.1.13 LabelHeight

         Declaration
         LabelHeight : Single;

         Description
         The height of the label. You can read this property to display the current height. If
         written, the properties RowCount and Vertical are changed accordingly.


7.8.1.14 Horizontal

         Declaration
         Horizontal : Single;

         Description
         The horizontal margin between labels (in CM or inch).


7.8.1.15 ColumnCount

         Declaration
         ColumnCount : Integer;

         Description
         The count of label colum on the sheet.
                                 ns


7.8.1.16 Caption

         Declaration
         Caption : string;

         Description




© 2004-2008 WPCubed GmbH - Munich, Germany
154     WPTools Version 6


         An optional caption for each label. This caption is printed on each label in a sm font
                                                                                          all
         (Arial Narrow). You can use it to specify the return address.


7.8.1.17 Bottom

         Declaration
         Bottom : Single;

         Description
         The height of the bottom margin in cm or inch.


7.8.1.18 AsText

         Declaration
         AsText : string;

         Description
         Retrieves or sets all parameters except for Caption, Active and StartNr as string. This
         methods m  akes it easy to load and save predefined label definitions.

         The form of the string is
                 at

         N e=
          am xx

         with xx as the properties encoded into hexadecim values. If required the unit (cm or
                                                         al
         inch) are converted as required.


7.8.1.19 Active

         Declaration
         Active : Boolean;

         Description
         When this property is set to true, the editor will display a label sheet. The page size
         which is currently defined in the editor is overridden when this m  ode is on. The event
         OnMeasurePage is disabled.


7.8.2    Example Project
         The demo label design contains the preview/edit windows and a TWPValueEdit control for each of
         the properties. It also allows saving and loading the definition and manages the list of definitions in
         the Items list of a TComboBox.




                                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   155




          Please locate the Delphi project in directory DemosWPTools6LabelDesigner.

          Here w e quoted only most of the code.


7.8.2.1   Initialization
          procedure TForm1.FormCreate(Sender: TObject);
          begin
            UseInch := false;
            // Width of the sheet
            WPRichText1.RTFData.LabelDef.SheetWidth := 2 1;
            WPRichText1.RTFData.LabelDef.SheetHeight := 2 9.7;
            // Rows and columns
            WPRichText1.RTFData.LabelDef.ColumnCount := 2;
            WPRichText1.RTFData.LabelDef.RowCount := 7;
            // Margins
            WPRichText1.RTFData.LabelDef.Left := 0.5;
            WPRichText1.RTFData.LabelDef.Right := 0.5;
            WPRichText1.RTFData.LabelDef.Top := 1.5;
            WPRichText1.RTFData.LabelDef.Bottom := 1.5;
            // Start with first
            WPRichText1.RTFData.LabelDef.StartNr := 0;
            // Return Address
            WPRichText1.RTFData.LabelDef.Caption := ReturnAdress.Text;
            // And activate
            WPRichText1.RTFData.LabelDef.Active := true;
            ReadProps;
          end;


7.8.2.2   After changing sheet size and margins
          procedure TForm1.MargHorizontalChange(Sender: TObject);
          begin
           // UseInch ---- true: we work with inch, false: we work with CM
            WPRichText1.RTFData.LabelDef.UnitIsInch := UseInch;

            WPRichText1.RTFData.LabelDef.SheetWidth := SheetWidth.ValueAsInchOrCM(UseInch);
            WPRichText1.RTFData.LabelDef.SheetHeight := SheetHeight.ValueAsInchOrCM(UseInch);

            WPRichText1.RTFData.LabelDef.Top := MargTop.ValueAsInchOrCM(UseInch);
            WPRichText1.RTFData.LabelDef.Left := MargLeft.ValueAsInchOrCM(UseInch);
            WPRichText1.RTFData.LabelDef.Right := MargRight.ValueAsInchOrCM(UseInch);
            WPRichText1.RTFData.LabelDef.Bottom := MargBottom.ValueAsInchOrCM(UseInch);




© 2004-2008 WPCubed GmbH - Munich, Germany
156     WPTools Version 6


            WPRichText1.RTFData.LabelDef.Horizontal := MargHorizontal.ValueAsInchOrCM(UseInch);
            WPRichText1.RTFData.LabelDef.Vertical := MargVertical.ValueAsInchOrCM(UseInch);

            // Read
            LabelWidth.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelWidth, UseInch);
            LabelHeight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelHeight, UseInch);

            StoreProps;
            WPRichText1.ReformatAll(true, true);
          end;


7.8.2.3   Change of column count or row count
          procedure TForm1.ColumnCountChange(Sender: TObject);
          begin
            WPRichText1.RTFData.LabelDef.ColumnCount := ColumnCount.Value;
            WPRichText1.RTFData.LabelDef.RowCount := RowCount.Value;
            // Read
            LabelWidth.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelWidth, UseInch);
            LabelHeight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelHeight, UseInch);

            StoreProps;
            WPRichText1.ReformatAll(true, true);
          end;


7.8.2.4   Change of label width and height
          Usually the labels are defined by the column count and row count property. But it is also possible to
          specify the width and height instead and the component will calculate the correct column and
          rowcount.

          procedure TForm1.LabelWidthChange(Sender: TObject);
          begin
            WPRichText1.RTFData.LabelDef.LabelWidth := LabelWidth.ValueAsInchOrCM(UseInch);
            WPRichText1.RTFData.LabelDef.LabelHeight := LabelHeight.ValueAsInchOrCM(UseInch);

            ColumnCount.SetValue( WPRichText1.RTFData.LabelDef.ColumnCount );
            RowCount.SetValue ( WPRichText1.RTFData.LabelDef.RowCount );

            StoreProps;
            WPRichText1.ReformatAll(true, true);
          end;


7.8.2.5   ReadProps and StoreProps
          ReadProps updates the visible controls

          procedure TForm1.ReadProps;
          begin
            SheetWidth.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.SheetWidth , UseInch);
            SheetHeight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.SheetHeight , UseInch);
            LabelWidth.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelWidth , UseInch);
            LabelHeight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelHeight , UseInch);

            MargTop.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Top , UseInch);
            MargLeft.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Left , UseInch);
            MargRight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Right , UseInch);
            MargBottom.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Bottom , UseInch);
            MargHorizontal.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Horizontal , UseInch);
            MargVertical.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Vertical , UseInch);

            ColumnCount.Value := WPRichText1.RTFData.LabelDef.ColumnCount;
            RowCount.Value := WPRichText1.RTFData.LabelDef.RowCount;




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       157



           LabelName.Text := WPRichText1.RTFData.LabelDef.Name;
         end;

         StoreProps saves the definition to the correct item in a string list. "Name" is used to identify the
         item.

         procedure TForm1.StoreProps;
         var i : Integer;
         begin
              i := LabelName.Items.IndexOfName(WPRichText1.RTFData.LabelDef.Name) ;
              i f i>=0 then
                    LabelName.Items[i] := WPRichText1.RTFData.LabelDef.AsText
              else
              begin
                 i := LabelName.Items.Count;
                 LabelName.Items.Append(WPRichText1.RTFData.LabelDef.AsText);
              end;
              LabelName.ItemIndex := i;
         end;



7.9      HTTP Interface
         WPTools 6 includes the unit "wphttpget_unit", It implements a set of routines to load text, image
         data and style sheets over HTTP connections.

         The interface unit requires the powerful HTTP library Arart Synapse. It is not included.
         http://synapse.ararat.cz/

         Info: The WPTools Demo does not include this unit.

         The interface is attached to the WPTools Kernel using function pointers. This makes it possible to
         separate the HTTP support from the rest of the application and is an effective mean to avoid any
         security risks through open HTTP connection points.

         In this demo (see directory DemosHTTPGet) we discuss how to implement a webbrowser like
         application, including history with forward and backwards buttons.

         The HTTP interface can be temporarily disabled by setting the boolean variable wphttp_Disable =
         true.




© 2004-2008 WPCubed GmbH - Munich, Germany
158    WPTools Version 6


7.9.1   Form Setup

        The Form is simple:




        Also required are 4 variables and 2 functions. Most of the code will be inserted into event handlers:

          public
            history: TStringList;
            historypos: Integer;
            pendingload: Boolean;
            procedure Load(url: string; Update: Boolean);
            procedure UpdateButtons;
          end;

        In the Form.OnCreate event we insert

        procedure TWPWebBrowser.FormCreate(Sender: TObject);
        begin
          history := TStringList.Create;

          WPRichText1.AsWebpage := [wpFormatAsWebpage];
          WPRichText1.OneClickHyperlink := true;
           // No Table Resize
          WPRichText1.EditOptions := [wpActivateUndo, wpActivateUndoHotkey];

           // Hot Hyperlinks
          WPRichText1.HyperlinkTextAttr.HotEffect := wpeffTextColor;
          WPRichText1.HyperlinkTextAttr.HotEffectColor := clBlue;

          // Limit the used fonts
          WPRichText1.RTFData.RTFProps.PreselectedFonts.Assign( Screen.Fonts );
          WPRichText1.RTFData.RTFProps.PreselectedFonts.Add('sans-serif=Frutiger' ;
                                                                                )
        end;



        The property PreselectedFonts is important for the CSS reader.
        It makes it possible to select one font alternative in cases multiple are offered in a comma separated
        list.


        In the Form.OnDestroy event we insert




                                                                   © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      159


         procedure TWPWebBrowser.FormDestroy(Sender: TObject);
         begin
           history.Free;
         end;




7.9.2    Unit Initialization
         To update the status bar we need to create a global method. This method will be called when data is
         loaded over HTTP connections. It also initializes a timer on the form to update the screen and to
         clear the status bar.

         procedure do_wphttp_Notify(code: Integer; text: PAnsiChar); stdcall   ;
         begin
           i f WPWebBrowser <> nil then
           begin
              i f code = 1 then //Load HTML
              begin
                 WPWebBrowser.StatusBar1.Panels[1].Text := StrPas(text);
                 i f WPWebBrowser.historypos < WPWebBrowser.history.count then
                    WPWebBrowser.history[WPWebBrowser.historypos] := StrPas(text);
              end
              else i f code = 2 then // Called Synchronized !
              begin
                 WPWebBrowser.StatusBar1.Panels[2].Text := StrPas(text);
                 WPWebBrowser.UpdateScreenTimer.Enabled := TRUE;
                 WPWebBrowser.pendingload := TRUE;
              end;
           end;
         end;

         This is the timer method

         procedure TWPWebBrowser.UpdateScreenTimerTimer(Sender: TObject);
         begin
           i f not pendingload then
           begin
              WPWebBrowser.StatusBar1.Panels[2].Text := ' ';
              UpdateScreenTimer.Enabled := FALSE;
           end;
           WPRichText1.Repaint;
           pendingload := FALSE;
         end;



         The method do_wphttpNotify and the 4 methods from unit wphttpget_unit are attached to the
         WPTools engine using function pointers. The pointers are set in the initialization section of the unit:

         initialization

           // HTTP functions
           WPRTEDefs.wphttp_Init := @wphttpget_unit.wphttp_Init;
           WPRTEDefs.wphttp_Exit := @wphttpget_unit.wphttp_Exit;
           WPRTEDefs.wphttp_get := @wphttpget_unit.wphttp_get;
           WPRTEDefs.wphttp_copydata := @wphttpget_unit.wphttp_copydata;
           wphttp_Init_param := 'WPCubed_GmbH_HTTP1';

           // Also initialize wphttp_Notify
           WPRTEDefs.wphttp_Notify := d o_wphttp_Notify;

         end.




© 2004-2008 WPCubed GmbH - Munich, Germany
160     WPTools Version 6


7.9.3   User Action and History Management
        The history uses a string list and an index into this list.

        Event for both buttons.

        procedure TWPWebBrowser.BackBtnClick(Sender: TObject);
        begin
          i f Sender = BackBtn then // Click on <--
             dec(historypos)
          else inc(historypos); // Click on -->
          Load(history[historypos], false);
        end;

        and the method which updates the enabled state

        procedure TWPWebBrowser.UpdateButtons;
        begin
          BackBtn.Enabled := (historypos > 0) and (history.Count > 0) ;
          NextBtn.Enabled := (historypos < history.Count - 1) ;
        end;

        The Page is loaded when clicking "Refresh" or when clicking on a hyperlink or when pressing enter
        in the URL edit field.

        procedure TWPWebBrowser.RefershBtnClick(Sender: TObject);
        begin
          Load(URLEdit.Text, false);
        end;

        procedure TWPWebBrowser.WPRichText1HyperLinkEvent(Sender: TObject; text,
          url: string; IgnoredNumber: Integer);
        begin
          inc(historypos);
          Load(url, true);
        end;

        procedure TWPWebBrowser.URLEditKeyPress(Sender: TObject; var Key: Char);
        begin
          i f Key = #13 then
          begin
             Load(URLEdit.Text, true);
             Key := # 0;
          end;
        end;


7.9.4   Load Method
        The method load is responsible to load documents and also images. For unsupported file extensions
        it calls MessageBeep and exits. It does not yet preload the data and check it for errors.

        procedure TWPWebBrowser.Load(url: string; Update: Boolean);
        var s: string;
          obj: TWPOImage;
          load_the_text: Boolean;
        begin
          load_the_text := true;
          s := lowercase(ExtractFileExt(url));
          i f (s = '.rtf') o r (s = '.txt') o r (s = '.doc') then
          begin
           // Standard Mode for Documents
             WPRichText1.AsWebpage := [];




                                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      161


           end
           else
           i f (s = '.jpg') o r (s = '.gif') o r (s = '.png') o r (s = '.jpeg' then
                                                                              )
           begin
                // Mode for images
                obj := TWPOImage.Create(WPRichText1.RTFData);
                i f obj.LoadHTTPFromThread(nil, WPRichText1.RTFData, WPRichText1.RTFData.HTTPPrepareURL(ur
                begin
                   WPRichText1.AsWebpage := [];
                   WPRichText1.Clear;
                   WPRichText1.InputObject(obj);
                   load_the_text := false;
                end else
                begin
                   obj.Free;
                   MessageBeep(0) ;
                   exit;
                end;
           end
           else // Ignore data right away
           i f (s = '.exe') o r (s = '.zip') o r (s = '.pdf')
               or (s = '.rar') o r (s = '.chm') o r (s = '.hlp')
           then
           begin // Unsupported extensions
                   MessageBeep(0) ;
                   exit;
           end
           else
           begin // Mode for websites
                   // TODO - we should load now preload the data and check if valid
                   WPRichText1.AsWebpage := [wpFormatAsWebpage];
           end;
           // Update Statusbar
           URLEdit.Text := url;
           StatusBar1.Panels[1].Text := url;
            // Update History NOW - otherwise do_wphttp_Notify cannot update the filename correctly
           i f Update then
           begin
              while history.Count > historypos d o history.Delete(history.Count - 1) ;
              historypos := history.Count;
              history.Append(url);
              UpdateButtons;
           end;
           // Do we need to load text (maybe we loaded images)
           i f load_the_text then
           begin
              WPRichText1.Clear;
              WPRichText1.LoadFromFile(url);
           end;
         end;

         Notes:
         Most of the work is done in WPRichText.LoadFromFile - here WPTools 6 detects http urls and uses
         the http functions to load the data.

         Images are loaded multithreaded - so the page appears quickly.

         The new TWPObject class implements the method LoadHTTPFromThread (it will not work with
         threads though, if the last parameter is false).

         Here we also activate the special HTML formatting mode, or disable it for regular RTF documents.




© 2004-2008 WPCubed GmbH - Munich, Germany
162     WPTools Version 6


7.9.5   Webbrowser with WPTools

        Although WPTools 6 is not meant to replace a specialized HTML component, You can build a pretty decent
        HTML view er w ith it.




7.9.6   Source View
        It is possible to capture the HTML source code and display it in a second editor:

        Here w e have tw o tabs, the first show s the TWPRichText w hich displays the formatted text, the other
        show s the source code and uses the XML syntax highlighting.
        The editors are individual, edits in one w ill not update the other editor.




                                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     163




         The second editor is initialized like this:

         procedure TWPWebBrowser.FormCreate(Sender: TObject);
         begin
          ...
           // Update the Source view
           WPRichText1.RTFData.AfterLoadFromStream := WPRichText1LoadFromStream;
           // uses WPSyntaxHighlight:
           SourceView.CustomSyntax := TWPXMLSyntax.Create(nil) ;
           ...
         end;

         The text is assigned in the event TWPRTFDataCollection.AfterLoadFromStream The handler
                                                                                  .
         uses this code:

         procedure TWPWebBrowser.WPRichText1LoadFromStream(
              RTFData: TWPRTFDataCollection;
              Stream: TStream;
              Reader: TWPCustomTextReader;
              OnlyBodyText: Boolean;
              var LoadedText: TWPRTFDataBlock);
         begin
           i f not OnlyBodyText then
           begin
               Stream.Position := 0;
               i f Reader.CopyOfBodyData<>nil then
                     // HTML extracted from MIME data
                     SourceView.LoadFromStream(Reader.CopyOfBodyData, 'ANSI', true)
                     // Original Stream
               else SourceView.LoadFromStream(Stream, 'ANSI', true);
               Caption := WPRichText1.RTFVariables.Strings['Title' ;
                                                                   ]
           end;
         end;

         Here we use the property CopyOfBodyData. This memory stream is only filled by the MIME reader
         to capture the HTML body source. The normal stream would show the complete message text,
         including all header lines and attachments.




7.10 MIME Import / Export
         WPTools 6 includes the unit "WPIOMime", It implements a read and a writer for MIME encoded
         HTML Data.

         Info: The WPTools Demo does not include this unit.

         The interface unit requires the powerful HTTP library Arart Synapse. It is not included.
         http://synapse.ararat.cz/




© 2004-2008 WPCubed GmbH - Munich, Germany
164    WPTools Version 6


7.10.1 Reader / Writer
        To activate MIME support please add the unit WPIOMime to the uses clause. (C++Builder requires
        #pragma link).

        Now it is possible to load *.MHT, *.MSG and *.EML files. These file extensions automatically trigger
        the MIME reader and writer classes due to the class methods.

        class function TWPMimeReader.UseForFilterName(const Filtername: string): Boolean;
        begin
          Result := (CompareText(Filtername, 'TWPMimeReader' = 0) // not "inherited"
                                                            )
             o r (CompareText(Filtername, 'MIME') = 0)
             o r (CompareText(Filtername, 'MHT') = 0)
             o r (CompareText(Filtername, 'MSG') = 0)
             o r (CompareText(Filtername, 'EML') = 0) ;
        end;

        and

        class function TWPMimeWriter.UseForFilterName(const Filtername: string): Boolean;
        begin
          Result := (CompareText(Filtername, 'TWPMimeWriter' = 0) // not "inherited"
                                                            )
             o r (CompareText(Filtername, 'MIME') = 0)
             o r (CompareText(Filtername, 'MHT') = 0)
             o r (CompareText(Filtername, 'MSG') = 0)
             o r (CompareText(Filtername, 'EML') = 0) ;
        end;

        The writer supports the format options:
         -nohtml, do not save HTML text
         -noplain, do not save PLAIN text

        The MimeReader initializes and fills the property TWPCustomTextReader.CopyOfBodyData a with
        copy of the HTML text which is loaded as body. The data can be used to display the HTML source
        code (example).



7.10.2 Demo
        Instead of creating a new demo, we decided to enhance the WebBrowser application and add 2
        buttons, "Load MIME" and "SaveMime".

        First we need to add WPIOMime to the uses clause:

        uses
          Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
          Dialogs, StdCtrls, Buttons, WPRTEDefs, WPCTRMemo, WPCTRRich, ComCtrls,
          ExtCtrls, wphttpget_unit, wpobj_image, WPIOMime;



        To save a web archive or message file we use

        procedure TWPWebBrowser.SaveMIMEClick(Sender: TObject);
        begin
          with TSaveDialog.Create(self) d o
          try
             Filter := 'Webarchives (*.MHT)|*.MHT|Messages (*.MSG,*.EML)|*.MSG,*.EML';
             DefaultExt := 'MHT';
             Caption:= 'Save as MIME data';
             i f Execute then




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     165


               begin
                 // Web Archive
                 i f SameText( ExtractFileExt( FileName ), '.mht' ) then
                        WPRichText1.SaveToFile(FileName, false, 'MIME-noplain'
                                                                             )
                 else WPRichText1.SaveToFile(FileName);
               end;
           finally
              Free;
           end;
         end;



         To load a MSG or MHT file we use

         procedure TWPWebBrowser.LoadMIMEClick(Sender: TObject);
         begin
              with TOpenDialog.Create(self) d o
           try
               Filter := 'Webarchives (*.MHT)|*.MHT|Messages (*.MSG,*.EML)|*.MSG,*.EML';
               DefaultExt := 'MHT';
               Caption:= 'Load MIME data';
               i f Execute then
               begin
                  WPRichText1.SaveToFile(FileName, true);
               end;
           finally
              Free;
           end;
         end;




7.11 PDF export with wPDF
         Used alone, with your own component or linked with WPTools, wPDF instantly creates
         PDF files at high speed.

         wPDF supports
         · Developer Express(tm EXPRESS PrintingSuite, (exam
                                  )                                 ple included)
         · ReportBuilder, (interface included)
         · ACE Reporter, (interface included)
         · RichEdit, (exam ple included)
         · RAVE Report, (interface included)
         · HTMLView,
         · FAST Report 2, (interface included)
         · FAST Report 3+ (interface included)
                            4,
         · QuickReport, (interface included)
         · WPTools 4 (incl. links and bookm   arks, com ponent included) ,
         · WPTools 5 (incl. links and bookm   arks, com ponent included) ,
         · WPTools 6 (incl. links, fields and bookm  arks, component included) ,
         · WPForm (exam
                   ,       ple included)
         · List&Label
         and m ost other com   ponents which can create a m   etafile or draw to a HDC / Canvas.
         You always can com    bine the output of different com ponents into one PDF file!


         The integration with WPTools extremely tight. So, other than just exporting text and
         images these features are supported:
         · Export hyperlinks
         · Export Bookm arks




© 2004-2008 WPCubed GmbH - Munich, Germany
166    WPTools Version 6


        · Export JPEG data without additional com pression
        · Create PDF tags (Also known as "m  arked PDF" - this is a prerequisite for PDF/A
          com pliancy. Tagged PDF Docum  ents can be better converted to form    atted text. Our
          own "PDF to RTF" converter will even recreate table structures!)
        · new in WPTools 6: create edit fields (Exam ple ...)
        · new in WPTools 6: create checkbox fields (Exam    ple ...)
        · new in WPTools 6: em bed data stored in a special object instance (Exam    ple ...)



7.11.1 Export to PDF
        This is the most compact code to export the RTF or HTML text from a WPTools Editor
        to PDF:

        uses ..., WPPDFWP, WPRTEDefs, WPCTRMemo, WPCTRRich;

        procedure TForm1.ExportFromWPTools(Sender: TObject);
        var pdf : TWPPDFExport;
        begin
          pdf := TWPPDFExport.Create(nil);
          pdf.Source := WPRichText1;
          try
             pdf.FileName := 'c:wp5out.pdf';
             pdf.Print;
          finally
             pdf.Free;
          end;
        end;

        The TWPPDFExport com    ponent can be alternatively dropped on the form and the
        properties can be set in the IDE. Then only one line of code is required: WPPDfExport1.
        Print.




                                                           © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      167


7.11.2 Export using dialog

         You can use the provided PDF creation dialog to create a full featured PDF file with wPDF.




         To display it only these lines are required:

         uses WPToPDFDlg;

         var pdfcreate: TWPCreatePDF;
         begin
           pdfcreate := TWPCreatePDF.Create(Self);
           pdfcreate.EditBox := WPRichText1;
           try
              pdfcreate.ShowModal;
           finally
              pdfcreate.Free;
           end;
         end;


7.11.3 Export using PaintRTFPage()
         Alternatively this simple code can be used to export PDF files from WPTools Version 6.

         The drawing code used by WPTools Version 6 will makes sure that the hyperlinks and bookmarks
         are exported to PDF as they are with the 'old' WPPDFExport component. Please note that the
         component WPRichText1 is a TWPRichText component created on the form with the property
         Visible set to FALSE. All other properties have not been changed.

         // uses WPRTEPaint, WPPDFR1, WPPDFR2;

         procedure TForm1.ExportToPDF(Sender: TObject);
         var WPPDFPrinter1: TWPPDFPrinter;
             i,w,h : Integer;
         begin
            WPPDFPrinter1 := TWPPDFPrinter.Create(nil) ;




© 2004-2008 WPCubed GmbH - Munich, Germany
168    WPTools Version 6


         WPPDFPrinter1.FileName :='c:wptools5demo.pdf'  ;
         WPPDFPrinter1.CompressStreamMethod := wpCompressFastFlate;
         WPPDFPrinter1.AutoLaunch := TRUE;
         WPPDFPrinter1.BeginDoc;
         try
           i := 0;
           while i<WPRichText1.CountPages d o
           begin
              w := MulDiv(WPRichText1.Memo._PaintPages[i].WidthTw,WPScreenPixelsPerInch,1440);
              h := MulDiv(WPRichText1.Memo._PaintPages[i].HeightTw,WPScreenPixelsPerInch,1440);
              i f (w=0) o r (h=0) then
              begin
                   w := Round( WPRichText1.Memo.PaintPageWidth[i] / WPRichText1.Memo.CurrentZooming );
                   h := Round( WPRichText1.Memo.PaintPageHeight[i] / WPRichText1.Memo.CurrentZooming );
              end;
              WPPDFPrinter1.StartPage( w, h, Screen.PixelsPerInch, Screen.PixelsPerInch, 0) ;
              try
                 // Use 0 as w and h to let the function calculate the width and height
                 WPRichText1.Memo.PaintRTFPage(i,0,0,0,0,WPPDFPrinter1.Canvas, [wppInPaintForwPDF] );
              finally
                 WPPDFPrinter1.EndPage;
              end;
              inc(i);
           end;
         finally
           WPPDFPrinter1.EndDoc;
           WPPDFPrinter1.Free;
         end;
      end;

      To create watermarks simply add additional code which prints on the WPPDFPrinter1.Canvas.

      Or you can easily print 2 pages on the same PDF page, just make changes in 4 lines:

      var WPPDFPrinter1: TWPPDFPrinter;
          i, w, h : Integer;
      begin
         WPPDFPrinter1 := TWPPDFPrinter.Create(nil) ;
         WPPDFPrinter1.FileName :='c:wptools5demo.pdf' ;
         WPPDFPrinter1.CompressStreamMethod := wpCompressFastFlate;
         WPPDFPrinter1.AutoLaunch := TRUE;
         WPPDFPrinter1.BeginDoc;
         try
          i := 0;
          while i<WPRichText1.CountPages d o
          begin
               h := WPRichText1.Memo.PaintPageHeight[i];
               w := WPRichText1.Memo.PaintPageWidth[i];
               WPPDFPrinter1.StartPage(w, h div 2,
               Screen.PixelsPerInch, Screen.PixelsPerInch, 0) ;
             try
               // Use 0 as w and h to let the function calculate the width and height
               WPRichText1.Memo.PaintRTFPage(i,0,0,w div 2,h div 2,WPPDFPrinter1.Canvas,
      [] );
               WPRichText1.Memo.PaintRTFPage(i+1,w div 2,0,w div 2,h div 2,
      WPPDFPrinter1.Canvas, [] );
             finally
               WPPDFPrinter1.EndPage;
             end;
             inc(i,2);
          end;
         finally
          WPPDFPrinter1.EndDoc;
          WPPDFPrinter1.Free;




                                                            © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     169


            end;
         end;




7.11.4 Create edit / memo fields

         Using WPTools 6 and wPDF V3 ist is now possible to create text fields in PDF files.

         Example:




         Create a simple edit field

            with WPRichText1.InputTextFieldName('FORMEDITFIELD') do
            begin
              Source := FieldName.Text;
              Params := SFieldText.Text + '@@HINT@@' + SHintText.Text;
            end;


         Create a edit field based on a TWPObject class:

         Here it is also possible to create multi line fields.

         var obj : TWPTextObj;
         begin
          i f Multiline.Checked then
                  obj := WPRichText1.TextObjects.InsertClass('TWPOEditControl' 360*5, 260*5 )
                                                                               ,
          else obj := WPRichText1.TextObjects.InsertClass('TWPOEditControl' 360*5, 260 );
                                                                               ,
          i f obj.IsImage then
          begin
              obj.ObjRef.ObjName := AFieldName.Text;
              (obj.ObjRef a s TWPOEditControl).Text.Text := TextEdit.Text;
              (obj.ObjRef a s TWPOEditControl).Hint := HintEdit.Text;
              (obj.ObjRef a s TWPOEditControl).PDFFont := TWPOEditControlPDFFont( FontSelect.ItemIndex );
              i f not AutoSize.Checked then
                    (obj.ObjRef a s TWPOEditControl).PDFOptions :=
                    (obj.ObjRef a s TWPOEditControl).PDFOptions - [wpecAutosizeFont];
              (obj.ObjRef a s TWPOEditControl).Multiline := Multiline.Checked;
              i f Multiline.Checked then (obj.ObjRef a s TWPOEditControl).FontSize := 1 0;
          end;
         end;


7.11.5 Create a check box field


         Using WPTools 6 and wPDF V3 ist is now possible to createcheck boxes in PDF files.

         Example:




© 2004-2008 WPCubed GmbH - Munich, Germany
170     WPTools Version 6



        This box w as created w ith this code:



              with WPRichText1.InputTextFieldName('FORMCHECKBOX' d o
                                                               )
              begin
                 Source   := FieldName.Text;
                 Params   := 'true';   //'false'
              end;


7.11.6 Create embedded data objects

        Using WPTools 6 and wPDF V3 ist is now possible to add an object to the PDF file which
        holds embedded data.

        Example:




        This feature uses the class TWPODataContainer. It is a descendant of TWPOImage and so able to dis

        The embedded data is loaded by AddDataFile or AddDataStream.
         function AddDataFile(Filename: WideString;
              fsmode: TPDFEmbeddedFileElementFS = wpembDefault): string;

         function AddDataStream(data: TStream;
              fsmode: TPDFEmbeddedFileElementFS;
              compressmode: TPDFEmbeddedFileElementCompress;
              const ext_o r_subtype: string): string;



        Example code:
        var obj : TWPTextObj;
        begin
         obj := WPRichText1.TextObjects.InsertClass('TWPODataContainer' 360, 360 );
                                                                      ,
         i f obj.IsImage then
         begin
             obj.Mode := obj.Mode + [wpobjSizingDisabled];
            // obj.ObjRef.LoadFromFile('c:a.bmp');
             obj.ObjRef.AssignBitmap(Image1.Picture.Graphic);

            (obj.ObjRef     as   TWPODataContainer).AddDataFile(Edit1.Text,wpembDefault);
            (obj.ObjRef     as   TWPODataContainer).Icon := wpemTag; // wpemGraph;
            (obj.ObjRef     as   TWPODataContainer).AddParam('Contents','Dies ist eine Datei') ;
            (obj.ObjRef     as   TWPODataContainer).AddParam('Title' 'Julian Ziersch') ;
                                                                    ,
         end;




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Guide        171



7.12 Adding Spellcheck
         WPTools comes with an integrated spell check interface which can be used by the third party
         products Addict Spell and EDSSpell. (Please see latest partner links)
         Our own product WPSpell also uses this procedures and events.

         This screen shots show the spell-as-you-go feature with WPSpell and Addict Spell




         To activate the spell check interface all you have to do:

         · with Addict Spell: add unit WPTAddict to the project and use the WPTools spell check actions.

         · with EDSSpell: add unit eds_wptools to the project

         · with WPSpell (registered version. (order link: single, SITE)
                      :

                 1.   Drop the component TWPSpellController          (activate symbol WPSEPLL in file
                      WPINC.INC to compile it into the WPTools package)
                 2.   Set the property WPSpellController1.Active to TRUE
                 3.   Add the unit wpspell_link to the uses clause
                 4.   Use the command WPRichText1.StartSpellCheck() to start/stop spellcheck

         · with WPSpell (demo version)
                        :
                Just add the unit wpspell_link to the uses clause. You cannot create an instance of the
                spellcheck controller since it loaded at runtime from the demo DLL.

         Advantages of WPSpell

            ·    Spellcheck while typing
            ·    WPSpell has been esspecially tailored to work with WPTools.
            ·    Traditional spellcheck dialog
            ·    Support for spellcheck during input (curly underlines + popup dialog)
            ·    With WPTools Version 6: instant update of spellcheck markers when switching languages
            ·    Use multiple dictionaries
            ·    Low overhead - dictionaries are not completely loaded into memory (although this option
                 exists, too)
            ·    Setup information automatically stored in INI file or registry
            ·    Dictionary compiler included
            ·    Optional compond word checking with German dictionary
            ·    Very fast dictionary routines




© 2004-2008 WPCubed GmbH - Munich, Germany
172     WPTools Version 6


           ·    Complete source code for spellcheck engine included with registered version. The engine
                has been rewritten to make best use of the latest compiler technology.


        In the editor two properties are of interest for spellchecking:

        SpellCheckStrategie possible values are wpspCheckInInit (default), wpspCheckInPaint and
                            ,
        wpspCheckInInitAndPaint. We recommend to use wpspCheckInInitAndPaint with WPSpell.

        ViewOption flag wpTraditionalMisspellMarkers: If this flag is active instead of the big underlines (
            ) smaller lines are drawn under misspelled words:




7.12.1 Use WPSpell
        WPSpell is an addon to WPTools.

        1) Please add the required units to the uses clause

        uses WPSpell_link, WPSpell_Controller, WPSpell_OptForm, WPSpell_StdForm

        2) Create a TWPSpellController (you can also drop the component on the form) and set the
        properties. (Note: This step is not required if you are using the DEMO version since here the
        SpellController is provided by a DLL - the registered version does not use a DLL)

        in TForm we need a variable:
        FSpellControler : TWPSpellController;

        This variable is initialized in the event OnCreate

        procedure TForm1.FormCreate(Sender: TObject);
        begin
          FSpellControler := TWPSpellController.Create(self);
          FSpellControler.PersistencyMode := wpUseRegistry;
          FSpellControler.Active := TRUE;
          FSpellControler.LoadSetup(false);
          // UpdateLanguges; - this procedure fills a combobx
        end;

        procedure TForm1.FormDestroy(Sender: TObject);
        begin
          FSpellControler.AutoSaveSetup;




                                                                     © 2004-2008 WPCubed GmbH - Munich, Germany
Guide   173


           FSpellControler.Free;
         end;

         3) Switch SpellAsYouGo on and off (Spell is a checkbox in this example)

         procedure TForm1.SpellClick(Sender: TObject);
         begin
          if Spell.Checked then WPRichText1.StartSpellCheck(wpStartSpellAsYouGo)
          else WPRichText1.StartSpellCheck(wpStopSpellAsYouGo);
         end;

         4) Add a configure button or menu item

         procedure TForm1.ConfigureClick(Sender: TObject);
         begin
          i f FSpellControler.Configure then
          begin
              // UpdateLanguges; - if we update a combobox
              i f Spell.Checked then
              begin
                 WPRichText1.StartSpellCheck(wpStopSpellAsYouGo);
                 WPRichText1.StartSpellCheck(wpStartSpellAsYouGo);
              end;
          end;
         end;

         alternatively you can also call:
          WPRichText1.StartSpellCheck(wpShowSpellCheckSetup);

         5) If you want to show a combobox with the available dictionaries

         // This procedure updates the combobox
         procedure TForm1.UpdateLanguges;
         var i, j : Integer;
         begin
           // Checkbox
           Spell.Checked := (FSpellControler.OptionFlags and WPSPELLOPT_SPELLASYOUGO)<>0;
           // ComboBox
           SpellLanguages.Items.Clear;
           j := -1;
           for i:=0 t o FSpellControler.LanguageIDCount-1 d o
           begin
              i f FSpellControler.CurrentLanguage=FSpellControler.LanguageID[i] then
                  j := SpellLanguages.Items.Count;
              SpellLanguages.Items.AddObject(FSpellControler.LanguageName[i],
                   Pointer(FSpellControler.LanguageID[i]));
           end;
           SpellLanguages.ItemIndex := j;
         end;

         //this procedure applies a language change
         procedure TForm1.SpellLanguagesChange(Sender: TObject);
         begin
            i f SpellLanguages.ItemIndex>=0 then
            begin
               FSpellControler.CurrentLanguage :=
               Integer(SpellLanguages.Items.Objects[SpellLanguages.ItemIndex]);
               i f Spell.Checked then
               begin
                   WPRichText1.StartSpellCheck(wpStopSpellAsYouGo);
                   WPRichText1.StartSpellCheck(wpStartSpellAsYouGo);
               end;




© 2004-2008 WPCubed GmbH - Munich, Germany
174    WPTools Version 6


          end;
       end;

       The property CurrentLanguage is used to select the current dictionary. You have to use one of the
       language or language-group IDs which are defined in file WPLanguages.INC
          Example:
          English General = 9,
          English UD= 1033,
          English British = 2057,
          French = 1036,
          German = 1031,
          Italian= 1040,
          Spanish = 1034




7.13 WPReporter Addon
       WPReporter is part of WPTools Bundle, WPTools Professional Bundle and WPTools Premium.

       With WPReporter you get a powerful reporting tool which is tightly integrated into the word
       processor. The resulting report is a text which can be edited. It creates the reports by merging data
       into a template with the ability to loop parts of the template (bands). In contrast to the the
       plenty reporting applications and tools available already, our reporting engine is based
       on a word processor. This m        eans the reporting tem     plate is just a text docum   ent, so is
       the output.

       Also included is a component to add calculation to tables, also for dynamically calculated fields to
       display subtotals in headers, footers, header-rows and footer-rows.

       WPReporter is able to create tables with header and footer rows and sections if you need different
       page formats in a document.

       The following classes are included:

              TWPEvalEngine            This class implements the support for
                                       formulas.
              TDBWPEvalEngine          This class adds database access to
                                       TWPEvalEngine
              TWPFormulaInterface      This class creates a link between an editor
                                       and an TWPEvalEngine to support
                                       calculation in text and tables
              TWPSuperMerge            This is the main class of WPReporter. It
                                       implements the logic to create a new text
                                       from data and template texts.

       new: WPTools 6 includes powerful Token to Template Conversion. ReportTemplates can be editied
       using certain plain text tokens.

       Order link to the upgrade WPTools Standard or WPTools Standard PRO WPTools "Bundle"



                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     175




7.13.1 Comparison to "usual" reporting
         1) End user can modify templates

         Many reporting tools are very complicated to use or do not offer end user
         modifications at all.

         a) With WPReporter it is possible to load a regular docum  ent with added tags for fields
         (i.e. <<name>>) and bands (i.e. <<#ORDERS>> .... <<#/ORDERS>> ) and
         WPReporter can convert such a docum     ent into a reporting tem  plate (=token to
         tem plate conversion). Syntax highlighting is possible while editing the reporting
         tem plate in text form.

         b) If the database structure is rather com plicated you can use the alternative
         tem plate architecture. Here the report logic has been split up into two parts (pre
         tem plate and tem plate architecture).

         One part is created and m aintained by the developer. It contains the outline of the
         report with bands which can but do not have to be used, fields which can be used and
         variables which are calculated while the report is being processed as XML data.

         The second part is the report tem   plate. It can be edited by the end user (you can of
         course hide it, too) using the word processor. It is possible to insert fields and
         variables from the "repository". It is also possible to reset a selected group to its initial
         state in case it has been m  essed up. It is saved as docum   ent with added proprietary
         attributes to m aintain the bands.

         2) No fixed page layouts

         Most reporting tools work with page layouts. This means you m place graphics at
                                                                         ay
         exact positions on a form and when the report is created it will exactly look as the
         designed form s.

         This approach is often very good, but is som cases you want the text created by the
                                                       e
         reporter to be edit able. The m entioned approach has a problem here - while it is
         som  etim possible to create RTF docum
                  es                               ents with the reporting tool theses are not
         really "edit able" because the text has been broken up into the tiniest pieces - just
         single text boxes. Usually the RTF export is optimized to be best viewed in MS Word
         only.

         With the WPReporter a text file (RTF or WPT form   at) is created which allows full
         editing, including changing of the page size, and other operations which m  akes the re-
         pagination of the text necessary.

         This means that the reporting feature is optim if you need to create longer texts,
                                                           al
         such as contracts. It will be suitable to print lists and invoices. If you need to print
         form which look like pre printed paper form (i.e. TAX form you cannot use the
             s                                         s                s)
         WPTools reporting. But in this case you will probably not need sophisticated form    atted
         text.

         3) Most RTF attributes usable




© 2004-2008 WPCubed GmbH - Munich, Germany
176    WPTools Version 6


        Usually the reporting tools only support very lim  ited RTF features, sometim even
                                                                                     es
        justified text is a problem not to speak of im
                                   ,                  ages with text wrapping around, tables
        and m   ore sophisticated tab stops which use fill signs.

        Since the WPTools reporting uses the sam text engine all the powerful word
                                                  e
        processing features can be used in the created report.

        4) No external installation

        Many reporting tools require to be installed separately, they can be quite cost
        intensive and the licensing can be restrictive.

7.13.2 Calculation in Text and Tables
        When you have licensed WPReporter you can use powerful calculation commands in WPTools. To
        use the calculation names and formulas add the component TWPFormulaInterface to the
        application.

        The calculation tool uses names and formulas. Names can be assigned to paragraphs or cells
        only.
        Formulas can be assigned to paragraphs (or cells) and also special TWPTextObj objects. When the
        text is calculated the paragraph text or the displayed text of the TWPTextObj will show the floating
        point result of the calculation.

        If a formula is just a name (assigned to one or many other paragraphs) the result is the sum of the
        numbers found in all the paragraph which use this name. This feature makes it easy to sum up
        values.

        Please see the demo TableCalc. This demo includes code to create a simple invoice. It also shows
        how to activate the optional display of paragraph names and formulas.

        Which this option activated you will see an output like this:




        You can see that the cells in each column use a different name (highlighted in red). The formula (in
        blue) uses a relative function left(N) which returns the value of the Nth cell to the left .
        The total row uses a formula (in blue) just the name used by the cells which should be summed up.

        Please note that this way to calculate is optimized for invoices and similar: The numbers will be
        always summed as displayed (rounded), not using possible additional decimal values.




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      177



         The text object which also displays the total is created as simple as:

           obj := par.AppendNewObject(wpobjTextObject,false, false);
           obj.Name := 'CALC'; // fixed name
           obj.Source := 'PAR_TOTAL' // display the sum of all par with this name
                                    ;
           obj.Params := '???'; // initial display text

         Note: the objects name is 'CALC' which is obligatory.

         If you need to create sub totals in header or footer texts You can use a TWPTextObject with the
         name PAINT_CALC.
         The 'Source' should be a + sign followed by the name of all paragraphs which should be summed up.
         Other formulas are not possible since the calculation is not performed by the WPEval unit. This
         simple calculation is the default action done for the OnTextObjectPaintCalc of the
         TWPFormulaInterface. Please also see below.

         Using HTML syntax such a footer can be created like this:

           WPRichText1.HeaderFooter.Get(wpIsFooter,wpraNotOnLastPage).RtfText.AsString :=
             '<html><div align=right style="border-top-width:0.5pt">Subtotal: <TEXTOBJ
         name="PAINT_CALC source="
                         "         +PAR_TOTAL">???</TEXTOBJ></div></html>';

         This functions are created by the unit WPTblCalc and can be used in formulas:

         left(N, N2, ...Nn) : sum up the cells to the left
         right(N, N2, ...Nn) : sum up the cells to the right
         previous(N, N2, ...Nn) : sum up the cells in the same column but previous rows
         prior(N, N2, ...Nn) : synonym for previous()
         average(name) - calculate the average of all paragraphs with the give name
         valcount(name) - count the paragraphs with the give name


         The event TWPFormulaInterface.OnTextObjectPaintCalcmakes it possible to calculate the
         contents of fields at paint time. This is very useful for fields in header or footer texts or repeated
         table header or footer rows. These fields are not physically duplicated, they are just painted on
         several pages. So their contents must be calculated at paint time.




© 2004-2008 WPCubed GmbH - Munich, Germany
178    WPTools Version 6




        The event OnTextObjectPaintCalc provides several parameters which make it possible to evaluate
        the text on the current page (the page they are painted upon).

        Please see the TableCalc demo. There we sum up all values which are in a certain mail merge field
        placed on a certain page. A total sum is simply retrieved from a value which is added to each row.
        We are searching for the last occurance of this value and use it. So if the page break changes and
        the last row becomes the first row of the next page we use the new last value instead.

7.13.3 Reporting with WPReporter
        The reporting creates a new text from a template by mixing in data or calculated text.

        A template consists of text which is sperated into different parts using bands and groups. Unlike
        groups, bands (data, header or footer) always end with the start of the next band or group. Groups
        end with the closing of the group - they can also be nested.

        Example for a template:




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      179




         (Hint: You can double-click on the     to collapse any group)

         This report is created by this template in our demo application:




         Note that the table uses two footer rows. One is used at the end, the other is used only before a
         pagebreak. When the created report is saved to RTF MS-Word can use the repeated headers.




© 2004-2008 WPCubed GmbH - Munich, Germany
180    WPTools Version 6


      Unfortunately it does not support repeated footers and hidden rows so both footers will be displayed
      at the end of the row.

      Note: Using the property ColumnWidthSnapValue You can control that the column widths which are
      very close (max. difference ColumnWidthSnapValue twips) are set to the same value. The default
      value 15 makes sure that one screen pixel difference does not count. This mode can be deactivated
      in the property "Options".

      If you have long field names and want to avoid word wrap in your template, You can either apply
      the property WPAT_NoWrap to the cells which should not wrap or you can shorten the fieldnames
      automatically using MergeText, event OnMaileMergeGetText. You can still show the complete
      fieldname in an hover event - please see chapter MailMerge. Note that WPAT_NoWordWrap must
      be enabled in property RichText.FormatOptionsEx.

      Please note that the word wrap is highly influenced by the way the font width is calculated by the
      screen driver.

      The property SuppressAutomaticHeaderFooter can be used to avoid that header and footers which
      cannot be properly used with MS Word are created.

      Please also see the event TWPFormulaInterface.OnTextObjectPaintCalc it can be used to
                                                                        -
      calculate subtotals for the repeated rows. (See demo TableCalc)

      WPReporter includes the band dialog which can be easily used to edit the template:




      This dialog is displayed by the TWPReportBandsDialog component. Please specify the editor and
      the SuperMerge component. Then use this code to show the dialog: WPReportBandsDialog1.
      Execute;

      The buttons "New Band" and "New Group" open popup menus to create new control bands. For
      groups cou can choose where the group should be created - ie. if the current group should be
      surrounded by the new one. Please note that while a group or band is selected, pressing ENTER




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      181


         creates a new line at the beginning of the contained text. If a group is selected pressing INSERT
         creates a new line AFTER the group. Tip: When text and regular bands (no groups) are selected you
         can place this text into a new group using "create at the current position".

         (Hint: After a band has been added you can use the "Band Type" dialog to change its type. Please
         also activate one of the check boxes.)

         The SuperMerge component (TWPSuperMerge actually does all the work. It combines the text
                                                        )
         from the source component with the data with the data which was inserted using the
         OnMailMergeGextText event and sends it to the destination, another memo component of the class
         TWPRichText.

         To attach the two TWPRichText to the TWPSuperMerge please use one line of code to call the
         procedure SetSourceDest. (In WPTools 4 there were 2 properties for this task - they had to be
         removed due to the different architecture of the new WPReporter)

         procedure TForm1.FormCreate(Sender: TObject);
         begin
            WPSuperMerge1.SetSourceDest (
               SourceText.Memo.RTFData,
               DestText.Memo.RTFData
               );
         end;

         During the creation of the document (inside the destination control) the processing of each band can
         be switched off and each group can be repeated as often as required.

         After one paragraph of the template has been copied to the destination control the fields in this
         paragraphs are replaced by data values. This work is performed by the mail merge function which
         can be also used without WPReporter. The mailmerge function triggers the OnMaileMergeGetText
         event for each field which is found in the text. Inside the event the data can be assigned to the object
         which is used to transfer the data, an image can be inserted or the text format can be changed.




7.13.4 WPReporter - step by step
         In this chapter we show how to build an application which creates a certain report.
         (full source in directory "TasksWPReporter_MasterClient")

         1) Create a form with a page control with 2 pages. The first page will be the template editor, the
         second page will display the complete report. You can easily hide the first page if you do not want to
         show your end user the editor.

         Also drop a TWPReportBandsDialog and a TWPSuperMerge component.




© 2004-2008 WPCubed GmbH - Munich, Germany
182    WPTools Version 6




      2) Add a TWPToolBar, TWPRuler, a TWPRichText and also a TButton and connect the controls.




      The button is used to show the WPReportBandsDialog1 which is used to add and delete bands.

      3) Now please add a second TWPRichText on TabSheet2. We will use this second editor to show

      the created report. You can also hide the form completely and a TWPPreviewDlg      instead.
      (Property EditBox set to WPRichText2)

      4) Now configure the TWPSuperMerge component. This must be done in the OnCreate event of the
      form.

       procedure TForm1.FormCreate(Sender: TObject);
       begin
          WPSuperMerge1.SetSourceDest(
             WPRichText1.Memo.RTFData,
             WPRichText2.Memo.RTFData );




                                                             © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      183


              WPReportBandsDialog1.EditBox := WPRichText1;
           end;

         Also configure the ReportBands dialog:




         The property DataBases holds a string list with names which can be selected for the group bands.
         This names are used select a certain data set or to create and reset a query.

         In our example we enter the strings CUSTOMERS and INVOICES.

         5) now its time to create and attach the data bases. To do so we create a separate data module. (In
         a real application you would use your existing data module)

         For this demo we select the databases CUSTOMERS and ORDERS from the Borland demo
         database directory and set a master-detail relationship based on the field 'CustNo'.




         6) In the event Form.OnShow we fill the field collection of the SuperMerge component. The field list
         is used to create the drop down menu for the InsertField menu. The collection can be also filled at
         design time. The field names can optionally use the syntax name=label_text. If the equation sign is
         used the part after it will be displayed in the insert-field menu of the report editor dialog.

         procedure TForm1.FormShow(Sender: TObject);
         var i : Integer;
         begin
           WPSuperMerge1.Fields.Clear;
           with WPSuperMerge1.Fields.Add d o
           begin
                ParentDatasetName := 'CUSTOMERS' ;
                ParentDatasetDescription := 'Customer Data';
                RequiredParentGroup := ' ';
                for i:=0 t o DataModule1.CUSTOMER.Fields.Count-1 d o
                   FieldNames.Add( DataModule1.CUSTOMER.Fields[i].FieldName
                    + '=' + DataModule1.CUSTOMER.Fields[i].DisplayLabel );
           end;




© 2004-2008 WPCubed GmbH - Munich, Germany
184     WPTools Version 6



        with WPSuperMerge1.Fields.Add d o
        begin
             ParentDatasetName := 'ORDERS' ;
             ParentDatasetDescription := 'Orders' ;
             RequiredParentGroup := 'ORDERS' ;
             for i:=0 t o DataModule1.CUSTOMER.Fields.Count-1 d o
                FieldNames.Add( DataModule1.ORDERS.Fields[i].FieldName
                  + '=' + DataModule1.CUSTOMER.Fields[i].DisplayLabel                   );
        end;
      end;

      7) Now we want to implement a procedure which creates a generic template which works with our
      data.


      Was add a button:                        and attach this code:

      procedure TForm1.CreateGroupsClick(Sender: TObject);
      begin
        WPSuperMerge1.AddReportGroup('CUSTOMERS' ,
           [wpCreateBorders,wpCreateDataRow ],
           nil, SetCellStyle, 2) ;
        WPSuperMerge1.AddReportGroup('ORDERS'  ,
           [wpCreateBorders,wpCreateSmallHeaderRow,wpCreateDataRow,wpCreateSmallFooterRow
      ],
           nil, SetCellStyle, 2) ;
      end;

      This code uses the procedure AddReportGroup which creates a group, optional with header and
      footer rows and with already inserted fields. It accepts a list of field names but can also collect the
      fields from the field names in the collection Field which we initialized in step (6).

      Similar to you can use a callback which will be executed for each created cell. In this callback you
      can change the text and set properties for the cell. We use this callback.

      procedure TForm1.SetCellStyle(RowNr, ColNr: Integer; par: TParagraph);
      begin
         i f (RowNr<0) and ((RowNr and 1) =1) then   // Header Rows
         begin
             par.ASetColor(WPAT_FGColor, clBtnFace);
             i f ColNr>1 then include(par.prop, paprColMerge)
             else
             begin
                par.ASet(WPAT_Alignment, Integer(paralCenter));
                par.SetText('Orders' ;
                                    )
             end;
         end
         else i f (RowNr<0) and ((RowNr and 1) =0) then   // Footer Rows
         begin
             par.ASetColor(WPAT_FGColor, clBtnFace);
             par.ASet(WPAT_SpaceBetween, -100) ;
             i f ColNr>1 then include(par.prop, paprColMerge);
         end;
      end;

      to get this report template as result:




                                                                   © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     185




         8) Now we can add the logic to actually create the report.

         We need an event handler for BeforeProcessGroup. Here we check if the 2 tables are at EOF and
         reset the client table.

         procedure TForm1.WPSuperMerge1BeforeProcessGroup(Sender: TWPSuperMerge;
           Band: TWPBand; Count: Integer; var CustomData: TObject; var ProcessGroup,
           IsLastRun: Boolean);
         begin
           i f Band.Alias='CUSTOMERS' then
           begin
              ProcessGroup := not DataModule1.CUSTOMER.Eof;
              i f ProcessGroup then
                  DataModule1.ORDERS.First;
           end else
           i f Band.Alias='ORDERS' then
           begin
              ProcessGroup := not DataModule1.ORDERS.Eof;
           end;
         end;

         In AfterProcessGroup we move to the next record.

         procedure TForm1.WPSuperMerge1AfterProcessGroup(Sender: TWPSuperMerge;
           Band: TWPBand; var CustomData: TObject; var Abort: Boolean);
         begin
           i f Band.Alias='CUSTOMERS' then
           begin
              DataModule1.CUSTOMER.Next;
              Abort := FALSE;
           end else
           i f Band.Alias='ORDERS' then
           begin
              DataModule1.ORDERS.Next;
              Abort := FALSE;
           end;
         end;

         Now we need to merge in the data.

         We use the event OnMailMergGetText. In this event we locate the field in the sepecified dataset and
         assign the contents. Of course it would be possible to use calculated fields or variables and
         constants, too!




© 2004-2008 WPCubed GmbH - Munich, Germany
186     WPTools Version 6


      procedure TForm1.WPSuperMerge1MailMergeGetText(Sender: TObject;
        const inspname: String; Contents: TWPMMInsertTextContents);
      var f : TField;
      begin
        i f Contents.DatasetnamePart='ORDERS' then
              f := DataModule1.ORDERS.FindField(Contents.FieldnamePart)
        else f := DataModule1.CUSTOMER.FindField(Contents.FieldnamePart);
        i f f=nil then
              Contents.StringValue := ' ' // undefined!
        else Contents.StringValue := f.AsString;
      end;

      It is also possible to insert formatted text using the event OnMailMergGetText. For example if you
      have a letter stored in a database or a different editor. Simply assign RTF, WPTOOLS or HTML code
      to Contents.StringValue.

      If the inserted text starts with a table we recommend to set the mail merge option
      mmDeleteThisField With this option the fields are deleted in the destination editor. So no
                              .
      paragraph has to be created above a table to store the field markers.

      procedure TWPRepForm.WPSuperMerge1MailMergeGetText(Sender: TObject;
        const inspname: string; Contents: TWPMMInsertTextContents);
      begin
        i f CompareText(inspname, 'RTFTEXT' = 0 then
                                           )
        begin
            Contents.StringValue := ARTFTEXT.AsANSIString('RTF') ;
            Contents.Options := Contents.Options + [mmDeleteThisField ;
                                                                    ]
         end else ....
      end;

      9) Almost complete - we want to show the update report when the active page in the page control is
      changed

      procedure TForm1.PageControl1Change(Sender: TObject);
      begin
        i f PageControl1.ActivePageIndex=1 then // Secod page then
        begin
            DataModule1.CUSTOMER.Open;
            DataModule1.ORDERS.Open;

            DataModule1.CUSTOMER.First;

           WPRichText2.Clear;
           WPRichText2.Header := WPRichText1.Header; // Assign page properties
           WPSuperMerge1.Execute;
           WPRichText2.DelayedReformat;
        end;
      end;

      10) Improve the template

      At runtime you can change the reporting template, add fields and also header and footer bands. You
      can delete rows, move fields, merge cells.

      After some changes we got this template - still based on the automatic created template.
      Tip: You can save the template as WPT file and load into WPRichText1 when you click on it inside the IDE
      with right mouse button.




                                                                   © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      187




         The first, new header and footer bands create page header and footer. The page numbers have been
         inserted with WPRichText1.InputTextField(wpoPageNumber)        - this function can be also selected
         from the InsertField dropdown in the report editor dialog.

         This is the created report:




         Advanced Techniques:

         Use the BeforeFormatTable event to focr certain tables to be on one page.

         Using the FormatOptions you can force all tables to be left intakt (unless they are too long for a




© 2004-2008 WPCubed GmbH - Munich, Germany
188    WPTools Version 6


        page). Using the RTFDataCollection event BeforeFormatTable you can enable this mode for certain
        tables:

        WPRichText2.
                   HeaderFooter.BeforeFormatTable := BeforeFormatTable;

        procedure TWPRepTest.BeforeFormatTable(RTFData : TWPRTFDataCollection;
             tablepar: TParagraph; var KeepTogether : Boolean);
        begin
          i f tablepar.RowCount=2 then
              KeepTogether := TRUE;
        end;




7.13.5 WPReporter Events
        Reporting with WPReporter is controlled by events. This makes it possible to work with any
        database system, or also without a database, for example if load calculated data.

        Within the event code you can check the properties of the object WPSuperMerge.Stack to get
        information about the current position within the report template. The property Stack.Previous can be
        used to check the propeties of the parent group of bands. Other useful properties are Stack.
        GroupBand, Stack.Band and Stack.CurrentParagraph.

        This events are published by the class TWPSuperMerge:

        OnMailMergeGetText- the most important event, it is used to insert the data for certain data
        fields.

        This event uses the same parameters like the TWPRichText event OnMailMergeGetText. In the
        simplest case the event handler can be




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide    189


             procedure TForm1.DoMailMergGetTexte(
                Sender: TObject; const inspname: string;
                Contents: TWPMMInsertTextContents);
             begin
               Contents.StringValue := 'This is a test';
             end;

         It is possible, for example, to use this field name to retrieve the text from a data set:

             Contents.StringValue := DataSet.FieldByName(inspname).AsString;

         You can also change the attribute of the inserted text using 'MergeAttr'.

              Contents.MergeAttr.SetColor(clRed);


         BeforeProcessGroup:

                 This event is the second most important. It is used to control if a group should be processed
                 or not. If the group should be processed set the parameter ProcessGroup to true, if it should
                 be not processed set the parameter ProcessGroup to false. If you know that this would be
                 the last time this group is being used set the parameter IsLastRun to true.

                 When the template uses nested groups the BeforeProcessGroup will be triggered for the
                 nested group before AfterProcessGroup is triggred for the outer group.

                 Typically you test the DataSet for being at the end (EOF) and set the parameter
                 ProcessGroup accordingly:
                 i f Band.Alias = 'MAIN' then ProcessGroup := not MainDataSet.EOF;

         OnPrepareHeader
                       :

                 This event is triggered before a header band is being processed. You may set the parameter
                 Abort to true to skip the band.

         OnPrepareText
                     :

                 This event is triggered before a text band is being processed. You may set the parameter
                 Abort to true to skip the band.

         OnPrepareFooter
                       :

                 This event is triggered before a footer band is being processed. You may set the parameter
                 Abort to true to skip the band.

         OnPostProcessBandData :

                 This event makes it possible to modify a paragraph after it was created in the destination
                 text buffer. It is triggered after the entire text for a band was created. The start and end
                 paragraphs are passed to the event. The paragraph references can refer to normal
                 paragraphs or table row paragraphs. You can use this event to add flags to paragraphs to
                 mark certain areas in the report.

         AfterProcessGroupData :

                 This event is processed after the data bands in a group have been processed. You can use




© 2004-2008 WPCubed GmbH - Munich, Germany
190    WPTools Version 6


                it to sum up values which should be used as totals in footers. AfterProcessGroupData will
                be triggered each round the group is used. You can set WPSuperMerge.Stack.
                PagebreakAtGroupEnd = true inside this event to force a pagebreak after the hroup data.

        AfterProcessGroup:

                This event is the triggered after a group has been processed. Typically you use this event to
                advance to the next record in the database.

                i f Band.Alias = 'MAIN' then MainDataSet.Next;




7.13.6 Convert text into template
        One unique strength of our WPReporter concept is the possibility to convert an existing report
        (maybe you used to create it using OLE before) quickly into a report template.

        You can use the procedure ConvertLetterIntoTemplate This procedure creates a report with
                                                                   .
        header and footer bands which are initialized to create the header and footer texts found in the
        original document. Around the body of the document a group is created which makes it easy to
        create many letters in a row.

        1) All texts which are fixed have to remain in the template

        2) All text blocks which depend on selected data must be replaced by mail merge fields.

        3) Tables can be converted into groups with the utility function SuperMerge.
        ConvertTableIntoGroup This utility can be called from within the report editor dialog. The tool can
                                 .
        be used when the cursor is inside of a table, please do not select the table.




                                                                      © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     191




         Sometimes it is a good idea to simplify the table before you use "ConvertTableIntoGroup". Very
         useful will be the API 'SplitTable to split up a table which contains data from different logical
                                           '
         elements.

         4) Make text blocks conditional:

         Please add a possibility to the application to set the Name of a band. i.e. you can use a combo box
         or popup menu.

         The code would be basically:
           i f WPSuperMerge1.Bands.CurrentBand<>nil then
              WPSuperMerge1.Bands.CurrentBand.Alias := 'ANAME';

         With the OnPrepareTextevent You can then check text bands (the green ones). If the band uses a
         certain Alias (alternatively You can use property Name) You can set the variable 'Abort' depending
         on a certain condition.

         procedure TWPRepTest.WPSuperMerge1PrepareText(Sender: TWPSuperMerge;
           Band: TWPBand; Count: Integer; var ParProps: TParagraphProperty;
           var Abort: Boolean);
         begin
           i f Band.Alias = 'ANAME' then
           begin
               Abort := TRUE;
           end;
         end;

         Now you can insert a data band and assign the 'Alias':




         Note: If you assign a string to property 'Name', this text will be displayed instead of 'Data'




© 2004-2008 WPCubed GmbH - Munich, Germany
192    WPTools Version 6


7.13.7 Reporter and Bookmarks
        WPSuperMerge is able to create bookmarks around the text which was created in the destination
        document for a certain band or group.

        This bookmarks will be created after the text was entirely created if the property 'Bookmark' was set
        to a non empty string.

        Bookmarks (TWPTextObj objects) embedded in the template will also be copied to the destination,
        but since it is not possible to place bookmarks in band paragraphs the above mentioned functionality
        is the only way to do it.

        In this example template embedded bookmarks are used. The first group uses the bookmark
        property.




        Note: The bookmarks are usually invisible. They are displayed only if the flag
        wpShowBookmarkCodes was used in property FormatOptions.

7.13.8 Token to Template Conversion
        If you use the token to template conversion you can edit the reporting template with
        an editor such as MS Word. This feature has been added to WPTools 6 with the
        WPReporter addon.

        The tem plate is loaded into TWPRichText. In this control the template can be further
        edited with the additional convenience of syntax highlighting and on dem and
        converted into a "true" reporting template. (The latter uses nested paragraphs to
        represent groups and special paragraph types for bands. Fields are not text based but
        use objects instead.).

        Tip: The report templates can be used further in our .NET and OCX components
        TextDynam and TextDynam Server.
                   ic               ic




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Guide     193


         If you used the m m
                           ail erge feature before and have docum  ents with em    bedded m   erge
         fields those can be easily used a reporting templates as well! It is also possible to
         convert an existing report into a template.

         To activate syntax highlighting only one line of code is required:

         SourceText.CustomSyntax := TWPFieldBandSyntax.Create(nil);

         The created instance of TWPFieldBandSyntax will be freed automatically.

         To convert the text to a reporting template simply execute the method
         WPConvertReportScript from unit WPRTEReport.

         function WPConvertReportScript(
           Source: TWPRTFDataCollection;
           Mode: TWPConvertReportScriptMode
                = [wpClearErrorsAndWarning,
                   wpConvertFields,
                   wpConvertBands,
                   wpConvertGroups];
           // If this is nil the 'Body' will be converted
           DataBlock: TWPRTFDataBlock = nil;
           // Parameters used to detect fields and bands
           FieldStart: WideString = '<<';
           FieldEnd: WideString = '>>';
           BandChar: WideChar = ':';
           GroupChar: WideChar = '#'): TWPConvertReportScriptResult;

         Example:

         procedure TWPRepForm.ConvertClick(Sender: TObject);
         begin
           WPConvertReportScript( SourceText.RTFData );
           SourceText.ReformatAll(true,true);
         end;

7.13.8.1 General Syntax - Fields
         The token to template conversion uses special character combinations to separate
         the com ands from the text. Fields have to be em
                m                                        bedded into the characters << and
         > >.

         (This codes < , > , : and # can be custom
                       < >                          ized in TWPFieldBandSyntax for syntax
         highlighting. Other values can be passed to the m ethod WPConvertReportScript)

         Note:

         The parser expects that after the < and before the > characters no whitespace
                                            <                  >
         characters are typed. Otherwise the characters will be interpreted as text.

         Example for fields:

         <<name>>

         The nam of a field m contain space characters.
                e            ay




© 2004-2008 WPCubed GmbH - Munich, Germany
194     WPTools Version 6



         Optionally the closing '/' character can be printed:

         < nam />
          <   e >

         Using such fields m m
                             ail erge docum    ents can be created. Such m  erge docum ents only
         require fields to be filled with data. Using m m
                                                       ail erge does not require the reporting
         extension so we decided to m     ake the syntax highlighting and token to template
         conversion available in the basis edition.

         If you need repeated data rows in a docum  ent you need groups and bands. Bands
         m ark certain text to be the header and footer of a docum ent or group while groups are
         used to loop certain parts of the template as long as data to fill in the fields is
         available. Groups can also be used to disable certain parts of the tem  plate. While
         bands are not nested, groups can be nested and so consist of a start and end token.

         Note: The nam of a field will be passed to the event WPRichText.OnMailMergGetText
                        e
         or WPSuperMerge.OnMailMergeGetTextwhile m     erging the text or creating a report. This
         event can retrieve the text which should be inserted inside the field.

7.13.8.2 Syntax Highlighting
         WPTools includes a syntax highlighter for XML and also for the syntax described in
         this chapter (see TWPFieldBandSyntax)

         Using the syntax highlighting for report templates is easy - and - the highlighting
         works non destructive!

         Show highlighting:
         SourceText.Custom Syntax := TWPFieldBandSyntax.Create(nil);




         Remove highlighting:
         SourceText.CustomSyntax := nil




         Please note, how the original text attributes are restored - here the bold characters in the third line.




                                                                        © 2004-2008 WPCubed GmbH - Munich, Germany
Guide    195


7.13.8.3 Bands
         Bands are identified by a colon (':') after the opening < characters.
                                                                  <

         Example for header bands:

         <<:HEADER>>

         This starts a group header or, if used outside of any group a document header text. In
         the latter case the following variations are possible:

         HEADERF = header on first page only
         HEADERO = header on odd pages
         HEADERE = header on even pages
         HEADER_OFF = this header is disabled.

         Please note that bands are not im  plemented using opening and closing tokens ("i.e.
         < ..> ...< /...> ") so optionally the closing '/' character can be typed: < :HEADER/
          < > <          >                                                          <
         >>

         Example for footer bands:

         <<:FOOTER>>

         This starts a group footer or, if used outside of any group a document footer text. In
         the latter case the following variations are possible:

         FOOTERF = footer on first page only
         FOOTERO = footer on odd pages
         FOOTERE = footer on even pages
         FOOTER_OFF = this footer is disabled.

         Inside header and footer bands fields, images and text is possible. A header and footer
         band ends where either a different header or footer band starts or a data band:

         <<:DATA/>>

         Bands m ust be the first non white space (white space= space or tab characters) in a
         paragraph. All text after the band token will be ignored and can be used to write
         com ents.
             m



7.13.8.4 Groups
         Groups are identified by a double cross ('#') after the opening < characters. While
                                                                          <
         bands < :.../> are not nested, groups can be nested and so are em
                 <     >                                                      bedded into a
         tag pairs <<#...>> <<#/....>.

         Unlike header and footer bands the nam of the group tags are not fixed. Practically
                                                  e
         any nam can be used if it does not contain spaces. However the opening token m
                  e                                                                        ust
         match the closing token. For practical reasons the nam should m
                                                               es        atch the database
         which is referenced inside of the group.

         Example:

         <<#CUSTOMERS>> comment: we list all customers in this group




© 2004-2008 WPCubed GmbH - Munich, Germany
196     WPTools Version 6


               <<Customers.Name/>>
               <<Customers.Address/>>
               Ordered Items:
               <<#OR  DER S>> comment: we list all items ordered by the current
         customer
                     <<Orders.Name/>>
               <<#/OR  DER S>>
         <<#/CUSTOMER    S>>

         Note: The nam of a group will be passed to the band and group events while creating
                         e
         a report. This event has to decide if a group should be processed (again) or not. It
         can create a sql query and calculate sub totals.




7.13.8.5 Parameters for Fields
         1. Name - may contain spaces! (required)

           If first character is the @ sign, the complete text will be handled as formula. (no other options are
         possible)

         2. Displayname in " " - must be second position !

         3. Options.
                +spc - this will add a space after the field if it was NOT empty.
                +spc/ - this will add a space before the field if it was NOT empty
                +nl - to add a new-line if it was not empty
                f "some text" - will be added after the field if it was NOT empty. Alias: + "..."
                b "some text" - will be added before the field if it was NOT empty. Alias: + "..."/
                -"some text" - will be printed if it WAS empty
                r "some text" - will be printed instead of the field

         Special attributes
               remove - the field will be removed
               setattr - the paragraph attribute will be overwritten by field contents attributes
               autosetattr - if this is first field in line use the para attribute
               keepattr - protect the current paragraph attributes
               loadimage - interpret field value as file name of an image file
               loadtext - interpret field value as file name of a text file

         Supports Word Syntax: b before f after. Spaces are allowed after +, -, b, f ...

         4. Format @"...."
                @ "%f" - uses this formatting code to format the field (usually floating point numbers)


         5. Condition ?...=...
               ?fieldname=null - use this field if the specified field was null
               ?fieldname# null - use this field if the specified field is not null
               ?fieldname=zero - use this field if the specified field was zero
               ?fieldname#zero - use this field if the specified field is not zero

                Modify: Contents.IsNull to tell the engine that a field is null or zero.




                                                                       © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       197


7.13.8.6 Parameters for Bands and Groups
         1. Name - predefined header/footer names or one of the possible group names

         2. Displayname name in " " - must be second position

         3. Option +-
               +ff - start a new page after the band/group
               -ff - start a new page before the band/group

         Only header and footer: ("<<:HEADER>>)
               +afterstretch - header/footer used after a streched band
               +between - use band between records
               -start - don't use header at start
               -end - don't use footer at end

         Only Data Bands ("<<:DATA>>)
               -stretch - deactivate stretching (default = on)
               +keep - keep this paragraph together with next
               +newtable - start a new table

         4. Condition ?...=...
               The following conditions to use a band are possible:
               =null - field must be null
               #null - field must not be null
               =zero - field must be zero
               #zero - field must not be zero
               ="..." - the field must have a certain value
               #"..." - the field must be different to a certain value

               Example:




               Modify: Contents.IsNull to tell the engine that a field is null or zero.

         5. Formula - must be last option
            @....

         It is used as start condition in a group start and a continue condition if used in a group end token.

         Any text in the paragraph after the closing '>>' will be ignored as comment!

7.13.8.7 Example Template



            <<:HEADERF "my header"/>> -- any text after the group will be ignored as
            comment
            This is the header on the first page
            <<:HEADER "my header"/>> -- HEADERF, HEADERO, HEADERE, HEADER
            This is the header on all pages



© 2004-2008 WPCubed GmbH - Munich, Germany
198    WPTools Version 6


        <<:TEXT>> -- start the regular text

        Dear Developer,

        This letter documents and demonstrates the reporting feature which is based on a
        template written in regular formatted text with additional tags:

        The "<<#" signs are expected as first non-space signs in a paragraph. Any text
        after the closing >> signs is ignored and can be used as comment. Fields are
        inserted between the signs << and >>. It is important that after the '<<' no white
        space or punctuation is written.

        Headers in groups are written using single, not open/closing tags. They cannot be
        nested anyway. The / before the closing >> signs should be added but is not
        required.

        Only groups are nestable. Groups are started using the code <<#. The name after
        the # sign will be the group name, so a database name can be used. An optional
        alias can be specified. It is possible to set up a list of possible group names.

        Now our list starts:

        <<#GROUP1 ?name#null "Invoice">> -- the table will be given the display name
        "invoice", the logical names remains "GROUP1". After the optional name a
        condition is expected.
        <<:HEADER/>> -- this header will be displayed at the start of the group
        Group Header. Fields are possible: <<fieldname +spc/>>
        <<:DATA ?"has orders"=null/>> -- this is the data row.
        Some data here - under condition that there are no orders. (Note that a field name
        may used spaces. In this case use " in the field name part as well.)
        <<:DATA ?hasorders#null/>> -- this is the data row.
        Some data here - under condition there are orders.
        <<:FOOTER/>> -- this footer will be displayed at the end of the group
        Group Footer. Fields are possible: <<fieldname/>>
        <<#/GROUP1>> -- close the group.

        This text comes after the group.


      When viewed with activated the syntax highlighting the document will look like




                                                          © 2004-2008 WPCubed GmbH - Munich, Germany
Guide      199




         Note: The syntax highlighter does not m     ake any m odifications to the attributes of the
         text. All highlighting is done just visual and is updated while the text is edited.

         After the conversion to the internal reporting template structure the document looks
         like this:




7.14 WPPremium Addon
         WPTools Premium adds the support for footnotes, text boxes and (soon) columns to the
         edition WPTools Professional Bundle. It comes with 100% Source code.

         If you have purchased WPTools Premium please see the dedicated WPTools Premium



© 2004-2008 WPCubed GmbH - Munich, Germany
200    WPTools Version 6


        manual (PDF) which also includes interesting technical information.

        For latest information about WPTools Premium please click here, orderpage.

        This text was created by the WPPremium demo. It also uses the "mirror margin" feature,
        the left and right margin are swapped on each second page.




        the footnote in edit mode:




7.14.1 Text boxes
        To insert a text box use this code:

        var obj: TWPORTFTextBox;
          txtobj: TWPTextObj;
        begin
          i f WPRichText1.CursorOnText.Kind <> wpIsBody then
             ShowMessage('Cannot insert object in Object') else
          begin
             obj := TWPORTFTextBox.Create(WPRichText1);
             obj.WidthTW := 3000;
             obj.HeightTW := 1000;
             obj.ObjName := '_AUTO_' + IntToStr(GetTickCount);
             obj.AsString := '<b>Textbox</b> text in HTML, ANSI or RTF format!';
             txtobj := WPRichText1.TextObjects.InsertMovableImage(obj);
             i f txtobj <> nil then
             begin
                txtobj.Mode := txtobj.Mode + [ wpobjObjectUnderText, wpobjCreateAutoName ];
                txtobj.RelX := 1440;
                txtobj.RelY := 0;
                // optional
                txtobj.Frame := [wpframe1pt,wpframeShadow];
                WPRichText1.ReformatAll;
                obj.Edit;
                WPRichText1.SetFocus;
             end;
          end;
        end;




                                                           © 2004-2008 WPCubed GmbH - Munich, Germany
Guide       201



         This code in the OnTextObjectDblClick event makes the text box editable:

           i f pobj.ObjType = wpobjImage then
           begin
              i f pobj.ObjRef <> nil then pobj.ObjRef.Edit;
              ignore := TRUE;
           end;

         Screenshot of the created box in edit mode (after double click):




         Tip: To create a text box which is automatically positioned in the margin of the page use the modes
         wpobjLockedPos,wpobjPositionInMargin



7.14.2 Footnotes
         Please use the method

           InputFootnote(PlaceCursor: Boolean; CreateNumber: Boolean = TRUE; InitText: string = #32);

         to create a footnote. Like textboxes, headers and footers the footnotes are also "text layers".

         The text layers are all stored as collection items in the collection HeaderFooters.



7.14.3 Columns
         WPTools Version 6 "Premium" supports columns.

         Please note that "text balancing" is supported since WPTools Version 6.05..

         This code starts a 2 column layout at the current paragraph with 0.5 cm margin inbetween.

           WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS, 2) ;
           WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS_X, WPCentimeterToTwips(0.5));
           WPRichText1.Refresh;

         This code will ceate 3 columns

           WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS, 3) ;
           WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS_X, WPCentimeterToTwips(0.5));
           WPRichText1.Refresh;

         With this code a column break is inserted so this paragraph will be moved to next column or page.
         The user will need this functionality if a column should not be extended to the end of the page.

           include(WPRichText1.ActiveParagraph.prop, paprNewColumn);
           WPRichText1.Refresh;




© 2004-2008 WPCubed GmbH - Munich, Germany
202     WPTools Version 6



          To switch of column layout use

            WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS, 1) ;
            WPRichText1.ActiveParagraph.ADel(WPAT_COLUMNS_X);
            WPRichText1.Refresh;

          Column properties are loaded and saved in WPT and RTF format.




7.15 Trouble Shooting
          When creating a package with C++Builder 2007

          Go to Project Options > Delphi Compiler > Other options

          In the 'Additional options' box, enter
          > -LUDesignIDE

          Leave the 'Use these packages when compiling' box empty.

          Compile.

          This is described in the CB2007 help system. Search in the Index for "Delphi packages (C++)"


8         Reference
          The registered version of WPTools 6 also includes an organized CMH file which can serve as
          reference.




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Reference       203



8.1      Reader and Writer
         WPTools makes it easy to add support for different file formats.

         The import and export is done through a reader and a writer class which must inherit from
         TWPCustomTextReader and TWPCustomTextWriter.

         This basic classes (defined in unit WPRTEDefs) already implement the necessary code for buffered
         reading and writing.




         To use a different reader or writer simple use its classname in the property TextLoadFormat or
         TextSaveFormat or use the alias names, RTF, HTML, ANSI and WPTOOLS.
         The reader class also includes a function to check for the format using the first 500 characters of a
         file, this makes it possible to implement auto detection.

         It is possible to select a certain reader or writer using a 'format string'. This string is passed to load
         and save methods, such as LoadFromFile and also in the properties TextLoadFormat and
         TextSaveFormat.

         To select a certain reader or writer simply name it in the format string.
         You can pass options to the reader or writer, too.

         This options are appended to the format string after a minus sign, i.e "HTML-onlybody". Multiple
         options are separated by comma.

         You can also set the code page for the loading and or saving operations. This can be useful with the
         data sensitive control DBWPRichText:

         Example:
             DBWPRichText1.TextLoadFormat := 'ANSI-codepage1251' // cyrillic
                                                               ;
             DBWPRichText1.TextSaveFormat := 'ANSI-codepage1251'
                                                               ;

         In general these options are supported but not all reader/writer can support all options:

         In our web based forum we have posted several FAQ topics and articles.




© 2004-2008 WPCubed GmbH - Munich, Germany
204    WPTools Version 6


        The article "Compose an e-mail in HTML format / Save image to HTML" shows how to create a
        HTML e-mail.

        Overview
        For details please see table here: http:
                                               //www.wpcubed.com/manuals/formatstrings.htm
        onlybody - only write body part
        ignorefonts - do not load font information
        ignorefontsize - do not load font size information
        nostyles - do not load or save styles
        nonumstyles - do not load or save number styles
        noimages - do not load or save images
        basetext - only save text in WPTOOLS format, no styles or other info
        nomergefields - do not save merge fields, only contents
        nohyperlinks - do not save hyperlinks
        nobookmarks - don't save bookmarks
        novariables - dont save or load RTF variables
        nobinary - try to convert all binary to ASCII
        nopageinfo - do not save or load page size information
        ignorekeepn - don't load the keepn flag from RTF
        ignorerowmerge - do not load row merging from RTF
        ignorecollapsedpar - don't save table rows which are hidden by
        WPReporter
        codepage12xx - set the code page XY for loading. Default is 1252.
        complete - load header and footer information although we are inserting
        text
        alwaysembed - embed image data also for linked images

        For further reference please see the implementation of the reader and writer classes in the units
        WPIO*.PAS. All options are processed by the procedure "SetOptions". The reader and writer publish
        "Opt_name" properties which are set to true when an format option with the same name was used.



8.2     TParagraph API
        This object stores the text. It is organized in a linked list (NextPar/
        PrevPar) starting from TRTFData.FirstPar. Paragraphs can also contain
        sub-paragraphs (ChildPar).

        Similar to WPTools Version 4 tables cells are handled as paragraphs.
        In contrast to previous versions, WPTools 5 handles child paragraphs
        to support multiple paragraphs in the one table cell. Even tables can
        be inside a table cell - (but they will always start under, and not
        beside the normal text since they always start on a new line.)

        Here we list the most important properties and methods.



8.2.1   TParagraph Properties
        _ActCellWidth

        AClass




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Reference   205


         align

         ANSIChr

         ANSIText

         Cell

         ChildPar

         Children

         ChildrenCount

         ColCount

         ColFirst

         ColLast

         ColLeft

         ColNext

         ColNr

         ColPrior

         ColRight

         Cols

         ColSpan

         CustomParameters

         EndSpanH

         EndSpanV

         FirstLine

         FirstSibling

         HasChildren

         Hidden

         id

         indentfirst

         indentleft

         indentright




© 2004-2008 WPCubed GmbH - Munich, Germany
206    WPTools Version 6


      IsFirstTextPar

      IsLastTextPar

      IsNewPage

      LastChild

      LastInnerChild

      LastLine

      LastSibling

      LineCount

      LoadedCharAttr

      LogNextPar

      LogPrevPar

      MinCHeight

      next

      NextPar

      nextpardown

      ObjectIndex

      ObjectRef

      ParagraphType

      ParentCell

      ParentGroup

      ParentPar

      ParentParentPar

      ParentParentRow

      ParentParentTable

      ParentRow

      ParentTable

      ParLength

      prev




                           © 2004-2008 WPCubed GmbH - Munich, Germany
Reference   207


         PrevPar

         RowCount

         RowDown

         RowFirst

         RowLast

         RowLogNr

         RowNext

         RowNr

         RowPrior

         Rows

         RowSpan

         RowUp

         RTFData

         Sibling

         SiblingCount

         SiblingNr

         spaceafter

         spacebefore

         spacebetween

         StartSpan

         TableCount

         Tables

8.2.2    TParagraph Methods
         _FixAllCellWidths

         _IsWidthTw

         _SetMinMaxWidth

         AddFlagAttr

         ADelAllCharAttrDefinedIn




© 2004-2008 WPCubed GmbH - Munich, Germany
208    WPTools Version 6


      ADelColumn

      ADeleteEqualSettings

      AdjustTableRow

      AGetBaseAndSpan

      AGetFBBGCOlor

      AGetInherited

      AGetInheritedFromCell

      AGetInheritedFromPar

      ANeedUpdateProps

      Append

      AppendChar

      AppendChild

      AppendNewCell

      AppendNewObject

      AppendNewObjectPair

      AppendNewPar

      AppendNewRow

      AppendNewTable

      AppendTree

      AsChildOfPreviousPar

      ASetColumn

      ASetNeutral

      ASetRow

      Assign

      AUpdateProps

      CalcBorderLeftRightIndent

      CheckTable

      ClearCharAttr




                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Reference   209


         ClearCharAttributes

         ClearProps

         ClearText

         Compare

         ComparePar

         CompareW

         Contains

         ContainsText

         CopyChar

         CPOfPos

         Create

         CreateCopy

         CreateCopyList

         CreateRow

         CreateTable

         CurrentSection

         DeleteChar

         DeleteChars

         DeleteMarkedChar

         DeleteParagraph

         DeleteParagraphEnd

         DeleteParagraphKeepChildren

         DeleteWPTextObj

         DelFlagAttr

         Depth

         Destroy

         Duplicate

         Empty




© 2004-2008 WPCubed GmbH - Munich, Germany
210    WPTools Version 6


      EndRow

      Exchange

      ExcludeProp

      ExcludeProps

      FirstLevelPar

      FixAllCellWidths

      FixAllRightCellWidths

      FontSizeAtPosition

      FreeObjectRefs

      GetAllText

      GetCell

      GetCharAttr

      GetCharAttrAt

      GetCharAttrIndexAt

      GetChildrenAsList

      GetDebugTreeString

      GetFirstCharAttr

      GetLineText

      GetNumberText

      GetObjList

      GetRowNext

      GetRowPrior

      GetRTLCursorPos

      GetSubText

      GetText

      GetWPTextObj

      globalnext

      globalNextPar




                              © 2004-2008 WPCubed GmbH - Munich, Germany
Reference   211


         HasAttr

         HasObjects

         HasParent

         HasProp

         HasText

         HasTextW

         Height

         HeightTotal

         InbetweenObjects

         IncludeProp

         IncludeProps

         Insert

         InsertEx

         InsertNewObject

         IsCharObject

         IsEmpty

         IsFirstPar

         IsLastPar

         IsLowercase

         IsNonABC

         IsNonSpace

         IsNum

         IsPunctation

         IsRTL

         IsSpace

         IsTable

         IsUppercase

         IsWordDelimiter




© 2004-2008 WPCubed GmbH - Munich, Germany
212    WPTools Version 6


      LastChar

      LimitCPToLineLength

      LimitLines

      LineAllCount

      LineEndOffset

      LineHeight

      LineIsLast

      LineLength

      LineOffset

      LineOfPos

      LinePageNr

      LinePosFromX

      LineStartNr

      LineXFromPos

      LoadFromFile

      LoadFromStream

      LoadFromString

      LocateNextChar

      LocatePrevChar

      MakeLine

      MergeCell

      MoveChar

      NeedAttr

      NeedCharPos

      nextcell

      NextLine

      Optimize

      OptimizeObjectRefs




                            © 2004-2008 WPCubed GmbH - Munich, Germany
Reference   213


         Overwrite

         paprIsLeftPar

         paprIsRightPar

         ParagraphLines

         ParagraphObjAdd

         ParagraphObjDel

         ParagraphObjFind

         ParentCellFromTable

         ParNr

         Position

         PositionOfObject

         PosOfCP

         prevcell

         PrevLine

         QuickFind

         Reformat

         Refresh

         Replace

         ReplaceW

         RowAppend

         SaveToStream

         SetAllText

         SetCapacity

         SetCharAttr

         SetChildrenFromList

         SetRTFData

         SetRTLCursorPos

         SetStyle




© 2004-2008 WPCubed GmbH - Munich, Germany
214     WPTools Version 6


        SetText

        SplitAt

        SplitCell

        SplitTable

        StartNewSection

        StartWith

        StartWithW

        SubPar

        SwapWithNextPar

        SwapWithPrevPar

        TableDepth

        TextAreaWidth

        TotalLength

        UnlinkParagraph

        UnlinkParagraphList

        UpdateMinMaxWidth

        ValidateTable

8.2.3   AppendParCopy
        If you need a low level routine to copy one paragraph and all the included paragraphs
        (this can be table rows or table cells) to the destination editor use:

        var par : TParagraph;
        begin
          // Get the reference to current paragraph
          par := WPRichText1.ActiveParagraph;
          // Append it to the active RTFDataBlock
          DestWP.ActiveText.AppendParCopy(par);
          // This moves to the next paragraph! Useful in a loop!
          WPRichText1.ActiveParagraph := par;
          // Format is required sometimes later
          DestWP.DelayedReformat;
        end;

        For better understanding here the source of the AppendParCopy method:

        function TWPRTFDataBlock.AppendParCopy(var SourcePar: TParagraph; SkipObjects:
        TWPTextObjTypes = []): TParagraph;
        var toPar : TParagraph;
        begin
          i f SourcePar = nil then Result := nil else




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Reference        215


           begin
              Result := SourcePar.CreateCopy(Self, SkipObjects);
              i f Result.ParagraphType = wpIsTableRow then
              begin
                 i f Empty then
                    toPar := CreateTable(nil)
                 else begin
                    toPar := LastPar;
                    i f toPar.ParagraphType <> wpIsTable then
                       toPar := CreateTable(nil) ;
                 end;
                 toPar.AppendChild(Result);
              end else
                 AppendPar(Result);
              SourcePar := SourcePar.NextPar;
           end;
         end;

         You can see from this code that this routine tries to add new table rows to a table object which
         already exists in the text. So instead of moving the complete table you can also copy only selected
         rows. Since the result value of the AppendParCopy function is the new paragraph you can also do
         some pro-processing, for example apply certain attributes.

         You can also use the SET parameter SkipObjects to leave out certain object types, such as
         [wpobjMergeField] to ignore mail merge fields (the contained text will be copied of course).



8.3      TWPRTFDataCursor
         The cursor class is responsible for cursor movement, text selection and the assignment of properties
         to the selected or current text. It is owned by the TWPRTFDataCollection. This means if different
         editor components share the same RTFDataCollection they also share the same cursor.

         The class TWPRTFDataCursor has versatile methods to manage markers which are dropped in the
         text to be collected again later, for example to restore a cursor position or a selection.
         It also contains moving and selection methods. It offers access to the interfaces to change the
         attributes of the selected text or the current writing mode.




8.3.1    Drop-Markers

         The 'Drop Markers' are special markers which can be placed in the text. They are not really inserted
         in the text (such as bookmarks). They are simple flags which can be used to quickly return to a
         certain position in the text. They are not saved with the text. Many of the input routines
         automatically move the drop marker, this makes them much more powerful than simply storing the
         text position (CPPosition).

         function DropMarker: Integer;
         function DropMarkerAt(par: TParagraph; PosInPar: Integer): Integer;

         This functions drop a marker which can be collected later with CollectMarker.Text insertions and
         deletions - as long as no paragraphs are inserted or deleted - will will automatically modify the
         markers of the affacted paragraphs to make sure their logical position is not changed. This makes




© 2004-2008 WPCubed GmbH - Munich, Germany
216     WPTools Version 6


      markers much more powerful than cursor character offsets, such as 'CPPosition'.

      We suggest to delete all markers with CollectAllMarker when they are not required anymore.

      Note:
      · a) that markers are not saved with the text.
      · b) If the paragraph has been deleted which was used for a marker, the marker will be moved to
        the start of the following paragraph.

      Drops a marker at the start/end of the selected text:
        function DropMarkerAtSelStart: Integer;
        function DropMarkerAtSelEnd: Integer;


      Returns the text position of a certain marker. The result value will be -1 if the marker is not defined or
      if it is located in a RTFDataBlock which is currently not edited. (ActiveText) Please use GotoMarker
      to move the cursor to a certain position.
           function DropMarkerPosition(DroppMarkerID: Integer): Integer;

      Moves to a marker which was dropped by 'DropMarker'. If the parameter 'Collect' = TRUE this
      invalidates all markers which were dropped after the specified marker. You can use (true,-1) to
      collect the last marker or (true,X) to delete all markers including the marker X. (true,1) will collect all
      markers! If it is not possible to move to that marker the result value is FALSE.
         function GotoMarker(Collect: Boolean = TRUE;
                                  DroppMarkerID: Integer = -1): Boolean;
         function GotoMarker(DroppMarkerID: Integer): Boolean;

      Select the text between 2 markers.
        function SelectMarker(FromMarker, ToMarker: Integer): Boolean;

      Select text with a give length starting with a given marker.
        function SelectMarkerStartLen(FromMarker, Length: Integer): Boolean;

      Removes all markers from the text:
        procedure CollectAllMarker;

      Collects all markers including and after DroppMarkerID:
        procedure CollectMarker(DroppMarkerID: Integer);


      Example: This is the implementation of the ReplaceTokens procedure. It converts text which is
      wrapped by special characters such as "<<" and ">>" into mail merge fileds, It uses the
      DropMarkers and the Finder. It also uses some 'Code' methods to create the objects which are used
      to mark mail merge fields.

      function TWPCustomRtfEdit.ReplaceTokens(const opening, closing: string): Integer;
      var
        s, r: string;
        StartID, SelStartID, SelEndID, rl: Integer;
        RestoreSel: Boolean;
        startf, endf: TWPTextObj;
      begin
        StartID := 0;
        RestoreSel := FALSE;
        SelEndID := 0;
        SelStartID := 0;
        Result := 0;
        with TextCursor d o




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Reference     217


           try
             s := opening + '*' + closing;
             StartID := DropMarker;
             SelStartID := DropMarkerAtSelStart;
             SelEndID := DropMarkerAtSelEnd;
             RestoreSel := HideSelection;
             with Finder d o
             begin
               ToStart;
               while Next(s) d o
               begin
                 r := FoundText;
                 rl := FoundLength;
                 CPPosition := FoundPosition + rl - Length(closing);
                 DeleteChar(Length(closing));

                   r := Copy(r, Length(opening) + 1,
                     Length(r) - Length(opening) - Length(closing));

                  endf := InputSingleCode(wpobjMergeField, r);
                  endf.Mode := [wpobjUsedPairwise, wpobjIsClosing];
                 // Move the cursor to the found position
                  CPPosition := FoundPosition;
                  DeleteChar(Length(opening));

                   startf := InputSingleCode(wpobjMergeField, r);
                   startf.Mode := [wpobjUsedPairwise, wpobjIsOpening];
                   endf.SetTag(startf.NewTag);

                   MoveNext(Length(r));
                   inc(Result);
                 end;
              end;
           finally
              HideSelection;
              i f RestoreSel then
              begin
                 TextCursor.SelectMarker(SelEndID, SelStartID);
              end;
              TextCursor.GotoMarker(StartID);
              Refresh;
           end;
         end;


8.3.2    Attribute Interfaces

         The following references are accessible through the TWPRTFDataCursor class:

         The interface to change the selected text. It is also available as WPRichText.SelectedTextAttr
                                                                                                      .
         property SelectedTextAttr: TWPSelectedTextAttrInterface;

         The interface to change the current writing mode. It is also available as WPRichText.WritingAttr
                                                                                                        .
         property WritingTextAttr: TWPCurrentWritingmodeAttrInterface;

         This interfaces changes the character atr the cursor position, similar to WPRichText.CPAttr
                                                                                                   .
         property CurrentCharAttr: TWPCursorCharAttrInterface;

         This function returns SelectedTextAttr if text is selected, otherwise WritingTextAttr:
         function CurrAttribute: TWPSelectedTextAttrInterface;

         Also available is an interface in the finder class to modify the found text.



© 2004-2008 WPCubed GmbH - Munich, Germany
218    WPTools Version 6


      property Finder.FoundAttr: TWPFoundTextAttrInterface.



      The TWPAttrInterface group contains classes to change attributes of different text parts. This chart
      shows which classes there are and how you can access each of them.




      The most important interface is TWPAbstractCharParAttrInterface. It defines the methods which are
      implemented by TWPSelectedTextAttrInterface and TWPCursorCharAttrInterface. It also inherits of
      TWPAbstractCharAttrInterface.

      Please note that the 'Get' functions return a boolean value. This value will be false if the property was
      not set. In this case the passed variable will not be modified.

      If you work with colors you need to know that colors are saved as index values in the TextColors
      array. The methods with "Color" in their names automatically do the conversion.

      In TWPAbstractCharAttrInterface the following methods are available to access the attributes of a
      character:

          procedure Clear;
          procedure Clear(const FontName: string;
               FontSize: Single; FontColor: TColor = clBlack); overload;
          procedure BeginUpdate;
          { Saves the font name, color and background color and all other
          character attributes. Use AttrLoad to load.
          Note: The stored information survives a RTFProps.Clear! }
          procedure AttrSave(var store: TWPAbstractCharAttrStore);
          { Loads the font name, color and background color and all other character
          attributes which were stored with AttrSave. If there
          are no stored attributes the result value is FALSE. }
          function AttrLoad(var store: TWPAbstractCharAttrStore): Boolean;

           { This procedure assigns the character attributes stored in a certain text
            style or TParagraph to this attribute interface }
           procedure Assign(SourceStyle: TWPTextStyle);
           function EndUpdate: Boolean;
           { Applies style flags (such as WPSTY_BOLD..) to the character style. It is
             possible to switch a style explizietly off by setting the style bit
             in the "mask" and unsetting it in the "on" parameters. }

             The following mask bits are available:




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Reference      219


                  WPSTY_BOLD = 1; // Bit 1 bold
                  WPSTY_ITALIC = 2; // Bit 2 italic
                  WPSTY_UNDERLINE = 4; // Bit 3 underlined (solod)
                  WPSTY_STRIKEOUT = 8; // Bit 4 strikeout
                  WPSTY_SUPERSCRIPT = 16; // Bit 5 superscript
                  WPSTY_SUBSCRIPT = 32; // Bit 6 subscript
                  WPSTY_HIDDEN = 64; // Bit 7 hidden text
                  WPSTY_UPPERCASE = 128; // Bit 8 all uppercase
                  WPSTY_SMALLCAPS = 256; // Bit 9 all uppercase but non-captitals are 20%
         larger
                  WPSTY_LOWERCASE = 512; // Bit 10 all lowercase
                  xxx = 1024; // reserved bit
                  WPSTY_DBLSTRIKEOUT = 2048; // Bit 12 strikeout - double solid line
                  xxx = 4096; // reserved bit
                  WPSTY_PROTECTED = 8192; // protected text

              procedure SetCharStyles(WPSTY_mask, WPSTY_on: Integer);
              // switches a style on and off
              procedure ToggleCharstyle(WPSTY_code: Integer);

              { TOneWrtStyle is an enum which can be used to identify character styles.
                The following values are defined:
                  afsBold, afsItalic,afsUnderline, afsStrikeOut,
                 afsSuper,afsSub,afsHidden,afsUppercaseStyle,
                 afsSmallCaps,afsLowercaseStyle, afsNoProof,
                 afsDoubleStrikeOut, afsButton, afsProtected, afsUserdefine.
                  Note: afsNoProof and afsButton are reserved for future versions.
                   WrtStyle = set of TOneWrtStyle. }

              function GetStyles(var styles: WrtStyle): Boolean;
              procedure SetStyles(Value: WrtStyle);
              procedure IncludeStyle(Element: TOneWrtStyle);
              procedure ExcludeStyle(Element: TOneWrtStyle);
              procedure UndefineStyle(Element: TOneWrtStyle);
              procedure IncludeStyles(Elements: WrtStyle);
              procedure ExcludeStyles(Elements: WrtStyle);
              function HasStyle(Element: TOneWrtStyle; var Yes: Boolean): Boolean;
              function HasAStyle(Element: TOneWrtStyle): Boolean;
              procedure SetFont(const FontNr: Integer);
              procedure SetFontName(const FontName: string) ;
              { reads the font name as index in the FontNames arra yof the TWPRTFdataProps }
              function GetFont(var FontNr: Integer): Boolean;
              function GetFontName(var FontName: TFontName): Boolean;
              function GetFontCharset(var Charset: Integer): Boolean;
              { Assign the VCL style font flags. Better use IncludeStyle() and
                 ExcludeStyle() }
              procedure SetFontStyle(const FontStyle: TFontStyles);
              { Read the VCL style font flags. }
              function GetFontStyle(var FontStyle: TFontStyles): Boolean;
              procedure SetFontCharSet(const Charset: Integer);
              function GetCharSpacing(var DistanceTW: Integer): Boolean;
              procedure SetCharSpacing(const DistanceTW: Integer);
              function GetCharLevel(var CharlevelPC: Integer): Boolean;
              procedure SetCharLevel(const CharlevelPC: Integer);
              function GetCharWidth(var CharwidthPC: Integer): Boolean;
              procedure SetCharWidth(const CharwidthPC: Integer);
              procedure SetFontSize(Size: Single);
              function GetFontSize(var FontSize: Single): Boolean;
              procedure SetColorNr(const ColorNr: Integer);
              procedure SetColor(const Color: TColor);
              procedure SetColorString(const ColorName: string) ;
              function GetColorNr(var ColorNr: Integer): Boolean;
              function GetColor(var Color: TColor): Boolean;




© 2004-2008 WPCubed GmbH - Munich, Germany
220    WPTools Version 6


          procedure SetBGColorNr(const ColorNr: Integer);
          procedure SetBGColor(const Color: TColor);
          procedure SetBGColorString(const ColorName: string) ;
          function GetBGColorNr(var ColorNr: Integer): Boolean;
          function GetBGColor(var Color: TColor): Boolean;
          function GetTextLanguage(var Mode: Integer): Boolean;
          procedure SetTextLanguage(const Mode: Integer);
          function GetHighlightMode(var Mode: Integer): Boolean;
          procedure SetHighlightMode(const mode: Integer);
          function GetTextEffect(var Mode: Integer): Boolean;
          procedure SetTextEffect(const mode: Integer);
          function GetUnderlineMode(var Mode: Integer): Boolean;
          procedure SetUnderlineMode(const mode: Integer);
          procedure SetUnderlineColorNr(const ColorNr: Integer);
          procedure SetUnderlineColor(const Color: TColor);
          function GetUnderlineColorNr(var ColorNr: Integer): Boolean;
          function GetUnderlineColor(var Color: TColor): Boolean;
          function GetCharEffect(var Effect: Integer): Boolean;
          procedure SetCharEffect(const Effect: Integer);
          function GetCharStyleSheet(var StyleNr: Integer): Boolean;
          { WPTools can assign paragraph styles also to character attributes }
          procedure SetCharStyleSheet(const StyleNr: Integer);
          { This function creates a CSS like style sheet using wptools special names.
              <br>If 'OnlyUsePTag' is set to true, only generic
              'P' tags are created: The created string can then only be used for text
              which uses the same RTFProps object in the same instance of the
      application. }
          function AGetWPSS(OnlyUsePTag: Boolean = FALSE;
            Abbreviated: Boolean = FALSE): AnsiString;
          { This procedure applies the properties defined in the given string. They must
          have been created using the AGetWPSS function.
          Please note that white space characters are not expected in the string.<br>
          If the optional parameter "Merge" is set to TRUE no properties in the
          style are initialized before the new properties are applied. }
          procedure ASetWPSS(const WPCSSString: AnsiString;
            Merge: Boolean = false;
            Abbreviated: Boolean = FALSE);

          { This function returns true if the provided character attributes
              are contained completely in this character attributes.}
          function Contains(var OtherCA: TWPCharAttr): Boolean;
          function Contains(CharAttrInterface: TWPStoredCharAttrInterface): Boolean;
          { This function returns true if the provided character attributes
              containes all attributes which are defined here. }
          function ContainedIn(var OtherCA: TWPCharAttr): Boolean;
          function ContainedIn(CharAttrInterface: TWPStoredCharAttrInterface): Boolean;

      TWPAbstractCharParAttrInterface defines this methods:

          { This procedure is used to set the paragraph style for all paragraphs }
          function AGetBaseStyle(var StyleNr: Integer): Boolean;
          { This procedure is used to set the paragraph style for all paragraphs }
          procedure ASetBaseStyle(StyleNr: Integer);
          { Increments a property (with offset>0) or decrements a property (with
      offset<0).
             In any case the value is checked for the minimum value }
          procedure AInc(WPAT_Code: Byte; Offset: Integer; MinValue: Integer = 0);
          {:: Assigns a color value - to reset to default use clNone }
          procedure ASetColor(WPAT_Code: Byte; Value: TColor);
         { Executes a bitwise OR operation with the current value and the passed
             value and assign the result }
          procedure ASetAdd(WPAT_Code: Byte; Value: Cardinal);




                                                          © 2004-2008 WPCubed GmbH - Munich, Germany
Reference   221


             { Executes a bitwise AND NOT operation with the current value and the passed
                value and assign the result }
             procedure ASetDel(WPAT_Code: Byte; Value: Cardinal);
             { This procedure is used to write most of the paragraph properties
               If the value is 0 it will delete an existing entry unless the 0 value is
               required to override an inherited value.
               Please note that you may only use 23 bits of Value }
             procedure ASetNeutral(WPAT_Code: Byte; Value: Integer);
             { This procedure is used to reset a property to the default value }
             procedure ADel(WPAT_Code: Byte);
             { This function returns the count of defined TabStops }
             function TabstopCount: Integer;
             { This function returns all defined tabstops one by one }
             procedure TabstopGet(nr: Integer; var Value: Integer;
                 var Kind: TTabKind; var FillMode: TTabFill;
                 var FillColor: Integer);
             { Adds a tabstop to the style. The value has to be specified in
               twips. If the function returns TRUE the tab was added, if
               it is false an existing was modified. }
             function TabstopAdd(Value: Integer; Kind: TTabKind;
               Fill: TTabFill; ColorNr: Integer): Boolean;
             { Deletes the tabstop with the giben value in twips + - the value RTFProps.
         TabPlusMinus) }
             function TabstopDelete(Value: Integer): Boolean;
             { Moves a tabstop specified by position }
             procedure TabstopMove(OldValue, NewValue: Integer);
             { Deletes all defined tabstops }
             procedure TabstopClear;
             { Selects a base style for this paragraph. }
             procedure SetStyle(ParStyleNr: Integer;
               ClearParStyles: Boolean = FALSE;
               ClearCharStyles: Boolean = FALSE);

             { Retrieves the number of the base style for this paragraph }
             function GetStyle: Integer;
             { If this property is true all paragraph manipulations (ASet, AGet, ASetAdd,
         ASetDel, ASetColor, SetStyle, GetStyle but NOT the tabstop procedures)
         will be executed with the current cell instead of the current or selected
         paragraph. This makes it easier to change the color and border attributes in table
         cells.

         The class TWPSelectedTextAttrInterface does not use this property, only
         TWPCursorCharAttrInterface.   }
             property ModifyCellsOnly: Boolean;



         Examples:

         a) Create formatted text under program control:

         WPRichText1.AttrHelper.Clear;
         WPRichText1.AttrHelper.SetFontName(
                                          'Courier New') ;
         WPRichText1.AttrHelper.SetColor(clGreen);
         WPRichText1.ActiveParagraph.SetText(
               'Some green text',
               WPRichText1.AttrHelper.CharAttr);
         WPRichText1.DelayedReformat;

         b) Set the default writing font of a DBWPRichText. We use the OnClear event:

         procedure TForm1.DBWPRichText1Clear(Sender: TObject);




© 2004-2008 WPCubed GmbH - Munich, Germany
222    WPTools Version 6


      begin
         DBWPRichText1.WritingAttr.Clear;
         DBWPRichText1.WritingAttr.SetFontName('Courier New') ;
         DBWPRichText1.WritingAttr.SetFontSize(1 8) ;
      end;

      c) Implement the hotkeys Ctrl+B, I and U to toggle the bold, italic and underline character style in
      the current writing mode or, if text is selected, the selected text. We use the OnKeyPress event.

      procedure TForm1.WPRichText1KeyPress(Sender: TObject; var Key: Char);
      begin
        i f Integer(Key) = Integer('B') - 6 4 then
        begin
           WPRichText1.TextCursor.CurrAttribute.ToggleCharstyle WPSTY_BOLD);
                                                               (
           Key := # 0;
        end
        else i f Integer(Key) = Integer('I') - 6 4 then
        begin
           WPRichText1.TextCursor.CurrAttribute.ToggleCharstyle(WPSTY_ITALIC);
           Key := # 0;
        end
        else i f Integer(Key) = Integer('U') - 6 4 then
        begin
           WPRichText1.TextCursor.CurrAttribute.ToggleCharstyle(WPSTY_UNDERLINE);
           Key := # 0;
        end;
      end;

      d) Change font size of one paragraph:

      WPRichText1. SelectParagraph ); // You can pass a 'par' here!
                                  (
         i f WPRichText1.SelectedTextAttr.GetFontSize(aSize) and (aSize<1 1) then
               WPRichText1.SelectedTextAttr.SetFontSize(1 2)
         else WPRichText1.SelectedTextAttr.SetFontSize(9) ;
         WPRichText1.HideSelection;

      e) Show all supported underline modes:

      procedure TForm1.ShowPossibleULClick(Sender: TObject);
      const
        cnames: array[1. .1 8] o f string =
        (   'WPUND_Standard'
          , 'WPUND_Dotted'
          , 'WPUND_Dashed'
          , 'WPUND_Dashdotted'
          , 'WPUND_Dashdotdotted'
          , 'WPUND_Double'
          , 'WPUND_Heavywave'
          , 'WPUND_Longdashed'
          , 'WPUND_Thick'
          , 'WPUND_Thickdotted'
          , 'WPUND_Thickdashed'
          , 'WPUND_Thickdashdotted'
          , 'WPUND_Thickdashdotdotted'
          , 'WPUND_Thicklongdashed'
          , 'WPUND_Doublewave'
          , 'WPUND_WordUnderline'
          , 'WPUND_wave'
          , 'WPUND_curlyunderline';  )
      var i: Integer;
      begin
        WPRichText1.Clear;
        WPRichText1.CheckHasBody;




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Reference        223



           WPRichText1.WritingAttr.Clear('Verdana' 1 0) ;
                                                 ,

           WPRichText1.InputString('The modes are applied with' + #10 +
             'WPRichText1.WritingAttr.SetUnderlineMode(x)' #13 + #13) ;
                                                           +

           WPRichText1.WritingAttr.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4);
           WPRichText1.WritingAttr.LockBorder;
           WPRichText1.WritingAttr.ASet(WPAT_IndentLeft, 720) ;
           WPRichText1.WritingAttr.ASet(WPAT_IndentFirst, 288) ;
           WPRichText1.WritingAttr.ASet(WPAT_Indentright, 3600) ;
           WPRichText1.InputString(#13) ;

           WPRichText1.WritingAttr.SetColor(clGray);
           WPRichText1.WritingAttr.SetUnderlineColor(clRed);

           for i := 1 t o 1 8 d o
           begin
             WPRichText1.WritingAttr.SetUnderlineMode(i);
             WPRichText1.InputString(cnames[i] + #13) ;
           end;

           WPRichText1.WritingAttr.SetUnderlineMode(-1) ;
           WPRichText1.WritingAttr.SetUnderlineColor(clNone);

           // After UnlockBorder the border will be closed with the next
           // new paragraph
           WPRichText1.WritingAttr.UnlockBorder;
           WPRichText1.InputString(#13) ;

           WPRichText1.WritingAttr.ADel(WPAT_IndentLeft);
           WPRichText1.WritingAttr.ADel(WPAT_IndentFirst);
           WPRichText1.WritingAttr.ADel(WPAT_Indentright);

           WPRichText1.WritingAttr.SetColor(clBlack);
           WPRichText1.InputString(#13 + 'The colors have been changed with' + #10 +
              'WPRichText1.WritingAttr.SetColor(clGray);' #10 +
                                                         +
              'WPRichText1.WritingAttr.SetUnderlineColor(clRed);' #13 + #13) ;
                                                                 +
         end;



8.4      Manage Style Properties
         Most paragraph properties are managed by the functions which are introduced by the TWPTextStyle
         class.

         Please note the inheritance chart of the TParagraph class:




         Note: The RTF engine also provides powerful interfaces to manipulate the paragraph and/or
         character attributes of the current text or the selected text. Both interfaces are part of the



© 2004-2008 WPCubed GmbH - Munich, Germany
224     WPTools Version 6


        TWPRTFDataCursor .

        The attributes of the TWPTextStyle/TParagraph objects are managed by the 'A' methods. Most
        important is the function AGet which reads a value.
        This method TWPTextStyle.AGet(WPAT_code : Integer; var Value : Integer) is a function which
        returns a boolean value. The return code is false if the property with the ID WPAT_code was not
        defined. In this case the variable "Value" will not be modified! Please make sure you initialized the
        variable Value!




8.4.1   List of 'A' methods
        The most important 'A' function is:

        Method ASet(WPAT_Code: Byte; Value: Integer);

        Set the value of a certain property element. Value may be an integer value in the range
          -8388607 .. +8388607. (24 bits)

        Note: If you need to set a color value you can use ASetColor

        Reference:

        Method ABorderEqual

        Method ABorderHash

        Method AClearCharAttr

        Method ACopy

        Method ADel
        This procedure is used to reset a property to the default value.

        Method ADelAllFromTo
        Deletes all properties from/to certain WPAT_values.

        Method ADelAllIn
        Delete all properties which are included in this array.

        Method ADelAttr

        Deletes groups of attributes attributes.

        Method ADeleteDifferentSettings
        This method deletes all properties from this paragraph or style which are not defined in the style which was
        passed as the parameter. Please also see ADeleteEqualSettings.

        Method ADeleteEqualSettings
        This method deletes all properties from this paragraph or style which are also set in the style which is passed
        as the parameter. . Please also see ADeleteDifferentSettings.

        Method AGet
        This procedure is used to read most of the paragraph properties. It returns as true if the value was found.

        Method AGetAsINI




                                                                           © 2004-2008 WPCubed GmbH - Munich, Germany
Reference        225



         Method AGetBorder
         Initialize the border record with the setting in this paragraph. When Init=TRUE all values will be initialized.

         Method AGetCharProps
         This procedure fills a TCharAttr record with character properties which are defined here. If
         Overwrite=FALSE, then it will not overwrite values which are marked as "used" in the mask except for the
         CharStyle value which is assigned using the 'or' operator.

         Method AGetCharStyle

         Method AGetColor

         Method AGetDef
         This procedure is used to read most of the paragraph properties.

         Method AGetDefInherited
         This function reads the attributes defined in this style or paragraph by following the inheritence order. The
         definition which was made last is used. (See AGetDef)

         Method AGetFontName
         This function retrieves the font name defined for this style or its basestyle (= the inherited WPAT_CharFont
         property). If no font is defined, the result value is an empty string.

         Method AGetInherited
         This function reads the attributes defined in this style or paragraph by following the inheritence order. The
         definition which was made last is used. (See AGet)

         Method AGetStringProp
         Reads a property which is a string. Strings are stored as index values into a global string list.

         Method AGetStyleCharAttr

         Method AGetWPSS
         This function creates a CSS-like style sheet using WPTools special names. Note: All position values are
         measured in twips. If 'OnlyUsePTag' is set to true, only generic 'P' and 'Tab' tags are created: The string
         created can then only be used for text which uses the same RTFProps object in the same instance of the
         application.

         Method AGet_CSS

         Method AInc
         Increments which increase a property (with offset>0) or decrease a property (with offset<0). In either case the
         value is checked for the minimum value.

         Method AMerge
         Merges Attributes

         Method ASet
         Set the value of a certain property element. Value may an integer value within the range -8388607 .. +8388607.
         (24 bits)

         Method ASetAdd
         Executes a bitwise OR operation with the current value and the passed value and assigns the result.

         Method ASetAddCharStyle
         Adds a character style attribute (WPSTY_BOLD...) to the paragraph or style.

         Method ASetAsINI




© 2004-2008 WPCubed GmbH - Munich, Germany
226     WPTools Version 6


        Set the propertyies in the WPTools 4 INI format used by the style collection

        Method ASetBaseStyle
        ASetBaseStyle sets the number of the base style for this element. The number is the ID (not the index!) of a
        style which is stored in the ParStyles property of the TWPRTFProps object.

        Method ASetBorder
        Define the borders using the given border record. Don't forget to set blEnabled in LineType, otherwise all
        borders will be disabled. This function overwrites all defined borders in these paragraphs and, if all borders
        are the same or 0, removes existing definitions.

        Method ASetBorderFlags

        Method ASetCharStyle

        Method ASetCharStyle

        Method ASetColor
        Assigns a color value;to reset to default use clNone.

        Method ASetColorString
        Assigns a color string; to reset to default use an empty string.

        Method ASetDel
        Executes a bitwise AND NOT operation with the current value and the passed value and assigns the result.

        Method ASetDelCharStyle
        Removes a character style attribute (WPSTY_BOLD...) from the paragraph or style. This actually adds a
        negative style attribute, this means it also deletes an inherited value.

        Method ASetFontName
        This method sets the font used by this style. If an empty string is passed, it deletes the current setting. It
        cannot be used to set an inherited value which is reported by AGetFontName.

        Method ASetNeutral
        This procedure is used to write most of the paragraph properties. If the value is 0, it will delete an existing
        entry unless the 0 value is required to override an inherited value. Please note that you may only use 23 bits
        of Value

        Method ASetStringProp

        Method ASetWPSS
        This procedure applies the properties defined in the given string. They must have been created using the
        AGetWPSS function. Please note that white space characters are not expected in the string. If the optional
        parameter "Merge" is set to TRUE, the name and the base style parameter are not changed (even if they are
        included in the string) and no properties in the style are initialized before the new properties are applied.

        Method AStringToNumber
        AStringToNumber saves a string to a global list and returns the number to identify the string. This feature is
        required for style properties which require string variables.



8.4.2   ASet/GetBorder
        function AGetBorder(var Border: TBorder; IsTableBord, Init, Overwrite: Boolean):
        Boolean;

        Initialize the border record with the setting in this paragraph.
              When Init=TRUE all values will be initialized.




                                                                           © 2004-2008 WPCubed GmbH - Munich, Germany
Reference          227



         procedure ASetBorder(const Border: TBorder);

         Define the borders using the given border record. Don't forget to set blEnabled in LineType
             otherwise all borders will be disabled. This function overwrites all defined borders in these
             paragraphs and, if all borders are the same or 0, removes existing definitions.

         TBorder is defined as:

         TBorderType = set o f (BlLeft, BlTop, BlRight, BLBottom,
             BlInsideV, BlInsideH,    BlDiagLB, BlDiagRB,   BLBar,
             BlFinish, BLBox, BlEnabled );

         TWPBrdLine = (brdLeft, brdTop, brdRight, brdBottom,
             brdInsideV, brdInsideH, brdDiagLB, brdDiagRB, brdBar);

         TBorder = record
             LineType: TBorderType; // Switch On certain Borders
             BorderType: array[BlLeft..BLBar] o f Integer; // Properties of this border
             BorderColor: array[BlLeft..BLBar] o f Integer;
             BorderWidth: array[BlLeft..BLBar] o f Integer;
             // If This values are <>0 or if "UseAllBorder=true" they
             // are used instead the above arrays
             UseAllBorder: Boolean;
             AllBorderType: Integer;
             AllBorderColor: Integer;
             AllBorderWidth: Integer;
           end;

         The TBorder record is not saved with the text style. Only the non-default values are stored as regular
         attributes, using the ASet and AGet procedures using the WPAT_codes.


8.5      WPAT_codes

         WPAT_codes are used to set and retrieve paragraph and style attributes.

         Not all codes which are defined are already used in WPTools Version 6. The reserved codes are
         printed in gray color.

         The method TWPTextStyle.AGet(WPAT_code : Integer; var Value : Integer) is mainly used to read a
         property. Please make sure you initialized the variable "Value"!

8.5.1    Character Attributes
          WPAT_CharFont = 1; // the index of the font
          WPAT_CharCharset = 2; // the CharSet of the font
          WPAT_CharFontSize = 3; // FontSize in pt*100
          WPAT_CharWidth = 4; // Character scaling value (display similar to WPAT_CharSpacing)
          WPAT_CharEffect = 5; // Special character effects and character styles
          FLAG: WPEFF_CUSTOM1 = 1; // wpcustN - 63 Custom tags for whatever fixed styles you want to
         develop
          FLAG: WPEFF_CUSTOMMASK = 63; // The following are bits
          FLAG: WPEFF_SHADOW = 64; // shad
          FLAG: WPEFF_INSET = 128; // embo
          FLAG: WPEFF_OUTSET = 256; // impr
          FLAG: WPEFF_OUTLINE = 512; // outl
          FLAG: WPEFF_FRAME = 1024; // chbrdr - only default brdrsbrdrw10




© 2004-2008 WPCubed GmbH - Munich, Germany
228    WPTools Version 6


       FLAG: WPEFF_ANIMbit1 = 2048; // animtext1
       FLAG: WPEFF_ANIMbit2 = 4096; // animtext2
       FLAG: WPEFF_ANIMbit3 = 8192; // animtext4
       FLAG: WPEFF_ANIMMask = 8192 + 2048 + 4096;

       WPAT_CharStyleMask = 6; // always used with WPAT_CharStyleON to allow the combination of
      styles
       WPAT_CharStyleON = 7; // Switch one or multiple of the following Styles on (WPSTY_BOLD ... )
       FLAG: WPSTY_BOLD = 1; // Bit 1 bold
       FLAG: WPSTY_ITALIC = 2; // Bit 2 italic
       FLAG: WPSTY_UNDERLINE = 4; // Bit 3 underlined (solod)
       FLAG: WPSTY_STRIKEOUT = 8; // Bit 4 strikeout
       FLAG: WPSTY_SUPERSCRIPT = 16; // Bit 5 superscript
       FLAG: WPSTY_SUBSCRIPT = 32; // Bit 6 subscript
       FLAG: WPSTY_HIDDEN = 64; // Bit 7 hidden text
       FLAG: WPSTY_UPPERCASE = 128; // Bit 8 all uppercase
       FLAG: WPSTY_SMALLCAPS = 256; // Bit 9 all uppercase but non-captitals are 20% larger
       FLAG: WPSTY_LOWERCASE = 512; // Bit 10 all lowercase
       FLAG: WPSTY_NOPROOF = 1024; // Bit 11 noproof - disable spellcheck for this
       FLAG: WPSTY_DBLSTRIKEOUT = 2048; // Bit 12 strikeout - double solid line
       FLAG: WPSTY_BUTTON = 4096; // button (use background color) - with frame
       FLAG: WPSTY_PROTECTED = 8192; // protected text - can be optionally handled as shaded text
       FLAG: WPSTY_USERDEFINED = 16384; // Bit 15 user defined flag
       {* bit 16 must be unused }

       // The following 'styles' are stored as bits in the highest byte of the CharAttr[x] integer.
       // They are usually applied and removed dynamically
       FLAG: cafsHyphen = $01000000; // assigned by reader or Ctrl+minus, break here
       FLAG: cafsWasChecked = $02000000; // used by spellcheck routine - don't check again
       FLAG: cafsMisSpelled = $04000000; // used by spellcheck routine - red line
       FLAG: cafsMisSpelled2 = $08000000; // used by spellcheck routine - green line
       FLAG: cafsInsertedText = $10000000; // WPTOOLS PREMIUM: Revision Marks
       FLAG: cafsDeletedText = $20000000; // WPTOOLS PREMIUM: Revision Marks
       FLAG: cafsWordHighlight = $40000000; // highlighted by Find Routine
       FLAG: cafsDelete = $80000000; // Text is marked for deletion
       FLAG: cafsALL = $FF000000;
       FLAG: cafsNONE = $00FFFFFF;
       WPAT_CharColor = 8; // The text color (as index in palette)
       WPAT_CharBGColor = 9; // The text background color (as index in palette)
       WPAT_CharSpacing = 10; // "Letter-Spacing" in twips, 0..$8000 = EXPAND, $8001- $FFFF =
      COMPRESS
       WPAT_CharLevel = 11; // Move Character up or down - in half points (RTF: up dn }
       // 0..$8000 = UP, $8001- $FFFF = down
       WPAT_CharHighlight = 12; // {reserved} Highlight mode (different styles and colors)
       WPAT_UnderlineMode = 13; // {reserved} Underlining mode, 0=off, 1=solid, 2=double, 3= dotted ...
       FLAG: WPUND_Standard = 1; // Underline Style 1
       FLAG: WPUND_Dotted = 2;
       FLAG: WPUND_Dashed = 3;
       FLAG: WPUND_Dashdotted = 4;
       FLAG: WPUND_Dashdotdotted = 5;
       FLAG: WPUND_Double = 6;
       FLAG: WPUND_Heavywave = 7;
       FLAG: WPUND_Longdashed = 8;
       FLAG: WPUND_Thick = 9;
       FLAG: WPUND_Thickdotted = 10;
       FLAG: WPUND_Thickdashed = 11;




                                                              © 2004-2008 WPCubed GmbH - Munich, Germany
Reference     229


          FLAG: WPUND_Thickdashdotted = 12;
          FLAG: WPUND_Thickdashdotdotted = 13;
          FLAG: WPUND_Thicklongdashed = 14;
          FLAG: WPUND_Doublewave = 15;
          FLAG: WPUND_WordUnderline = 16;
          FLAG: WPUND_wave = 17;
          FLAG: WPUND_curlyunderline = 18; // only used for spellcheck
          FLAG: WPUND_NoLine = 200; // Dont draw line !!!! When imported from RTF!
          WPAT_UnderlineColor = 14; // Underlining color, 0=text color, otherwise colorindex +1
          WPAT_TextLanguage = 15; // {reserved} Language of the text
          WPAT_CharStyleSheet = 16; // CharacterStyle (index in ParStyles)

         NOTE: gray symbols are reserved for future versions of WPTools!

8.5.2    Paragraph Attributes
          // Margins
          WPAT_IndentLeft = 17; // Indent Left (CSS = margin)
          WPAT_IndentRight = 18; // Indent Right (CSS = margin)
          WPAT_IndentFirst = 19; // Indent First (CSS = text-indent)
          WPAT_SpaceBefore = 20; // Space Before (CSS = margin)
          WPAT_SpaceAfter = 21; // Space After (CSS = margin)
          WPAT_LineHeight = 22; // LineHeight in in % ( Has priority over WPAT_SpaceBetween)
          WPAT_SpaceBetween = 23; // Space Between (CSS = margin) - negative : Absolute, Positive
         minimum

          // padding, only in tables:
          WPAT_PaddingLeft = 24; // Distance from Border to Text (CSS = padding) tscellpaddt / trpaddl
          WPAT_PaddingRight = 25; // Distance from Border to Text (CSS = padding)
          WPAT_PaddingTop = 26; // Distance from Border to Text (CSS = padding)
          WPAT_PaddingBottom = 27; // Distance from Border to Text (CSS = padding)

          // Alignment
          WPAT_WordSpacing = 28; // Value = 0 for default or % of EM (ignored for justifed text)
          WPAT_Alignment = 29; // paralLeft, ...
          WPAT_VertAlignment = 30; // Cells: paralVertTop, paralVertCenter, paralVertBottom

         // Colors and background
          WPAT_BGColor = 50; // Background Color
          WPAT_FGColor = 51; // Foreground Shading Color
          WPAT_ShadingValue = 52; // Background Shading Percentage in %
          WPAT_ShadingType = 53; // Background Shading Type
          VALUE: WPSHAD_solidbg = 0; // Solid Background - use WPAT_BGColor and
         WPAT_ShadingValue
          VALUE: WPSHAD_solidfg = 1; // Solid Background - use WPAT_FGColor and
         WPAT_ShadingValue
          VALUE: WPSHAD_clear = 2; // Clear Background
          VALUE: WPSHAD_bdiag = 3; // Backward diagonal pattern.
          VALUE: WPSHAD_cross = 4; // Cross pattern.
          VALUE: WPSHAD_dcross = 5; // Diagonal cross pattern.
          VALUE: WPSHAD_dkbdiag = 6; // Dark backward diagonal pattern.
          VALUE: WPSHAD_dkcross = 7; // Dark cross pattern.
          VALUE: WPSHAD_dkdcross = 8; // Dark diagonal cross pattern.
          VALUE: WPSHAD_dkfdiag = 9; // Dark forward diagonal pattern.
          VALUE: WPSHAD_dkhor = 10; // Dark horizontal pattern.
          VALUE: WPSHAD_dkvert = 11; // Dark vertical pattern.




© 2004-2008 WPCubed GmbH - Munich, Germany
230    WPTools Version 6


         VALUE: WPSHAD_fdiag = 12; // Forward diagonal pattern.
         VALUE: WPSHAD_horiz = 13; // Horizontal pattern.
         VALUE: WPSHAD_vert = 14; // Vertical pattern.
         WPAT_BGBitMap = 54; // Background Image.
         WPAT_BGBitMapMode = 55; // Bitfield for scroll, center, center, repeat

        Special Flags:
         WPAT_ParProtected = 92; // 1=protect, 0=not protected
         WPAT_ParKeep = 93; // 1=no page break
         WPAT_ParKeepN = 94; // 1=keep paragraphs together
         WPAT_ParIsOutline = 160; // Is Outline (used by PDF Export and for TOC) - value = level!


        NOTE: gray symbols are reserved for future versions of WPTools!


8.5.3   Numbering Attributes
          WPAT_NumberSTYLE = 31; // Reference to a different Style. It can be a single style or
          // a style which is part of an outline style sheet. In the letter case the correct
          // style will be be located inside this group using the WPAT_NumberLEVEL parameter.
          WPAT_NumberLEVEL = 32; // Numbering Level
          // The following styles are used for simple paragraph numbering and also inside
          // numbering styles. Numbering styles can also use all other paragraph attributes!
          // Please also note that 'WPAT_NumberLEVEL' on its own does NOT activate numbering.
          // WPAT_NumberSTYLE or WPAT_NumberMODE must be also specified.
          // If only WPAT_NumberLEVEL is used this just specifies the current outline level.
          WPAT_OUTLINELEVEL = 32; // synonym for WPAT_NumberLEVEL
          WPAT_NumberMODE = 33; // Supported elements are: (levelnfcN)
          {*}WPNUM_ARABIC = 1; // Arabic (1, 2, 3)
          {*}WPNUM_UP_ROMAN = 2; // Uppercase Roman numeral (I, II, III)
          {*}WPNUM_LO_ROMAN = 3; // Lowercase Roman numeral (i, ii, iii)
          {*}WPNUM_UP_LETTER = 4; // Uppercase letter (A, B, C)
          {*}WPNUM_LO_LETTER = 5; // Lowercase letter (a, b, c)
          {*}WPNUM_LO_ORDINAL = 6; // Lowercase Ordinal number (1st, 2nd, 3rd)
          {*}WPNUM_Text = 7; // Cardinal text number (One, Two Three)
          {*}WPNUM_ORDINAL_TEXT = 8; // Ordinal text number (First, Second, Third)
          {*}WPNUM_WIDECHAR = 15; // Double-byte character
          {*}WPNUM_CHAR = 16; // Single-byte character
          {*}WPNUM_CIRCLE = 19; // Circle numbering (*circlenum)
          {*}WPNUM_ARABIC0 = 23; // Arabic with leading zero (01, 02, 03, ..., 10, 11)
          {*}WPNUM_BULLET = 24; // Bullet (no number at all)
          WPAT_NumberTEXTB = 34; // Text Before (index in stringlist of RTFFProps) (obsolete)
          WPAT_NumberTEXTA = 35; // Text After (index in stringlist of RTFFProps) (obsolete)
          WPAT_NumberTEXT = 36; // Char #1..#10 are the level placeholders, the rest is the surrounding
        text
          WPAT_Number_STARTAT = 37; // Start Numbering if this is first in level
          WPAT_Number_ALIGN = 38; // 0=Left, 1=Center, 2=Right
          WPAT_Number_SPACE = 39; // Minimum distance from the right edge of the number to the start
        of the paragraph text
          WPAT_NumberFONT = 40; // Optional: Font for the text
          WPAT_NumberFONTSIZE = 41; // Optional: FontSize (pnfs) in pt * 100
          WPAT_NumberFONTCOLOR = 42; // Optional: FontColor (pncf)
          WPAT_NumberFONTSTYLES = 43; // Optional: CharStyles bitfield
          WPAT_NumberINDENT = 44; // Old Style Indent - NumberStyles may also use the INDENTFIRST/
        INDENTLEFT props!
          WPAT_NumberFLAGS = 45; //




                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Reference         231


          {*}WPNUM_FLAGS_COMPAT = 1; // Compatibility to old RTF
          {*}WPNUM_FLAGS_USEPREV = 2; // Use text from previous level ( pnprev)
          {*}WPNUM_FLAGS_USEINDENT = 4; // Use Indent from previous level
          {*}WPNUM_FLAGS_FOLLOW_SPACE = 8; // A space follows the number, Default = TAB!
          {*}WPNUM_FLAGS_FOLLOW_NOTHING = 16; // nothing follows the number
          {*}WPNUM_FLAGS_LEGAL = 32; // convert previous levels to arabic
          {*}WPNUM_FLAGS_NORESTART = 64;
            // if this level does not restart its count each time a number of a higher level is reached
          {*}WPNUM_FLAGS_ONCE = 128; // Number each cell only once in a table
          {*}WPNUM_FLAGS_ACROSS = 256; // Number across rows (the default is to number down
         columns)
          {*}WPNUM_FLAGS_HANG = 512; // Paragraph uses a hanging indent
          {*}WPNUM_NONumberING = 1024; // DO NOT NumberATE!
          {*}WPNUM_NumberSKIP = 2048; // Increase number but do not display
          WPAT_NumberPICTURE = 46; // Reserved for number pictures
          WPAT_Number_RES1 = 47;
          WPAT_Number_RES2 = 48;
          WPAT_Number_RES3 = 49;

8.5.4    Border Attributes
         The TBorder record is not saved with the text style, only the non-default values are stored as regular
         attributes, using the ASet and AGet procedures. The WPAT_ codes used for border parameters are:

           WPAT_BorderTypeL = 6 0;      // Border Mode Left(no, single, double etc)
           WPAT_BorderTypeT = 6 1;      // Border Mode Top (no, single, double etc)
           WPAT_BorderTypeR = 6 2;      // Border Mode Right(no, single, double etc)
           WPAT_BorderTypeB = 6 3;      // Border Mode Bottom (no, single, double etc)
           WPAT_BorderTypeDiaTLBR       = 6 4; // Diagonal Line - TopLeft/BottomRight ( cldglu )
           WPAT_BorderTypeDiaTRBL       = 6 5; // Diagonal Line - TopRight/BottomLeft

         The following constants are used as values for the 'Type' attribute

           {*}WPBRD_SINGLE = 0; // brdrs Single-thickness border. (=Default)
           {*}WPBRD_NONE = 1; // brdrnil brdrtbl No Border
           {*}WPBRD_DOUBLEW = 2; // brdrth Double-thickness border.
           {*}WPBRD_SHADOW = 3; // brdrsh Shadowed border.
           {*}WPBRD_DOUBLE = 4; // brdrdb Double border.
           {*}WPBRD_DOTTED = 5; // brdrdot Dotted border.
           {*}WPBRD_DASHED = 6; // brdrdash       Dashed border.
           {*}WPBRD_HAIRLINE = 7; // brdrhair     Hairline border.
           {*}WPBRD_INSET = 8; // brdrinset       Inset border.
           {*}WPBRD_DASHEDS = 9; // brdrdashsm    Dashed border (small).
           {*}WPBRD_DOTDASH = 10; // brdrdashd    Dot-dashed border.
           {*}WPBRD_DOTDOTDASH = 11; // brdrdashdd       Dot-dot-dashed border.
           {*}WPBRD_OUTSET = 12; // brdroutset    Outset border.
           {*}WPBRD_TRIPPLE = 13; // brdrtriple Triple border.
           {*}WPBRD_THIKTHINS = 14; // brdrtnthsg Thick-thin border (small).
           {*}WPBRD_THINTHICKS = 15; // brdrthtnsg       Thin-thick border (small).
           {*}WPBRD_THINTHICKTHINS = 16; // brdrtnthtnsg        Thin-thick thin border
         (small).
           {*}WPBRD_THICKTHIN = 17; // brdrtnthmg Thick-thin border (medium).
           {*}WPBRD_THINTHIK = 18; // brdrthtnmg Thin-thick border (medium).
           {*}WPBRD_THINTHICKTHIN = 19; // brdrtnthtnmg Thin-thick thin border (medium).
           {*}WPBRD_THICKTHINL = 20; // brdrtnthlg       Thick-thin border (large).
           {*}WPBRD_THINTHICKL = 21; // brdrthtnlg       Thin-thick border (large).
           {*}WPBRD_THINTHICKTHINL = 22; // brdrtnthtnlg        Thin-thick-thin border
         (large).




© 2004-2008 WPCubed GmbH - Munich, Germany
232    WPTools Version 6


        {*}WPBRD_WAVY = 23; // brdrwavy Wavy border.
        {*}WPBRD_DBLWAVY = 24; // brdrwavydb Double wavy border.
        {*}WPBRD_STRIPED = 25; // brdrdashdotstr      Striped border.
        {*}WPBRD_EMBOSSED = 26; // brdremboss Embossed border. (CSS=ridge)
        {*}WPBRD_ENGRAVE = 27; // brdrengrave Engraved border. (CSS=groove)
        {*}WPBRD_FRAME = 28; // brdrframe      Border resembles a "Frame."

      The following properties store the width in twips:

        WPAT_BorderWidthL = 6 6;      // Thickness left inner Line
        WPAT_BorderWidthT = 6 7;      // Thickness top inner Line
        WPAT_BorderWidthR = 6 8;      // Thickness right inner Line
        WPAT_BorderWidthB = 6 9;      // Thickness bottom inner Line
        WPAT_BorderWidthDiaTLBR       = 7 0; // Diagonal Line - TopLeft/BottomRight
        WPAT_BorderWidthDiaTRBL       = 7 1; // Diagonal Line - TopRight/BottomLeft


      These values store the color of the borders:

        WPAT_BorderColorL = 7 2;      // Color    left inner Line
        WPAT_BorderColorT = 7 3;      // Color    top inner Line
        WPAT_BorderColorR = 7 4;      // Color    right inner Line
        WPAT_BorderColorB = 7 5;      // Color    bottom inner Line
        WPAT_BorderColorDiaTLBR       = 76; //    Diagonal Line - TopLeft/BottomRight
        WPAT_BorderColorDiaTRBL       = 77; //    Diagonal Line - TopRight/BottomLeft

      If the values of all borders are the same, these codes can be used as a shortcut to set the value for
      a whole group:

        // Shortcut - set width and color of ALL lines. - Use Flags to switch on/off
        WPAT_BorderType = 8 7; // Border Mode ALL LINES AROUND BOX
        WPAT_BorderWidth = 8 8; // Thickness ALL LINES
        WPAT_BorderColor = 8 9; // Color ALL LINES

      This is the most important code. By setting a single bit a border is switched on.

        // Border Flags - switch borders on/off
        WPAT_BorderFlags = 9 0;
        {The following flags switch on certain borders. The type can be defined or
      inherited}
        {*}WPBRD_DRAW_Left = 1; // Left Border (Default = Single Line = Mode 0) = BlLeft
        {*}WPBRD_DRAW_Top = 2; // Top Border
        {*}WPBRD_DRAW_Right = 4; // Right Border
        {*}WPBRD_DRAW_Bottom = 8; // Bottom Border
        {*}WPBRD_DRAW_All4    = 1 5; // left + Top+ Right + Bottom
        {*}WPBRD_DRAW_DiagLB = 16; // Cells: Diagonal Top-Left -> Bottom-Right
        {*}WPBRD_DRAW_DiagRB = 32; // Cells: Diagonal Top-Right-> Bottom-Left
        {*}WPBRD_DRAW_Bar = 64; // Border outside (right side of odd-numbered pages,
        // left side of even-numbered pages)
        {*}WPBRD_DRAW_InsideV = 128; // Rows: Inside Vertical
        {*}WPBRD_DRAW_InsideH = 256; // Rows: Inside Horizontal
        {*}WPBRD_DRAW_Box = 512; // Draw Box around paragraph
        {*}WPBRD_DRAW_Finish = 1024; // Draw bottom border here, even if next paragraph
      has same border properties




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Reference   233


8.5.5    Table Size and Position
         A table usually uses the complete text area, this is the page width minus the left and right margins.

         Property to set the width in twips: WPAT_BoxWidth

         Property to set the width in percent * 100 of the page width
         WPAT_BoxWidth_PC

         Offset from the left margin. Can be negative to be to the lefgt of the text area.
         WPAT_BoxMarginLeft

         Offset from the left margin. If negative the table is extended into the margin area
         WPAT_BoxMarginRight

         Horizontal Alignment of the table: WPAT_Box_Align:
          possible values are WPBOXALIGN_RIGHT and WPBOXALIGN_HCENTERTEXT

         The column width is defined by the properties WPAT_ColWidth and WPAT_ColWidth_PC. The first
         is the width in twips, the latter is the width in percent * 10 (Example: 1000 sets a width of 10%).

         WPAT_ColWidth has priority over WPAT_ColWidth_PC. You will need to delete the
         WPAT_ColWidth flag if you need to set the width in percent.

                 Cell.ADel(WPAT_ColWidth)
                 Cell.ASet(WPAT_ColWidth_PC,1000); // 10%

         You can read the current width of a cell using the method cell.IsWidthTW. The text must be
         formatted. Once the user resizes columns in a table all widths which are defined by a percent value
         will be converted into exact WPAT_ColWidth values. You can force this conversion for the complete
         text using the function WPRichText.TableFixAllCellWidths. This method can also round the width
         values suing a 'snap value'. The method TableAdjustCellWidth can be used to recalculate the width
         of all columns to keep them visible.

         The property WPAT_BoxMinHeight can be used with table rows to set the minium height of a table
         row. WPAT_BoxMaxHeight is used to set the maximum width. Both properties will be ignored in
         cells which are merged vertically. They can be used together.

         You can use reference Cell.ParentRow to set or read a property in a row. The editor allows the
         modification of row heights if this mode has been enabled in the property EditOptions.

         Example Apply row height to all rows in current table
                :

         var par : TParagraph;

         i f WPRichText1.Table<>nil then
         begin
             par := wp.Table.ChildPar;
             while par<>nil d o
             begin
               par.ASet( WPAT_BoxMinHeight, twips_value );
               par.ASet( WPAT_BoxMaxHeight, twips_value );
               par := par.NextPar;
             end;
         end;

         Example Apply row height to selected rows only
                :




© 2004-2008 WPCubed GmbH - Munich, Germany
234    WPTools Version 6


          var par : TParagraph;

          i f WPRichText1.Table<>nil then
          begin
              par := wp.Table.ChildPar;
              while par<>nil d o
              begin
                i f par.HasProp( paprCellIsSelected ) then
                begin
                   par.ASet( WPAT_BoxMinHeight, twips_value );
                   par.ASet( WPAT_BoxMaxHeight, twips_value );
                end;
                par := par.NextPar;
              end;
          end;




9         Notes for Upgraders
          ... from WPTools Version 5

          The RTF-Engine of WPTools 6 is based on WPTools 5. We are even able to create a WPTools 5
          build from WPTools 6 since all addons in WPTools 6 are activated by conditional compiling. If the
          compiler symbol WP6 ($DEFINE WP6) is not active, a Project can be compiled as if it was
          WPTools 5. So upgrading should be extremely smooth.

          The major changes will come up when You upgrade to Delphi 2009. This new version is based on
          WideStrings instead of AnsiString and WPTools 6 honors this. Where it makes sense the API still
          uses ANSI String. At present time the Delphi 2009 support is not 100% tested.

          .... from WPTools Version 4

          As emphasized before WPTools Version 6 is based on a new RTF Engine. (We call this RTF engine
          although it internally works with data structures which are much more similar to HTML/CSS than to
          RichText-Format)

          This means that if you have modified the RTF engine before or use undocumented features the
          affected parts of the code must be updated. We will assist you here to make the transition easier.
          WPTools Version 6 contains so many new features and possibilities that it is very likely that a very
          elegant way to solve the problem can be found.

                     Please check out the FAQ web forums
                      FAQ: Questions when upgrading
                      FAQ: General

          Important:

          WPTools Version 6 uses 'delayed reformat'. This means the formatting of the text is delayed
          until the next idle phase. Therefore, If you are using InputString or similar it is not required
          to use BeginUpdate/EndUpdate to speed up the application. On the other hand, if you want
          to print the text (or convert it to PDF) right after loading or creation, it it is required to
          execute the procedure ReformatAll;

          The same is required if you want to print or create a PDF file right after the use of




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Notes for Upgraders        235


         LoadFromFile.

         If you used to create an editor at runtime using TWPRichText.Create(nil) please change the code to
         use the constructor CreateDynamic; (C++Users call the method _MakeDynamic() after the new)
         This way the editor knows it is invisible and has no parent. You need to execute ReformatAll
         whenever you need the text to be formatted for printing or export to PDF.
         Do not create editor windows which should work interactively using this method!

         Please note that the property WorkOnText used to select a completely different text (the header/
         footer text) in WPTools 4. In WPTools Version 6 it will simply move the cursor to that text.
         Esspecially the function MergeText works normally works with the body text, the property
         WorkOnText will not make any difference. But the MergeText function to select the modification of
         all text parts. (See Mailmerge and forms)

         WPTools Version 6 works with text attributes which can be undefined. So it is possible that the
         current font has no name. In this case the font used for the text will be defined by the paragraph
         style or the default attributes.

         To set the default font for an editor use the OnClear event:

         procedure TForm1.DBWPRichText1Clear(Sender: TObject);
         begin
            DBWPRichText1.WritingAttr.Clear;
            DBWPRichText1.WritingAttr.SetFontName('Arial' ;
                                                         )
            DBWPRichText1.WritingAttr.SetFontSize(1 1) ;
         end;

         Please note that the properties of the reader and writer (LoadOptions, StoreOptions) are nbow
         defined by format strings. These format strings can be used with all IO methods. To retrieve the text
         as RTF string you can simply use str := WPRichText.AsANSIString('RTF');


         Overview

             When you convert older projects you will at least have to modify the uses clauses

             remove: WPDefs, WPObj, WPRTF*, WPPrint, WPRich, WPWinCTR

             add: WPRTEDefs, WPRTEPaint, WPCtrMemo, WPCtrRich, WPObj_Image, WPIO

             Please note that code which works with pointers (lin : PTLine, pa : PTAttr) cannot be easily
             converted to work with WPTools Version 6 so please do not try to update the old logic to work
             with WPTools Version 6. It is better to find a way to do it using the new, advanced API of
             WPTools. Please don't hesitate to post a question in the forum: Many problems which required
             hundred lines of code were converted into a few lines with "WPTools Version 6" code.

             Style handling is now done inside the RTF-Engine. The WPStyleCollection is still there but it is
             only a container for template styles.

             WPReporter works differently in V5 - please see WPReporter




© 2004-2008 WPCubed GmbH - Munich, Germany
236    WPTools Version 6



9.1     Updated Rendering and Formatting
        WPTools Version 6 formats as close to MS Word(tm) as possible.

        So it ignores the paragraph spacing on top of pages. You can enable the old behavior in property
        FormatOptionsEx by adding flag wpDontIgnoreSpacebeforeOnTopOfPage.

        Please also see the other options in FormatOptions and FormatOptionsEx.


9.2     Changed Unit Names
        One of the first things you might realize when you try to compile a WPTools V4 project with
        WPTools Version 6, is that some unit names no longer exist.
        This is because we decided to create new units for program code which is entirely new. At the same
        time obsolete units were deleted.

        We recommend to delete all wp* units from the uses clause of each unit, add units
        WPRTEPaint and WPObj _Imageand let Delphi add the other required units.

        The following changes are required:

        Change
         WPDefs, WPObj, WPRtfTXT, WPRTFIO
        all to W PRTEDefs

        Change
          WPRtfIO, WPRtfInp
        to W PRTEPaint

        Change
          WPEmOBJ
        to WPObj _Image

        WPRTEDefs and WPRTEPaint are the main units of the "RTF-Engine". Their pascal code is only
        included in WPTools Professional and WPTools PREMIUM.

        Change
          WPPrint, WPWinCtr
        to W PCTRMemo

        The unit WPCTRMemo contains the editor control and the preview, making unit WPPreVw obsolete.

        Change
          WPRich
        to W PCTRRich

        The unit WPCtrRich contains the procedures, objects and properties which were mainly added to
        provide compatibility to older WPTools versions. It is required by the TWPToolBar, TWPRuler and
        TWPAction classes.

        The unit WPStat2 is not included.
        Please use a standard status bar (Win32 tab). The old WPTools 1 status bar has been
        discontinued.

        The HTML support is included in unit WPIOHTML, the units WPReadHT, WPWrtHT and
        WPXMLFile are obsolete. WPTools Version 6 will always use CSS in the created HTML code.




                                                                 © 2004-2008 WPCubed GmbH - Munich, Germany
Notes for Upgraders        237



         The RTF reader is implemented in unit WPIOReadRTF, the RTF writer in WPIoWriteRTF. (WPreader
         and WPWrtRTF is obsolete)

         The ANSI reader and writer are implemented in WPIoANSI, not WPWrite2.

         Important: You need to use "FormatStrings" instead of the properties LoadOptions and
         StoreOptions!

         unit WPPapBin always was nothing more than an example unit. The old version will still work. Also
         see demo: "PrinterSetup"

         The main WPReporter class TWPSuperMerge is now located in WPRTEReport, not in wpmerge.
         pas.

         The component WPFiler is not supported anymore.

         Quickreport support has been discontinued.


9.3      Changed Classes
         RTF-Engine

         The RTF Engine concept has been changed greatly. It is no longer possible to use a RTF-Engine
         object, such as "TWPRtfTextPaint" in WPTools 4, to identify certain text or text properties - In
         WPTools Version 6 the text objects are accessed directly, not through the 'RTF-Engine': The
         TWPRTFProps are now used for text properties, such as colors and styles. For text either the
         TWPRTFDataCollection or the TWPRTFDataBlock is used. An exception of this rule is the cursor
         class, also accessible through TWPRichText.TextCursor. It contains many variables and procedures
         which used to be in the TWPRtfTextPaint object.(see Data Structures)

         Usually code does not require a reference to the RTF-Engine since this reference is provided by the
         editor control (TWPCustomRichText, TWPCustomRtfEdit).

         Thus, in general it is possible to replace something like "RtfText : TWPRtfTextPaint" with a reference
         to a TWPCustomRtfEdit.

         Editor

         The TWPCustomRtfEdit class is defined in the unit WPCtrMemo. It contains access to the RTF
         engine (Memo), the TWPRTFData object (Memo.RTFData) and the possibility to change attributes
         (through Memo.Cursor). However, it does not contain the 'CurrAttr' property, which has been defined
         under the unit WPCTRRich, in the class TWPCustomRichText.


9.4      Changed Pointers
         To make compilation with Delphi8 for .NET possible, WPTools Version 6 no longer makes use of
         pointers (exception: some optimized conversion code).

         As a result, all pointers have been replaced. The PTParagraph pointers have all been changed to
         references to a TParagraph object. Since references and pointers can be used in a very similar
         manner, you can compile your code by simply removing the ^ sign (Delphi) or changing -> into . (c+
         +)

         The RTF-Engine paragraph pointers (WPRichText1.Memo.active_paragraphand others) have
         been moved. The references which represent the cursor position are now in WPRichText.Memo.



© 2004-2008 WPCubed GmbH - Munich, Germany
238    WPTools Version 6


        Cursor or, if no editor is used, in RTFDataCollection.Cursor.

        Please note that in WPTools Version 6 the reference active_paragraph can be undefined (nil). The
        same is true for the 'FirstPar' reference of a TWPRTFDataBlock - although the code will create a first
        paragraph as soon as this property is read.

        The pointer for the TLine record of WPTools Version 6 is no longer supported. The TLine record has
        been completely replaced, a position in a paragraph is now described solely by the position,
        posinpar.

        The cursor object still supports a property called active_line. It is an integer value which can be used
        to access the wrapped lines.

        Pointers to border descriptions (TBorder) can no longer be used. The border definitions are now
        stored in the regular properties of a TParagraph or TWPTextStyle class. But to provide compatibility
        to WPTools 4 it is possible to fill a TBorder record 'on the fly' with values calculated from the stored
        properties.

        This means that if you have a procedure which expects a TBorder record or pointer it is necessary to
        pass a reference to a TWPTextStyle class and calculate the border record inside of this procedure
        using the TWPTextStyle procedure AGetBorder(). Please see the next chapter for further
        information.


9.5     Changed GUI elements


        TWPToolCtrol

        In WPTools 4 the control TWPToolCtrol was used to create the link between a TWPComboBox and
        the editor.

        This class is not supported anymore since it was not compatible to modern 3rd party toolbar
        controls. This means that it is not possible to use any TPanel as a toolbar by simply dropping a
        TWPToolCtrl on its surface. We recommend to use the TWPToolPanel instead.

        The best approach is to use the wptools standard actions to link to buttons and menu items and the
        new TWPToolsCustomEditContolAction. The latter class can be also added to any TActionList
        and is used to create a link to the TWPComboBox class. (property AttachedControl)

        Please read more about actions and Use WPTools5 with TBX (Toolbar2000 Extension)

        TWPEdit

        The component TWPEdit (the single line RTF object) is not available anymore.

        You can use a standard TWPRichText and set certain properties to replace it.

            object WPRichText1: TWPRichText
                LayoutMode = wplayNormal
                ScrollBars = ssNone
                EditOptions = [wpActivateUndo, wpActivateUndoHotkey, wpNoVertScrolling]
                XOffset = 1 5
                Width = 300
                Height = 2 2
            end




                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Notes for Upgraders        239


         Now add an event handler for OnKeyDown to suppress the Return key:

              procedure TForm1.WPRichText1KeyDown(Sender: TObject; var Key: Word;
              Shift: TShiftState);
              begin
                 i f Key = VK_RETURN then key := 0;
              end;




9.6      New Border Handling
         Border definitions are now stored in the regular properties of a TParagraph or TWPTextStyle class.
         These properties are usually read by the AGet function and written using the ASet procedure.

         For your convenience all border properties can be saved in and restored from a TBorder record.

         This record is written by the ASetBorder procedure.

         The TBorder record is similar to the one used by WPTools 4, but has been improved to hold different
         modes, colors and widths for each line by using arrays for the values BorderType, BorderColor and
         BorderWidth.

         Notes:
         a) The blDouble and blDot LineType no longer exist. Instead the 'type' must be used to choose a
         different border line style.

         So code such as
          Ndouble.Checked     := blDouble i n Border.LineType;

         must be changed to
          Ndouble.Checked := Border.AllBorderType = WPBRD_DOUBLE;

         Please note that this is using the AllBorderType item which contains the type of all borders, if they
         are the same. To read or set a single style for one of the possible borders (left, right ...) use the
         array Border.BorderType[BlLeft..BLBar].

         b) The value 'FUse256Colors' or 'Use256Colors' no longer exists. WPTools always uses at least 256
         colors.

         c) The elements HColor, HColorR, VColor, VColorB have been replaced by the array BorderColor:
         array[BlLeft..BLBar] of Integer;

         So please change code such as
                btnLColor.Tag        :=   Border.HColor;
                btnRColor.Tag        :=   Border.HColorR;
                btnTColor.Tag        :=   Border.VColor;
                btnBColor.Tag        :=   Border.VColorB;

         to
                btnLColor.Tag        := Border.BorderColor[blLeft];
                btnRColor.Tag        := Border.BorderColor[blRight];
                btnTColor.Tag        := Border.BorderColor[blTop];




© 2004-2008 WPCubed GmbH - Munich, Germany
240    WPTools Version 6


               btnBColor.Tag         := Border.BorderColor[blBottom];

        d) The Thickness value no longer exists. Please use either the AllBorderWidth or the BorderWidth[]
        elements. Please note that the width is stored as twip value, not as 1/2 pt.

        e) The Space value is no longer used. The styles now support padding values which are defined by
        the WPAT_ codes WPAT_PaddingLeft, WPAT_PaddingRight, WPAT_PaddingTop and
        WPAT_PaddingBottom. These values cannot be set in the TBorder record.

        f) The function Memo.Set_ParBorder no longer exists. Instead you can use

           CurrAttr.SetBorders(
               LineSelection: TBorderType = [blLeft,blTop,blRight,blBottom];
               WPBRD_mode: Integer = -1;
               ThicknessTW : Integer = -1;
               LeftColor   : Integer = -1;
               RightColor : Integer = -1;
               TopColor    : Integer = -1;
               BottomColor : Integer = -1;
               AllPadding : Integer = -1;
               DeleteDefaultSettings: Boolean = TRUE).

        A value of -1 is used to select the default value. By default using -1 will delete the corresponding
        attribute from the list of attributes which causes the inherited values to be used.




9.7     Changed Style Handling
        In WPToois 4 the style handling was performed by the TWPStyleCollection component. This is not
        the case anymore.

        This component can be optionally used to store the style in their non-binary representation (which is
        a string list with name, value pairs) and assign this style to one or more TWPRichText when
        required. This can help to synchronize the style sheet to provide a default sheet.

        Please read here about how to use the paragraph styles in a native way.



9.8     BackgroundImage
        WPTools Version 6 does not have the property "background image" anymore.

        Instead you can draw the image using the water mark event - see Demo 'WaterM2'. You can create
        a different tiled background on each page and it is also possible to show a form in the background.
        WPTools Version 6 takes care about the necessary buffering so no flickering will be visible.

        We recommend to use RTFVariables to store the file name of the background image which should
        be used with a document.



10      Release Notes - WPTools 6
        WPTools 6 is based on the code of WPTools 5. While we develop WPTools 6 further we also
        integrate improvements into WPTools 5 (see WPTools 5 Release Notes).

        When you have the PRO or PREMIUM version you can also compile WPTools Version 6 as if it was



                                                                    © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 6      241


         Version 5 if you un-define the compiler symbol WP6 in the file WPINC.INC.

         Syntax: defined symbol: {$DEFINE WP6} = Compile WPTools 6
                 undefined symbol: {.$DEFINE WP6} = Compile WPTools 5


         Release Notes:
         15.7.2009 - WPTools 6.05
         + Scroll with middle mouse button



         + new XML editing mode (see XML editor mode )
         + TParagraph.Trim method to remove white spaces at start and end
         + Vertical Scrolling by pressing the middle mouse button now works.
         + improved auto thumbnail mode
         * enhancement to HTML reader / writer to handle embedded SPAN objects
         + new method: ApplySPANStyles(and_remove : Boolean=false; ignore_charattr : Boolean = false);
           can be used to apply SPAN styles to the text which it embeds
         + The function InputSpanObjects( Attributes : TWPAbstractCharAttrInterface ) : TWPTextObj;
           can be used to wrap the selected text into SPAN objects
         + method LoadCSSheet can be used to load paragraph styles in CSS format from a string. There is
         also SaveCSSheet.
         + new even OnTextObjectMovePosition (move event) - OnTextObjectMove is still used for resize
         (unchanged)
         * several improvements in editor
         - fix problem with Wordrwap and centered text

         28.6.2009 - WPTools 6.04
         + WPTools Premium: Column Balancing




         * many improvements in RTF reader. Word documents are now understood better
         * Improvement in check for protected text (ppMergedText)
         + new ViewOptionsEx property
         - auto hyperlinks were not working
         + TWPComboBox has an event OnUpdateItems which will be triggered after the items had been
         automatically assigned.


         24.6.2009 - WPTools 6.03.6
         * thinner page borders in thumbnail mode.
           ViewOptionsEx: wpAutoThumbnailMode will show pagenumbers only when in thubmbnail mode (=
         wpShowPageNRinGap in ViewOptions)
         + property ColorDesktop and DeskGradientHorizontal to render the background with a
         gradient fill
         * fix for protected text handling (CR after a field)
         * fix for text alignment near a movable image
         - EditOption AutoDetectHyperlinks was not working anymore
         * WPReporter: SuperMerge.Stack.PageBreakAFterGroup := true was ot working when footers were
         used




© 2004-2008 WPCubed GmbH - Munich, Germany
242     WPTools Version 6



      1.6.2009 - WPTools 6.03.5
      - fix problem with display of character attributes when attributes were inherited from paragraph styles
      - fix problems with selection deletion in single column, single row tables
      - improvement of RTF writer when writing sections

      11.5.2009 - WPTools 6.03.3
      - improved report band dialog, new ShowOptions property
      - fix in RTF reader to load header/footer
      - change in HTML writer to save SPAN instead of FONT tag
      - several fixes in editor
      * WPTools Premium: better column support. Fixed column height now splits correctly on 2 pages.

      28.4.2009 - WPTools 6.03.2
      - fix problem with justified text in PDF

      21.4.2009 - WPTools 6.03.1
      - fix problem with images when used in Delphi 2009
      - better support for header/footer in RTF files created by word. (Ignore bogus header/footer)
      - some stability fixes


      25.3.2009 - WPTools 6.03
      + improved text rendering - optimation for character distances on screen to provide better display
      + improvement on ShowMergeFieldNames to improve cursor movement and drag and drop
      + automatic disable dragging of fields inside of fields
      + improved merge field selection. TextObject.SelectedObject now returns the mergefield if it was
      completely selected
      + change in HTML saving code to save src in <img> after width adn height (for outlook)
      * various bugfixes


      17.1.2009 - WPTools 6.01.5
      - WPPREMIUM: Text after Columns initialized with WPAT_COLUMNS_Y is now allowed
      + TWPToolBar FontName drop down now lists fonts used by document first
      - fix for tables which use a fixed row height and are splitted on different pages
      + improvements necessary for Delphi 2009 - the Locaization demo now works
      + EditOptionEx wpDontPreserveObjectsAgainstDeletion
      - fix problem in ImageObject LoadFromStream when GraphicEx is used
      - fix problem with Delphi 2009 when loading WPReporter templates
      - fix problem with HTML reader with paragraph style of first paragraph


      26.10.2008 - WPTools 6.01
      * updated HTTP Demo, now with "Source View"
      + DELETE/BACKSPC at start of line removes right/center alignment
      + loads background images for paragraphs, tables and styles
      * improvement to text protection (empty lines)
      - improvements to HTML and CSS reader
      - improved HTML format routine
      - improved MIME loading - now supports binary data despite Synapse does not)
      + MIME reader capturesHTML body for SourceVIew
      * DataProvider now uses MergeText('',true) instead of MergeText
      + boolean wphttp_Disable to disconnect HTTP temporarily
      * several changes to improve compatibility with Delphi 2009

      17.10.2008 - WPTools 6.00.1
      - several changes to fix problems which occured with use of Delphi 2009




                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 6     243


         * update to WPIO_MIME to also load binary encoded GIFS and JPEGS from EML files




11       Release Notes - WPTools 5
         WPTools 6 is based on the WPTools Source files plus several additions and optimations. We
         include the WPTools 5 release notes here to provide You with hints to interesting changes and
         improvements.

         26.9.2008 V5.0 Release 43
         - WPTools PRO / PREMIUM can be now compiled with Delphi 2009 (several changes)
         - fix bug in InsertClass method
         - GetPageOfBookmark works for all bookmarks
         - Code to move images has been updated

         24.9.2008 V5.0 Release 42
         * updated manual topic "Mailmerge and forms"
         - ANSI writer: Separates cells by TABS and rows by CRNL
         - DB Control now switches to readonly when dataset does not use AutoEdit
         - Fix in preview dialog property DisabledDialogs
         - PREMIUM: improvement to TextBox selekting
         - improvement to MeasurePage event
         * some enhancements to API

         10.8.2008 V5.0 Release 40.1
         * some minor bugfixes

         15.7.2008 V5.0 Release 40
         * WPREMIUM: tables are handled in columns better
         * RTF did not save foreign characters in current codepage correctly when <> cp1252
         * WPReporter - a group with "always hidden" will never be processed
         * Better Landscape setting when printing - there was a problem with tables in sections

         30.5.2008 V5.0 Release 39
         * small improvement to CSS reader
         - some stability improvements
         - PNG objects were sometimes not freed.
         - fixed problem with EURO character

         4.4.2008 V5.0 Release 38
         - some small fixes in editor
         - better text box positioning with WPPremium
         - HTML reader - apply paragraph style to first paragraph as well
         - fix when saving a single selected cell
         * Changed attribute detection for selected text - should work much better now.
           This can be deactivated using const DefaultAttrAlsoForSelectedText = false in WPCtrRich
           but should be on for better editing possibilities.
         - fix for missing bottom border before page break
         - MoveToTable does not look for non-table paragraphs
         + RTFDataBlock.FindParByNameEx locates a paragraph with a given name and a given type


         12.3.2008 V5.0 Release 37
         + LoadFromString procedure (more intuitive than property SelectionAsString)
         * apply bottom border when last row was deleted




© 2004-2008 WPCubed GmbH - Munich, Germany
244     WPTools Version 6



      22.1.2008 V5.0 Release 36
      - fix of broken drag&drop support
      - quicker desletion of text when clicking near text
      - some fixes in rendering engine
      + detect PNG, GIF and JPEG automatically in TWPImageObj.LoadFromStream (solves GIF saving
      problem)
      * improved Compress method in WPObj_Image.pas
      * change in WPIOHTML to not save empty header texts


      20.12.2007 V5.0 Release 35
      - fix to not draw border around table objects
      - fix problem when pasting text in form completion mode
      - fix problem is two DFM files
      - fix problem with double grid lines (around tables)
      * improved update of GUI methods - now using inherited style properties (Use CUrrAttr)
      + When printing all colors can be set to black - see PrintParameter.PrintOptionbs: wpAllColorsAreBlack
      - improved padding saving for table cells
      * the code dealing with reading attributes of the selected text now also reads attributes of attched styles.
        This can be switched off using the EditOptionEx: wpDontInitSelTextAttrWithDefaultFont
        If a character attribute was not defined in a style the document default is retrieved
        This only works for character attributes, not for paragraph attributes. Those can be read using
        ActiveParagraph.AGetInherited in case SelectecTexAttr reports an undefined attributesx
      * Font "System" is now mapped to "Arial" since the cursor advance does not work otherwise


      27.11.2007 V5.0 Release 34
      + WPRichText1.TextCursor.CurrAttribute.AInc(WPAT_CharFontSize, pt*100, 300) can now also be used to
         increment/decrement font size of text w hich is controlled by a style sheet.
      * in normal layout modes borders are not draw n betw een virtual pages
      * Update to WPReporter table calculation. When the functions left() and previous() refer to non-existing cell
         The result of the function w ill be undefined and "[ERR]" w ill be displayed.
      * Some updates to RTF reader and HTML w riter
      + ANSI text w riter understand option "-nolinefeed" to use CR instead of CR+LF
      * some savety checks to avoid AVs w ehn paragraphs are deleted
      + HTML reader loads <sup>
      * w hen in ppAllE xceptForE  ditFields Mode the not editable merge fields w ill not be accessed by the TAB keys anymore.
      (can be sw itched off by compiler symbol MOVE       TO_ALL_FIE   LDS)
      - fix in RTF reader for better import of text w ith several nested tables in one table cell
      + new format string for WPTools w riter: -allnumberstyles, forces also the unused styles to be saved
      * WPRichText.Assign( Source ) w ill also copy the number styles
      - fix problem introduced by "fix AV w hen resizing table". Adding additional fix.
      + new flag ppIsHyperlink in property ProtectedPro
      - fix of problem w ith w pShow InvisibleText
      + w hen pasting ANSI text (or one RTF line) the inserted text w ill inherit current
        paragraph attributes, except that
        the new flag w pcoPastedANSIDoesNotInheritParAttr has been set in ClipbordOptions
      - fix AV w hen resizing table an deleting a row at the same time
      - fix problem w ith space_before and invisible merge fields start tags at beginning of line
      + function Print(PageRange): Boolean now also supports @@ODD@@ and @@E N@@ as page range short cuts
                                                                                              VE

      11.09.2007 V5.0 Release 30
      + SplitCells now includes a bollen parameter "before" (default=false)
      *E  ditHyperlink w ill insert the link as text if no linktext w as provided in procedure call or as text selection
      + function WP.Printing to check if currently printing text
      * the TWPPreview w ill not paint itself w hile the attached editor is printing
      * ReformatAll(true, true) now clears all know n character w idth (important for toggling visiblity of fields!)
      * RTF reader loads infocompany and infomanager + infohlinkbase
      + new method: SplitCellsVertically
      - fix in ReplaceTokens. Tokens not seperated by spaces w ere not recognized
      * w hen pasting RTF text into an empty numberd paragraph the number property is retained.




                                                                                  © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 5     245


         + new format string: IgnoreSpan for HTML reader
         + IgnoreSpan is automatically used for pasted HTML text (better for pasting from e-mails)
         - fix in CodeLocate - compare ObjType

         27.07.2007 V5.0 Release 25
         + Object (par or page relative) cannot be moved w hen w pobjLockedPos is used in the TWPTextObj.Modes
         + TP  aragraph.IsUpperCase
         + TParagraph.IsLow ercase
         - fields w ith background color w ere displayed char by char w hich reduced display quality
         - some small tw eaks in engine

         5.07.2007 V5.0 Release 24.4
         * changed virtual method DoUpdateE  ditState to DoUpdateEditStateEx
         + added event: OnE  ditStateChanged (replaces V4 E  ditChangeE  vent)
         * image loading checks for empty stream
         - fixed AV w ith ppNoE ditAfterProtection

         2.07.2007 V5.0 Release 24.3
         * updated OnToolBarIconSelection - removed "except end" w hen pressing "Open"
         - some fixes to undo handling and tables
         - some fixes to image handling (can be selected w hen outside page)
         * improved HTML reader (better handles non "X" HTML)

         04.06.2007 V5.0 Release 24.1
         - fix for dropped character problem (w hen first paragraph of all w as longer than page)
         - sect w hich does not define section break in RTF code now inserts paragraph
         - w hen deleting a table w hich w as follow ed by another table UNDO w ill not insert the next table
         * paprIsHidden flag now saved to WPT format
         + new property: WP.RTFData.InsertTextIntoNew Row - copy in table alw ays insert into new row s
         *E  ditBox mode checked after paste from clipboard
         + HTML reader loads UTF8 - use formatstring '-utf8'
         - KeyPress does not check GetAsyncKeyState for space key
         - selection w as not removed sometimes on click
         - fix in SetOuterCellBorders
         - cell split could cause AV w hen UNDO w as active
         - pasting ignores merged cells
         + Support for Delphi 7 - Win32
         - solves problem in Paragraph.Reformat w hen inserting tabs
         - Shift+Delete is now handled (CutToClipboard)
         - Ctrl+Left handling improved (problem w ith single char w ords)
         - suppress bottom border in layout mode w hen outside of page area
         - better handling of undo for page break added inside table
         - 2 units in PRO version w ere w rong in V5.22
         - WPWordDelimiterArray['-'] := true w ill disable w ord w rap in w ords w ith - sign
         - paste ANSI w as disabled
         - DeleteFieldAtCP now w orks w ith protected fields, too
         - end of page border line is not printed in normal layout mode
         - fix in BulletStyleDlg - EditStyleNums
         - don't position cursor in empty line under text box
         * change variable "new " to "new nr" to avoid C++ problem
         - centered text w ith bullets now paints bullet besideds the text, not at start of line
         - WP REP MIUM - improved column reading/w riting code (RTF format)

         1.03.2007 V5.0 Release 23
         + WPPremium: Load&Save of column properties in RTF format
         + TParagraph.E  xchange method to exchange tw o characters in the text
         * automatic hyperlink creation (w pAutoDetectHyperlinks) now moves trailing dots after the link
         - table borders after long headers w ere painted w rongly
         - w hen inserting a paragraph in a table cell the border attributes is not copied
         - WPPremium: TextBoxes w ere sometimes not loaded at correct position
         - WPPremium: Second Column w as started one line higher
         - WPPremium: Column break now starts a new column BE         FORE the paragraph (expected behaviour)
         * updated Section reading from RTF (non breaking mode w as checked too early)




© 2004-2008 WPCubed GmbH - Munich, Germany
246     WPTools Version 6


      - KeepN did now w ork correctly w hen space-after w as defined
      + NumberStyles can now be loaded and saved (using GetWPCSS, SaveToFile)
      * updated unit WPIOWPTools: When loading numberstyles the ids are mapped and duplicates are removed.
      + FormatOptionsE new flag w pfNumberingControlledByStyles
                         x:
        If defined numbering modes are directly stored and used in paragraph styles.
        Please note that this w ill only w ork w hen you use "WPT" format for load&save
      - HTML w riter created unnecessary open/close attribute tags before and after text objects

      24.01.2007 V5.0 Release 22
      + improved auto indet code when numbering styles are used. (Can be switched off in EditOptionsEx
      wpDontUseNumberIndents)
      + alignment now updated for header/footer before paint code to provide
        propper alignment when fields such as "page number" was used.
        Can be switched off using Memo. _DontUpdateObjInHeaderFooter := true
      + property RTFDataCollection.RTFViewOptions with flag wpLockDATEandTIME
        to lock the value of DATE and TIME fields
      - improved drag&drop detection
      - when RTF is loaded and text uses the charset 1 automatically the sysetm default code page is used
      * several improvements to HTML reader and writer
        using the format string "-WriteAllColWidths" all table cells with be written with a width param
        "-DontWriteStyleParam" will switch off the saving of the inline styles style=""
        -csspath:"..." can be used to specify a CSS style for loading and saving
      - fix for ine height problem when fields or bookmarks were used at the start of a line
      * several small stability improvements

      26.11.2006 V5.0 Release 21.1
      + when saving HTML files embedded images will always be written as files in same directory as HTML file
      + new format option: -imgpath:"xxx" - embedded HTML images will be written to the path xxx
         use -imgpath:"" to switch off saving of embedded HTML graphics.
      + HTML reader now detects ISO charsets
      - improvement to RTF reader to better handle corrupt RTF files
      - some improvements to engine
      - fix to render engine to set font attribute of mailmerge tags (sometimes inherited attribute was used)
      - better detection of black-on-black text
      * the optional ReportBuilder (9/10) support was rewritten and enhanced.
      + optionally FastReport support is now available

      9.11.2006 V5.0 Release 21
      + new EditOptionEx: wpZoomWithMouseWheel to zoom with mouse wheel + Control
      - invisible chars, such as bookmarks are now handled like spaces (ghost cursor bug)
      - reactivated Ctrl+C - code was deleted by mistake
      - some fixes to make upgrade form V4 easier (additions to finder,
        added functions GetSelTextBuf, InsertParText, ChangeAttr, GetParText) activated by compiler symbol
      V4COMAPT)
      - removed reference to TransparentBitBlt in unit WPObj_image since not supported under Windows NT
      - TWPTextStyle.AGet_CSS has additional parameter "IgnoreMargins" to suppress the
        writing of margin and indent attribute (useful when writing <li> tag
      * some improvements to HTML reader and writer
      * HTML reader will allign tables in the middle by default (like IE)
        This can be switched off by undefining HTML_CELLS_VALIGN_MIDDLE in WPIOHTML
      + new option for HTML reader: -onlyinbodytag, text outside <body> tags is
        always ignored.

      15.10.2006 V5.0 Release 20.9
      + unless compiler symbol DONTREQ_SHIFT_FOR_UNDER_TEXT_OBJ has been set, images which are
      under the text
       require the SHIFT key to be pressed to become selected
      * tabstops wrapped to next line were ignored (width=0) - now they will be used to jump to first tab.
       (can be switched off in PRO version using compiler symbol DONT_USE_TAB_IN_NEXT_LINE)
      * improved response time after mouse click




                                                                       © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 5    247


         + the ANSI text reader will convert #12 chars (form feed code) into page breakes. (switch off with
         DONTUSEFF)
         - changes to improve the usage of inhereited font and font size information
         - fix for line draw problem for table cells which span a page
         * several small changes to fix stability issues
         - fix of problem in conversion of unicode to ANSI
         - fix in HTML reader: alignment in DIV was applied to previous paragraph
         + load and save to unicode strings: GetUNICODE and SetUNICODE. (Internally the UNICODE reader/writer
         are used)
         + new: ruler properties IntervallStepsInch and IntervallStepsCM

         11.8.2006 V5.0 Release 20.8
         + property WPRichText.Memo.TextColor - this color is used for the text which uses the default color.
           It is initialized from the global variable wpClWindowText which has the default value clBlack.
           Note: To set the color of the editor window use property DeskColor and PaperColor
         + new flags in ProtectedProp: ppBookmarkKeepStructure and ppInsertpointKeepStructure
           --> if text is deleted the contained bookmark or field objects can be recreated.
         + new method: SetOuterCellBorders(Activate : Boolean; BorderWidth : Integer = -1);
           It is now used by the "outer border" standard action
         * StartSpellcheck automatically positions cursor before current word.
         - Some improvements to further improve stability
         + if compiler symbol TOTALREADONLY is active (see WPINC.INC) no table or object resizing
           is possible when the Readonly property is true
         + new ClipboardOption wpcoAlsoCopyHTML to also create a HTML block when copying text. This solves a
           problem when the text is pasted into Outlook express which seem to not handle RTF correctly.
         * numbering action will now continue numbering after bulleted paragraphs
           The numbering will restart, unless the CTRL key is pressed.

         17.7.2006 V5.0 Release 20.7
         + new event: OnLeaveRTFDataBlock
         * improved HTML reader - assign border attributes from styles
         - InputCode automatically moves to first cell if currently in table ot table row object
         - some secuity checks (GetPosition, SetPosition)
         + improved RTF reader (reading nested tables)
            * fix for wrong headerr tag in WPWord written files
            * ignore wrong textb code in TX written RTF files
            * under some circumstances paragraphs were appended
         - WPPREMIUM: KeepN was broken
         - some stability issues

         13.6.2006 V5.0 Release 20.6
         + new quick start chapter in manual
         * don't color paragraph symbol when merge field at end of line
         - fix in DeleteMarkeredChar API
         - change in RTF reader to handle table rows with no cells
         - added load formatstring option: -overwriteparattr to always use attributes of first paragraph
         + added REDO hot key Shift+Ctrl+Z (in addition to Ctrl+Y)
         * modified numbering action - http://wpcubed.com/forum/viewtopic.php?t=2148
           with changes to make it also work with selected text
           added similar code for bullet button
         * Table dialog now allows wpDefaultTableInTable if option wpAllowTableInTable was not set
           new: default Option wpNestingAsInEditOptions to use wpAllowCreateTableInTable of TWPRichText.
         EditOptions
         - improvement of cursor position restore when applying UNDO

         17.5.2006 V5.0 RELEASE 20.5
         + TIME and DATE text object now handle the data format string correctly
         + w hen using the tab key to navigate through a table the destination cell w ill be automatically
           selected unless you have specified w pDontSelectCellOnSpreadsheetMovement in E           ditOptionEx
         * The interface SelTextAttr w ill now report the default attributes if no other attributes are




© 2004-2008 WPCubed GmbH - Munich, Germany
248     WPTools Version 6


        defined by the selected text. This behavoir can be disabled w ith E ditOptionE w pDontInitSelTextAttrWithDefaultFont
                                                                                        x
      * Punctation chars are now handled as 'w ords' w hen using Ctrl+Cursor left/right
      - several fixes in engine
      * the save dialog can create a default extension if the extension does not match HTM, HTML, TXT, WPT, RTF or DOC
        (this must be enabled using compiler define CRE  ATE _AUTOE    XTE NSION. By default the extension w ill be
        appended if it is just a number. Now the selected format (filterindex) w ill be passed to the save procedure.
      - fix range check in cursor up/dow n (w as introduced by XPosLineUpDow n)
      - better bullets in right aligned text
      - StyleDialog hides TAB option unless compiler symbol STY_DONTHIDE        TAB w as defined

      18.4.2006 V5.0 RELEASE 20.3
      + new pow erful function FieldLocate w hich can be used to enumerate the fields in the document
        to read or w rite their contents. It w as created to offer an alternative to Mergetext w hich does
        not require the use of a callback.
      * Cursor Up/Dow n now tries to retain the horizontal cursor position (can be sw itched of in E    ditOptionsEx)
      + MailMerge(name) now allow s ONE w ildchars chaaracter '*' in the name parameter
      + MailMergeE   x(name, command) also compares the command property of the fields. Also allow s w ildcard
      + WPRichText.Memo.DisableBackgroundOnBWPrinter can be set to TRUE if (and only if!) there are
        problems w ith the printer printing colored text. Some old printers seem to "think"
        they should print the text using w hite color if the background style is clear. (doesn't make much sense)
      * other changes and stability fixes

      01.3.2006 V5.0 RELEASE 20.2
      + new event PaintPageHint: Customize the canvas properties or paint the page number in your ow n code (then set
      "Ignore" to true)
      + new E    ditOptionsE w pAlw aysColWidthPC w hen changine a column w idth all w idth w ill be calculated in %.
                            x:
      + new global variables WP    HTMLUL_ListI  mageURL_circle and WP     HTMLUL_ListImageURL_bullet to set an image
        name for the HTML export to be used for <ul> items
      + CSS now understands the color 'transparent'
      + new options for Contents.Options in OnMailMergeGetText:
        mmIgnoreLoadedFonts and mmIgnoreLoadedFontSize to ignore fonts w hen loading RTF
      - some fixes in engine
      - (!) fix in RTF reader to w ork w hen correctly w hen Czech list sorting is active
      + new event: OnTestForLinkE      vent to detect hyperlinks in plain text.
      + new : [Ctrl+D LE ] deletes w ord or w hite space to the right
                      E TE
      + CSS format now supports the MS Office elements: mso-style-parent and mso-style-parent
      * better detetection of symbol fonts
      * function IsSelected returns FALSE if text is selected but the length of the selection is 0 character
      + new demo: PrintOnBMP - for those w ho w ant to FAX pages
      + new demo: PlainTextLinks - have hyperlinks in plain text (w ithout having <a> tags in text)
      + new procedure ScrollLinePos(par, posinpar) makes this text line first of screen (w hen text long enough)
      - paste of tables in RTF code w orks better
      - improved automatic field selection
      * better display of selection of paragraph breaks
      * also show manual pagebreak (dashed line) w hen property WordWrap=true
      + Display hint w ith "Page/ PageCount" w hen the text is scrolled. Can be sw itched off using
        compiler symbol NOP    AGE NHINT or View Option 'w pDontDisplayScrollP   ageHint' also see event: OnPaintPageHint




      + OnPaint event now allow s flicker free painting
      - several fixes to RTF reader (i.e. linepar in header)
      - fix for default tabstops in WordWrap mode
      + New EditOption: w pSelectCompleteFieldAlsoWhenInside - even w ehn selection is done w ithin a field
        the complete field w ill be selected.
      + EditOption: w pDontSelectCompleteField - unless activated, alw ays select a complete fields w hen
        the selection contains part of a field
      - fix for default tabstops in WordWrap mode
      + new ClipboardOption: w pcoDontCopyProtectedAttribute, dont copy the protected attr (RTF, WPTOOLS)




                                                                               © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 5            249


         * better support for the WordWrap mode (w hen page LayoutMode is selected)
         + support for context menu key. The event OnMouseDow nWord w ill be triggered w hen the context menu key w as
           pressed. If you use the new E    ditOptionE w pDontTriggerPopupInContextE
                                                      x:                            vent the old behavior is
           established, the event w ill be then only triggered in OnMouseDow n.
         * some fixes to improve stability



         31.1.2006 V5.0 RELEASE 19.7
         + the WPTools Version 6 Delphi setup now also includes the Package WPTools5_BCB10_W32 for the C++ Personality.
           It uses the pascal compiler symbol "NODB" since the linker error 'cannot find DB.OBJ' w as persistent
         * Delphi 2006 files now compiled w ith D2006 - Update 1
         + DevE  xpressBars support (define USE XP SSBARS)
                                                    E RE
         + DoubleClick w ord selection now excludes ()[] signs. When clicked on this signs the matching character is found
         + ruler now show s page size and margins w hich w ere assigned in OnMeasurePage event
         - better operation of rulers in normal layout mode
         - better handling of tabs w ith justified text
         - problem w ith spacebefore has been fixed (w as sometimes used at start of page)
         - RTF reader did not handle tables at the start of a file correctly (w hen importing from Word).
         + compiler symbol: NUMBE    RACTION_SIMPLE if defined the number button w ill create a simple list, not an outline!
         + for Version 4 compatibility: new methods SelectPages, PagesAsString
         * improved table header-row and footer-row handling.
         - some additional checks to improve stability
         * improved RTF reader to better handle charsets

         12.1.2006 V5.0 RELEASE 19.6
         + added support for Delphi 2006
         * character styles w ill not applied to the symbols of bulleted lines
         + negative tabs are now possible
         * the RTF reader w ill now apply the maximum column w idth to a table. That produces output
           as seen in Word. To sw itch it off globally use compiler define ALWAYS_IgnoreTableWidth or
           the reader format string "-IgnoreTableWidth"
         * The horizontal Ruler now allow s it to move the right indent into the right page margin
         - several improvements w hen reading RTF tables, better nested tables due to table start/end tags
         + Drag&Drop now supports auto scroll (move mouse close to, but not over the border)
         - fixed problem w ith 'space_after'
         - WPReporter: fix of editing bug in
         - WPReporter: no par is appended after table w hen loading RTF text template (w e suggest to use WPT)
         - Preview Form now updates page number in scroll event
         * if in SinglePageMode TWPPreview .PageCount now retuns the PageCount in attached TWPRichText.
           Also: Scrollbar w ill be updated according to pagecount if AutoZoom = fullpage
         + new FormatoptionsE w pfNoTableHeaderRow s and w pfNoTableFooterRow s to sw itch off the duplicate display of
                                  x:
           table header and footer row s.
         - automatic decimal tabs in tables w ork better (w ord w rap bug) and automatically use ',' or '.' if
           the respective other char is not present

         3.1.2006 V5.0 RELEASE 19.5
         - InputEditField returns reference of *first* marker
         - fixed problem w ith text in first cell of table w hich extends over left page margin
         * show empty "size" combobox w he selected text uses different font sizes (WPAction.PAS)
         - WPPRE   MIUM: fixed problem w hen a footnote w as first char on a page

         22.12.2005 V5.0 RELEASE 19.4
         - fix for w rongly aligned images in header
         - WPReporter copies tabstops
         - RTFDataCollection.Clear did not clear numberstyles
         - compiler define 'SAVE  _ALL_NUMSTYLE     S_WP w as set in unit WP
                                                           T'                  IOWP TOOLS
         - avoid one pixel padding for regular texts lines
         - improvements to RTF reader
         - AutoScrollFeature now disables itself w hen text cannot be scrolled any further
         * resizing of really small images now w orks
         + procedure PrintPages can now print in reverse order (to value < from value!)
         + support for double, tripple and quadro click to select w ord, sentence and paragraph
         + new E   ditOptionsE w pDblClickCreateHeaderFooter
                               x




© 2004-2008 WPCubed GmbH - Munich, Germany
250     WPTools Version 6


      + new event OnClickCreateHeaderFooter (create header/footer after double click in margins)
      + textobj.Name and txtobj.Sourece is now saved w ith image objects to RTF
      * some changes to make WPTools PRO and PRE    MIUM w ork w ith Delphi 2006
      * load black character background color from RTF

      07.11.2005 V5.0 RELEASE 19
      + Ruler now have OnChanging and OnChanged events
      + If there is just one decimal tab in a table cell the text w ill be formatted as if it starts w ith a tabstop
        (can be sw itched off using FormatOptionE w pfNoAutoDecTabInTable)
                                                      x
      * in paragraphs w ith borders the padding betw een paragraphs w hich use the same borderflags is now ignored
      * CodeInsideOf checks if cursor is on the closing object and then also returns the start object
      - RTF reader had problems w ith WPReporter templates w hen groups w ere empty
      - avoid w rap of last char w hen right tabstop is near right border
      - fixed misplacement of cursor after first char in a w rapped paragraph (happened sometimes during typing)
      - fixes in HTML reader/w riter to better support <li> tag
      - WPTOOLS w riter now w rites the the tag <StandardFont/> correctly. Reader repairs previously saved tag.

      28.10.2005 V5.0 RELEASE 18.10
      + faster initialization of the text (loading+pagination+display of test document "RTF Spec 1.8"
        = 220 pages, 8MB RTF in about 7 sec on 1.6 GHZ Test PC.)
      + faster typing in texts w hich very long paragraphs (1 par=40 pages!). This mode can be sw itched off
        in EditOptionsE w pDisableFastInitOnTyping - w hich should not be necessary.
                         x:
      * change of 'DelayedInvalidate' logic in unit WPCTRME       MO now using a timer. This avoids
        problems in MDI applications w hen a form w as destroyed w hich uses a TWPPreview control
      - MoveToField moved the cursor in E       ditFields one char to far.
      - field 'NEXTPAGE w as not w orking
                           '
      - w hen RTF w as loaded merge fields removed the KeepN property from their paragraph
      - fixed handling of the automatic tab to indent first (did only w ork w hen first indent w as on left page margin)
      - highlight of current field did not w ork (E  ditField demo)
      + FormatOptionE w pfKeepNUsesParImages - keepN also check for paragraph aligned images.
                         x:
      + RTF reader/w riter now supports the sbknone, sbkpage tags for sections
      * much improved performance w hen w orking w ith files w hich use SPAN styles
      * some improvements to paragraph border dialog
      - Save section starts also before tables to RTF
      - w hen loading sections saved w ith w ord not automatically page breaks are created
      - fix small problem im HTML w riter w hich caused </td> to be saved for merged columns
      - Fix to KeepN support (only one block w as supported per page)
      - it w as not possible to edit an 'undefined' value in the value editbox by typing. It stayed grayed.
      * some improvements to HTML reader/w riter

      17.10.2005 V5.0 RELEASE 18.8
      + new function GetImageAtXY - to locate all images in MouseMove event
      * revised UNICODE copy&paste
      * format routine now handles nagative left/first indents
      + The format routine w ill *not* ignore empty paragraphs at the end of the footer.
        If your Application needs this behaviour use the flag FormatOptionsE : w pfIgnoreTrailingE
                                                                              x                    mptyParAtFooter
      - fixed 'ghost image' problem
      - fixed problem of center alignment of images in table cells w hen combined w ith new line characters
      - fixed problem w ith section header/footer w hen section started w ith a table
      - improvements to KeepN support. (note: KeepN requires 2 reformat runs)
      * ParProp dialog now show s inherited values in gray color

      27.9.2005 V5.0 RELEASE 18.7
      * WP  Reporter w ill create long documents faster
      * in event OnTextObjGetTextE the property TXTObject.ParentRTFPage can no be
                                      x
        used to know the page the object is painted. (Useful in header/footer)
      - Paste in header/footer w hen displayed text is not the body does not create ghost RTFDatablock ('DoubleVision bug')
      + new event: RTF.BeforeFormatTableRow to sw itch on KeepRow Togethere for certain row s
      + new ClipboardOption w pcoDontCopyProtectedText - do not copy / cut protected text
      + WP  Tools P ium HTML export: footnotes w ith hyperlinks, textboxes as aligned tables
                   rem

      12.9.2005 V5.0 RELEASE 18.6
      * collection RTFProps.CharStyles is disabled - it w as not used. Now ParStyles is consistently used for




                                                                               © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 5                251


         characterstylesheets, too
         * better support for character styles load&save in WPTOOLS format
         - fixed format problem w ith space_betw een
         + RTF reader can now load RTF texts and use the existing style sheets w ith option "-dontoverw ritestyles"
         - improved handling of inc-indent action

         6.9.2005 V5.0 RELEASE 18.5
         + new E  ditOptionsE w pAllow Draw DropBetw eenTextBlocks - for Drag&Drop into/from header + footer texts
                              x:
         + new AddCopy function in the paragraph style collection. Copys a style w ith all base styles from a different collection
         + WPReporter templates print much better since a left margin of 1/2inch is respected - group arrow s are now visible.
         * improved nested tables: If a nested table is only cell content no padding w ill be used.
         - bug fixes in RTF reader: Read styles w ith pn group, nested tables
         - WPReporter now w orks w ith paragraph styles even if Source/Dest does not use shared TWPRTFDataProps
         - Save dialogs now w orks for TXT files
         - fixed problems w ith NL in table cells and tabstops
         - fixed problem w ith cursor positioning in right aligned paragraphs
         * better display of highlighted text (background color) w ith certain printer drivers and w PDF
         * TParagraph.CreateCopy now also copies style sheets w hich are used by this paragraph
         * images now belong to the TWPRTFDataCollection and not the TWPRTFProps. This avoids problems w hen
           w hen several RTFDataCollections used the same RTFDataProps. Using the new FormatOptionsE       x
           w pfStoreWPObjectsInRTFDataProps the TWPObject can be still stored in the RTFProps - they w ill
           be only deleted if RTFDataProps.ClearAllWPObjects is executed.
         * improved cursor movement, also in forms
         * WPTOOLS format now uses <StandardFont/> tag to save the current default font.
         + new procedure InsertRow Above
         + w hen using the InsertRow action or toolbutton press CTRL to insert ABOVE of current row
         * TWPPreview Dlg now automatically uses events (w atermarks) from attached editbox. (assigned using code: dia.
         WP reView 1.AssignP
             P                   rintProperties(FEditBox);)

         27.8.2005 V5.0 RELEASE 18.3
         - RTF reader: unlock default font also in paragraphs w hich use a style
         - fixed clipping problem (under rare circumstances the first line w as not displayed)
         - HTML reader/w riter supports ID property (<p id="...">)
         + The HTML reader w ill create a page break after tag <pagebreak/> (useful for on the fly created HTML code)
         + The HTML reader w ill create a page reference to a certain bookmark w ith tag <pageref name="bookmarkname"/>
         + Reference as HTML-Help (.cmh) file is now available (see registered dow nloads)
         + CurrAttr Style, GetStyleE COlor and BGColor now also report paragraph, paragraph style and Default Attr
                                       x,
         + FormatOptionsE w pDontAddE
                              x:             xternalFontLeading - render lines smaller (more like WPTools 4)
         + new API: TWPOw nedCharAttrInterface.LockChanging, UnlockChanging - any attempts to change
         the attributes w ill be ignored.
         * loading RTF w ill now modify the RTFData.ANSITextAttr to reflect the default font defined in the RTF. (Use
         WPRichText.DefaultAttr.LockChanging to disable!) This is an important chage since otherw ise the standard font is
                alw ays used.
         - RTF-Reader: handle codepage in reader stack
         * disable drag and drop w hen multiple cells are selected (except for complete table!)
         * HTML reader: now allow s <ul>, <ol> tags w ithin <P> or <DIV> tags
         * Print() and PrintDialog functions automatically disable WordWrap property for the time of printing. You can define the
                symbol ALLOWWORDWRAP RI to disable this change
                                             P NT
         - padding-right in table cells w as sometimes duplicated by format routine
         - fixed paint problem w ith TWPRichTextLable w hich is using AutoZoom
         - fixed problem w ith property View Options: w pNoE   ndOfDocumentLine
         - fixed problem 'clipdebug' not anymore $defined in unit WPCtrMemo
         - some small bug fixes in Preview Dlg + scrollbars

         18.8.2005 V5.0 RELEASE 18.1
         + new IDE dialog (click right on TWPRichText control) to pre configure format- and edit options.
         * WPPRE   MIUM: InputFootnote now expects instead of the 'CreateNumber' boolean a new parameter a 'mode'
           Using 'w pNumberInFootnoteIsSuperScript' the number in the created footnote w ill be super script.
         * RE PORTBUILDE   R(tm) Support units have been updated, now w ith metafile cache for faster display
         * improved RTF style handling: all redundant character and paragraph attributes are removed automatically
           (can be sw itched doff using FormatOption : "-DontFixAttr")
         + CurrAttr.FontName and Size w ill now report the default/style attributes.
           Can be sw itched off using $define DONT_RE   PORT_DE   FAULT_ATTR
         + updated DefaultAttr handling. Using this property you can set the default font




© 2004-2008 WPCubed GmbH - Munich, Germany
252     WPTools Version 6


      + new E   ditOptionsE w pDontResetPagesizeInNew - the "New " action w ill not reset the page size!
                            x:
      + new E   ditOptionsE w pSetDefaultAttrInNew - the "New " action w ill reset the w riting mode to the default
                            x:
      + new method: ClearE     x(DontClearStyles,DontResetP  ageSize,ResetWritingAttr : Boolean);
      * updated function Draw ()
      * if EditOptionsE flag 'w pClearAttrOnStyleChange' is used assigning a style w ill remove the redundant
                        x
        information first. This is not required w ith WPTOOLS format and RTF unless "-DontFixAttr" w as used.
      + new property: AcceptFilesOptions. Create movable images or linked images w ith drag&drop!
      + new event: AfterLoadText - preprocess the text before after load operations
      + much improved Par.SplitCell method and new property E      ditOptionsE w pAllow SplitOfCombinedCellsOnly
                                                                                x
        (Disables a function w hich allow s the creation of tables w ith different coloumn count per row )
      - PageProp dialog w ill not report custom size anymore
      - fix of drag&drop of text and images betw een pages in multi column layout
      * RTF reader now appends an empty paragraph after tables. This can be disabled using the
        compiler define DONT_AP E    P ND_P  AR_AFTE   R_TABLE but should be better for the usability.
                                                               S
      + PrintParamameter.PageSides now w orks w ith the Print() function
      + The print dialog now also allow s printing of selected text. This can be disabled using PrintOption
      'w pDontAllow SelectionP    rinting'
      + speed optimation of the RTF reader (especially for files w ith images)
      * removed the unused state element from record: TLine
      - fixed spacing problem for paragraphs w hich w ere follow ing a table
      - some other small bug fixes and improved handling.

      3.8.2005 V5.0 RELEASE 18
      * support for UNICODE copy&paste
      - better support for UNDO in DeleteColumn
      * CombineColumns does not anymore combine cells in tables w hich are embedded in the selected cells
      + support for vertical alignment also in vertically merged cells
      + new property FormatOptionsE     x
      + w pClearDoesNotDelete in the attribute 'locked' of paragraph styles and numbering styles is now w orking
        This property makes it easy to set up a standard set of styles w hich is available in new texts.
      * HTML reader/w riter uses "w idth" element in style strings for images, tables and cells
      + new property: TWPStyleDlg.SaveCSSAsWPCSS. If true the WP-CSS format w ill be created w hen the
        user selects to saves to CSS format. WPCSS supports all properties. WPCSS w ill also be saved
        w hen the file extension is w pcss.
        When the extension is INI or STY the INI format w ill be saved. This format also contains all
        properties. STY file created by WPTools 4 are now imported better.
      + new event: BeforePasteImage - possibility to change the embedded object.
      + new method: GetParXYBaselineScreen can be used to calculate the baseline of certain text,
        for example to set the position of a drop dow n menu.
      + TWPSelectedTextAttrInterface now supports: ToggleCharstyle
        E xample: Implement Hotkey CTRL+B in OnKeyP      ress event:
        if (Key=#2) then begin WPRichText1.TextCursor.CurrAttribute.ToggleCharstyle(WPSTY_BOLD); Key := #0; end;
      * changed property WriteObjectMode in 'default editor' to w obRTF. It w as 'Standard'
      * improved TParagraph.SetStyle method w hich can remove properties w hich are defined in style
      - several smal bug fixes in RTF engine
      * Additions to this manual, see Table Attributes, Mailmerge and forms, TWP TFDataCursor
                                                                                   R

      15.7.2005 V5.0 RELEASE 17.4
      + new PrintParameter.PrintOption: w pAlw aysHideFieldmarkers - to hid field markers in Print; and PrintDialog;
      + new edit functionality: w hen resizing a table w hile pressing CTRL key the
        w idth of each column w ill be adjusted by preserving the aspect-ratio of the column w idth to the table w idth
      * editor improvements: better protection against unw anted change of column -w idth and -height.
      + improvements to HTML reader to display certain new sletter a lot better
      + WPReporter: new property ColumnWidthSnapValue- make sure table columns use same w idth
        (the default value 15 maps column lines w hich are not further aw ay than one screen pixel)
      + WPReporter: new Option flag "w pFixAllColumnWidth" - converts variable w idth columns into fixed w idth columns
      + TOCs can now be also created from the first line in a table cell using the new
        mode flag [w ptocAlsoProcessTables] for the CreateTableOfContents method.
      + WPAT_NoWrap can be used to sw itch off the w ord w rap in one paragraph.
        This mode has to be specifically actived if property FormatOptionsE  X
      * updated RTF load metafile routine
      * border dialog now displays state of current paragraph
      - fix: draw paragraph border at end of page
      - fix: additional hyphen draw n at end of line




                                                                             © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 5           253


         - fix: Paragraph.MergeCell procedure improved

         10.7.2005 V5.0 RELEASE 17.3
         + new localizable strings. See file "WP  Tools_EN_ADDE   D.XML" in DemosTasksLocalisation
         + new procedure TWPOImage.Compress - automatically used after paste from clipboard.
          R equires $D FI ECOM R SSBI AP
                      E N         PE      TM ASJP G  E
         + RTF reader now supports vietnamese charset
         + WPRE   PORTE the option w ppNew PageAfter can now be used for report groups
                         R:
         + WP PRE ORTE new utility functions in WP
                         R:                            SuperMerge:
           FindGroup, FindBand: Locate bands and groups
           ConvertLetterIntoTemplate        : Create a banded report template from a text w ith header/footer
           (also see: ConvertTableIntoGroup: Convert a table into a report group w ith header, data and footer bands)
         + WP E OR R band.Bookm
               R P TE :                ark to automatically w rap the text w hich w as created by a
           band or group into bookmarks. The bookmarks are applied after all text w as copied!
         + WPRE   PORTE new event: AfterCopyParagraph - triggered after new par w as appended but before the data is
                         R:
               merged
         + new component: TWPManageHeaderFooterDlg opens the dialog to create and delete header+footer, now localizable!
         * improved XMLE   ditor for WP LanguageControl
         + new flag for Contents.Options in OnMailMergeGetText: mmDeleteThisField deletes the field markers!
         + WP PRE ORTE Option 'w pDeleteFieldsInDestination' deletes the fields in destination. (uses mmDeleteThisField)
                         R:
         + ReplaceAll through the replace dialog now
           a) uses UNDO b) w ill w ork w ithin current selection only
         + Replacement in TParagraph.Replace now supports UNDO
         Bugfixes:
         - Select Word Procedure
         - DB control automatically uses '-nobinary',
         - HTML reader and w riter improvements
         - RTF reader now creates OnRequestHTTPImage event of embedded TWPObject (import from V4 files) and ignores next
               I C D I AGE
                N LU EM
         - RTF reader: Ignore rn after unicode u tag
         - RTF reader: apply subtrative properties
         - Fixes in WP TOOLS reader
         - some improvements to format and paint routine
         + new event: AfterCopyToClipboard makes it possible to add custom objects to clipboard
         + CombineCells now removes empty paragraphs
         - inputbuffer for fast w riteres (unit WOCtrMemo) optimized

         14.6.2005 V5.0 RELEASE 17.2
         [** IMPORTANT **] The LayoutMode "playLayout" did not hide
           header/footer before (as intended and described in manual)
           This has now been fixed. Header and footer w ill be hidden.
           Please make sure you use __playFullLayout__ to also show header/footer
         - automatic header+footer row s: improved alignment w ith other row s
         * new property "DefaultNumberIndent" (must be changed in code) w hich
           sets the default indentiation for bullets and numbers applied by
           bullet dialog and bullet button
         - page numbers are grayed in header/footer
         * the HTML w riter can now create simple UL and OL lists. This feature
           can be deactivated defining the compiler symbol DONT_WRITE        _SIMP _LISTS
                                                                                   LE
         + new event: OnCalcPageNr makes it easy to change the displayed page nr.
         - some improvements of formatting function for merged table row s
         - improvement of paint procedure (selected text and background colors)
         + new SelectedTextAttr.ClearAttrOverride
         + new View Option: w pDraw HeaderFooterLines
         + new FormatOption: w pNoMinimumCellP        adding
         + new : TWP   TextStyle.ADelAllDefinedIn
         - fixed memory leak w ith the 'StoreComplete' undo object
         * Copy text from single table cell does not copy borders and table structure anymore
         * removed unused interfaces from RTFE         ngine
         * CountPages, CountLines, CountParagraphs now reports '1' for empty documents (better for GUI
           since that first line w ill be automatically created w hen the editor gets the focus)
           They count the body text if the cursor is not set to any other RTFDataBlock

         30.5.2005 V5.0 RELEASE 17




© 2004-2008 WPCubed GmbH - Munich, Germany
254     WPTools Version 6


      + added new 'categories' to online help
      + WPPRE     MIUM + WPRE    PORTE You can now use text boxes in report templates (fields can be used)
                                       R:
      + WPPRE     MIUM + WPRE    PORTE You can now use foor notes in report templates (fields can also be used)
                                       R:
      * Create table button alw ays disabled w hen in table (unless w pAllow CreateTableInTable is used in EditOptions)
      * WPRE    PORTE the StartCode of a group is now processed before the event BeforeProcessGroup!
                       R:
      + new FormatOption: w pDontAdjustFloatingImagePosition - do not modify the position of relative
        objects to keep on page
      + new FormatOption: w pDontAdjustFloatingImagePosition - do not modify x,y of floating images automatically
        to avoid that they are outside of page
      + new option for TParagraph.LoadFromStream: "w ploadpar_UseWritingAttr". Now the current attributes
        w ill be applied to the loaded text.
      + new : TParagraph.LoadFromString - makes it easy to set formated text in a parabgraph. (RTF or HTML commands are
              understood!)
      - fixed problem w ith WPReporter template editing w hen layout mode w as set to normal
      - improved case insensitive search in finder
      - several improvements to editor handling

      12.5.2005 V5.0 RELEASE 16
      - IMPORTANT: fixed problem w ith tabs in ruler w hich only occured w ith Delphi 5.
      * some important improvements to cursor handling w ith WPReporter
      + keep properties of images w hen pasting (or TextObj.Insert) image w hile other image is selected
      + several improvements to WPReporter and Report-Band Dialog (see new demo!              )
      * improved w riting of stylesheets in RTF code
      * improved saving of stylesheets in RTF code
      * the procedure ParStyle.LoadFromFile now has a parameter 'Merge' to merge in the new styles
      * improved stylesheet dialog (show focus in Listbox)
      * paint selection-background for selected text objects w hich use OnPaint event
      * the TWPRichText now publishes the event OnPrepareImageforSaving (used by the TWPRTFDataCollection)
        to make it easier to use in applications w hich do not use the "MultiView " feature.
        This event can be used to preprocess an image before it is saved, for example save it as GIF/JPE file        G
        and store the file name in the property TextObj.Source
      + new function: TParagraph.InsertE - makes it possible to insert text w ith r signs (new pars w ill be created)
                                              x
        This is internally used by TextObj.E   mbeddedText := 'new text' - so multiline text in bookmarks can be replaced
      + FORMTE fields are now converted to w ptools edit fields
                   XT
      + changed behaviour of FormatOption: w pfHangingIndentWithTab - the left indent w ill be handled as first
        tabstop not only if the tab is the first character but also if the text before the tab fits into the first indent.
      * OnTextObjectMouseUp, OnTextObjectMouseMove and OnTextObjectMouseDow n are now also triggered
        for non-image TWPTextObj. (See editBox demo for a checkbox example)
        Only w ith image objects the x and y parameters are relative to the objects coordinates!

      26.4.2005 - V5.0 RELEASE 15
      + WPRichText.ParStyles.SaveToFile / LoadFromFile to make it easy to load/save style sheet in WPCSS format
      + WPRichText.ParStyle.SetWPCSS(s) applieas a string w hich w as created by GetWPCSS
      * protected text is now also locked for attribute changes (unless ppDontProtectAttributes is used in ProtectedProp)
      * updated demo P     arStyles
      * updated RTF font/charset w riting. The resulting file w ill be a lot smaller
      + New procedure DeletePage - deletes the text on a certain page.
        This is a very complicated function w hich also handles multipage table row s!
      + new view option: w pDraw PageMarginLines to draw a doted line round the text area
      + function 'CodeListTags', w orks like 'GetCodeTags' but creates a TWPTextObjList
      * cleaner display of text selection (visible w ith italic text)
      * improved paragraph-border draw ing (respects indent-left/right)
      + RTL support can be activated by setting the flag paprRightToLeft in TParagraph.prop
        or for all paragraphs w ith WPRichText1.Memo._RTLSupport := TRUE
      * improvement to HTML w riter for better tables
      + WPFORM SUPPORT: now operational in WPForm V2.50 - only text rotation is not possible
      + ALL underline modes and the underline color feature are now w orking
      * automatic update of filter index for load/save dialogs
      + property TextLoadSaveOptions. Makes it possible to set a format string for
        Load, Save and SaveAs operations.
      + The attribute interfaces (such as WPRichText1.WritingAttr) now have a overloaded Clear procedure
        w hich allow s it to set the fontname and -size, + color right aw ay:
        WP  RichText1.WritingAttr.Clear('Verdana',10);




                                                                               © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 5               255


         7.4.2005 - V5.0 RELEASE 14
         * improve import of V4 mail merge templates. In RTF reader (w pioreadrtf.pas) the $DE  FINE FIXUP   _V4_FIELDS
           enables that trailing >> and ] are automatically removed.
         + WPPremium: cursor movement w ithin ootnote blocks using cursor up/dow n
         + "image under text" option in graphics menu of default actions
         + cursor movement w ithin visible header/footer blocks using cursor up/dow n and mouse click
         + improvements to the handling of forms (see new demo: E       ditFields )
         * Revised border dialog. (All properties are undefined by default, can be changed individually)
         * LoadFromFile, LoadFromStream now loads header/footer even if there is a body text defined
           (the function IsE   ,mpty) has been updated
         + the property WPAT_ProtectedPar is now also checking attached styles and parent table/row s
         * copy&paste, Drag&drop now automatically tries to not create orphan field opening/close tags
         + added support for IME editor
         + the ruler now alow s it to change the left indent only
         * better update of WPComboBox
         * possibility to have a tabstop before the left indent
         * new handling of font names in RTFPros object (list instead of array)
         * changed logic of Ctrl+Left/Right to jump to start of w ord instead of end of w ord
         + font charset load&save in RTF format
         * several improvements to cursor positioning in forms (ProtectedProp=[ppAllE    xceptForE ditFields])
         + new RTF w riter option: "-nonumberprops" - in RTF the numbers are saved as regular text
         + new w riter option: "-nomergefields," - merge fields are not saved, just the embedded text
         + new w riter option: "-nohyperlinks" - hyperlinks are not saved
         + new w riter option: "-nobookmarks" - Bookmarks are not saved
         + new RTF reader option: "-ignorerow merge" - ignore the combine row s RTF tag
         + procedure 'FastAppendText' is now a function. If the optional parameter 'AsNew Section' is true
           this function w ill return the reference to a new section property object.
         * linked images are now saved w ith w idth/height (Word still ignores the w h parameters)
         + the follow ing functions have been added, they now include table cell handling:
             function DeleteP   arWithCondition(Condition: TWPCheckP aragraph) : Boolean;
             function DeleteParWithE    mptyFields : Boolean;
             function DeleteParWithText(const FindText: string) : Boolean;
             function DeleteTrailingSpace(E   mptyFieldsToo: Boolean): Boolean;
             function DeleteLeadingSpace(E     mptyFieldsToo: Boolean;InFirstP : Boolean = TRUE Boolean;
                                                                                ar              ):
         - ... lots of small fixes to improve overall perfomance and reliability

         V5.0 - Release 13 (11.3.2005)
         - solved problem w hich occured under w indow s 98 (critical fix)
         + new IDE context menu for the TWPRichText 'Change Page Size'
         + new auto zoom mode: w pAutoZoomAsManyAsPossibleInRow
         + new demo: AppendAsSection: Create a big text out of several texts incl header + footer
         + enhanced the WPTOOLS format reader to understand the <new section/> tag. This makes it
           possible to create multi section texts w ithout loading them into an editor!
         +E  nhanced API to w ork w ith sub paragraphs. Plese see the new demo "SubP     aragraphs "!
         * InputTextField/InputTextFieldName are now functions returning the created TWP    TextObj
         + new event: BeforeDropText to abort drop operation
         + property WideStringValue : WideString of 'Contents' in OnMailMergeGetText
         + new format string option: '-codepageXXXX' to set code page for ANSI reader/w riter
         + property Text and SelText now use the current keyboard codepage (internally uses '-codepage' !)
         + possibility to create repeated table header and footer row s. See updated demo: CreateTable
         + possibility to use the TWPFormulaInterface to calculate the value for
               repeated fields in header/footer(OnTextObjectPaintCalc) See TableCalc demo.
         + WP  Reporter : added the possibility to have repeated header/footer w ith WP Reporter

         V5.0 - Release - 12.2 (22.2.2005)
         * improved code to size table row s (requires E   ditOption w pTableRow Resizing)
         + possibility to set a fixed table row height in editor (press CTRL)
         + vertical alignment in table cells is now handled
         + page up/dow n key is now handled differently to avoid deadlock
         * better handling of merged row s - now the last column can be alw ays merged
           even if the column count in the row s is different
         + option: "-nobinary" to save RTF code w ith hex encoded data
         + save binary RTF variables
         * improvement of scroll function: Scroll to selected object instead of anchor




© 2004-2008 WPCubed GmbH - Munich, Germany
256     WPTools Version 6


      * The footer now alw ays starts at the bottom of the page w ith MarginFooter distance.
        If you need the old behavior w ith the footer to start at the beginning of the footer use FormatOption
             w pFooterMinimumDistanceToText
      * started implementation of character styles
      * the RTF w riter interpreted OptOnlyBody incorrectly and so didn't w rite some RTF tags
      * improvement to E   ditOption w pAutoDetectHyperlinks to automatically exit a link w hen space or ')' is typed.

      V5.0 - Release - 12 (3.2.2005)
      + the E ditBoxModes w pemAutoSizeWidth and w pemAutoSizeHeight and the events
        OnChangeE   ditBoxWidth and OnChangeE    ditBoxHeight are now w orking. New demo: "EditBoxModes"
      + format option: w pfKeepOutlineWithNext to keep headline w ith chapter text even if seperated by empty lines
      + PrinterParameter are w orking now . Please check out the new demo "PrinterSet       "
      * updated chapter 'M erge '
                           ailm
      * new chapter TWPTextObj w ith custom draw event
      * save non standard RTF-Variables as 'userprops' to RTF
      + format option: w pfKeepOutlineWithNext to keep headline w ith chapter text even if separated by empty lines
      - paragraphs longer than 2 pages w ere not formatted correctly.
      - better sizing + movement of images in "normal" layout mode
      * sizing rectangles are not any longer shrinked w hen zooming out
      * save and load new page starts before a table row in a Word compatible w ay

      V5.0 - Release - 11.1 (23.1.2005)
      + Readonly property for header/footer (TWPRTFDataBlock class) - if true they cannot be selected in page layout mode
      *E  ditOptions spreadsheetcursormovement now w orks (jump to next cell w ith TAB)
      + TWP   VirtPageP  aintParam w hich is parameter of event: CustomLineP   aintBefore
        now has new boolean property: PaintingInE     ditor
      + unit WPSyntaxInterface to use the SYNTAX HIGHLIGHTING modules w hich are
        part of SynE w ith WPTools Version 6. (See demo SynHighlight )
                     dit
      + SP EE DRE  FORMAT (can be disabled in FormatOptions): During regular text editing only
        the current and the next page is formatted, the rest of the text is untouched until
        the next time CR or Ctrl+CR is pressed or the user scroll the text.
        The delay betw een keystrokes w hich w as noticeable w ith very long texts is so minimized.
      + new component: TWP aintEP     ngine . Used to paint the text from a TWPRTFDataCollection.
        See demo: TasksDynAssignRTFData
      + KeepN support activated
      * Widow /Orphan control revised (--> property FormatOptions)
      * improved handling of double buffer. Now the creation of 1000+ editors at a time is possible
      + Hyphenation (manual, use Ctrl + '-' to mark a character to go into next line)
      + Support for BB codes in the HTML reader. Must be enabled w ith -useBBCodes in format string.
        Use -ignorehtml to ignore regular HTML tags
      + use #13 code to create new paragraphs in HTML. Must be enabled w ith -useCRin format string
      * the DefaultAttr and the WritingAttr didn't survive a Clear of the text. This has been fixed.
      * better line number display in WPGutter - now start w ith 1 instead of 0
      * LoadFromFile now uses the FormatString parameter

      V5.0 - Release - 10.5 (22.12.2004)
      * faster paint routine
      * new E  vent: OnNew RTFBlock: Makes it easy to apply a default font/style/text (see online HLP)
      * TWPObject.Paint() function now receives TWPTextObj and Mode paremeter to adjust painting for different devices
      - several bugfixes (see history.txt)

      V5.0 - Release 10 (7.12.2004)
      * new unit WPCreateDemoText - must read chapter: Set Attributes in code
      * new demo LabelP  rint w hich implements an easy to use form to print labels.
      * new demo E  xternalP ages to show how to mix custom printed pages w itn text
      * new demo Find Text
      * updated demo: CreateTable
      * update demo: GlobalStyle (includes self running demo)
      * updated section in this manual: Header and Footer
      * updated manual section and VCL functionality: Interactive Text
      * far improved RTF reading and w riting
      * improved WPTOOLS format reader and w riter
      * improved HTML format reader and w riter




                                                                               © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 5          257


         + support for legal outlines
         + updated CreateTableOfContents procedure
         * many fixes and additions to programing API

         V5.0 - Release 9 (26.10.2004)
         * better handling for PageWidth/P   ageHeight actions
         * better handling of the tables w ith WordWrap set to TRUE
         + added demo "ThreadSave" to show how to do threadsave mailmerge
         + added procedure: DeleteFields
         + now possible: colors and sizes for bullets
         + added FormatOption: w pfAlw aysFormatWithScreenRes - for better display w hen you only display on screen but do
         not print
         + added event: OnCustomLinePaintAfter - print borders around paragraphs or group of paragraphs
         + added event: OnCustomLinePaintBefore- print background of paragraphs or group of paragraphs
         + added event: BeforeInitializePar - syntax highlighting, dynamic hiding of pars etc
         + new : pow erful TWP  SuperP  rint component to print labels, multiople pages on one page and booklets
         + WPReporter: added TWPFormulaInterface - calculation in tables, paragraphs and "CALC" fields
         - fixed format routine: centered and right aligned text w as not handled correctly w hen indents w ere used.
         + added localization

         NEW and updated Demos:
         * CreateTable - show s how to modify an existing table!
         + SuperPrint - print labels and booklets using a new pow erful component: TWPSuperPrint
         + ThreadSave - merge letters in a several threads
         +M  ini   - create a compact w ptools editor w indow w ith split screen in code
         + WPReporter_Calc - requires WPTools bundle: pow erful calculation in text and tables

         V5.0 - Release 8 (6.10.2004)
         - fix to GetXPositionTw and GetYPositionTw to w ork w ith zooming and XOffset properly
         + new procedure: Memo.GetXYP      ositionAtRTFTW
         * improved unit WP  Obj_Image to save compatible RTF images in BMP WMF, JP G and P format
                                                                             ,      E       NG
           (see property WriteObjectMode. It must be set to w obRTF for this)
         * improved image saving code for PNG files - they are now saved compressed in WPT format
         - improved painting of bullets created w ith WPTools 4
         + added support for BCB6 and BCB5 (WPTools Standard E     dition)
         + added events to TRTFDataCollection to modify reader and w riter (BeforeSaveToStream etc)

         V5.0 - Release 7.5 (30.9.2004)
         + new MDI Demo - show s how to use DefActions w ith MDI form
         + new "Lines" property for E  ditor and RTFDataBlock
         * improved DefAction Module
         * revised RTF saving code: style and table handling improved. Fixed problem w ith nested tables.
         - RTFw riter: In landscape mode the non-sw apped page size values w ere w ritten
         + new FormatOption: XMLOutline - show s the text as HTML outline
         * revised HTML reading logic
         * support for hyperlinks and bookmarks w hen printed w ith w PDF
         - improved draw ing of tables in header or footer
         * added support for E  DSSP LL
                                     E

         V5.0 - Release 7 (13.9.2004)
         + added reusable data module WPDefAct - it contains main menu, image list and actions
         + added new popup editor WPDefE ditor - it can be used in your applications (read more)
         + new procedure SetZoomMode to change layout mode and zooming quickly
         + improved performance of MergeText and FastAppendText

         V5.0 - Release 6.5 (8.9.2004)
         + Redo support (activated in EditOptions!)
         - bugfixes to cursor movement procedure
         - improvement of formatting procedure
         * added property Draw Options to rulers
         * added OnPaint event to rulers

         V5.0 - Release 6.5 (4.9.2004)



© 2004-2008 WPCubed GmbH - Munich, Germany
258     WPTools Version 6


      + completely rew ritten TWPRuler
         (many properties need to be ignored w hen the form is loaded in the IDE     )
          The ruler now supports undefined, inherited indents and grays out tabstops w hich are not active in al selected
          paragraphs.
          The height / w idth is now fixed to 24 pixel. This is important for a clear display.
      + completely rew ritten TWPVertRuler     .




      + Page relative images are now supported : PositionMode w potPage
      + added autoscroll (w ith variable speed) - can be sw itched off in EditOptions
      * improved selection across page borders
      - fixed problem in spellcheck interface
      - fixed problem w hen saving tab stops
      * added E ditField demo
      - several bugfixes and additions to API

      V5.0 - Release 6 (24.8.2004)
      - renamed unit WP    OBJI mage to WP    OBJ_I age to avoid conflict w ith TWPObjType: w pobjImage
                                                    m
      + new Demo 'WaterM ' show s how to draw a form or image tiles in the background
                              2
      * updated Demo 'P    arStyles ' - to also show how to w ork w ith style combo box and dialogs
      * The PRO version is now compatible to BCB5 and BCB6 (see BCB notes)
      - renamed unit WP    OBJImage to WP     OBJ_Image to avoid conflict w ith TWPObjType: w pobjImage
      * improved deletion of selected tables row s
      + added support for references (reference: display page number of page w ith bookmark)
      * improvement to bullet handling
      + reformat optimized for best screen and print quality (see WYSI     WYG)
      * WPTools format handles Numberstyles, complete style table and RTFVariables
      + improvement to function Draw () - now also w ork w hen SetWindow Org API is active
      - bug fix in SaveToFile() - parameter Format w as ignored
      + procedure ParStylePaint to paint a style name into a listbox or combo
      + added: StyleDialog
      + modernized text selection w ith mouse (selects w ords automatically)
      * updated drag&drop code, now also betw een different TWPRichText
      + added: StyleSheetDialog
      * finished: TWPStyleCollection (please note: You don't need it for the paragraph style support.
        It is only a container. The dialogs are attached best to an editor using property 'EditBox'
      + added style saving to RTF
      - improved style loading from RTF
      + optimized WPReporter draw ing code
      * added popups to WPReporter E        ditor Dialog

      V5.0 - Release 5.5 (11.8.2004)
      + new function: WPRichText.Assign - copies the text and the view options + special text attr.
      * updated TWPStyleCollection. This class stores the style templates
      + new Demo 'P  arStyles ' - this show s how to w ork paragraph and span styles - natively and fast
      * many improvments to HTML loading and saving, esspecially the CSS support has been updated
      + several improvements to the programming API to make it more consistent
      - solved problem w ith tabstops
      * extended TBX demo (also see Use WPTools5 w ith TBX)

      V5.0 - Release 5.1 (6.8.2004)
      +E  ditor sw itches off numbering on Return in empty line
      + new demo: GridM    ode - create a table from text and images loaded from database
      + loading and saving of numbering (complete new code to w rite list styles)




                                                                             © 2004-2008 WPCubed GmbH - Munich, Germany
Release Notes - WPTools 5      259


         - bugfix for property CPColNr
         - better handling of TWPRichText.DefaultAttr (it w as only partly used)
         - fix to property 'Readonly' - w as also declared also in unit WPCtrRich
         - improvement to SpellAsYouGo: do not check w ord during w riting
         - fix to OnDblClick. The last parameter 'Ignore' now is passed as 'var'

         V5.0 - Release 5 (2.8.2004)
         * All Layout Modes are now operational - see Layoutmodes
         * All View Options now w ork (Show CR etc)
         * new table resizing code
         * hyperlink support in RTF label
         * added: OnP ageGapGetText
         - improved RTF and WPTOOLS reader and w riter classes
         - improved loading of RTF text w hich contains charsets
         - improved loading of tables
         - improved HTML w riting: saving of <font> and <span> tags
         - improved HTML w riting: saving of <br> tag
         * added OnChange event
         - removed LayoutModes 'w playFullLayoutColumns' and 'w pThumbNailView Nr' (redundant)

         V5.0 - Release 4.5 (25.7.2004)
         - improved handling of soft line breaks = Char(10)
         - improved action handling
         - new pseudo action: 'TWPToolsCustomE     ditContolAction' w hich is used to replace the TWPToolControl
         - added TBX demo (also see Use WPTools5 w ith TBX)

         V5.0 - Release 4 (16. July 2004)
         * many improvements to RTF reader (load header/footer for sections)
         - improvement to rendering of tabstops
         - improvement to formatting of justified text
         + new method: HyperlinkConvertOldWPT3Links to convert the old WPTools hyperlink syntax
         - sw itch off unw anted painting of paragraph borders
         * increased performance of InputString()
         + Support for overw rite mode: new property Inserting and TextCursor.Inserting
         + added funtion GetPar(parindex) : TParagraph
         + added property ProtectedProp and event OnCheckProtection.
         * improved "editfield" protection and edit code, also added edit-field events
         * improvement to HTML w riting code to reduce file size
         - WPRuler now handles tabstops
         - fixed bug w hich SetCharAttr used by the ChangeAttr demo

         V5.0 - Release 3 (2. July 2004)
         - undo for image moving + resizing
         - undo for Drag&Drop and Copy&Paste
         - improvement to format routine to better support text w rapping around images
         * save header and footer to RTF - now also the optional names of header and footer are saved!
         - improvement to selection + cursor placement
         - fix to avoid unw anted drag&drop
         - revised loading and saving of fields and objects from and to RTF
         - Image handling, resizing and moving - highly improved for character and paragraph dependent images
         - now supported: different w rap mode (TWPTextObj.WRAP)
         - bugfix: format routine: w ord w rap around images did not w ork at start of paragraph
         + WPReporter 2 - beta 1 - now w ith new group folding function.
           Currently only 'IgnorePageHeight' operation supported
         + WPReporter: added WPE E   val ngine and created functions to make it possible
           w ith WPReporter to change text styles in scrips (= band commands)
         + WPReporter: added improved band dialog, now w ith insert/delete band buttons
         + added unit WP   WordConv
         + added unit w pManHeadFoot
         - improvements to the handling of property 'WorkOnText'
         - property "ScrollBars" w orks as expected
         - added undo support (70% complete)
         + new View Option: w pDontPaintPageFrame




© 2004-2008 WPCubed GmbH - Munich, Germany
260     WPTools Version 6


      + new View Option: w pCenterPaintPages - to center the pages automatically in the preview dialog
      + new property for TWPPreview : SinglePageMode. If true only one row of pages are displayed (1 or 2)

      V5.0 - Release 2 (17. June 2004)
      - The HTML loading has been improved.
      - The function Draw () is now w orking. Please note the new demo project FunctionDRAW. Draw w ill render the text
      using the same w ord w rap as it is used in the editor. It is used to fill rectangles vertically w ith text. A new rectangle can
      be started w hen the text w as not completely printed.

      V5.0 - Release 1 (14. June 2004)
      This first release includes the pow erful new RTF engine w ith its versatile capabilities to use paragraph and character
      attributes. This versatility does not only come from the amount of possible attributes, but how the attributes can be
      stored - attached to a paragraph or a style or inherited. The GUI controls have been taken from WPTools 4 and adapted
      as far as possible.
      The look and feel w as not changed - on purpose. Later new property dialogs w ill be delivered.




                                                                                © 2004-2008 WPCubed GmbH - Munich, Germany
Index   261
                                                LoadImageFromFile 34

Index                                           LoadImageFromStream 34
                                                Localization 14

                                                -M-
-A-
                                                Mailmerge 27
Actions    49                                   Merge Images   34
Attributes   74, 81                             Multithreading 130
AutomaticTextAttr 31

- B-                                            -O-
                                                OnMailMergeGetText     33
Bookmarks         98

-C-                                             - P-
                                                PDF Export   9, 165
C++Builder 147                                  PDF View   9
Custom Draw  115, 120, 128                      Printing 103, 104, 107, 110

-D-                                             - R-
Default Editor 47                               RTF2PDF     1
DevExpessBars    70

-F-                                             -S-
                                                Sections    66
FastAppendText  39                              ShowMergeFieldNames        31
FieldLocate 38                                  Splitscreen 142
Format Strings 203                              Styles    86
Forms    41
                                                -T-
- H-
                                                Tables    78, 81, 112
Hyperlinks    96                                TBX 70
                                                TextDynamic     1
-I-                                             Token Conversion 192
                                                ToolBar 2000 70
Images     123                                  TParagraph 20
InsertPointAttr        31                       Translation 14

-L-                                             TWPRTFDataBlock       20


LabelPrinting 149
                                                -W-
Language 14                                     Watermarks 115
License 7                                       wPDF 165
Load & Save 203                                 WYSIWYG 25




   © 2004-2008 WPCubed GmbH - Munich, Germany

More Related Content

PPTX
Guerra fría
PDF
Metro Beijing
PPT
AFSA Winter 2010 Training Session
PDF
Athletica Alliance - media support
PDF
Zaigham wastewater management in indus basin pakistan
PDF
Fostering Social Entrepreneurship in the New Tunisia
PPT
приполярный урал
PPT
Afsa Training Sessionfinal
Guerra fría
Metro Beijing
AFSA Winter 2010 Training Session
Athletica Alliance - media support
Zaigham wastewater management in indus basin pakistan
Fostering Social Entrepreneurship in the New Tunisia
приполярный урал
Afsa Training Sessionfinal

Viewers also liked (6)

TXT
Buku 1 2015_edisi_revisi_2
PDF
Hadoop development in China Mobile Research Institute
DOCX
Kegiatan belajar 2
PPT
Splish Splash
PPSX
Cultivo de camaron en el istmo
PPS
Valle Del Tránsito
Buku 1 2015_edisi_revisi_2
Hadoop development in China Mobile Research Institute
Kegiatan belajar 2
Splish Splash
Cultivo de camaron en el istmo
Valle Del Tránsito
Ad

Similar to Wp Tools6 Manual (20)

PDF
B035-2447-220K.pdf
PDF
PaperCut MF 11.0 User Manual
PDF
Begining j2 me
PDF
Pc 811 transformation_guide
PDF
Sql Front Manual
PDF
Introduction to BIRT
PDF
cpd42421.pdf
PDF
Openobject developer
PDF
Doors Getting Started
PDF
Business objects51en
PDF
Openobject developer (2)
PDF
Openobject developer1
PDF
Openobject developer
PDF
Open erp openobject-developer
PDF
Win plc engine-en
PDF
Modelsim Tuttranslate
PDF
01 introduction tovulcanmanual_v81_20120817-libre
PDF
An introduction to tivoli net view for os 390 v1r2 sg245224
PDF
2226 v3 rev_a
PDF
B035-2447-220K.pdf
PaperCut MF 11.0 User Manual
Begining j2 me
Pc 811 transformation_guide
Sql Front Manual
Introduction to BIRT
cpd42421.pdf
Openobject developer
Doors Getting Started
Business objects51en
Openobject developer (2)
Openobject developer1
Openobject developer
Open erp openobject-developer
Win plc engine-en
Modelsim Tuttranslate
01 introduction tovulcanmanual_v81_20120817-libre
An introduction to tivoli net view for os 390 v1r2 sg245224
2226 v3 rev_a
Ad

Wp Tools6 Manual

  • 1. WPTools 6 GUIDE 15.07.2009 Copyright 2005 - 2009 by WPCubed GmbH created by Julian Ziersch
  • 2. I WPTools Version 6 Table of Contents Foreword 0 Part I What is WPTools? 1 Part II WPTools 6 new features 3 Part III WPTools Version 6 5 Part IV License 7 Part V Technical Notes 8 Part VI PDF Products 9 Part VII Guide 11 1 Localization - change Language in Dialogs ................................................................................................................................... 14 2 Programming Overview/QuickStart ................................................................................................................................... 18 Modify the look and feel of the editor ......................................................................................................................................................... 18 Change current w riting mode ......................................................................................................................................................... 19 Move the ......................................................................................................................................................... 19 Cursor Change Page Size and Page margins ......................................................................................................................................................... 19 Insert Text ......................................................................................................................................................... 19 Mail Merge (replace fields w ith data) ......................................................................................................................................................... 19 Input TextObjects (i.e. page numbers) ......................................................................................................................................................... 19 Create an ......................................................................................................................................................... 19 ow n toolbar Save and load HTML ......................................................................................................................................................... 19 Get and set the text "as string" ......................................................................................................................................................... 20 3 Data Structures ................................................................................................................................... 20 4 WYSIWYG ................................................................................................................................... 25 5 Mail-merge and forms ................................................................................................................................... 27 Create Field ......................................................................................................................................................... 28 I nputM ergeField .................................................................................................................................................. 28 I nputE ditField.................................................................................................................................................. 29 ReplaceTokens .................................................................................................................................................. 29 Low Level .................................................................................................................................................. 30 Customize Field Display ......................................................................................................................................................... 31 Update Field (Insert Text from Database) ......................................................................................................................................................... 32 Start Merge process .................................................................................................................................................. 32 E vent OnMailMergeGetText .................................................................................................................................................. 33 TWP MnsertTextContents M I ........................................................................................................................................... 33 procedure Clear...................................................................................................................................... 34 procedure Abort...................................................................................................................................... 34 procedure LoadTextFromStream(s: TStream) ...................................................................................................................................... 34 procedure LoadTextFromFile(const FileName: string) ...................................................................................................................................... 34 function LoadImageFromFile(const FileName: string; w : Integer = 0; h: Integer...................................................................................................................................... 34 = 0): Boolean; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 3. Contents II property DataCollection: TWP ...................................................................................................................................... 34 RTFDataCollection property DataBlock: TWP ...................................................................................................................................... 35 RTFDataBlock property MergeAttr: TWPStoredCharAttrInterface ...................................................................................................................................... 35 property MergeP TP ...................................................................................................................................... 35 ar: aragraph property MergeP os: Integer ...................................................................................................................................... 35 arP property Obj: TObject ...................................................................................................................................... 35 property CodeP ...................................................................................................................................... 35 age: Integer property StringValue: AnsiString ...................................................................................................................................... 36 property WideStringValue: WideString ...................................................................................................................................... 36 property OldText: string ...................................................................................................................................... 36 property OldFormattedText: string ...................................................................................................................................... 36 property OldIsP...................................................................................................................................... 36 lain: Boolean property CurrentObject: TWP ...................................................................................................................................... 36 Object property CurrentTxtObject: TWP ...................................................................................................................................... 36 TextObj property Options: TWP ...................................................................................................................................... 36 MailMergeContinueOptions property Name: string ...................................................................................................................................... 37 property FieldnameP ...................................................................................................................................... 37 art: string property DatasetnamePart: string ...................................................................................................................................... 37 property Command: string ...................................................................................................................................... 37 property StartInspObject: TWP ...................................................................................................................................... 37 TextObj property E nspObject: TWP ...................................................................................................................................... 37 ndI TextObj property DisplayName: string ...................................................................................................................................... 37 property Format: Integer ...................................................................................................................................... 37 property Modified: Boolean ...................................................................................................................................... 38 property Hyperlink: string ...................................................................................................................................... 38 property HyperlinkName: string ...................................................................................................................................... 38 property I...................................................................................................................................... 38 sNull: TWP nsertTextContentsNull MMI property ReplaceMode: TWP nsertTextContentsReplaceMode ...................................................................................................................................... 38 MMI FieldLocate: Modify Field Name or Contents .................................................................................................................................................. 38 Use TWP .................................................................................................................................................. 39 M DataP M rovider FastAppendText: Create text w ith multiple letters ......................................................................................................................................................... 39 E xample: FastAppendText .................................................................................................................................................. 39 Create Sections w ith FastAppendText .................................................................................................................................................. 40 Create Lists .................................................................................................................................................. 40 Save created text .................................................................................................................................................. 40 Hide empty paragraphs ......................................................................................................................................................... 40 Forms/Edit Fields ......................................................................................................................................................... 41 Create ComboBox ......................................................................................................................................................... 43 6 Tasks ................................................................................................................................... 45 Mini Editor ......................................................................................................................................................... 45 Save to HTML / Load from HTML .................................................................................................................................................. 47 How to use the "Default Editor" ......................................................................................................................................................... 47 Toolbar and Action Classes ......................................................................................................................................................... 49 Change Behaviour and Appearance of Editor ......................................................................................................................................................... 51 Layoutmodes .................................................................................................................................................. 51 Hover E .................................................................................................................................................. 54 ffects EditOptions.................................................................................................................................................. 56 View Options .................................................................................................................................................. 58 Format Options.................................................................................................................................................. 59 HideTableBorders .................................................................................................................................................. 61 Header and Footer ......................................................................................................................................................... 61 Create Sections ......................................................................................................................................................... 66 Full implementation - show s how to w ork w ith sections .................................................................................................................................................. 67 Use utility .................................................................................................................................................. 69 procedure AppendAsSection © 2004-2008 WPCubed GmbH - Munich, Germany
  • 4. III WPTools Version 6 Use strings in WPTOOLS format w ith the <new section/> tag .................................................................................................................................................. 69 Append section w ith individual footer (or header) .................................................................................................................................................. 69 Use WPTools w ith TBX (Toolbar2000 Extension) ......................................................................................................................................................... 70 Set Attributes in code (unit WPCreateDemoText) ......................................................................................................................................................... 74 Tables ......................................................................................................................................................... 78 Set w idth .................................................................................................................................................. 79 in inch of a certain column Work w ith.................................................................................................................................................. 81 % w idth Create Table in Code ......................................................................................................................................................... 81 Work w ith Styles and Stylesheets (in code) ......................................................................................................................................................... 86 Numbering ......................................................................................................................................................... 93 Hyperlinks ......................................................................................................................................................... 96 Bookmarks ......................................................................................................................................................... 98 XML editor mode ......................................................................................................................................................... 100 Printing - how to set printer properties ......................................................................................................................................................... 103 Superprint: Print Booklets and Labels ......................................................................................................................................................... 104 Print Labels (TWPSuperPrint) ......................................................................................................................................................... 107 Print/Edit......................................................................................................................................................... 110 elements of TWPRTFDataCollection Create Table from Database ......................................................................................................................................................... 112 Print Watermarks ......................................................................................................................................................... 115 Use "External Pages" ......................................................................................................................................................... 120 Images ......................................................................................................................................................... 123 Provide a Graphic Popup Menu .................................................................................................................................................. 125 Linked I .................................................................................................................................................. 127 mages Technical Information .................................................................................................................................................. 127 TWPTextObj w ith custom draw event ......................................................................................................................................................... 128 Working ......................................................................................................................................................... 130 w ith multiple threads Create Text Paths ......................................................................................................................................................... 131 Syntax Highlighting ......................................................................................................................................................... 133 TWP SynE ighlight .................................................................................................................................................. 134 ditH TWP CustomSyntax (added to WP .................................................................................................................................................. 134 Tools 6) TWP LSyntax XM .................................................................................................................................................. 135 TWP LR XM .................................................................................................................................................. 136 TFSyntax TWP FieldSyntax .................................................................................................................................................. 136 TWP FieldBandSyntax .................................................................................................................................................. 136 Auto capitalisation ......................................................................................................................................................... 136 Search&Replace Text ......................................................................................................................................................... 137 CPChar, CPMoveNext, etc. ......................................................................................................................................................... 140 Share Styles betw een TWPRichText ......................................................................................................................................................... 141 Multiple Editors for the Same Text ......................................................................................................................................................... 142 Use TWP.................................................................................................................................................. 143 RTFStorage Create Multi View in Code .................................................................................................................................................. 144 Work w ith sub paragragraphs ......................................................................................................................................................... 144 7 BCB Notes ................................................................................................................................... 147 Example: Create dynamic TWPCustomRTFEdit ......................................................................................................................................................... 148 Example: Create image object and insert ......................................................................................................................................................... 149 8 Label Priniting ................................................................................................................................... 149 LabelDef......................................................................................................................................................... 149 Vertical .................................................................................................................................................. 151 UnitI nch.................................................................................................................................................. 151 sI Top .................................................................................................................................................. 151 StartNr .................................................................................................................................................. 151 SheetWidth .................................................................................................................................................. 151 SheetHeight.................................................................................................................................................. 152 Row Count .................................................................................................................................................. 152 © 2004-2008 WPCubed GmbH - Munich, Germany
  • 5. Contents IV R ight .................................................................................................................................................. 152 P adding .................................................................................................................................................. 152 N e am .................................................................................................................................................. 152 Lef t .................................................................................................................................................. 153 LabelWidth .................................................................................................................................................. 153 LabelHeight .................................................................................................................................................. 153 Horizontal .................................................................................................................................................. 153 Colum .................................................................................................................................................. 153 nCount Caption .................................................................................................................................................. 153 Bottom .................................................................................................................................................. 154 AsText .................................................................................................................................................. 154 Active .................................................................................................................................................. 154 Example ......................................................................................................................................................... 154 Project I nitialization .................................................................................................................................................. 155 After changing sheet size and margins .................................................................................................................................................. 155 Change of column count or row count .................................................................................................................................................. 156 Change of label w idth and height .................................................................................................................................................. 156 ReadP .................................................................................................................................................. 156 rops and StoreP rops 9 HTTP Interface ................................................................................................................................... 157 Form Setup ......................................................................................................................................................... 158 Unit Initialization ......................................................................................................................................................... 159 User Action and History Management ......................................................................................................................................................... 160 Load Method......................................................................................................................................................... 160 Webbrow ser w ith WPTools ......................................................................................................................................................... 162 Source View......................................................................................................................................................... 162 10 MIME Import / Export ................................................................................................................................... 163 Reader / ......................................................................................................................................................... 164 Writer Demo ......................................................................................................................................................... 164 11 PDF export with wPDF ................................................................................................................................... 165 Export to......................................................................................................................................................... 166 PDF Export using dialog ......................................................................................................................................................... 167 Export using PaintRTFPage() ......................................................................................................................................................... 167 Create edit / memo fields ......................................................................................................................................................... 169 Create a ......................................................................................................................................................... 169 check box field Create embedded data objects ......................................................................................................................................................... 170 12 Adding Spellcheck ................................................................................................................................... 171 Use WPSpell ......................................................................................................................................................... 172 13 WPReporter Addon ................................................................................................................................... 174 Comparison to "usual" reporting ......................................................................................................................................................... 175 Calculation in Text and Tables ......................................................................................................................................................... 176 Reporting w ith WPReporter ......................................................................................................................................................... 178 WPReporter - step by step ......................................................................................................................................................... 181 WPReporter Events ......................................................................................................................................................... 188 Convert text into template ......................................................................................................................................................... 190 Reporter......................................................................................................................................................... 192 and Bookmarks Token to......................................................................................................................................................... 192 Template Conversion General Syntax - Fields .................................................................................................................................................. 193 Syntax Highlighting .................................................................................................................................................. 194 Bands .................................................................................................................................................. 195 Groups .................................................................................................................................................. 195 Parameters for Fields .................................................................................................................................................. 196 Parameters for Bands and Groups .................................................................................................................................................. 197 © 2004-2008 WPCubed GmbH - Munich, Germany
  • 6. V WPTools Version 6 Example Template .................................................................................................................................................. 197 14 WPPremium Addon ................................................................................................................................... 199 Text boxes ......................................................................................................................................................... 200 Footnotes ......................................................................................................................................................... 201 Columns ......................................................................................................................................................... 201 15 Trouble Shooting ................................................................................................................................... 202 Part VIII Reference 202 1 Reader and Writer ................................................................................................................................... 203 2 TParagraph API ................................................................................................................................... 204 TParagraph Properties ......................................................................................................................................................... 204 TParagraph Methods ......................................................................................................................................................... 207 AppendParCopy ......................................................................................................................................................... 214 3 TWPRTFDataCursor ................................................................................................................................... 215 Drop-Markers ......................................................................................................................................................... 215 Attribute......................................................................................................................................................... 217 Interfaces 4 Manage Style Properties ................................................................................................................................... 223 List of 'A' methods ......................................................................................................................................................... 224 ASet/GetBorder ......................................................................................................................................................... 226 5 WPAT_codes ................................................................................................................................... 227 Character Attributes ......................................................................................................................................................... 227 Paragraph Attributes ......................................................................................................................................................... 229 Numbering Attributes ......................................................................................................................................................... 230 Border Attributes ......................................................................................................................................................... 231 Table Size and Position ......................................................................................................................................................... 233 Part IX Notes for Upgraders 234 1 Updated Rendering and Formatting ................................................................................................................................... 236 2 Changed Unit Names ................................................................................................................................... 236 3 Changed Classes ................................................................................................................................... 237 4 Changed Pointers ................................................................................................................................... 237 5 Changed GUI elements ................................................................................................................................... 238 6 New Border Handling ................................................................................................................................... 239 7 Changed Style Handling ................................................................................................................................... 240 8 BackgroundImage ................................................................................................................................... 240 Part X Release Notes - WPTools 6 240 Part XI Release Notes - WPTools 5 243 Index 261 © 2004-2008 WPCubed GmbH - Munich, Germany
  • 7. What is WPTools? 1 1 What is WPTools? WPTools is a word processing component for Borland Delphi and C++Builder. It loads and saves RTF files. Its RTF implementation is one of the most complete on the component market (header/footer, paragraph styles, optional footnote support, table header rows). The "premium" edition also does columns, text boxes and footnotes. But it does not only serve to edit text, it is a powerful toolset for mass mailing and, optional, RTF reports. If you need a text component for Microsoft Access(TM), VisualFox PRO(TM), VisualBasic (TM) or .NET please use our new word processing component TextDynamic. This component has been esspecially created for .NET. It offers the same word porcessing features as WPTools Version 6 does. The concept of the programming API is similar. The .NET version does not use an OCX but an assembly written in C#, but an OCX is also included at no extra charge. Info: www.textdynamic.com If you need word processing or text conversion features (RTF to PDF, HTML to PDF, RTF to HTML) on a server (ASP) or with .NET or as ActiveX please check out our product RTF2PDF / TextDynamic Server. It now includes the same powerful API as used by TextDynamic. The History The first version of our product was released on the Delphi market in January 1996. Over the years it has evolved further to become what you now see. First of all, HTML and WYSIWYG support was added, later we also added the page layout view and fast zooming. At the beginning of 2004 version 4.22 was released - it was the last release of a WPTools version which was still partially based on the RTF Engine created in 1996. During 2003 and 2004 the WPCubed GmbH, managed by Julian Ziersch, developed a new word processing engine. This new engine was constructed to provide solutions for the wide variety of demands which were raised over the last 8 years and addresses issues which could not be solved within the framework of the old WPTools engine. WPTools has been quite successful over the last 8 years and was used in a multitude of projects, both large and small. It is the only text editor which was developed in native Delphi and which supports WYSIWYG page layout view (with WYSIWYG header and footer), including support for tab stops. The competition continues to struggle to achieve the standard set by WPTools, thus demonstrating that the original concept was very good. So why was this rewrite necessary? In-depth modifications were required to add support for new features, such as nested tables. Plus, potential .NET compliancy made it necessary to remove pointer aritmetic completely. This had been very important in 1996 to enhance performace and because the compiler did not support arrays with variable lengths. Furthermore, some parts of the programming interface had become redundant over the years and last, but not least, CSS and XML development brought new ideas to word processing, which could only be implemented in a complete re-write. WPTools 4 had heaps of functionality, but a great deal of it was developed in an ad-hoc © 2004-2008 WPCubed GmbH - Munich, Germany
  • 8. 2 WPTools Version 6 manner - a problem arose and we provided a solution. But the various solutions provided did not necessarily gel consistently into an integrated framework and the planned architecture of the engine. In the end we decided it would be a good idea to take advantage of the opportunity to develop a new RTF-Engine to fulfill the needs which had arisen within a structured environment. The new RTF-Engine was first used for WPTools 5. WPTools 6 is build upon the stable WPTools 5 kernel, but introduces several interesting new features. We also optimized the engine to improve load and save times. WPTools 5 is still serviced but new features will go exclusively into WPTools 6. The migration from WPTools 5 to WPTools 6 is made as easy as possible. What does WPTools Version 6 do? a) Word processing (WYSIWYG, page layout view, headers + footers, tab stops, paragraph styles, UNICODE). b) Special text editing tasks - most importantly, editing one text stream with multiple editors which can be on different forms. c) Reporting - WPTools has the ability to dynamically create and display text during page formatting. This makes it possible to display calculated sums in dynamic table footers. Because the display changes after each reformat, this is an ideal solution for creating invoices since the report is completely editable! d) Preview - The developer can insert pages from any source (owner drawn) into the displayed pages. This way it is possible to mix these pages with RTF pages and preview and print them all at once. It is also possible to have an editable text, followed by a report created by the specialized reporting engine and preview everything in the same editor! e) Spread sheet - WPTools has incredibly powerful and fast table support. It is fast enough to hold thousands of rows! f) Mail merge - It is possible to merge in text, plain or formatted and also images. g) HTML editing - WPTools supports additive paragraph attributes which makes it perfect for this task. In contrast to other solutions which completely import or export the HTML properties, the form of the imported HTML text remains intact. h) Automatic text creation. The new TableAdd function is very easy to use but still very powerful. As we prove in our "ThreadSave" demo the text creation can take place in sub threads. i) new: Integrated Label printing. j) new: Alternative formatting routine to display web pages. k) new: MIME support (based on Synapse). l) new: integrated HTML and XML syntax highlighting. m) new: automatic HTTP download (based on Synapse) n) new: PREMIUM version only: Application Server Mode o) new: better Clipboard control and security p) improved section support q) other additions to API and various code optimation. r) Optimized GUI - it is possible to use a marquee effect in the window © 2004-2008 WPCubed GmbH - Munich, Germany
  • 9. WPTools 6 new features 3 2 WPTools 6 new features WPTools 6 includes many improvements to the editor and general working experience. It has an enhanced API. But it is also compatible to WPTools 5 and we tried to make the upgrade as smooth as possible. This are the most notable new features: 1) Application-Server-Mode WPTools 6 introduces a feature which is called "Application-Server-Mode". This is only available when you have the PREMIUM version. This mode is activated when true is assigned to the global boolean variable WPAppServerMode. When this mode is activated the editor does not use the double buffered output anymore. While this can cause some flickering the network traffic is reduced when the application runs on an application server, such as Citrix. Please note, effective with WPTools 6 software which was written for application servers (such as clinic software) may only be distributed when a TEAM or SITE license of WPTools was acquired. 2) Integrated Label Printing When activated the integrated label printing shows multiple labels on one virtual sheet of paper. The cursor can move from label to label freely. The user can so edit the labels, add new or delete unwanted labels before the complete sheet is printed. This is a very unique and versatile feature. 3) Additions to the PDF export with wPDF V3 Create embedded data objects Create edit / memo fields Create a check box field Also the creation of PDF tags was enhanced. So now hints to paragraph styles will be also exported. 4) Additional Control over Clipboard Actions a) properties to select the format b) added security 5) Added section API + WPRichText1.ActiveSection + WPRichText1.InputSection + TWPPagePropDlg has new method ExecuteEx. Use it to change current page size or Section WPPagePropDlg1.ExecuteEx(WPRichText1.ActiveSection); 6) Load over HTTP connections (requires Synapse) 7) Load and save MIME encoded HTML with embedded images (requires Synapse) 8) Integrated XML syntax highlighting 9) WPReporter: Token to Template conversion with syntax highlighting 10) Scroll with middle mouse button © 2004-2008 WPCubed GmbH - Munich, Germany
  • 10. 4 WPTools Version 6 11) Premium Edition: Now Column Balancing is now supported 12) draw gradient effect in background of editor 13) XML editor mode here w e use a style sheet to auto format the embedded texts, in this case the style sheet Lemma{font-family:'Courier New';font-weight:bold;color:red} Entsprechung{font-family:'Tahoma';font-size:13.00pt;} 14) new Insert Symbol Dialog © 2004-2008 WPCubed GmbH - Munich, Germany
  • 11. WPTools Version 6 5 3 WPTools Version 6 WPTools Version 6 has an entirely new RTF Engine, compared to WPTools 1 to 4. This makes it much easier to work with the paragraph text and offers an object-oriented approach whenever such an approach is beneficial. Please read chapter "Release notes", "Data Structures" and "Quick Start". The new data model supports a separation between data and editing logic. This makes it possible to attach multiple editors to one text object in order to view different parts of the same text. This feature can be used to create a split view of the same text or, even more interesting, to link different editors to specific pages. This feature can also be used to edit text paths in DTP applications. The result is a suite of components with a combination of features you will not find available in any other single component package. New concepts found in WPTools Version 6 include: · storage of character attributes in a special record which is assigned to the character which uses these particular attributes. This makes it easy to copy characters and assign new attributes. Other products use start and end tags to store character attributes with the danger of inconsistency if a tag 'gets lost'. Since WPTools caches the attributes, it does not consume a lot memory for them! · paragraph storage in a linked list with sub-elements (children) - this reflects the document structure of HTML and makes it possible to support HTML/CSS editing. · inherited attributes - in WPTools paragraph and character attributes can be added and removed. If an attribute is not defined the 'default' or 'inherited' value is used instead. For application designers WPTools Version 6 supports · different types of multiple page layout which can be displayed quickly · fast zooming · the possibility of editing ONE text in TWO (or more) windows (split-screen) · effective property dialogs (NEW: The dialogs shade 'undefined' values) · integrated localization · and all important action classes are included. For word processing WPTools Version 6 includes · a vast number of paragraph and character attributes for text (numbering, alignment, indents, spacing - the usual RTF features, but also color and style for various underlines, different border styles, background colors) · strong table support - including the ability to nest tables (table within a table) and merging of table columns and table rows, with support for page breaks within table rows · Repeated table header and footer rows · pictures with text flow on one or (new!) both sides · powerful support for headers and footers · extensive support for paragraph styles · improved support for tab stops - including support for leading signs (.......1.00). · insertion of foreign pages - i.e. pages which are painted by an owner-provided function. These pages appear in the text, but cannot be accessed with the cursor · WYSIWYG · and different layout modes - so powerful that the preview dialog now uses a standard © 2004-2008 WPCubed GmbH - Munich, Germany
  • 12. 6 WPTools Version 6 editor which is switched to read only. It still allows thumbnails and side-by-side page layout views! · Support for "sections" - have different page sizes in one document. · new in V6: Clickable Section marker and dialog For HTML/CSS editing WPTools Version 6 enables · loading of HTML/CSS files · saving of HTML/CSS files · and powerful CSS support - the word processing engine supports inherited attributes and nested tables and paragraphs. · new in V6: Alternative formatting routine to display web pages. · new in V6: Ready to use unit to load over HTTP connection (based on Synapse) · new in V6: MIME support to read *.MSG / *.EML / *.MHT (based on Synapse). · new in V6: Integrated HTML and XML syntax highlighting. For developers WPTools Version 6 is an improvement because it · is not bloatware - in fact WPTools V5 is smaller than WPTools 4! · offers effective memory management. It also supports many more paragraph and character attributes without consuming more memory than the previous version (under the same OS). · is safe for multi-threaded applications · allows the addition of new paragraph attributes · makes it possible to insert 'external' or 'owner drawn' pages into a document · offers support of most RTF features in HTML/CSS file format and vice versa. (Notable exception: Tab stops cannot be coded into HTML/CSS.) · makes it possible to share styles and other properties (color palette, font table) between texts. This makes it easier to work with two synchronized RTF texts. · allows linking of editors to text paths (the text is never copied between these editors). · provides support for Delphi 5, 6, 7 and 2005(Win32), 2006, 2007 · provides support for C++Builder 5 and 6, C++Builder 2006 · provides an effective storage format which produces the minimum amount of RTF and HTML/CSS code possible. · optionally: Support for FastReport 3 & 4 (supports stretching) · optionally: Support for ReportBuilder 9 & 10 (supports stretching) · optionally: Support for QuickReport 4 Optional in WPTools PREMIUM: · editing and printing of footnotes (WYSIWYG!) · text boxes (movable boxes with RTF text. Anchor is in text body) · support for columns (newspaper layout). · Application Server Mode - this mode activates text rendering which does not utilize a double buffer. This makes it possible to minimize the network traffic. Other products in WPTools family: · WPSpell - spell checking highly integrated into the WPTools environment · wPDF - perfect and fast PDF creation, not only from WPTools since it also does conversion of metafiles. Supports PDF/A. · WPViewPDF - display and print the PDF files not only created by wPDF but also several competing products. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 13. WPTools Version 6 7 We hope that you are as satisfied with WPTools Version 6 as we are and that the improvement in your product is worth the effort which may be required for the upgrade to this new version. WPTools Version 6 was built to be the most powerful word processor available on the component market. In addition, it also works as a HTML editor, offering convenient word processing features, while still working as closely to the HTML document model as possible. 4 License 1. NO ROYALTIES F EXE-PROJECTS OR IF YOU ARE REGISTERED YOU HAVE THE RIGHT TO DISTRIBUTE PROGRAMS (EXE-FILES) YOU HAVE CREATED WITH THE HELP OF WORD PROCESSING TOOLS ROYALTY-FREE. YOU MAY NOT DISTRIBUTE MODULES WHICH MAY BE USED BY OTHER (ALSO NOT "INHOUSE") DEVELOPERS (SUCH AS COMMANDLINE TOOLS, VBX, OCX, VCL, DLL, VCL OR ACTIVE-X) WITHOUT WRITTEN PERMISSION. THE LICENSE DOES NOT INCLUDE THE PRODUCTION OF ACTIVE-X MODULES FOR THE USE WITHIN THE INTERNET. THE SOFTWARE SUPPLIED MAY BE USED BY ONE PERSON ON AS MANY COMPUTER SYSTEMS AS THAT PERSON USES. GROUP PROGRAMMING PROJECTS MAKING USE OF THIS SOFTWARE MUST PURCHASE A COPY OF THE SOFTWARE FOR EACH MEMBER OF THE GROUP. THIS DOES *ALSO* APPLY WHEN "ONLY ONE" PERSON IN THE GROUP IS DEVELOPING WITH WPTOOLS! CONTACT JULIAN ZIERSCH FOR VOLUME DISCOUNTS AND SITE LICENSING AGREEMENTS. Note: the distribution license requires: If WPTools is used in a project which is developed by a group of developers, all members of this group must have a WPTools development license! In case only one developer works with WPTools but there are others in the project who work with other development systems, those other developers still need a WPTools license since the work of the first developer is a "Module" for the others. Please note, effective with WPTools 6 software which was written for application servers (such as clinic software) may only be distributed when a TEAM or SITE license of WPTools was acquired. If this condition is not met, the product may not be distributed. If developers join the project, new licenses are required. This license model makes it possible for us to provide and support a product as powerful and versatile as WPTools. 2. THE LICENSE DOES NOT ALLOW PRODUCTION OF MODULES, DLLS, ActiveX OR COMMAND LINE UTILITIES UPON REGISTRATION OF THE STANDARD VERSION YOU WILL RECEIVE 70% OF THE SOURCE FILES FOR VERSION 5.x. YOU MAY ALTER THEM BUT YOU MAY NOT DISTRIBUTE THEM TO ANY OTHER PERSON WHO HAS NOT REGISTERED! YOU MAY NOT DISTRIBUTE WPTOOLS-DCU FILES OR DELPHI/ BCB DESIGNING PACKAGES EITHER. IT IS NOT ALLOWED TO USE WPTOOLS IN COMMAND LINE UTILITIES, SUCH AS TOOLS WHICH DESIGNED TO ONLY RENDER RTF OR HTML - EXCEPT FOR INHOUSE USE. THE USE IN A GENERAL "VIEWER" APPLICATION WOULD BE AGAINST THIS LICENSE. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 14. 8 WPTools Version 6 IF YOU NEED THE COMPLETE SOURCE PLEASE PURCHASE THE PRO OR PREMIUM VERSION! 3. NO REVERSEENGINEERING YOU MAY NOT REVERSE ENGINEER, DECOMPILE, OR DISASSEMBLE THE PRODUCT UNLESS ALLOWED BY APPLICABLE LAW. THE PROVISION OF SOURCE CODE DOES NOT CONSTITUTE A TRANSFER OF ANY LEGAL RIGHTS TO SUCH CODE, AND RESALE OR DISTRIBUTION OF ALL OR ANY PORTION OF ALL SOURCE CODE AND INTELLECTUAL PROPERTY WILL BE PROSECUTED. THIS COMPONENT IS LICENSED FOR USE WITH DELPHI OR C++BUILDER WIN32 ONLY - THE SOURCE MAY NOT BE ALTERED TO BUILD .NET TOOLS OR TOOLS FOR OTHER COMPILERS OR OPERATION SYSTEMS. THE WPTOOLS STANDARD AND STANDARD-PRO VERSION DOES NOT INCLUDE THE RIGHT TO EXTEND IT TO SUPPORT COLUMNS, TEXTBOXES OR THE PRINTING OF FOOTNOTES. THIS IS RESERVED TO THE "PREMIUM" EDITION. THE SAME IS TRUE FOR TEXT BOXES BASED ON OUR LAYER TECHNOLOGY. THE DISTRIBUTION LICENSE FOR CREATED APPLICATION(S) REQUIRE THIS LICENSE AGREEMENT TO BE RESPECTED! 4. YOU MAY NOT RENT, LEASE, OR LEND THIS SOFTWARE COMPONENT. ONCE AN APPLICATION WHICH USES THIS LIBRARY WAS DISTRIBUTED, THE LICENSE MUST STAY WITH THE COMPANY WHICH HOLDS THE DISTRIBUTION RIGHT TO THE DISTRIBUTED APPLICATION. 5. LIABILITY LIMITATION THE DOCUMENTATION AND THE VCL ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR SUITABILITY FOR A PARTICULAR PURPOSE. THE USER ASSUMES THE ENTIRE RISK OF ANY DAMAGE CAUSED BY THIS SOFTWARE. THIS INCLUDES DAMAGE BECAUSE OF INFRINGEMENT OF ANY PATENTS. IN NO EVENT SHALL JULIAN ZIERSCH OR WPCUBED GMBH BE LIABLE FOR DAMAGE OF ANY KIND, LOSS OF DATA, LOSS OF PROFITS, INTERRUPTION OF BUSINESS OR OTHER PECUNIARY LOSSES ARISING DIRECTLY OR INDIRECTLY FROM THE USE OF THE PROGRAM. ANY LIABILITY OF THE SELLER WILL BE EXCLUSIVELY LIMITED TO REPLACEMENT OF THE PRODUCT OR REFUND OF PURCHASE PRICE. GOOD DATA PROCESSING PROCEDURE DICTATES THAT ALL PROGRAMS BE THOROUGHLY TESTED WITH NON CRITICAL DATA BEFORE THEY CAN BE RELIED UPON. 4. COPYRIGHT MESSAGEREQUIRED IF YOUR PROGRAM HAS AN "ABOUT BOX" THE FOLLWING CREDIT SHOULD BE DISPLAYED IN IT: "WPTools (C) Julian Ziersch" or "WPTools (C) WPCubed GmbH" 5 Technical Notes WPTools Version 6 supports Delphi 5,6,7 and 2005, 2006 (Win 32) and Delphi 2007. It also supports Borland C++ Builder 5 and 6 and C++Builder 2006. Delphi 3 and 4 are not supported since the code requires modern language features, such as method overloading. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 15. Technical Notes 9 If you need a text component for Microsoft Access(TM), VisualFox PRO(TM), VisualBasic(TM) or .NET please use our new word processing component TextDynamic. Info: www.textdynamic.com. For ASP and ASP.NET we have RTF2PDF / TextDynamic Server. This component includes most of the prowerful interface methods TextDynamic has. Please check out our demo webserver at http://www.rtf-net.com/ The code uses pointers only in very few functions - mainly to optimize the performance. The reader and writer classes do not use static buffers. The use of global variables has been limited. The most important ones are stored in the TWPToolsEnviroment object. By creating several instances of this class it is possible to create a threadsave application. (See demo ThreadSave) WPTools Version 6 has been designed for modern PCs. The Text rendering engine requires an up-to-date graphics adapter. We recommend a CPU with at least 500Mhz. The Memory consumption has been highly optimized. It is equal or less than with WPTools 4. The general text editing functionality require Windows 98 or later. Unicode support was tested with XP only - special word wrap rules for unicode text have not been implemented, such as Japanese rules. Support for RTL languages is limited (experimental). For questions about WPTools Version 6 please use our web based forum: Discussion FAQ: Questions when upgrading FAQ: General You will find the Release notes at the end of this manual. 6 PDF Products WPCubed GmbH also markets this PDF products: wPDF: Powerful and versatile PDF creator for Delphi and C++Builder. It supports WPTools (see "PDF export with wPDF") and the most important Delphi reporting engines. Also converts metafiles into PDF data. New Features in wPDF Version 3 · Support for standard brush styles (hatching) · TransparentBitBlt · Automatic reuse of the same image data. This way, when you export a document which often uses a logo the PDF file will be significantly smaller! · Creation of PDF/A complient PDF files (with added meta data and PDF © 2004-2008 WPCubed GmbH - Munich, Germany
  • 16. 10 WPTools Version 6 tagging when you use it with WPTools) · Support of CID fonts (known as "unicode" support) · Binary Data embedding: You can store the document source which was used to create a PDF file within this PDF file. When you use WPTools for the PDF creation you can store the RTF source document inside of the created PDF data, the user only has to click on an icon to extract this document. This can be a great feature if you use it to embed programming examples within your programming manual! WPViewPDF: To view, print and manipulate PDF files right in your Application our product WPViewPDF Version 2 may be interesting for you. It is not only usable with . NET and as ActiveX, but also in Delphi and C++Builder. This component was created to view PDF files which were created using the wPDF engine, but it is also capable of viewing PDF files created with other windows based engines which utilize TrueType(tm) fonts. In contrast to many competing solutions WPViewPDF is very fast. You can also use WPViewPDF to convert PDF to EMF and to convert PDF to JPEG. New Features in WPViewPDF Version 2 · now with bookmark tree · now text selection and copy to clipboard is supported · auto scrolling (use middle mouse key). · Optionally high quality font rendering of embedded Type1 and TTF subset fonts WPViewPDF PLUS: With the PLUS license you can save the PDF information from WPViewPDF which makes it a versatile pdf conversion software. This means you can load in multiple PDF files and save all pages into a new PDF file (=pdf merge, edit pdf). Certain pages can be marked to be deleted, they will not be displayed by WPViewPDF. When you save the PDF file this pages will be removed. It is also possible to set new security properties (apply, remove encryption) and set property strings int this pdf conversion tool. The WPViewPDF Demo has the PLUS features enabled, but when a new file is created a red cube will be printed on all pages. With the "PLUS" version it is possible to add text and vector graphics to certain pages of a PDF file (pdf stamping). Any text will be converted to vectors - this allows it to use special fonts. The graphics will be already visible in the viewer before the PDF data has been updated! © 2004-2008 WPCubed GmbH - Munich, Germany
  • 17. PDF Products 11 NEW: it is also possible to read and modify Acro Form field in PDF files! WPViewPDF: merge, split, stamp, encrypt, decrypt PDF files! 7 Guide In this chapter we collected introduction texts to important tasks which can be solved with WPTools. We recommend to also review the HLP file since it contains a structured list of all classes, properties and methods. It also contains 'Categories' which are a big help. In chapter 'Tasks' we will explain how to create the first small editor, how to use mail merge, how attach a generic toolbar using actions and much more. There is also an introduction to WPReporter . Please check out the demos which are described in this chapter: Mini Editor - shows how to create a small, yet powerful editor Create Table in Code - demos the most effective way to create tables in code TBX Demo - how to use WPTools with TBX, the toolbar 2000 extension GridMode - how to create tables dynamically from a database DynAssign TWPRTFDataCollection (create MDI app without MDI windows) ParStyle - this demo shows how to work with the CSS like paragraph styles Localization - how to localize (translate) the dialogs and messages. Also see the Programming Overview . QuickStart © 2004-2008 WPCubed GmbH - Munich, Germany
  • 18. 12 WPTools Version 6 After having dropped the TWPRichText you can click right to use the QuickConfig dialog: [the WPTools Propery Dialog] © 2004-2008 WPCubed GmbH - Munich, Germany
  • 19. Guide 13 © 2004-2008 WPCubed GmbH - Munich, Germany
  • 20. 14 WPTools Version 6 Loading and Saving To load text into the editor You can use the functions LoadFromFile, LoadFromStream and also the properties AsString and SelectionAsString (the latter inserts the text). To move the cursor before the insertion or after the load modify the property CPPosition. To save the text You can use the functions SaveToFile, SaveToStream and AsANSIString. The function AsANSIString is useful to convert the text into a data string of a given format, i.e. AsANSIString('HTML') will create a string with HTML tags. If the load and save functions ask for a second string parameter this is a "format string" - please read more here http://www.wpcubed.com/manuals/formatstrings.htm In our web based forum we have posted several FAQ topics and articles. The article "Compose an e-mail in HTML format / Save image to HTML" shows how to create a HTML e-mail. The WPRichText component implements several functions which open a dialog box: Load, Save, SaveAs, InsertGraphicDialog and Insert. 7.1 Localization - change Language in Dialogs For anyone wanting to work with inch units, please add the following line in your code (for example, in the FormCreate event). GlobalValueUnit := euInch; WPTools Version 6 supports the localization of the texts which are used for filters and error messages and also the localization of the provided property dialogs. Steps to update the dialog language in WPTools 5 and 6: We start with a simple form: Now w e add the component TWPLanguageControl to the form © 2004-2008 WPCubed GmbH - Munich, Germany
  • 21. Guide 15 A double click opens the XML editor. Here we can load (and merge in) the language files which are provided under DemosTasks Localization. Close the form with File/OK Please note that the properties Active, AutoLOadString and AutoSaveStrings are not supported in WPTools 5 or WPTools 6. Here we need to create a COM interface like this: Add the units WPUtil and WPActnStr to the uses clause. To active use this code in the OnCreate event of the form: procedure TForm1.FormCreate(Sender: TObject); begin WPLangInterface := TWPLocalizationInterface.Create(WPLanguageControl1); WPLanguageControl1.GlobalLanguage := 'DE'; WPLocalizeLoadForms := TRUE; WPTools_LoadVCLStrings; WPTools_LoadActionStrings; end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 22. 16 WPTools Version 6 In the OnDestroy event add this: procedure TForm1.FormDestroy(Sender: TObject); begin WPLangInterface.Free; end; Done: We have hints in German: And Dialogs, too: To change the language at runtime use code like this: WPLanguageControl1.GlobalLanguage := 'DE'; WPLocalizeLoadForms := TRUE; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 23. Guide 17 WPTools_LoadVCLStrings; // from unit WPUtil WPTools_LoadActionStrings; // from unit WPActnStr You need to create the TWPLanguageControl and the Interface on the Form which is created first in the project. If necessary You can put it into a Datamoduel. How does the localization work? In WPTools Version 6 we are using a localization interface which is defined as: IWPLocalizationInterface = interface ['{A12EF1F7-E592-4483-855F-67E28332AFC5}' ] // This method can be used to save the menu items and captions on a certain form. I f you use the TWPLocalizeForm class you don't need to care about that. } procedure SaveForm( const Name: string; Form: TWinControl; Menus, Captions, Hints: Boolean); // Load all Components on a certain TForm. } procedure LoadForm( const Name: string; Form: TWinControl; Menus, Captions, Hints: Boolean); // This method saves a string list under a certain name. The string list has to use the syntax NAME=xxxn } procedure SaveStrings( const Name: string; Entries: TStrings; Charset: Integer); // Loads back the string(s) saved with WPLangSaveStrings } function LoadStrings( const Name: string; Entries: TStrings; var Charset: Integer): Boolean; // Method to save a certain string. To save multiple strings use WPLangSaveStrings procedure SaveString( const Name, Text: string; Charset: Integer); // Loads back a string saved with WPLangSaveString function LoadString( const Name: string; var Text: string; var Charset: Integer): Boolean; end; This interface is implemented by the TWPLanguageControl. The TWPLocalizeForm (implemented in unit WPUtil, it is the anchestor of all localizable dialogs) automatically uses this interface through the instance of the TWPLocalizationInterface class which must be created by your code: WPLangInterface := TWPLocalizationInterface.Create(WPLanguageControl1); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 24. 18 WPTools Version 6 7.2 Programming Overview/QuickStart This topic should help you to find the correct procedures and properties in the reference manual when you start programming with WPTools. Please note that the reference defines categories. When you found one property you can browse the list of topics in the same category (link to list of all categories). Also see: Mini Editor Hyperlinks Save to HTML / Load from HTML Hover Effects Localization/Translation Bookmarks Mailmerge and forms Printing - how to set printer properties Create Field Superprint: Print Booklets and Labels Merge: Change Field Text/Read Field Text Print Labels (TWPSuperPrint) Merge: Insert/Modify Image Print/Edit elements of TWPRTFDataCollection Modify Field Name or Contents Create Table from Database Create text with multiple letters Print Watermarks Hide empty paragraphs Use "External Pages" Forms/Edit Fields Images Create ComboBox Provide a Graphic Popup Menu How to use the "Default Editor" Linked Images Toolbar and Action Classes Technical Information Localization TWPTextObj with custom draw event Layoutmodes Working with multiple threads Header and Footer Create Text Paths Create Sections Syntax Highlighting Use WPTools5 with TBX (Toolbar2000 Extension) Search&Replace Text Set Attributes in code (unit WPCreateDemoText) CPChar, CPMoveNext, etc. Tables PDF export with wPDF Set width in inch of a certain column Multiple Editors for the Same Text Work with % width Use TWPRTFStorage Create Table in Code Create Multi View in Code Work with Styles and Stylesheets (in code) Work with sub paragragraphs Numbering 7.2.1 Modify the look and feel of the editor Please use the properties ViewOptions, EditOptions and EditOptionsEx. The properties FormatOptions and FormatIOptionsEx change how the formatting routine works, they have a significant influence on how the text appears. Please also see the Layout Catagory. To change the language (for localization, translation) please see demo "Lozalisation". © 2004-2008 WPCubed GmbH - Munich, Germany
  • 25. Guide 19 7.2.2 Change current writing mode See property WPRichText.CurrAttr, here you can set attributes such as Bold, Italic etc. using AddStyle and DeleteStyle. CurrAttr also controls the paragraph attributes (Alignment) indents and spacing. CurrAttr will change the current writing mode or the selected text - if text is selected. See this FAQ if you want to implement ShortCuts, such a Ctr+B = bold. WPTools Version 6 also has more specialized attribute interfaces. They can be used to only change the current attribute, only the selected text, the attributes of the text which was found by "Finder" or the attributes of merged text. (Attribute Interface Category) 7.2.3 Move the Cursor Please use the CP.. properties. CPPosition is the current character position, assign 0 to go to the start, MaxInt to go to the end. Also procedure MovePosition is very useful. When the user changes the cursor position the event OnChangeCursorPos is triggered. 7.2.4 Change Page Size and Page margins Modify WPRichText.Header. The properties with "default" in their name are the values which will be applied by Clear, the others are the current values. Method SetPageWH can be used to set several values at once, the values which should not be changed can be passed as -1 7.2.5 Insert Text Use the method InputString() to insert text at cursor position. The char codes #13 will create a new paragraph, #12 a new page. To create a table use TableAdd (). Also see the chapter Set Attributes In Code. 7.2.6 Mail Merge (replace fields with data) This is done by once procedure, MergeText and the event OnMailMergeGetText. If you have a text with fields marked with special characters (<name>) use method ReplaceTokens. Otherwise crate fields with method InputMergeField . Note, that mail merge fields are embedded into two instances of the TWPTextObj class. This FAQ shows how to work with images. Note: If you need to print (or export to PDF) the text right after the merge process you need to call ReformatAll(false, true)! 7.2.7 Input TextObjects (i.e. page numbers) This objects can be create with InputTextField(type) and InputTextFieldName(name). All text objects can show custom text which is define by event OnTextObjectGetTextEx. Custom text objects will usually display the text assigned to their property Params. 7.2.8 Create an own toolbar If you decide to not use the toolbar we provide please open unit WPCtrRich.PAS and check out method OnToolBarIconSelection. This method is executed for all toolbar button clicks and WPTools actions. You can see how things are done. You can also call this method from "outside". 7.2.9 Save and load HTML HTML is autotected when using the LoadFromFile or LoadFromStream methods. Images must be directly linked to local files. Otherwise the image must be loaded in the event OnRequestHTTPImage . (This event is also execoted for images in RTF files which have not been embedded but just linked.) Also see this FAQ and the info about format strings. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 26. 20 WPTools Version 6 7.2.10 Get and set the text "as string" Use the property AsString - you can use SelectionAsString to read only the selected text. You can also assign text - the property SelectionAsString will insert the text at the cursor position. The function AsANSIString will work like property AsString but you can specify the format string, optionally only save the selection. Also see the load & save category. 7.3 Data Structures Here is a general description of the architecture and concept of the RTF engine, for your reference. Please read this carefully! This knowledge is necessary for you to understand WPTools Version 6. Note: the separation between edit/display and data-objects make some elegant solutions possible - ie. create MDI editor without using MDI windows! (See demo DynAssign ) Since not all details are listed here, please look for further information on the classes written in bold in the online help (reference). In the WPTools RTF-Engine (we always refer to the 'RTF-Engine', however this does not mean that the engine is limited to the Rich-Text, *.RTF), a text is split up into several parts. The main parts are stored in two objects which are linked together: a) RTF Data is stored in the TWPRTFDataCollection(see: Multiple Editors for the Same Text) b) RTF properties, such as paragraph or number styles, are stored in the TWPRTFProps object. (see: Share Styles between TWPRichText) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 27. Guide 21 Note: This concept allows multiple TWPRTFDataCollection objects to share the same TWPRTFProps object. Thus, they share the same attribute identifier (such as index values for colors). If you use this feature you can simply copy texts parts between RTFData objects or compare text. The TWPRTFDataCollectionalso hosts the text cursor (TWPRTFDataCursor) and a few parameters which are shared by the RTF editors (TWPRTFDataCollectionEngineParams). This means that even if you have several editors using one TWPRTFDataCollection there is only one cursor which is the same for all editors attached. The cursor object also controls text selection and changing properties of the selected text (SelectedTextAttr : TWPSelectedTextAttrInterface or the) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 28. 22 WPTools Version 6 current writing mode (CurrentCharAttr : TWPCursorCharAttrInterface). It also contains the CPAttr ( TWPTAttrEmulator) interface which changes the attribute at the cursor position. (Please see last inheritance chart and "Character Attributes" below) The TWPRTFDataCollection is home to the TWPRTFDataBlock collection items. Such an item contains the text which is displayed. The text body and the header or footer texts are all different collection items. When a new text is loaded, it is first loaded into a new TWPRtfDataBlock and, if everything is all right, then inserted into the body. The editor can display any of the RTFDataBlocks, or even display several at once. The TWPRTFDataBlock contains the text within a nested list of TParagraph objects. The TParagraphobjects are linked using the references NextPar/PrevPar and for nested dependencies, ChildPar/ParentPar references. Note: WPTools 4 only supported linking in one level using next/prev pointers. The new TParagraph object contains functions to emulate these pointers. Using this function it is still very easy to create a loop which checks all paragraphs in a text. The first paragraph is referenced by the property FirstPar. The TParagraph class inherits the complete functionality of the TWPTextStyle class which contains the code to maintain attributes and tab stops. The TWPTextStyle class is also used by other classes which need this functionality. How does TParagraph store the text? The text is separated into characters, character attributes and objects. Each of these elements is stored in its own dynamic array. For the characters an array of WideChar is used, the character attributes are stored in an array of cardinal (double word) values. When objects are used, you can read the TWPTextObject for a certain position in the paragraph using the array ObjectRef. The count of elements is stored in the variable CharCount. Note: The TParagraph class has several functions to insert and delete text and objects. In the instance that it is part of a table, TParagraph also has functions to find other parts of the same table (rows, cells or the parent table object). The memory architecture of a table is very similar to the system used by HTML: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 29. Guide 23 (All rows of a table and all cells of one row are connected using NextPar/PrevPar, the levels are created using ChildPar/ParentPar.) There are also useful properties which provide reference to the parent row or the parent table of a cell, or, for cells which are in a nested table (= table in a table cell), to get the first level ("ParentParent") row or table. To copy the first row of a table after the current row you can use this simple code: current_row.NextPar := current_table.RowFirst.Duplicate(true, true); In this code the first row is duplicated and inserted into the chain of rows by assigning it to the NextPar property. Duplicate() needs two parameters, the first enables the copying of the text (othwise only the properties are copied) the second enables the copying of the children, in case of a table row this are the cells. Paragraph Attributes: WPTools Version 6 supports many different paragraph, table and border attributes. These attributes are identified by a code, the WPAT_code. (The constants all start with WPAT_). It is important to remember that not all property ids make sense in all TParagraph objects, for example a table row cannot use the column width property. Some properties override each other (WPAT_ColWidth override WPAT_ColWidth_PC) and some are reserved for future versions. To read a, attribute you can use the method TParagraph.AGet( code, value ). 'Value' is passed as var parameter (by reference) and is only modified if that property was defined by this TParagraph or TWPTextStyle. In case the property was defined the function AGet returns true, otherwise false. Alternatively you can use the function AGetDef( code, default_value ). Here the value of the property is returned if defined, otherwise the provided default value. There are more 'A' methods, to delete a property (ADel), to read the properties of the paragraph or the style it uses (AGetInherited), to read and set a color value (AGetColor, ASetColor). Please see the TParagraph reference in the HLP file. Important: The method TWPTextStyle.AGet(WPAT_code : Integer; var Value : Integer) is a functions which returns a boolean value. The return code is false if the property with the id WPAT_code was not defined. In this case the variable "Value" will not be modified! Please make sure you initialized the variable Value! Tabstops: Tabstops are not stored as WPAT_ properties. They are accessed through several methods, such as TabstopAdd, TabstopMove or TabstopGet. (See reference) Character Attributes: As stated character attributes are stored in just one double byte value. You may ask, 'How can this work?' Particularly since WPTools Version 6 supports 15 different character attributes with multiple settings possible for each of these. WPTools Version 6 does not save the attributes directly in this CharAttr value. It only saves an index there. This is then used to retrieve the actual attributes from a global attribute cache. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 30. 24 WPTools Version 6 We find this concept ideal - other text editors use start/end tags to store character attributes, others even split up the text into elements which are using the same combination of attribute styles. In both cases it is extremely difficult to 'apply' a certain attribute to text. Our concept makes it possible to simply set a number value and the style is changed. If styles have to be updated, the interface classes, such as TWPAbstractCharAttrInterface, make it easy to create and use the index values. WPRichText1.AttrHelper.Clear; WPRichText1.AttrHelper.SetFontName( 'Courier New') ; WPRichText1.AttrHelper.SetColor(clGreen); WPRichText1.ActiveParagraph.SetText( 'Some green text', WPRichText1.AttrHelper.CharAttr); WPRichText1.DelayedReformat; Explanation: AttrHelper is an obj ect of class TWPStoredCharAttrInterface. It calculates "CharAttr" index values. 'Clear' will delete all attributes - the CharAttr index will be 0. SetFontName and SetColor are used to define new character attribute. Reading the property CharAttr (inside the call to the TParagraph method SetText) will create a new CharAttr index which is used for the text. The calculated CharAttr can be used at different places for text which should look the same. It will become invalid when the document is cleared by TWPRichText.Clear. Read more... Inheritance Charts: TWPRichText, the RTF memo and TWPRTFEnginePaint, the RTF Engine (used by the TWPRichText as object 'Memo', the TWPRichTextLabel inherits from it) Please note that we now use format strings to pass properties to the reader and writer classes. Example: WPRichText1.AsANSIString('RTF-onlybody') creates a string in RTF format which contains only the body text. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 31. Guide 25 To update TParagraph and TWPTextStyle objects you will have to use the "A" methods (ASet, AGet) - the interface classes are only used to either change the current writing mode or the attributes of multiple paragraphs and characters (such as selected text). All classes which change the attribute of certain elements inherit from TWPAbstractCharAttrInterface. In cases where it makes sense the classes are also able to change paragraph attributes as well. The only exception is TWPAttrEmulator, which does not work like the other interfaces since it is mainly used to offer compatibility to the WPRichText.CPAttr pointer in WPTools 4. 7.4 WYSIWYG The word WYSIYWG abbreviates What You See Is What You Get - which means that the printed output of an application which supports WYSIWYG will match the screen output it displayed before. WPTools Version 6 will always work in WYSIWYG mode, this means the printed output will always match the output you saw in the editor. Making this work is actually a quite complicated task and the editing engine has to be well prepared for it. The concept of WPTools5 was created from ground up to allow several WYSIWG modes: a) Default: render for best screen and best printing quality b) Render for optimal printing quality c) Render for optimal screen quality - print quality can be low © 2004-2008 WPCubed GmbH - Munich, Germany
  • 32. 26 WPTools Version 6 Usually you do not have to change anything - but we recommend to add a switch to the application to activate mode (b) - simply execute TWPRichText1.Memo.RTFData.UpdateReformatMode(true) . Now the RTF-Engine will use the current printer to measure the fonts. For special printer fonts this can make a big difference for the output quality. To work with mode (c) you can simply set the flag wpfAlwaysFormatWithScreenRes in the property FormatOptions of the TWPRichText. If you know that there is no printer available for the application, you can set the global boolean WPNoPrinterInstalled to true. This property is automatically initialized by using the windows EnumPrinters() API. Please note that the property WordWrap disables WYSIWYG. If this property is set to TRUE this means that the text is formatted to the width of the editor, not the paper size defined in the property Header or the section. When WordWrap is set to false, word wrapping is still performed, but not using the width of the editor but the defined page size. You can, of course, set WordWrap to false and still modify the page size dynamically (Header.PageWidth according to the size of the editor. In this case WYSIWYG printing is possible, but you probably need to set the flag PrintParameter. PrintOptions := [wpDoNotChangePrinterDefaults] - otherwise the printer will select a custom paper size. Upgrade note: There are no properties ScreenResMode and WYSIWYG in WPTools Version 6, they are not required anymore. Using the mode (a) mentioned above provides good print out quality without the need for a default printer - this solves the problems which used to occur in applications when not printer was available. If the current printer is changed the reformat of the text is not required. WPTools supports many different layout modes. It is possible to see the page with header and footers, several pages side by side, thumbnails, just the body text etc. Please read the chapter about LayoutModes. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 33. Guide 27 7.5 Mail-merge and forms "Mail-merge" means the automatic update of data fields in any document. It can be used to do mass mailing or to create customizable database record views. Concept of mail-merge in WPTools: The text contains merge fields, on command "MergeText" the component locates all fields and triggers the event OnMailMergeGetText for each of it. This event is used to fill data into the field or read out the current contents. Please note, that this concept differs from the usual "search and replace" and is much more verstile and faster. With WPTools merge fields are not destroyed by the merge process, the field data can be exchanged as soon as it changes. So it is possible to scroll through a database with a merge letter being "attached". It is also possible to read out the contents of the merge field. So the document can be also used as data entry from. You can merge in standard ANSI text, formatted text and images. Formatted text may be encoded in HTML, RTF or the WPTOOLS format. Info: Mail merge templates can be converted to reporting templates which use the WPTools WPReporter addon. Three steps to create a working prototype of mail-merge in Your application: 1) Add code to create a field (more...) procedure TForm1.Button1Click(Sender: TObject); begin WPRichText1.InputMergeField('NAME','Default-Name' ; ) end; 2) Provide an event handler for the event OnMailMergGetText (more...) In the created handler please type some lines of code procedure TForm1.WPRichText1MailMergeGetText (Sender: TObject; const inspname: String; Contents: TWPMMInsertTextContents); begin i f inspname='NAME' then Contents.StringValue := 'Julian Ziersch' © 2004-2008 WPCubed GmbH - Munich, Germany
  • 34. 28 WPTools Version 6 else Contents.StringValue := '<unknown>' ; end; 3) Launch mail merge with a different button (more...) procedure TForm1.Button2Click(Sender: TObject); begin WPRichText1.MergeText; end; Demo Projects Please check out the ThreadSave demo to learn how to use mail merge in a thread. There is also the demo project DemosTasksMailM4 which shows how to work with a database and merge multiple records. 7.5.1 Create Field InputMergeField - create a merge field InputEditField - create a form field ReplaceTokens - convert tokens into fields Low Level - create a field in a TParagraph object 7.5.1.1 InputMergeField To create a field use the procedure InputMergeField function InputMergeField( const FieldName: string; const DisplayText: string = ' '; Command: string = ' '; Format: Integer = 0; DisplayChar: Char = # 0 //<-- obsolete parameter! ): TWPTextObj; The parameters are: FieldName = the name of the field. Will be stored in TWPTextObj.Name DisplayText = the text which will be placed inside the field. Will be stored in TWPTextObj. Params. Can be modified in the editor. Command = any text which will be stored in TWPTextObj.Source Format = any integer which will be stored in TWPTextOnj.IParam DisplayChar should be not used anymore. The result of this function is a reference to the TWPTextObj which marks the start of the field. Please note, a merge field always consists of two object, a start and an end object. Only the start object contains the properties of the field. WPTextObj instances can be deleted and restored at any time by the editor. It is not recommended to save the references in a list. To fill a list with reference to field objects you can use the procedure FieldGetList at any time. You can also use the 'Code' API with field objects - for example the procedure CodeListTags. (See reference, HLP) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 35. Guide 29 7.5.1.2 InputEditField WPTools Version 6 also supports 'form fields'. They work like merge fields but if you use a special mode in property ProtectedProp the complete text can be protected, only the text inside this form fields can be edited. To create such a fields use the Method InputEditField. More about forms ... 7.5.1.3 ReplaceTokens ReplaceTokens(const opening, closing: string; FieldPreText: string = ''): Integer; This method (and its sister ReplaceTokensInAllTexts) updates the text and converts tokens such as <NAME> into the respective field. The start and end character sequence is variable, you have to pass it to the function: ReplaceTokens('< '> ', '); The third param eter is the text which will be used to create the field nam You can e. use it to create fields such as "CUSTOMER. NAME" by using 'CUSTOMER.' as param eter FieldPreText. ReplaceTokensInAllTexts does not only work in the current text but in all, header and footer texts. Both function return the count of replacements. Tip: WPTools 6 with the WPReporter addon also supports "Token to Template Conversion". If you use the token to tem plate conversion you can edit the mail-merge/reporting tem plate with an editor such as MS Word. The tem plate is loaded into TWPRichText. In this control the template can be further edited with the additional convenience of syntax highlighting and on dem and converted into a "true" reporting template. In case no bands are used, this technique can be also used to create m mail erge tem plates. (WPTools' Reporting is backward com patible to m m ail erge) Example: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 36. 30 WPTools Version 6 7.5.1.4 Low Level If you work with TParagraph references You maybe want to create fields using low level routines. There are two possibilities. a) Use TParagraph.AppendNewObject var starto, endo : TWPTextObj; par : TParagraph; begin par := WPRichText1.ActiveParagraph; starto := par.AppendNewObject(wpobjMergeField, true, false); // Start Object par.Append('Julian Ziersch'); // Displayed Text endo := par.AppendNewObject(wpobjMergeField, true, true); // End Object // Link both objects together endo.SetTag(starto.NewTag); // Set Name of field starto.Name := 'DB_NAME'; // Reformat and display WPRichText1.ReformatAll(false, true); end; b) Use TParagraph.AppendNewObjectPair var fieldo : TWPTextObj; par : TParagraph; begin par := WPRichText1.ActiveParagraph; fieldo := par.AppendNewObjectPair(wpobjMergeField, 'Julian Ziersch') ; fieldo.Name := 'DB_NAME'; // Reformat and display WPRichText1.ReformatAll(false, true); end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 37. Guide 31 Using method (a) You can initialize the field with formatted text by subsequently adding text and changing the current writing mode between the text parts. 7.5.2 Customize Field Display The merge fields always use a start and an end marker. The markers use internally the TWPTextObj class. The start marker stores the name of the field in the 'name' property. The ObjType property of both, the start and the end marker is both set to wpobjMergeField. By default this objects are displayed like in this image: The display of the markers is optional. Please set the property WPRichText.InsertPointTextAttr. Hidden = true to hide the field markers. WPRichText.InsertPointTextAttr.Hidden should be set to true when the document is printed. To permanently delete the fields (and keep the text) use the procedure.DeleteFields. This method will toggle display depending on the state of a check box: procedure TForm1.ShowFieldsClick(Sender: TObject); begin i f ShowFields.Checked then begin wprichtext1.InsertPointAttr.hidden:=false; wprichtext1.automatictextattr.BackgroundColor := clYellow; wprichtext1.automatictextattr.UseBackgroundColor := TRUE; end else begin wprichtext1.InsertPointAttr.hidden:=true; wprichtext1.automatictextattr.UseBackgroundColor := FALSE; end; wprichtext1.ReformatAll(false, true); end; It is also possible to show a different text in a different color. The text is defined by the public (not published) properties CodeOpeningText and CodeClosingText. The variables %N, %S, %Y and %P can be used. The color can be changed with property CodeTextColor. WPRichText1.InsertPointAttr.CodeOpeningText := ' [% N= '; // % N inserts the TWPTextObj.Name property // %S inserts the TWPTextObj.Source property // %Y inserts the TWPTextObj.StyleName property - only useful for span styles // %P inserts the TWPTextObj.Params property WPRichText1.InsertPointAttr.CodeClosingText := ']'; WPRichText1.InsertPointAttr.CodeTextColor := clBlue; This is how the field is displayed now: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 38. 32 WPTools Version 6 Display Fieldnames only: WPTools 6 also allows to hide the embedded text and the fieldmarker and display just a small box with the field marker: This mode is controlled by property ShowMergeFieldNames The value TRUE will show the boxes . while the value FALSE will enabled the default display (with the field markers visible or not). 7.5.3 Update Field (Insert Text from Database) The mail merge process activates some or all all fields one after the other and calls an event to let the code fill in text and images in each of it. 7.5.3.1 Start Merge process The mail merge is started by the method MergeText(const FieldName: string = ''; AllTexts: Boolean = FALSE). Both parameters are optional. If you need to merge only the text the cursor is located in (header, footer ..) use procedure MergeActiveText; Example: MergeText( ',true) - merge the fields in all areas, headers and footers ' MergeText('A*', true) - merge the fields whith names starting with "A" in all areas, headers and footers MergeText('A*', 'name', true) - merge the fields whith names starting with "A" and Source='name' in all areas, headers and footers Important: If you need to print (or export to PDF) the text right after the merge process you need to call ReformatAll(false, true)! If you need to merge the fields only in a header or footer text use the MailMerge procedure of any TWPRTFDataBlock.You will have to pass the OnMailMergeGetText procedure described below as © 2004-2008 WPCubed GmbH - Munich, Germany
  • 39. Guide 33 callback. Example : Merge fields only in all header texts: for i:=0 t o WPRichText1.HeaderFooter.Count-1 d o i f (WPRichText1.HeaderFooter[i].Kind=wpIsHeader and ) // only header not (WPRichText1.HeaderFooter[i].IsEmpty) then // and not empty WPRichText1.HeaderFooter[i].MergeText( WPRichText1, // object used as 'Sender', can be also datasource ... WPRichText1MailMergeGetText, // event handler (see below) false, // readonly, we want to modify '', nil, nil ); // optional to restrict merge range 7.5.3.2 Event OnMailMergeGetText This event is used to modify a field. It can also be used to enumerate fields and also to reads the properties of the field or the embedded text. The event OnMailMergeGetText receives the following parameters: Sender: TObject - this is a reference to the parent editor const inspname: String - the name of the field Contents: TWPMMInsertTextContents - this is the most important parameter. It provides You with an interface to evaluate and manipulate the field and the embedded text. In the easiest case You can use one line of code to assign text to a field: procedure TForm1.DoMailMergGetTexte( Sender: TObject; const inspname: string; Contents: TWPMMInsertTextContents); begin Contents.StringValue := DataSet.FieldByName(inspname).AsString; end; This code will read the contents of a given field and use it as the embedded text of a field. If the field contains HTML or RTF formatted text the text will be inserted as formatted text. If you need to modify the character attributes (such as font name, font style and color) of the field inside this event, please use the interface MergeAttr. Attention: Do NOT call ReformatAll, do not move the cursor position, do not change InsertPointTextAttr.Hidden inside this event! Example: Display a checkbox: Contents.MergeAttr.SetFontName if data=true then Contents.StringValue := #254 // þ else Contents.StringValue := #168; // ¨ 7.5.3.2.1 TWP nsertTextContents MMI The TWPMMInsertTextContents is used as a parameter 'Contents' in the event OnMailMergeGetText. You can replace a string by simply assign a string to StringValue. To Modify the attribute of the inserted text (i.e. the font name or style) change the © 2004-2008 WPCubed GmbH - Munich, Germany
  • 40. 34 WPTools Version 6 property 'MergeAttr'. You can modify the paragraph the start of the field is located. This paragraph is accessible through MergePar. Upgrade Note: The parameter 'c' is not supported anymore. But please note that you can use the common programming interface to insert text and objects. Note: When the event is called the the whole field is selected. 7.5.3.2.1.1 procedure Clear Clears the contents of this object. 7.5.3.2.1.2 procedure Abort Notifies the merge routine to abort the process. 7.5.3.2.1.3 procedure LoadTextFromStream(s: TStream) Load text from a stream. 7.5.3.2.1.4 procedure LoadTextFromFile(const FileName: string) Load text from a file. 7.5.3.2.1.5 function LoadImageFromFile(const FileName: string; w : Integer = 0; h: Integer = 0): Boolean; Load an image into this field. This methods have been added to WPTools 6. If You specify the width and height (twips values) the image will be scaled, keeping the original aspect ratio. You can pass negative values for w and h to preserve the width and height of the image currently embedded in the field. If currently no image is in the field, w and h will be used as absolute values. if inspname='IMAGE_A' then begin Contents.LoadImageFromFile('c:a.jpg', -1440, -1440); end; Also available is function LoadImageFromStream(const ImageData: TStream; FileExt: string; w: Integer = 0; h: Integer = 0): Boolean; It expects the data in a stream object and the file extension which defines the contents of the stream. For example ".JPG" if it is JPEG data. 7.5.3.2.1.6 property DataCollection: TWPRTFDataCollection This is the current RTFDataCollection © 2004-2008 WPCubed GmbH - Munich, Germany
  • 41. Guide 35 7.5.3.2.1.7 property DataBlock: TWPRTFDataBlock The is the DataBlock which hosts the current paragraph 7.5.3.2.1.8 property MergeAttr: TWPStoredCharAttrInterface This interface allows it to modify the attributes of the text which is about to be inserted. You can use the methods of the AttributeInterfaces. Example: Contents.MergeAttr.SetColor(clRed); The object 'MergeAttr' is initialized with the character properties of the start object of the mailmerge field. If you want to use the first character of the merged text (this is the visible field name or the field data) You can use this code in the the OnMailMergeGetText event: Contents.MergeAttr.CharAttr := Contents.MergePar.CharAttr[ Contents.MergeParPos+1] ; This code assigns the character attribute of the character which follows the the mergefield start code (= the merge text). You can, for example, change the font name: Contents.MergeAttr.SetFontName(...); This can be very useful if you need to display checkboxes in the fields. In this case simply assigne the desired wingdings characters code to StringValue. Contents.MergeAttr.SetFontName i f data=true then Contents.StringValue := #254 // þ else Contents.StringValue := #168; // ¨ 7.5.3.2.1.9 property MergePar: TParagraph MergePar is the paragraph the merged field starts within. MergeParPos is its position. 7.5.3.2.1.10 property MergeParPos: Integer MergePar is the paragraph the merged field starts within. MergeParPos is its position. 7.5.3.2.1.11 property Obj: TObject If an object of type TWPObject is assigned to this value, the new object is inserted into the text. This can be used to merge images. (Example... More easy to use is LoadImageFromFile and ) LoadImageFromStream .. 7.5.3.2.1.12 property CodePage: Integer This CodePage, if <> 0, the value will be used to convert the string value to the internal representation. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 42. 36 WPTools Version 6 7.5.3.2.1.13 property StringValue: AnsiString This is the result string as ANSI string. You can use the property CodePage to specify which code page should be used to convert it to the intern UNICODE representation. Please also see WideStringValue. You can also assign formatted text in RTF, HTML or WPTOOLS format to StringValue. If you merge in RTF text and the inserted text starts with a table you will see an empty line. This "empty" line is used to store the field marker which is not automatically deleted by the merge process. If it is not required to repeat the merge process or to read out modified text you can let the Merge procedure delete the field marker. Simply set the flag mmDeleteThisFieldin the property Contents.Options. This flag can be also very useful if the merged text contains field markers on its own which have to be processed in a second run! 7.5.3.2.1.14 property WideStringValue: WideString This is the result string as unicode string. If you need to insert formatted text (RTF, HTML) please use StringValue. 7.5.3.2.1.15 property OldText: string This is the current text inside the field. 7.5.3.2.1.16 property OldFormattedText: string This is the current text inside the field including formatting tags. 7.5.3.2.1.17 property OldIsPlain: Boolean This value is true if the "OldText" does not use different character attributes. 7.5.3.2.1.18 property CurrentObject: TWPObject This is a reference to the object currently INSIDE the field. It can be used to update a graphic container. 7.5.3.2.1.19 property CurrentTxtObject: TWPTextObj This is a reference to the object currently INSIDE the field. It can be used to update a graphic container. 7.5.3.2.1.20 property Options: TWPMailMergeContinueOptions This SET contains flags which change the way the data is inserted and how the method proceeds. mmStopNow, aborts the merge process mmMergeTrim, // WPTools 6: removes leading and trailing spaces from the replacement string. (Not used for formatted text) mmUseFirstLoadedParProps, // When loading RTF or HTML we also assign the paragraph props of the first loaded paragraph (WPT6: Use /setattr in Extras) mmUseFirstLoadedParPropsAuto, // use mmUseFirstLoadedParProps if the field is the first NON SPACE sign in the paragraph mmUseFirst_AlsoBorders, // refines "mmUseFirstLoadedParProps" to copy also the border and padding properties mmIgnoreNewParAttr, // If we are loaded in RTF or HTML string then paragraph attributes are © 2004-2008 WPCubed GmbH - Munich, Germany
  • 43. Guide 37 preserved (WPT6: Use /keepattr in Extras) mmIgnoreNewCharAttr, // If we are loaded in RTF or HTML string then character attributes are preserved mmIgnoreLoadedFonts, // When loading RTF ignore the Fonts mmIgnoreLoadedFontSize, // When loading RTF ignore the Font sizes mmIgnoreLoadedFontStyles, // When loading RTF ignore bold/italic and underline mmMergeAsRTF, mmMergeAsHTML, mmMergeAsWPTOOLS, mmSkipSpacesBehind, // not used yet mmInsertObject, mmDeleteEmptyParagraph, // not used yet mmDeleteUntilFieldEnd, // not used yet mmDeleteThisField, //Delete the field markers! (WPT6: Use /remove in Extras) mmDontUseLoadedParTabs, // When loading RTF optionally IGNORE the tabs mmDontUseLoadedParStyle // When loading ignore the style , mmMergeTrimSpaces //WPTools 6: remove double spaces between words, can be combined with mmMergeTrim (Not used for formatted text) 7.5.3.2.1.21 property Name: string This is the field name. 7.5.3.2.1.22 property FieldnamePart: string This is the part of the string NAME after the character '.', converted to uppercase characters. If there is no '.', 'Name' will be returned. 7.5.3.2.1.23 property DatasetnamePart: string This is the part of the string 'NAME' before the character '.', converted to uppercase characters. If there is no '.' DatasetnamePart will be empty. 7.5.3.2.1.24 property Command: string This is the command - it is placed in the "Source" property of the field object. 7.5.3.2.1.25 property StartInspObject: TWPTextObj The reference to the starting merge field object. 7.5.3.2.1.26 property EndInspObject: TWPTextObj The reference to the closing merge field object. 7.5.3.2.1.27 property DisplayName: string Reserved 7.5.3.2.1.28 property Format: Integer Reserved © 2004-2008 WPCubed GmbH - Munich, Germany
  • 44. 38 WPTools Version 6 7.5.3.2.1.29 property Modified: Boolean This value is true if a value has been assigned to StringValue or Obj. 7.5.3.2.1.30 property Hyperlink: string If this property is not empty, a hyperlink with this URL and the name "HyperlinkName" will be created. 7.5.3.2.1.31 property HyperlinkName: string The name of the hyperlink with the URL "Hyperlink". 7.5.3.2.1.32 property IsNull: TWPMMInsertTextContentsNull This property is only used for reporting in WPTools 6. This new property can be used to provide the WPReporter engine with additional information about a field. This is esspecially useful when a field is used for a condition. The standard value is wpFieldDefault - here the contents will be evaluated using the StringValue and Modified properties. wpFieldDefault, // Preset when reading field data wpFieldIsUnknown, // Preset when conditions are checked (?...=...) wpFieldIsNull, // If this is set any value will be ignored! wpFieldIsZero, // Should be set if an integer or float value = 0 wpFieldIsDefined // Should be set if field is defined 7.5.3.2.1.33 property ReplaceMode: TWPMMInsertTextContentsReplaceMode wpconNoChange, wpconStringValue, wpconWideStringValue, wpconObject, wpconStream 7.5.3.3 FieldLocate: Modify Field Name or Contents The powerful function named FieldLocate can be used as alternative to the MergeText/ OnMailMergeGetText double. It is used to locate certain fields. This code will enumerate a certain group of fields and update their contents. obj := nil; FromStart := TRUE; repeat obj := WPRichText1.FieldLocate('A*B', ' ', FromStart, [wplocGlobalSearch,wplocDontMoveCursor]); i f obj<>nil then obj.Embeddedtext := 'Test'; FromStart := FALSE; until obj = nil; An alternative method to enumerate the fields is the function FieldGetList. It will fill a list (an instance of the TWPTextObjList class) with references of fields. This list can be used to change the names of the fields and also to read or change the contents (EmbeddedText). The property FieldAtCP can be used to retrieve a reference to the active field at the current cursor position. Please use this function with care since the backward search for the open object can be © 2004-2008 WPCubed GmbH - Munich, Germany
  • 45. Guide 39 slow, esspecially if no field can be found. CPObj is faster, it returns any TWPTextObj directly at the current cursor position (= at the current text insertion point - do not confuse with mouse-cursor). 7.5.3.4 Use TWPMMDataProvider This component can be used to automatically attach a mail merge template to a data set. The property NextDataProvider can be used to build a chain of data provider. The event OnGetDataSet can be used to locate the correct dataset for a given field. (i.e. evaluate Contents.DataSetNamePart) Fieldsnames which are listed in the list BMPFields are expected to be pictures, the fields in RTFFields are expected to contain formatting tags. If a field is of type TGraphicField, automatically the contained image will be inserted. Here the flag wpmmPreserveObjectSize can be used in property "Options" to load the image into the current container (if there is one). Info: The data merging is performed by procedure TWPMMDataProvider.DoMergeGetText(Sender: TObject; const fieldname: string; Contents: TWPMMInsertTextContents); found in unit wpdbrich.pas. We recommend to read it. 7.5.4 FastAppendText: Create text with multiple letters Sometimes you need to create a longer text which contains copies of the same template filled with different data. You can use a second TWPRichText object "AllRTFText" to receive the text of all the single letters. Then You can use code like this to loop through the complete database, merge each record and append the result to AllRTFText. The first time the text is copied using "AsString" to make sure the page format and the header and footers are copied too. Later records use FastAppendText. 7.5.4.1 Example: FastAppendText var i : Integer; Table1.DisableControls; try Table1.First; i := 0; AllRTFText.BeginUpdate; AllRTFText.Clear; while not Table1.EOF d o begin WPRichText1.MergeText; i f i=0 then // FIRST RUN begin AllRTFText.AsString := WPRichText1.AsString; AllRTFText.CPPosition := MaxInt; // to end end else i f i>0 then // SUBSEQUENT RUNS © 2004-2008 WPCubed GmbH - Munich, Germany
  • 46. 40 WPTools Version 6 begin AllRTFText.FastAppendText(WPRichText1,true, [wpCreateNewPage ); ] end; Application.ProcessMessages; Table1.Next; inc(i); end; finally AllRTFText.EndUpdate; AllRTFText.ReformatAll(true, true); Table1.EnableControls; end; 7.5.4.2 Create Sections with FastAppendText The above code simply copies the text to the destination. It will be one large text without sections. To create sections please add the marked lines in red. We use the section property wpsec_ResetOutlineNums to make sure each section uses its own outline numbering. var Section : TWPRTFSectionProps; try Table1.First; ... // Need page break Section := AllRTFText.FastAppendText(WPRichText1,true, [wpCreateNewPage]); Section.Select := [wpsec_ResetOutlineNums, wpsec_ResetPageNumber]; end; ... end; finally ... end; 7.5.4.3 Create Lists You can use the flag wpCombineTableIfPossibleto create a large table from a template which consists only of a single table with fields. If this flag is not used, for each run one table will be created in the destination editor. If the flag wpReuseLastPar was used, empty lines in the destination will be avoided. Both flags were added to WPTools 6. 7.5.4.4 Save created text To save the text use Dest.SaveToFile or Dest.SaveAs; When you save the resulting text you can use the following writer options in the format string to create better RTF code: -nonumberprops: Write the numbers as text -nomergefields: Do not save the fields, only the contents 7.5.5 Hide empty paragraphs After the mail merge procedure it is possible that some paragraphs are completely empty, except for the remaining fields and maybe space and tab chars. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 47. Guide 41 a) Using the function DeleteParWithEmptyFields this paragraphs can be deleted. This function internally uses the function DeleteParWithCondition. The function DeleteParWithCondition works only with paragraphs and tables in the first level (not nested tables). Tables rows which do only contain cells with can be deleted will be deleted as well. If all rows in a table have been deleted that table will be deleted, too. Inside a table cell all child paragraphs of that cell (if any) are individually checked. If those child paragraphs trigger the 'condition' to true, they will be deleted. If the main cell paragraph trigger the condition to true it will be cleared. The cell will only be deleted if all sibling cells have to be deleted, too. (the complete row) b) You can also temporarily hide paragraphs which do only contain empty fields and spaces. To do so use the event BeforeInitializeParwith this code: i f par.HasObjects(false,[wpobjMergeField]) and not par.IsNonSpace([wpobjMergeField]) then include(par.prop, paprHidden) else exclude(par.prop, paprHidden); c) Delete leading or trailing spaces function DeleteLeadingSpace(EmptyFieldsToo: Boolean; InFirstPar : Boolean = TRUE): Boolean; function DeleteTrailingSpace(EmptyFieldsToo: Boolean): Boolean; Both functions will stop at the first table they find. They will delete the text (and optionally empty fields) from the start or from the end of the text. 7.5.6 Forms/Edit Fields WPTools can be also used to create forms. These are sepecial texts which are generally protected. The user may only edit the text in specially marked areas. We call this areas 'Edit Fields': Edit fields work like mail merge fields. The only difference is that the objects use the mode flag "wpobjWithinEditable". When saved to RTF a formfield instead of a field tag is written. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 48. 42 WPTools Version 6 To create a field use procedure InputEditField(const FieldName: string; DisplayText: string = ' '; PlaceCaret: Boolean = FALSE; Command: string = ' '; // will be written to TWPTextObj.Source Format: Integer = 0 // will be written to TWPTextObj.IParam ): TWPTextObj; All procedures which work with mail merge fields will work for the edit fields, too. Like with mail merge fields the presentation of the start and end markers is controlled by the property InsertPointAttr. The text within the markers is controlled by AutomaticTextAttr. The editor for the example above had been set up with: DataEdit.ProtectedProp := [ppAllExceptForEditFields]; DataEdit.EditOptionsEx := [wpTABMovesToNextEditField,wpRepaintOnFieldMove]; DataEdit.InsertPointAttr.Hidden := FALSE; DataEdit.InsertPointAttr.CodeTextColor := $E0FFE0; DataEdit.InsertPointAttr.CodeOpeningText := '['; DataEdit.InsertPointAttr.CodeClosingText := ']'; The most important property change is ProtectedProp := [ppAllExceptForEditFields]. This makes it impossible for the cursor to move anywhere else than within edit field tags. To make it possible to highlight the current field (yellow background) the property UseOnGetAttrColorEvent and the event OnGetAttributeColor has been used: DataEdit.AutomaticTextAttr.UseOnGetAttrColorEvent := TRUE; procedure TWPEdTest.DataEditGetAttributeColor(Sender: TObject; var CharStyle: TCharacterAttr; par: TParagraph; posinpar: Integer); var obj : TWPTextObj; begin obj := DataEdit.CodeInsideOf(par,posinpar,wpobjMergeField); i f obj = DataEdit.FieldAtCP then begin CharStyle.BackgroundColor := $A0FFFF; CharStyle.UseBackgroundColor := TRUE; end; end; Edit fields can be read out using procedure MailMerge and event OnMailMergeGetText: // Read the data which is currently displayed in the editor procedure TWPEdTest.ReadData; begin FReadingData := TRUE; // global boolean to change behaviour DataEdit.MergeText; end; // Write back the data procedure TWPEdTest.WriteData; begin FReadingData := FALSE; DataEdit.MergeText; end; // This reads and writes the data fro the database 'Table1' procedure TWPEdTest.DataEditMailMergeGetText(Sender: TObject; const inspname: String; Contents: TWPMMInsertTextContents); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 49. Guide 43 begin i f FReadingData then Table1.FieldByName(inspname).AsString := Contents.OldText else Contents.StringValue := Table1.FieldByName(inspname).AsString; end; end; This code can be used to move to a certain field. If the cusror is within a field with that name the next field will be located and selected. procedure TWPEdTest.MoveToField(fieldname : String) ; begin fieldname := SelectField2.Text; // If this is the current move on ... i f DataEdit.CurrentEditField=fieldname then DataEdit.MoveToNextField(false); // Try from here i f DataEdit.MoveToField(fieldname,false) then DataEdit.SelectFieldAtCP(false, true) // or from start else i f DataEdit.MoveToField(fieldname,true) then DataEdit.SelectFieldAtCP(false, true); DataEdit.SetFocus; end; 7.5.7 Create ComboBox Now we show how to create a pick list for a merge field: We use a panel with a speed button to display the drop down button. This panel is moved to the correct location in the MouseMove event. A timer is used to hide this panel if it is not required anymore. The picklist itself is a listbox, also placed on the form. It would be better to display this list on a seperate form located over the mainform but we wanted to make this example as simple as possible. The name of the current field (for which the picklist is displayed) is stored in the string variable CurrField. The MouseMove event handler for the editor. It sets 'CurrField' procedure TWPEdTest.DataEditMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 50. 44 WPTools Version 6 var fieldobj, fieldobjend : TWPTextObj; px, py : Integer; begin fieldobjend := nil; fieldobj := DataEdit.CodeInsideOf(x, y, wpobjMergeField); i f (fieldobj <> nil) and ((CompareText(fieldobj.Name,'name') =0) o r (CompareText(fieldobj.Name,'company' =0)) then ) begin fieldobjend := fieldobj.EndTag; i f fieldobjend<>nil then begin DataEdit.GetParXYBaselineScreen(fieldobjend.ParentPar, fieldobjend. ParentPosInPar, px, py ) ; PickPanel.Left := px - PickPanel.Width div 2; PickPanel.Top := DataEdit.Top + py - MulDiv(PickPanel.Height,4,5) ; CurrField := fieldobj.Name; end; end; i f fieldobjend=nil then HidePickPanelTimer.Enabled := TRUE // we hide it 500ms delayed else begin PickPanel.Visible := true; HidePickPanelTimer.Enabled := FALSE; end; end; The timer HidePickPanelTimer disables the button procedure TWPEdTest.HidePickPanelTimerTimer(Sender: TObject); begin HidePickPanelTimer.Enabled := FALSE; PickPanel.Visible := false; end; The OnExit event of the listbox (it is called when the listbox looses the focus)is used to hide the listbox when the user clicks on the editor: procedure TWPEdTest.PicklistExit(Sender: TObject); begin Picklist.Visible := FALSE; end; A click on the speedbutton display the listbox: procedure TWPEdTest.PickDropClick(Sender: TObject); begin Picklist.Left := PickPanel.Left + PickPanel.Width - Picklist.Width; i f CompareText(CurrField,'name') =0 then Picklist.Items.Assign(PicName.Lines) else i f CompareText(CurrField,'company' =0 then ) Picklist.Items.Assign(PicCompany.Lines) else Picklist.Items.Clear; i f PickPanel.Top>EditTab.Height-100 then begin Picklist.Height := PickPanel.Top -2 0; i f Picklist.Height>150 then Picklist.Height := 150; Picklist.Top := PickPanel.Top - Picklist.Height; end else begin Picklist.Top := PickPanel.Top + PickPanel.Height; Picklist.Height := EditTab.Height - Picklist.Top-2 0; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 51. Guide 45 i f Picklist.Height>150 then Picklist.Height := 150; end; Picklist.Visible := TRUE; Picklist.SetFocus; end; Last but not least - a click in the listbox should update the current field. We use the function [b] CodeListTags[/b] to find all the field with a given name and simply update the property EmbeddedText . procedure TWPEdTest.PicklistClick(Sender: TObject); var objlst : TWPTextObjList; i : Integer; s : string; begin i f Picklist.ItemIndex>=0 then s := Picklist.Items[Picklist.ItemIndex] else exit; objlst := DataEdit.CodeListTags(wpobjMergeField,CurrField, true); try for i:=0 t o objlst.Count-1 d o objlst[i].EmbeddedText := s; finally objlst.Free; DataEdit.ReformatAll(false, true); end; DataEdit.Setfocus; // also hides Picklist! end; You can download the complete example here http://www.wpcubed.com/ftp/ex/EditFieldDemo.zip 7.6 Tasks 7.6.1 Mini Editor With WPTools Version 6 you can create extremely compact editor applications which still do not miss any functionality the end user might expect - such as support for headers and footers, WYSIWYG, scaling, tables etc. When you need a really compact editor we suggest to create objects of the class TWPCustomRtfEdit (defined in unit WPCTRMemo) in code. This way you can also attach two editors to the same TWPRTFDataCollection to create an editor with split screen support. Our demo uses 4 variables defined inside the form interface: TWPMiniEd = class(TForm) ... public WPRichText1, WPRichText2 : TWPCustomRtfEdit; RTFData : TWPRTFDataCollection; RTFDataProps : TWPRTFProps; end; We also added a splitter, a graphic popup menu and a main menu. At runtime the demo looks like this screen shot: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 52. 46 WPTools Version 6 The editor objects are created and connected in code inside of the OnCreate event of the form: procedure TWPMiniEd.FormCreate(Sender: TObject); begin RTFData := TWPRTFDataCollection.Create(TWPRTFDataBlock); RTFDataProps := TWPRTFProps.Create; RTFData.RTFProps := RTFDataProps; WPRichText1 := TWPCustomRtfEdit.Create(Self); WPRichText1.Parent := Self; WPRichText1.Align := alClient; WPRichText1.TabStop := FALSE; WPRichText1.AcceptFiles := TRUE; WPRichText1.Memo.SetRTFDataOrProps(RTFData,nil) ; WPRichText2 := TWPCustomRtfEdit.Create(Self); WPRichText2.Memo.SetRTFDataOrProps(RTFData,nil) ; WPRichText2.Parent := Self; WPRichText2.Align := alBottom; WPRichText2.Height := 100; Splitter1.Top := 0; We now assign the graphic popup menu. This menu is automatically used as contect menu for image objects. WPRichText1.GraphicPopupMenu := GraphicPopupMenu; WPRichText2.GraphicPopupMenu := GraphicPopupMenu; Now we add the text to the body. The HTML format makes it easy to add some formatting. WPRichText1.AsString := '<div align=left><font face="verdana" size=2>WPTools Demo</font></div>'; We also want to show a header text with page numbering. We also use HTML with the WPTools addition tag <pagenr/>. WPRichText1.HeaderFooter.Get(wpIsHeader, wpraOnAllPages).RTFText.AsString := '<div align=right><font face="verdana">www.WPTOOLS.de - Page <pagenr/></ font></div><hr>'; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 53. Guide 47 WPRichText2.SetZoomMode(-2 0) ; end; At last we use the SetZoomMode procedure to select a certain layout and zoom mode. The SetZoomMode makes it easy to modify several properties of the editor all at once. Since it only requires one integer parameter it can be used in menus or actions which are using the 'Tag' property to store the parameter for SetZoomMode. Hint: The TWPCustomRtfEdit can also be used in a thread save context, for example to create documents using mailmerge in a thread save context. Please check out the demo " ThreadSave " 7.6.1.1 Save to HTML / Load from HTML WPTools will create a HTML file if you save to a file with extension HTML or HTM. To get the HTML code as a string use WPRichText1.AsANSIString('HTML'); 'HTML' is a "format string" - please read more about this option strings here. If your text containes embedded images you will need to save them to a file during the creation of the HTML code. This FAQ shows how to do it: http://wpcubed.com/forum/viewtopic.php?t=1167 This FAQ shows how to load from HTML and include images: http://wpcubed.com/forum/viewtopic. php?t=1498 7.6.2 How to use the "Default Editor" Can you create a full blown word processing application in one minute? Yes, with WPTools Version 6 you can. A) The is the complete program code in Delphi: program UseDefEditor; uses Forms, WPDefEditor; {$R *.res} begin Application.Initialize; Application.CreateForm(TWPToolsEditor,WPToolsEditor); Application.Run; end. All you need is to use the included default editor, this is the editor which is also used by the IDE to edit the text which is contained in WPTools objects. It uses a form (defined in unit WPDefEditor) and a data module which contains the main menu and the actions. Of course, you can edit both files but you can modify them at runtime. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 54. 48 WPTools Version 6 The data module with the actions will be also a great help if you need to create an editor inplace, not using the provided default editor form! Please copy both units and accompanied DFM files to a save place if you intend to modify them. Otherwise they will be replaced by the WPTools setup. B) Even easier to use is the component TWPDefaultActions. Place this component on your form - also create a toolbar (using the TWPToolPanel - you can use Copy&Paste from unit wpDefEditor), and add a TWPRuler. Now you only have to create a link to the TWPRichText in the ControlledMemos collection of the TWPDefaultActions component. Using the OnInit event of the TWPDefaultActions component you can modify the menu. Please see the HLP file (=reference) for more information. You can also use the default editor within a MDI project: // This event for auto free ! procedure TWPMdiDemo.WPDefEditorFormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end; // Create a new wptools default editor as MDI child © 2004-2008 WPCubed GmbH - Munich, Germany
  • 55. Guide 49 procedure TWPMdiDemo.NewEditorClick(Sender: TObject); var lForm : TWPToolsEditor; begin WPIsMDIApp := true; // Make the Toolbar MDI compatible lForm := TWPToolsEditor.Create(nil) ; lForm.FormStyle := fsMDIChild; lForm.OnClose := WPDefEditorFormClose; end; 7.6.3 Toolbar and Action Classes WPTools contains a complete set of component to quickly build a user interface. You can use the ready-to-use TWPToolbar to create an editor within 5 seconds, or you can use the action classes and your own choice of tool buttons to let the user change the attributes of the text. a) Toolbar Components The tool-bar components (TWPToolBar and TWPToolPanel) can be attached to any TWPRichText component using its property WPToolBar. If you have more than one use the propety WPToolBar. NextToolBar to connect to the next toolbar in the chain. When the TWPToolBar is used on a MDI child window you need to set the global variable WPIsMDIApp := true; TWPToolBar This components makes it easy to start a new program which uses a TWPRichText component. You only have to activate some flags in the object inspector and the TWPToolBar will display action and status buttons and some combo boxes to select the font or color of the text in the TWPRichText control. TWPToolPanel Contrary to the toolbar, which creates and positions the buttons automatically, with the tool-panel component you have to drop the buttons in place. This gives you more freedom in the design of the user interface. TWPComboBox This components can be used together with a TWPToolPanel or TWPToolCtrl. It can control the font, font size or colors of the text - to select the mode use the property ComboBoxStyle. TWPToolButton This components can be used together with a TWPToolPanel. It can control the fonts styles or execute certain actions like 'Print', 'Load' or 'Save'. If you use the TWPToolBar you don't need the TWPComboBox or TWPToolButton control since the buttons and combo boxes are created by the TWPToolBar object. b) Work with Actions TActionList Actions objects are uses to connect menu items and buttons to a certain procedure of the TWPRichText editor. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 56. 50 WPTools Version 6 The TActionList which contains the action objects must be specified in the ActionList property of the TWPRichText component. To add an action to a ActionList please open its editor (double click) and select 'new standard action' Tip: In case you find out that certain hot keys do not work please check the short cuts defined in action lists or menus. It is possible that a shortcut is consumed somewhere else. Assigning an action to a menu item always overrides the image index of this element. So please specify the image index values in the actions and not in the menu items. The image list must be assigned to both, the action list and the toolbar! Please also see "Use WPTools with TBX" (TBX / DevExpressBars) Work with TWPComboBox The TWPToolCtrl component is not included in WPTools Version 6. If you want to use the TWPComboBox control which can display a list of fonts, colors or styles, You need to create a links using the TWPToolsCustomEditContolAction action class. This action class is created in the ActionList and its property AttachedControl is set to the TWPComboBox instance you need to attach. The property AttachedControlStyle to select the functionality is not used for TWPComboBox - they have their own property ComboboxStyle for the same purpose. Create shortcuts, such as Ctrl+I to activate/deactivate ITALIC: To do this You can use the event OnKeyPress. procedure TForm1.WPRichText1KeyPress(Sender: TObject; var Key: Char); procedure ToggleStyle(sty : TOneWrtStyle); begin i f sty i n WPRichText1.CurrAttr.Style then WPRichText1.CurrAttr.DeleteStyle([sty]) else WPRichText1.CurrAttr.AddStyle([sty]); WPRichText1.SetFocusValues(true); end; begin i f Key=Char(Integer('B') -6 4) then // Ctrl + B begin ToggleStyle(afsBold); Key := # 0; end else i f Key=Char(Integer('I') -6 4) then // Ctrl + I begin ToggleStyle(afsItalic); Key := # 0; end else i f Key=Char(Integer('U') -6 4) then // Ctrl + U begin ToggleStyle(afsUnderline); Key := # 0; end; end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 57. Guide 51 Note Please do not use actions if you want to execute certain methods of the TWPRichText component from your own code. You can call the procedure directly (i.e. WPRichText1.Save) or change text attributes using CurrAttr (i.e. WPRichText1.CurrAttr.AddStyle[afsBold]). 7.6.4 Change Behaviour and Appearance of Editor Please see: Localization Layoutmodes Hover Effects EditOptions ViewOptions HideTableBorders 7.6.4.1 Layoutmodes The different layout modes are probably one of the most exciting feature in WPTools Version 6. You will hardly find a component which offers this kind of versatility in a text editing tool. Different layout modes are mainly activated in property LayoutMode - but also the properties PageColumns, AutoZoom, Zooming, ViewOptions and OnPageGapGetText are important for the display of the text. If you are using our multiview technology (multiple editors show one text), each editor can use different settings for the mentioned properties. So it is possible that one editor displays the thumbnails while a different editor shows the text in 'normal' mode! Changing the layout modes is also extremely fast, usually the already formatted pages are rearranged on the virtual desktop! Please note that the TWPPreview component also inherits from the usual editor component. So it has the same properties. But it also introduces the property SinglePageMode. If this property is true, unlike the default display of all pages in a row, only one row of pages will be displayed. BTW - if you are using the TWPPreview or TWPPreviewDlg you are already using the multiview technology. Possible values of the property LayoutModes are: wplayNormal : Only show the text area without margins - do not paint background color. wpWordWrapView: Display like wplayNormal - used when the word wrap is set to the editor box. wplayShowManualPageBreaks like wpNormal but draws a dashed line for page breaks - wplayPageGap- display the text similar to wplayNormal with a bar iin between wplayExtendedPageGap works like wplayPageGap but does not suppress the left and right - © 2004-2008 WPCubed GmbH - Munich, Germany
  • 58. 52 WPTools Version 6 margin. wplayPageGap example: The display of the page numbers ("--- 1") is activated using the ViewOption wpShowPageNRinGap . You can use the event OnGetPageGapText to display a different text. wplayShrinkedLayout- show PageLayout without header and footer (reduces page height!) wplayLayout - show PageLayout but do not paint header and footer. wplayFullLayout - show PageLayout with header and footer. wpDualPageView- display 2 pages side by side. A similar effect can be accieved by setting the property "PageColumns" to 2 but wpDualPageView makes sure the 2 pages are handled as 1 by the auto zoom function. The DualPage view expects the first page to be ouside and the 2nd and 3rd to be side by side. If the property WPRichText.Memo.DualPageViewAlternate is true the first page is displayed side by side with the second. wpThumbNailView- display thumb nails of the pages, optionally with display of the page numbers in little boxes. This is activated by ViewOption wpShowPageNRinGap. property ViewOptions The following values are possible: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 59. Guide 53 wpShowGridlines- draw a gray line for table borders which would mbe otherwise invisible wpDisableHotStyles - disable the hot styles (or hover styles) which can be activated for hyperlinks or fields. wpShowCR - show a symbol at the end of a paragraph wpShowFF - displays at the end of a paragraph when the next paragraph starts on a new page wpShowNL - displays an arrow for a new line wpShowSPC- shows a dot for the code #32 (SPACE) wpShowHardSPC- shows a dot for the code #160 (non breaking space) wpShowTAB - show an arrow in the place of tabstops (suppressed if fillsigs are active) wpShowParCalcNames- Display the names assigned using property WPAT_PAR_NAME wpShowParCalcCommands- Display the formulas assigned to paragraphs and cells. wpShowParNames Display the names assigned using property TParagraph.Name - wpNoEndOfDocumentLine - display a line at the end of the document if not in pagegap mode. Ignore the typo 'No'. wpHideSelection- Always hides the selection wpHideSelectionNonFocussed - hides thenselection when editor does not have the focus wpShowPageNRinGap- displays a number or any other text provided by event OnPageGapGetText either at the right border or in a box under the page wpDrawFineUnderlines- always draw thin underlines wpDontGrayHeaderFooterInLayout- do not shaed the header and footer texts wpInfiniteTextArea- makes it possible to show a text as if it is infinite. This can be used for a scroller control, for example to show news or credits. To scroll change the property TopOffset in a timer event. wpDontPaintPageFrame- with page layout modes, do not draw a frame around the page wpCenterPaintPages- center the page horizontally in the window. This is useful for preview windows. wpDrawPageMarginLines draw dotted lines at the page margins. - wpDontDrawSectionMarker- do not draw the arrow which shows where a new section starts. wpDrawHeaderFooterLines- draw gray lines around header/footer areas. wpUseOwnDoubleBuffer - Usually a shared double buffer is used for all editors to limit the memory use - unless thumbnailmode has been activated or this flag is active. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 60. 54 WPTools Version 6 wpDontDisplayScrollPageHint - Do not display this default page number hint when pressing the scrollbar handle. The hint can be modified by changing the global string variable WPPageHintStr. The default is ' %d / %d '. property AutoZoom The following values are possible: wpAutoZoomOff - use the value of property Zooming to change the aspect ratio of the text display wpAutoZoomWidth - automatically adjust the aspect ratio to make room for the complete width of the page wpAutoZoomFullPage - automatically adjust the aspect ratio to make room for the complete size of the page wpAutoZoomAdjustColumnCount - automatically adjust the property PageColumns to show as many pages side by side as fit into the window. Usually the property Zooming should be set to a small value, for example 30. wpAutoZoomAsManyAsPossibleInRow - show as many pages side by side but allow a different count of pages each row. You can see the effect in the lower editor in the section demo. This mode should be also combined with a small zooming value. Please note that the property CurrentZooming can be read to get the current aspect ratio as a floating point multiplicator. 7.6.4.2 Hover Effects Certain text can change the attributes when the mouse is moved over it. In addition a hint window can be displayed. This is useful for mail merge fields and hyperlinks. All text which support this kind of interaction can also use global style and color definitions set up in these properties: i) property HyperlinkTextAttr: TCharacterAttrTags; property BookmarkTextAttr: TCharacterAttrTags; property SPANObjectTextAttr: TCharacterAttrTags; property AutomaticTextAttr: TCharacterAttr; ii) property ProtectedTextAttr: TCharacterAttr; property HiddenTextAttr: TCharacterAttr; iii) property FieldObjectTextAttr: TCharacterAttr ; property InsertPointAttr: TCharacterAttrTags; The group i) defines attributes for texts which is wrapped in TWPTextObj instances of the following © 2004-2008 WPCubed GmbH - Munich, Germany
  • 61. Guide 55 types: wpobjHyperlink, wpobjBookmark, wpobjSPANStyle and wpobjMergeField (= merged text). The two prioperties in group ii) affects text which uses the character style afsProtected and afsHidden. In group iii) FieldObjectTextAttr changes the appearance of wpobjTextObject objects (with the exception of objects with the name 'PAGE', 'NUMPAGES', 'SYMBOL'. InsertPointAttr changes the way wpobjMergeField objects are displayed and can be used to hide those objects. The TCharacterAttr class contains various properties to change the color of the "special" text, to add or remove underlines and to set the underline color. To display hint windows two events can be used: a) the OnActivateHint event This event is triggered when the mouse is moved over special text which uses the property OnHintEventIsActive set to true in the respective TCharacterAttr property. Since there is no OnDeactivateHint event we suggest to use a timer to hide the window. In contrast to property "HotStyleIsActive" the property "OnHintEventIsActive" does not force a repaint of the text window! a) the OnActivatingHotStyle event This event is triggered when the mouse is moved over special text which uses the property HotStyleIsActive set to true in the respective TCharacterAttr property. This code can be used to show a hint window with information about merged text. HotStyleIsActive must be set to TRUE in property AutomaticTextAttr: procedure TForm1.WPRichText1ActivatingHotStyle(Sender: TObject; par: TParagraph; posinpar: Integer); var p : TPoint; begin i f par <> nil then begin FHintForm.Caption := (Sender a s TWPCustomRTFEdit).FieldGetNameInPar(par, posinpar); p := TWPCustomRTFEdit(Sender).GetPointFromParLin(par, posinpar); i f p.x > TWPCustomRTFEdit(Sender).Width then p.x := TWPCustomRTFEdit(Sender). Width; p := TWPCustomRTFEdit(Sender).ClientToScreen(p); FHintForm.Left := p.x; FHintForm.Top := p.y; FHintForm.Show; end; end; The hint form is hidden in event OnDeactivateHotStyle procedure TForm1.WPRichText1DeactivateHotStyle(Sender: TObject); begin FHintForm.Hide; end; If you need to use OnClick events for certain texts use the event OnClickHotText and the property ClickableCode. See previous chapter for more information. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 62. 56 WPTools Version 6 7.6.4.3 EditOptions The properties EditOptions and EditOptionsEx control how the editor works. They are also used to disable certain actions, such as table resizing. TWPEditOptions = set of (wpTableResizing, // Mobve left right indent } wpTableOneCellResizing, // always only one cell, can be switched with CTRL key wpTableColumnResizing, // change column width wpTableRowResizing, // Change height of row. Also see EditOptionEx: wpTableRowResizingWithCTRL wpClearAttrOnStyleChange, //ON: clear the redundant properties when the style name is changed. wpNoAutoWordSelection, // don't select complete words (like Word) wpObjectMoving, // move images (ObjType=wpobjImage) wpObjectResizingWidth, // the width of objects can be changed wpObjectResizingHeight, // the height of objects can be changed wpObjectResizingKeepRatio, // the width/height of objects can be changed wpObjectSelecting, // objects can be selected wpObjectDeletion, // objects can be deleted (only used for TWPObject) wpNoAutoScroll, // Switch off the new Auto Scroll Feature // obsolete! wpFieldObjectsAsGraphicObjects, { work with TWPOFieldObject as if they were TWPOGraphics } wpSpreadsheetCursorMovement, { Cursor up/down in Rows } wpAutoInsertRow, { wpAutoInsertRow, TAB in last cell. Must be combined with wpSpreadsheetCursorMovement } wpNoEditOutsideTable, { to simulate spreadsheet - V5 ok } wpBreakTableOnReturnInRow, { V5: instead of inserting a row break up the table } wpActivateUndo, { activate UNDO } wpActivateUndoHotkey, { activate ALT + Backspace - requires wpAllowUndo set too } wpActivateRedo, { makes backup of complete text ! } wpActivateRedoHotkey, { makes backup of complete text ! } wpAlwaysInsert, { don't switch to overwrite } // wpDeactivateCharsetSwitching, wpMoveCPOnPageUpDown, { Move Cursor on Page up or Down code - V5 ok } wpAutoDetectHyperlinks, // Create a hyperlink after 'www.' was typed wpNoHorzScrolling, //V5=ok wpNoVertScrolling, //V5=ok // wpNoAutomaticHangingBulletsAndNumbers, - see FormatOption! // wpMDIDragAndDrop, // wpDontDeleteExtraSpace, // wpUseHyphenation, -> Moved to FormatOptions! wpDontSelectCompleteField, // Selections will always wrap the complete merge field wpSelectCompleteFieldAlsoWhenInside, // When selection inside of field also complete field is selected wpStreamUndoOperation, // saves also additional info like bands, objects .. //is default: wpToolBarDisableDifferentFontsInSelections, // Sets Size,Color, Font to blank is not = in a selection wpTabToEditFields, // not used. // wpAllowEditHeaderFooter wpSelectPageOnDblClick, //V5=ok // Used by TWPRichText only: wpAllowCreateTableInTable // - the create table button allows nested tables // Don't allow selection at all ); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 63. Guide 57 TWPEditOptionsEx = set of ( wpDisableSelection, // The user cannot select text (see ViewOptions to hide selection) wpDisableCaret, // The caret (insertion point marker at cursor position) is not displayed wpDisableGetFocus, // The editor will never receive the focus wpDisableEditOfNonBodyDataBlocks, // in Pagelayout mode other DataBlocks (header, footer) cannot // be selected for edtiting with a click of the mouse wpAllowCursorInRow, // the cursor can be placed in row end marker to create a new row with return wpTextObjectMoving, // move text objects (ObjType=wpobjTextObj) wpTextObjectSelecting, // By defualt allow selectiong of text objects wpNoAutoWordStartEndFieldSelection, // Normally a complete field is selected // when the cursor is moved over the start or end of a mail merge field. // unless wpNoAutoWordSelection is used. Also see EditOption: wpSelectCompleteFieldAlsoWhenInside // Note: wpNoAutoWordStartEndFieldSelection only applies to selection with mouse! wpDisableAutoCharsetSelection, // If true the charset is not retrieved by // checking the current keyboard layout when the user types wpIgnoreSingleCellSelection, // No cell selection by pointing in bottom left corner wpTABMovesToNextEditField, // used with forms wpDblClickCreateHeaderFooter, // Double click in Margin creates header/footer for all pages // Use 'OnClickCreateHeaderFooter' event to modify 'range' wpRepaintOnFieldMove, // When the cursor moves to a different field // the form is repainted. This is important if you use code to // highlight the current field. (using event: OnGetAttributeColor) wpKeepCellsWhenCombiningCells, // use the HTML way to combine cells horizontally wpAllowSplitOfCombinedCellsOnly, // use the HTML way to split cells, dont allow split if not combined wpDontClearStylesInNew, // If defined Action 'New' will not clear the defined styles wpDontResetPagesizeInNew, // If defined clearing the text will not set up the default page size wpSetDefaultAttrInNew, // If defined "New" will preset the writing attributes to the default wpAllowDrawDropBetweenTextBlocks, // Allow drag & drop between header and body wpDisableFastInitOnTyping, // Disable the improved typing performance in large paragraphs wpDontTriggerPopupInContextEvent, // Changes the time the event OnMouseDownWord is triggered (old behaviour) wpAlwaysColWidthPC, // Changine column width sets percentage colwidth in cells wpDisableXPosLineUpDown, // Disable the code which triues to keep cursor at same X position in Line up/down wpDontInitSelTextAttrWithDefaultFont, // SelltextAttr will not report the default attr for undefined wpDontSelectCellOnSpreadsheetMovement, // when tabbing throgh a table dont select the cell wpScrollLineWise, // When using line up&down do not move by 1/3 screen but only by the height of a line wpZoomWithMouseWheel, // Press Ctrl + use Mouse Wheel to zoom in and out wpTableRowResizingWithCTRL, // Resize rows when also CTRL is pressed wpDontUseNumberIndents // when using Inc/Dec Outline Level ignore the indents defined in number styles wpAutoCaptitalize // WPTools 6: Auto capitalize sentence starts ); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 64. 58 WPTools Version 6 7.6.4.4 ViewOptions The properties ViewOptions and ViewOptionsEx (added in WPTools 6) control how the text is displayed. TWPViewOptions = set of ( wpShowGridlines, // display gray lines around cells wpDisableHotStyles, // disable the hover styles (See HyperlinkTextAttr for example) wpShowCR, // Show Paragraph symbol wpShowCRButNotInCells, wpShowFF, wpShowNL, wpShowSPC, wpShowHardSPC, wpShowTAB, wpShowParCalcNames, // Display the names assigned using property WPAT_PAR_NAME wpShowParCalcCommands, // Display the formulas wpShowParNames, // Display the names assigned using property TParagraph.Name wpNoEndOfDocumentLine, // If enabled a line will be displayed in normal mode at the bottom. (Ignore the "no") wpHideSelection, // Selection possible but not displayed wpHideSelectionNonFocussed, // selection not displayed when not focussed wpHideSelectionNonFocussedAndInactive, // Selection not displayed if not active (not connected to toolbar) wpTraditionalMisspellMarkers, // Draw "Word like" curly underlines wpDisableMisspellMarkers, // Do not draw curly underlines wpShowPageNRinGap, wpDrawFineUnderlines, wpDontGrayHeaderFooterInLayout, wpInfiniteTextArea, wpDontPaintPageFrame, // Do not draw the rectangle around page wpCenterPaintPages, wpUseOwnDoubleBuffer, // Usually a shared double buffer is used // - unless thumbnailmode has been activated or this flag is active wpDrawPageMarginLines, wpDontDrawSectionMarker, wpDrawHeaderFooterLines, // Display gray lines around header and footer wpDontDisplayScrollPageHint, wpDontDrawObjectAnchors // Dont draw the anchor lines for movable objects } WPTools 6 adds TWPViewOptionsEx = set of ( // Unless wpDontDrawObjectAnchors was used for select objects the anchor will be drawn // with this option the anchor will be always drawn at the position of the anchor character wpAlwaysDrawImageAnchors, wpAlwaysDrawTextboxAnchors, wpAutoThumbnailMode, // when in thumbnail mode, page numbers are automatically displayed wpDisableAllSpecialAttributes, // disable, hyperlink, field ... color and underlines wpDisableCharacterStyles, // disable the character styles defined with RTF CS tag wpDisableColorInTableOfContents // TableOfContents will be all black, like in MS Word ); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 65. Guide 59 7.6.4.5 Format Options WPTools 6 uses the properties FormatOptions FormatOptionsEx and FormatOptionsEx2 to change, how the text is formatted. If changed for one RTF-Engine all other RTF-Engines which use the same RTFData object will be affected, too. You need to call ReformatAll(true,true) to update the text. TWPFormatOptions = set of ( // This flags change the display of tables wpDisableAutosizeTables, // - we suggest to enable this flag. Otherwise tables wpNoMinimumCellPadding, // Do not add a one pixel padding to all cells wpfDontBreakTables, // do not break tables at all. Also see wpKeepTogetherAdjac wpfDontBreakTableRows, // do not break table rows wpDontClipCells, // do not clip cells if absolute row heights are used wpfIgnoreMinimumRowheight, // Do not use the row height property wpfIgnoreMaximumRowheight, // Do not use the row maximum height property wpTableRowIndicator, // must be combined with EditOptionsEx : AllowCursorInRow // ------------------------------------------------------------------------- // This flags conmtrol the layout wpfIgnoreKeep, // The WPAT_ParKeep property is ignored (do not break par) wpfIgnoreKeepN, // The WPAT_ParKeepN property is ignored (do not break adjacent wpfKeepOutlineWithNext, // Text which uses the WPAT_ParIsOutline property is ke wpfAvoidWidows, // Avoid single lines on old page wpfAvoidOrphans, // Avoid single lines on new page wpfCenterOnPageVert, // Center text on all pages wpfHangingIndentWithTab, // V5: first tab in paragraph jumps to indent first (t // the left indent will be handled as first tabstop not only if the tab is the // first character but also if the text before the tab fits into the first inde wpfDontTabToIndentFirst, // V5: The oposite to wpfHangingIndentWithTab wpJustifySoftLinebreaks, // Justify n wpJustifyHardLinebreaks, // Justify r wpUseHyphenation, // Use soft hyphens in the text (inserted with Ctrl + '-') wpFooterMinimumDistanceToText, // The footer texts start after the body text (W // ------------------------------------------------------------------------- // This flags control the display of codes. // IMPORTANT: You need to call ReformatAll(true,true) after you have changed th wpShowBookmarkCodes, // display bookmark tags wpShowHyperlinkCodes, // display hyperlinks tags wpShowSPANCodes, // display SPAN tags wpShowInvisibleText, // show text which would be otherwise hidden // ------------------------------------------------------------------------- // Experimental flags wpfHideEmptyParElements, // reserved: Can be used when editing HTML files with wpfXMLOutlineMode, // Debugging mode: Show paragraph tree similar XML in IE wpWriteRightToLeft, // activate RTL writing wpAutoWriteRightToLeft, // reserved for future © 2004-2008 WPCubed GmbH - Munich, Germany
  • 66. 60 WPTools Version 6 // ------------------------------------------------------------------------- // Troubleshooting flags wpUseAbsoluteFontHeight, // Calculate the height of the text using the font siz wpfAlwaysFormatWithScreenRes, // .. even if RM600 is defined in WPCtrMemo wpDisableSpeedReformat, // format only the current page and the next page on re wpDontAdjustFloatingImagePosition // do not adjust image position to keep it on // note that it is not possible to click on an image which is outside of the pa ); TWPFormatOptionsEx = set of ( // ------------------------------------------------------------------------- wpDontAddExternalFontLeading, // When measuring the font height don't add the // value defined for a font: Metrics.tmExternalLeading. This improves compatibi // Alternatively set global variable WPDoNotAddExternalFontLeading := TRUE to // activate this mode for all editors! // ------------------------------------------------------------------------- // Layout flags wpfKeepTablesInTextArea, // If defined avoid that table go into right margin wpKeepTogetherAlwaysNewPage, // if wpfDontBreakTables is used a table which is wpKeepTogetherAdjacentTables, // When tables are not seperated by paragraphs th wpDontUseTablePadding, // Do not read the padding of cells from table wpfIgnoreVertAlignment, // Switches off the vertical alignment wpfKeepNUsesParImages, // When using KeepN paragraph aligned images will be // kept on same page as their anchor paragraph. (changes the value calculated b // Note: Images which use the wrap mode wpwrUseWholeLine will always be checked wpDontIgnoreSpacebeforeOnTopOfPage, // switch "Word" mode off // ------------------------------------------------------------------------- // Limit the use of inherited attributes wpDontUseRowPadding, // Do not read the padding of cells from table row wpDontUseBorderPadding, // Do not use the border width to calculate padding wpDontInheritCellAttr, // Dont inherit cell attributes from table row and table wpDontUseSPANStyles, // Do not use the stalyes of hyperlink and SPAN objects . // ------------------------------------------------------------------------- // modify the way the editor works wpAlwaysContinueBorderAfterCR, // Paragraph.SplitAt (= ENTER key in editor) wil // the new paragraph if the split position is at the end wpNoDefaultParStyles, // Disable default paragraph style handling (So you can h // it yoursel in the OnInitializePar event)! wpfAutoRestartSimpleNumbering, // Reset a numbering level after a line which wa wpfNestedNumberingInTableCells, // Each table cell uses its individual NumberLe // this only affects numbering which does not use outlines wpfSimpleNumberingPriorityOverOutlines, // When outlines (numberlevel>0) are us // numbered paragraphs the simple numbering will continue AFTER the outlines. ( wpfNoAutoDecTabInTable, // Do not automatically align to only decimal tabstop i wpfNoTableHeaderRows, // Ignore table header wpfNoTableFooterRows, // Ignore table footer wpfDisableJustifiedText, // Format Justified text as if it was Left Aligned // ------------------------------------------------------------------------- // Experimental Flags wpAllow_WPAT_NoWrap, // If active don't wrap par marked with WPAT_NoWrap wpfMixRTLText, // If a paragraph which uses the paprRightToLeft attribute the // western text is not reordered wpfStoreWPObjectsInRTFDataProps, // unless this flag is used the TWPObjects wil © 2004-2008 WPCubed GmbH - Munich, Germany
  • 67. Guide 61 // be stored in the TWPRTFDataCollection and not in the TWPRTFDataProps // ------------------------------------------------------------------------- // Activate User CharStyle wpCharEffectIsUserAttribute, // Currently the character attribute WPAT_CharEffe // It can be used to store custom information. If the flag wpCharEffectIsUserAt // the RTF engine will ignore this property. wpfIgnoreTrailingEmptyParAtFooter, // Empty paragraphs are ignored at´the foote wpfDontHideParAboveNestedTable, // allow empty paragraph before a nested table wpfDontCombineDifferentStylePars, // DeleteParagraphEnd will not merge paragrap // Can be selectively set for certain paragarphs using WPAT_ParFlags flag WPFLG wpfNumberingControlledByStyles, // Only supported by WPT format! wpfSectionsRestartFootnoteNumbers, wpfDontIgnoreKeepNInTable, // unless this flag is set the KeepN in table rows i wpfDontIgnoreEmptyHeader ); //:: New HTML formatting routine added to WPTools V6 TWPWebPageFormat = set of ( wpFormatAsWebpage, wpNoMinimumWidth, wpNoMinimumHeight); // + formats TWPFormatOptionsEx2 = set of ( wpfSectionsRestartPageNumbers // All pages restart their numbering , wpfUseKerning // initialize the text and also adjust kerning according to fon , wpfCodeObjectAsXMLTags // visualize the code objects as XML tags , wpDisableBalancedColumns // dont use the new column balancing , wpfCodeObjectCheckParStyles // code objects format the contained text accordi ); 7.6.4.6 HideTableBorders This property has been added to WPTools 6 to allow hiding of table borders. Possible values are: wpDontHide, wpHideOnScreen, wpHideOnPrinter, wpHideAlways 7.6.5 Header and Footer WPTools provides powerful support for headers and footers. You can create a header or footer which is valid for all pages or header and footers for the first, the odd and the even pages. In WPTools Version 6 ist is also possible to start a new section in the text. This section can then have its own set of header and footer and also, optionally, a different page size or different margins. Example: Create a Footer with the text "PAGE # of ##" var par : TParagraph; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 68. 62 WPTools Version 6 txtplain : Cardinal; begin par:=WPRichText1.HeaderFooter.Get(wpFooter,wpraOnAllPages).FirstPar; WPRichText1.WritingAttr.Clear; WPRichText1.WritingAttr.SetFontName('Courier New') ; WPRichText1.WritingAttr.SetFontSize(900); // 9pt txtplain := WPRichText1.WritingAttr.CharAttr; par.ClearText; par.ASet(WPAT_Alignment, Integer(paralRight)); par.Insert(0,'Page ',txtplain); par.InsertNewObject(maxint, wpobjTextObject, false, false,txtplain).Name := WPTextFieldNames[wpoPageNumber]; par.Insert(maxint,' of ',txtplain); par.InsertNewObject(maxint, wpobjTextObject, false, false,txtplain).Name := WPTextFieldNames[wpoNumPages]; end; Please note that the property 'FirstPar' will always create a paragraph if the text block was empty. "Manage Header and Footer", a useful dialog WPTools comes with a useful form in unit WPManHeadFoot to work with header and footer. This form makes it easy to navigate to a certain header or footer. It can be edited, copied or deleted. The two buttons switch between the page layout mode and the normal layout mode. If the user clicks on a header or footer which is currently not visible, the text cannot be edited in page layout mode, so the dialog will automatically select the normal mode. To use this form add the unit to the uses clause and create a global variable: ManHeadFoot : TWPManageHeaderFooter; Now, to show the form in a non-modal: i f ManHeadFoot=nil then ManHeadFoot := TWPManageHeaderFooter.Create(Self); ManHeadFoot.WPRichText := WPRichText1; ManHeadFoot.Show; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 69. Guide 63 We recommend to check out the source of this dialog since it also contains good example code. Properties TWPRichText.WorkOnText and TWPRTFDataBlock.WorkOnText This property selects the text which is currently edited. All commands will operate on the selected text part. Only ‚Load' and ‚Save' will automatically select the body. Possible values for 'WorkOnText' are wpIsBody wpIsHeader wpIsFooter If you need to select the special text for a certain 'range' you the property HeaderFooterTextRange. (type TWPPagePropertyRange). WPRichText1.HeaderFooterTextRange := wpraOnOddPages; WPRichText1.WokOnText := wpIsHeader; Now all the procedures work with the header for odd pages. You can execute mailmerge "MergeText", add number fields "InputTextFieldName('PAGE')" or inserts texts "InputString'Hello World')". If you have a reference to a certain TWPRTFDataBlock - for example provided by WPRichText1. HeaderFooter.Get - you can also set the boolean property WorkOnText of this element to TRUE to select it for editing! WPRichText1.HeaderFooter.Get(wpIsHeader,wpraOnFirstPage,' ').WorkOnText := TRUE; WPRichText1.InputString('WPTools Documentation') ; WPRichText1.WorkOnText := wpIsBody; Please note that you will only see the selected text exclusively in the 'normal' LayoutMode. Otherwise the cursor simply moves to the header or footer region. Notes a) Please note, the above puts the cursor into a certain header/footer text. It does not change which header or footer is currently displayed on the page. If you need to modify the way header and footer are selected for the display in page layout mode use the OnGetSpecialTextevent. This event handler selects the ALL PAGES header or footer for all pages, also first, odd and even no matter what other header or footer are there: procedure TForm1.WPRichText1GetSpecialText(Sender: TObject; par: TParagraph; PosInPar, PageNr: Integer; Kind: TWPPagePropertyKind; var IsLastPage, UseThis: Boolean; var SpecialText: TWPRTFDataBlock); begin // We use 'Get' to find the header or footer SpecialText := WPRichtext1.HeaderFooter.Get(Kind, wpraOnAllPages, ' ') ; // Only then the variable is actually used UseThis := TRUE; end; b) It is important to note that if the PrintHeaderFooter sub-property is set to wprNever, the headers and footers will not be displayed on screen either. Also, you can choose if the headers and footers will be displayed in grayed form by setting the wpDontGrayHeaderFooter sub-property of the ViewOptions property to false. c) The header and footer can be printed in the top/bottom margin area or in the text area. It is up to you what you like better, both possibilities are used by standard word processors. This behavior is controlled by the sub-property PrintHeaderFooterInPageMargins in property HeaderHeader. In the © 2004-2008 WPCubed GmbH - Munich, Germany
  • 70. 64 WPTools Version 6 property Header you can also modify the values for the margins and page and the default values that should be set when the buffer was cleared. Copy all header and footer from one editor to another: var i : Integer; begin for i:=0 t o WPRichText1.HeaderFooter.Count-1 d o i f WPRichText1.HeaderFooter[i].Kind i n [wpIsHeader, wpIsFooter] then WPRichText2.HeaderFooter.Get(WPRichText1.HeaderFooter[i].Kind, WPRichText1.HeaderFooter[i].Range, ' ').RtfText.AsString := WPRichText1.HeaderFooter[i].RTFtext.AsString; end; Collection HeaderFooter : TWPRTFDataCollection The headers and footers (and also the body and optional texts) are stored in the runtime collection property TWPRichText.HeaderFooter. This collection manages a list of instances of the class TWPRTFDataBlock. Each instance holds one 'special' text. This text can be used as a header or a footer within the selected range. TWPRTFDataBlock = class(TCollectionItem) ... published property Name: string property UsedForSectionID property Range: TWPPagePropertyRange property Kind: TWPPagePropertyKind property RtfText: TWPRTFDataContents end; TWPPagePropertyRange = (wpraOnAllPages, wpraOnOddPages, wpraOnEvenPages, wpraOnFirstPage, // these Modes are not compatible to the RTF Standard ! // They have priority !!!! wpraOnLastPage, wpraNotOnFirstAndLastPages, wpraNamed, wpraIgnored); TWPPagePropertyKind = (wpIsBody, wpIsHeader, wpIsFooter, wpIsFootnote, // The last 4 are for internal use only wpIsLoadedBody, wpIsDeleted, wpIsOwnerSelected); TWPRTFDataContents = class(TPersistent) public constructor Create(Source: TWPRTFDataBlock); procedure LoadFromStream(Stream: TStream); virtual ; procedure SaveToStream(Stream: TStream); virtual ; property AsString: string read GetAsString write SetAsString; procedure Assign(Source: TPersistent); override; property Format: string read FFormat write FFormat; end; To change the text you can load the text from a stream using Item.RtfText.LoadFromStream or you can simply set or read the property AsString! This string can also be in HTML or WPTOOLS format! © 2004-2008 WPCubed GmbH - Munich, Germany
  • 71. Guide 65 The RTFDataCollection provides this functions to find certain header or footer entries. You can of course enumerate all the items using the Items[] array. function Find(Kind: TWPPagePropertyKind; Range: TWPPagePropertyRange; const Name: string = '*'; UsedForSectionID: Integer = 0): TWPRTFDataBlock; procedure DeleteTexts(UsedForSectionID: Integer); overload; procedure DeleteTexts(Kind: TWPPagePropertyKind; UsedForSectionID: Integer); overload; procedure DeleteRTFData(RTFData: TWPRTFDataBlock); procedure DeleteText(Kind: TWPPagePropertyKind; Range: TWPPagePropertyRange; UsedForSectionID: Integer = 0) ; We suggest to use this code to add a new header: WPRichText1.HeaderFooter. Get( wpIsHeader, wpraOnAllPages, ' ').RtfText.AsString := WPEditor.AsString; // any other TWPRichText which is used to edit the header -or- WPRichText1.HeaderFooter.Get( wpIsHeader, wpraOnAllPages, ' ').RtfText.LoadFromStream( filestream1 ); C++Builder: WPRichText1->HeaderFooter->Get(wpIsHeader,wpraOnAllPages, " ")->RtfText->AsString; Event: OnGetSpecialText This event receives this parameters: Sender: TObject; par: TParagraph; PosInPar: Integer; PageNr: Integer; Kind: TWPPagePropertyKind; var IsLastPage: Boolean; var UseThis: Boolean; var SpecialText: TWPRTFDataBlock You can set UseThis to true to let the RTF Engine use as header or footer whatever item you have choosen in 'SpecialText'. To switch off the header or footer set this parameter to nil: SpecialText := nil; i f PageNr=1 then UseThis := TRUE else UseThis := FALSE; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 72. 66 WPTools Version 6 7.6.6 Create Sections Sections make it possible to use many different header and footer texts and different page sizes in one document. The editor will display an arrow in the left margin where a new section starts. The following code can be used to create a new section: var sectionprops : TWPRTFSectionProps; begin // New Page WPRichText1.InputString(#12); // New section properties sectionprops := WPRichText1.ActiveParagraph.StartNewSection; // Now we can do something with sectionprops ... end; Each section is defined by an instance of TWPRTFSectionProps. The property WPRichText.Header which stores the default page size for the whole document is consequently implemented using a class which inherits from TWPRTFSectionProps. Usually all instances of TWPRTFSectionProps use the property value defined in the master section property (WPRichText.Header). If certain attribute should be unique for a section the property Selected must be set accordingly. sectionprops.Select := [wpsec_PageSize]; sectionprops.Landscape := TRUE; The following flags exist in property Select: wpsec_PageSize --> Overwrite PageWidth, PageHeight and Landscape wpsec_Margins --> Top, left and other margins wpsec_TabDefault --> Change deftabstop property wpsec_PageMirror --> change the marginmirror property Note: The "speed reformat" feature of WPTools Version 6 does not work well with different page sizes yet. So please switch this feature off using WPAll.FormatOptions := [wpDisableSpeedReformat]; It is also possible to select that certain header or footer texts should be only used for one section. This is done by the property TWPRTFDDataBlock.UsedForSectionID. If this property is changed to sectionprops.SectionID the text block will be only used for that special section. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 73. Guide 67 The demo AppendAsSection shows how texts from different editors (WP1,WP2, WP3) can be appended to create one multi section document in the editor WPALL: The 3 buttons use 3 different approaches: 1.) Full implementation - shows how to work with sections 2.) Use utility procedure AppendAsSection - same functionality as 1) 3.) Use strings in WPTOOLS format with the <newsection/> tag. 4) Append section with individual footer (or header) 7.6.6.1 Full implementation - shows how to work with sections DELPHI CODE procedure TWPALL.AppendClick(Sender: TObject); procedure AppendText(Source : TWPRTFDataCollection); var sectionprops : TWPRTFSectionProps ; i : Integer; textblock : TWPRTFDataBlock; begin // Create a new Page if required i f WPAll.IsEmpty then WPAll.CheckHasBody else WPAll.InputString(#12) ; // Create new section properties sectionprops := WPALL.HeaderFooter.AddSectionProps; // Assign the default page size © 2004-2008 WPCubed GmbH - Munich, Germany
  • 74. 68 WPTools Version 6 sectionprops.Assign(Source.Header); sectionprops.Select := [wpsec_PageSize,wpsec_Margins]; // Copy all header + footer into certain section for i:=0 t o Source.Count-1 d o i f Source[i].Kind i n [wpHeader, wpFooter] then begin textblock := WPALL.HeaderFooter.Append( Source[i].Kind, Source[i].Range, Source[i].Name) ; textblock.UsedForSectionID := sectionprops.SectionID; textblock.RtfText.Assign(Source[i].RTFText); end; // The current paragraph starts this section WPAll.ActiveParagraph.SectionID := sectionprops.SectionID; include(WPAll.ActiveParagraph.prop,paprNewSection); // Copy the text as part of a certain section WPAll.CPPosition := MaxInt; WPAll.SelectionAsString := Source.AsANSIString('WPTOOLS' ;) end; begin WPAll.Clear; AppendText(WP1.HeaderFooter); AppendText(WP2.HeaderFooter); AppendText(WP3.HeaderFooter); end; C++BUILDER Example: This code appends the text from a different editor to "WPRichText1" as a new section void __fastcall TWPALL::AppendNewSection TWPRTFDataCollection * Source) ( { TWPRTFSectionProps * sectionprops; TWPRTFDataBlock * textblock ; int i; // Create a new Page if required i f (this->WPRichText1->IsEmpty()) this->WPRichText1->CheckHasBody(); else this->WPRichText1->InputString( "f",0); // Create new section properties sectionprops = this->WPRichText1->HeaderFooter->AddSectionProps(); // Assign the default page size sectionprops->Assign(Source->Header); //sectionprops->Select = [wpsec_PageSize,wpsec_Margins]; sectionprops->Select << wpsec_PageSize << wpsec_Margins ; // Copy all header + footer into certain section for (i=0; i < Source->Count; i++ ) { TWPRTFDataBlock * src = Source->Items[i] ; i f ( src->Kind == wpHeader || src->Kind == wpFooter ) { textblock = this->WPRichText1->HeaderFooter->Append( Source->Items[i]->Kind , Source->Items[i]->Range , Source->Items[i]->Name ); textblock->UsedForSectionID = sectionprops->SectionID; textblock->RtfText->Assign(Source->Items[i]->RtfText); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 75. Guide 69 } }//for() // The current paragraph starts this section this->WPRichText1->ActiveParagraph->SectionID = sectionprops->SectionID; //include(WPAll->ActiveParagraph->prop,paprNewSection); this->WPRichText1->ActiveParagraph->prop << paprNewSection ; // Copy the text as part of a certain section this->WPRichText1->CPPosition = MaxInt; this->WPRichText1->SelectionAsString = Source->AsANSIString("WPTOOLS" ); } 7.6.6.2 Use utility procedure AppendAsSection procedure TWPALL.Append2Click(Sender: TObject); begin WPAll.HeaderFooter.AppendAsSection(WP1.HeaderFooter); WPAll.HeaderFooter.AppendAsSection(WP2.HeaderFooter); WPAll.HeaderFooter.AppendAsSection(WP3.HeaderFooter); end; 7.6.6.3 Use strings in WPTOOLS format with the <newsection/> tag This technique allows it to create a multi section text by simply appending strings or streams without loading the text into an editor. This shows how versatile the WPTOOLS format can be used: procedure TWPALL.AppendWithStringsClick(Sender: TObject); begin WPAll.AsString := '<newsection/>' + WP1.AsANSIString('WPTOOLS') +'<newsection/>' + WP2.AsANSIString('WPTOOLS') +'<newsection/>' + WP3.AsANSIString('WPTOOLS' ; ) // Using <newsection pagebreak=0/> no page break will be inserted end; 7.6.6.4 Append section with individual footer (or header) You can use WPRichText1.ActiveParagraph.StartNewSection to add a new section property object to the current paragraph. The return object will be an object of class TWPRTFSectionProps. In property 'Select' you can change which properties should be used for this section. Using WPRichText1.HeaderFooter.Append you can append a new RTFDataBlock to be used as footer. 'Get' cannot be used, since this will reuse an existing RTFDataBlock. procedure TForm1.PortraitLandscapeClick(Sender: TObject); var sect : TWPRTFSectionProps; footer : TWPRTFDataBlock; begin WPRichText1.CPPosition := MaxInt; Inc(c); // start a section sect := WPRichText1.ActiveParagraph.StartNewSection; sect.Select := [wpsec_PageSize]; // 1. (in this order!) sect.Landscape := Sender = Landscape; // 2. // Now new page and some text WPRichText1.InputString(#12+#32+IntToStr(c)+#13); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 76. 70 WPTools Version 6 // also add special header+footer for this section footer := WPRichText1.HeaderFooter.Append(wpIsFooter,wpraOnAllPages,'' ); footer.UsedForSectionID := sect.SectionID; WPRichText1.ActiveText := footer; WPRichText1.InputString('Section ' + IntToStr(c) + #9); WPRichText1.InputTextFieldName('PAGE'); WPRichText1.ActiveParagraph.TabstopAdd( sect.PageWidth-sect.LeftMargin-sect.RightMargin, tkRight, tkUnderline ); // select body again WPRichText1.ActiveText := WPRichText1.BodyText; end; Since WPTools V6 You can also use this API: function InputSection(Select: TWPRTFSectionPropsSelect = [wpsec_PageSize, wpsec_Margins]): TWPR It returns a new section object. This property can be used to retrieve the current section object: function ActiveSection: TWPRTFSectionProps; 7.6.7 Use WPTools with TBX (Toolbar2000 Extension) Toolbar2000 is a component by Jordan Russel to build a modern GUI. It can be extended with TBX, written by Alex A. Denisov. You can download and order ToolBar2000 and TBX 2.1 from www.g32.org and www.jrsoftware.org . For additional TBX themes check out www.rmklever.com . It is easy to create an impressive word processing application using this 2 products and of course, WPTools Version 6. INFO: Using the WPTools Version 6 Demo VCL You cannot activate the support for TBX combos using the define USETBX. Therefore the demo does not install the TBX demo proj ect. Note, there is also experimental support for DevExpressBars - use compiler define: USE XP E E R SSBARS 1) Please activate the define USETBX in file WPINC.INC or, better, in your project options. This modifies the compilation of the units wpruler and wpaction. Please make sure you do a 'compile all' after the change. 2) Create a toolbar (see Toolbar2000 and TBX manual) Example: 3) Now you can bring life to the tool items a) For the buttons, such as 'bold' © 2004-2008 WPCubed GmbH - Munich, Germany
  • 77. Guide 71 Create a TActionlist on the form. Assign it to the property 'Actionlist' of the editor component, TWPRichText. In this action list you can create WPTools standard actions, such as TWPABold This new actions can be assigned to the 'Action' property of menu items and button elements. Now they will automatically work with the attached TWPRichText. b) To activate the color drop downs more code is requires. If you use 3 drop downs for text color, highlight color and paragraph background color use the tags 1, 2 and 3. Depending on the tags the drawing and OnChange code can be behave differently. This code is used in the OnDrawImage event of the button itself. procedure TForm1.bColorButtonDrawImage(Item: TTBCustomItem; Viewer: TTBItemViewer; Canvas: TCanvas; ImageRect: TRect; ImageOffset: TPoint; StateFlags: Integer); var DC: HDC; Color: TColor; ColorInd: Integer; begin DC := Canvas.Handle; ColorInd := -1; i f not Boolean(StateFlags and ISF_DISABLED) then begin case Item.Tag o f 1: ColorInd := WPRichText1.CurrAttr.GetColorEx(WPAT_CharColor); 2: ColorInd := WPRichText1.CurrAttr.GetColorEx(WPAT_CharBGColor); 3: ColorInd := WPRichText1.CurrAttr.GetColorEx(WPAT_FGColor); else ColorInd := -1; end; OffsetRect(ImageRect, ImageOffset.X, ImageOffset.Y); ImageRect.Top := ImageRect.Bottom - 4; i f ColorInd >= 0 then begin Color := WPRichText1.CurrAttr.NrToColor(ColorInd); Canvas.Brush.Color := Color; Canvas.FillRect(ImageRect); end else begin FrameRectEx(DC, ImageRect, clBtnShadow, True); DitherRect(DC, ImageRect, clBtnFace, clBtnShadow); end; end; end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 78. 72 WPTools Version 6 Each of the buttons has as subitems (which are used for the dropdown) and ColorPalette. We assigned the tags 1,2 and 3 to this 3 color palettes as well and use the same OnChange code. procedure TForm1.TBXColorPalette1Change(Sender: TObject); var aColor: Integer; begin aColor := (Sender a s TTBXColorPalette).Color; case (Sender a s TTBXColorPalette).Tag o f 1: WPRichText1.CurrAttr.Color := WPRichText1.CurrAttr.ColorToNr(aColor, true); 2: WPRichText1.CurrAttr.BKColor := WPRichText1.CurrAttr.ColorToNr(aColor, true); 3: WPRichText1.CurrAttr.ParColor := WPRichText1.CurrAttr.ColorToNr(aColor, true); end; end; This was already sufficient to make all three color buttons work. c) to bring life to the drop down combos, such as the font selection, you only need to use the special WPTools' pseudo actions (TWPToolsCustomEditContolAction) which have to be added to the action list as well. After such an action has been created in category 'WPT_COMBOS', you can select the style in property 'AttachedControlStyle' and the list box in property 'AttachedControl'. The first time the drop down will be used it will be initialized and the events to modify the attached editor will be set. Please note that the combo box styles cbsColor, cbsBKColor, cbsParColor are not supported by TWPToolsCustomEditContolAction. The style cbsStandard is the neutral value. Note: The TWPToolsCustomEditContolAction can be also used to attach TWPComboBox elements. In this case 'AttachedControlStyle' has to be set to cbsStandard. Now you can create the horizontal and if required, also the vertical ruler: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 79. Guide 73 You only need to attach the ruler controls to the the property WPRuler and VertRuler of the TWPRichText Control. If you are using a vertical ruler disable the flag wpNoVertRulerAttached in WPRuler.Options. How to use the predefined dialogs? Please drop one of the dialog components on the form: Then set the property 'EditBox' to point to the editor which should be used. Using a call to the method 'Execute' the dialog can be opend: (Screenshot of the Border dialog. When this dialog is opend all properties are set to 'undefined': the user can change any of the elements and leave the other unchanged) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 80. 74 WPTools Version 6 7.6.8 Set Attributes in code (unit WPCreateDemoText) WPTools can be perfectly used to create text and tables in code. This text can be saved in RTF or WPTOOLS format, printed and (with wPDF) exported to PDF. In unit WPCreateDemoText you will find a procedure which creates text with different character and paragraph attributes. We have included this procedure in this chapter and inserted screenshots of the output which is created by each part of the code. The procedure starts with the variable declaration. Most important is par: TParagraph which is used as reference to the current paragraph while the text is created. Each new paragraph (or table) is created after this paragraph and the reference is changed to this new object. cha: TWPStoredCharAttrInterface is used to create character attribute index values which are then used in par.SetText and par.Append methods. procedure CreateDemoText(RTFMemo : TWPCustomRtfEdit; Mode : TWPCreateDemoText); var par: TParagraph; // The current paragraph or table row, cell: TParagraph; // the current rows and cells cha: TWPStoredCharAttrInterface; HeadlineA, TextA, RedTextA: Cardinal; procedure CreateEmptyPar; begin par := par.AppendNewPar(true); par.LoadedCharAttr := TextA; // Default attribute for empty paragraphs end; begin cha := RTFMemo.AttrHelper; cha.Clear; cha.SetFontName('Times New Roman') ; cha.SetFontSize(1 2) ; HeadlineA := cha.CharAttr; cha.Clear; cha.SetFontName('Arial' ; ) cha.SetFontSize(1 1) ; TextA := cha.CharAttr; cha.SetColor(clRed); RedTextA := cha.CharAttr; i f Mode=wpNewText then // Clear and set page size and margins begin © 2004-2008 WPCubed GmbH - Munich, Germany
  • 81. Guide 75 RTFMemo.Clear; RTFMemo.Header.SetPageWH( WPCentimeterToTwips(1 5) , WPCentimeterToTwips(2 9.7) , WPCentimeterToTwips(1.5) , WPCentimeterToTwips(1.5) , WPCentimeterToTwips(1.5) , WPCentimeterToTwips(1.5) ); RTFMemo.CheckHasBody; par := RTFMemo.FirstPar; end else i f Mode=wpInsertText then // insert at current position begin par := RTFMemo.InsertPar; end else i f Mode=wpAppendText then // append at end of text begin par := RTFMemo.ActiveText.LastPar; CreateEmptyPar; end; // Set the text of the first paragraph par.SetText('A paragraph with a green background:', HeadlineA); // append a new, clean paragraph and set attributes par := par.AppendNewPar(true); par.ASetColor(WPAT_BGColor, clGreen); par.ASet(WPAT_ShadingValue, 3 0) ; par.SetText('This is 30 % green', TextA); CreateEmptyPar; Please see reference for supported WPAT_ codes. par := par.AppendNewPar(true); par.SetText('A paragraph with a red background and borders:', HeadlineA); // append a new, clean paragraph and set attributes par := par.AppendNewPar(true); // Indents par.ASet(WPAT_IndentLeft, WPCentimeterToTwips(2)); par.ASet(WPAT_IndentRight, WPCentimeterToTwips(2)); // Border par.ASet(WPAT_BorderFlags, WPBRD_DRAW_Left + WPBRD_DRAW_Right + WPBRD_DRAW_Top + WPBRD_DRAW_Bottom); // = WPBRD_DRAW_All4 par.ASet(WPAT_BorderWidth, WPCentimeterToTwips(0.0 5)); // 0,5 mm © 2004-2008 WPCubed GmbH - Munich, Germany
  • 82. 76 WPTools Version 6 par.ASetColor(WPAT_BGColor, clRed); par.ASet(WPAT_ShadingValue, 5 0) ; par.SetText('This is 50 % red, indented', TextA); CreateEmptyPar; par := par.AppendNewPar(true); par.SetText('A paragraph with colored borders and spacing', HeadlineA); par := par.AppendNewPar(true); par.ASet(WPAT_SpaceBefore, WPCentimeterToTwips(0.1)); // 1 mm padding par.ASet(WPAT_SpaceAfter, WPCentimeterToTwips(0.1)); // 1 mm padding par.ASet(WPAT_IndentLeft, WPCentimeterToTwips(0.1)); // 1 mm padding par.ASet(WPAT_SpaceBefore, WPCentimeterToTwips(0.1)); // 1 mm padding par.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4); // all lines par.ASet(WPAT_BorderWidth, WPCentimeterToTwips(0.0 5)); // 0,5 mm par.ASetColor(WPAT_BorderColorL, clRed); // Left par.ASetColor(WPAT_BorderColorT, clGreen); // Top par.ASetColor(WPAT_BorderColorR, clBlue); // Right par.ASetColor(WPAT_BorderColorB, clYellow); // Bottom par.SetText('Red, Green, Blue, Yellow', TextA); CreateEmptyPar; par := par.AppendNewPar(true); par.SetText('A paragraph with tabstops', HeadlineA); par := par.AppendNewPar(true); par.TabstopAdd(WPCentimeterToTwips(3), tkLeft); par.TabstopAdd(WPCentimeterToTwips(9), tkRight, tkDots); par.TabstopAdd(WPCentimeterToTwips(1 2), tkRight, tkNoFill); par.Append('START' RedTextA); , par.Append(# 9 + 'from' + # 9 + 'to' + # 9, TextA); par.Append('END', RedTextA); CreateEmptyPar; // CREATE A HORIZONTAL LINE CreateEmptyPar; with par.AppendNewObject(wpobjHorizontalLine) d o begin IParam := clGreen; // Width := WPCentimeterToTwips(10); CParam := -WPCentimeterToTwips(1) ; end; CreateEmptyPar; horizontal lines can use the follow ing parameters: Width: w idth in tw ips, if 0 the printable area is used © 2004-2008 WPCubed GmbH - Munich, Germany
  • 83. Guide 77 CParam:the offset to the margins of the printable area. Native values are possible IParam:the color as RGB value Height: the height in tw ips Note: AppendNew Object() and AppendNew ObjectPair() can also be used to create hyperlinks . par := par.AppendNewPar(true); par.SetText('A table with colored borders', HeadlineA); par := par.AppendNewTable; // a new table par.ASet(WPAT_BoxWidth, WPCentimeterToTwips(9)); // 9 cm wide par.ASet(WPAT_BoxMarginLeft, WPCentimeterToTwips(2)); // 2 cm from left margin row := par.AppendNewRow(true); // the first row row.ASet(WPAT_PaddingAll, WPCentimeterToTwips(0.2)); // 2 mm padding cell := row.AppendNewCell; pacell.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4); // all lines cell.ASet(WPAT_BorderWidth, WPCentimeterToTwips(0.0 5)); // 0,5 mm cell.ASetColor(WPAT_BorderColorL, clRed); // Left cell.ASetColor(WPAT_BorderColorT, clGreen); // Top cell.ASetColor(WPAT_BorderColorR, clBlue); // Right cell.ASetColor(WPAT_BorderColorB, clYellow); // Bottom cell.SetText('Cell A', RedTextA); cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(3)); // 3 cm wide cell := cell.AppendNewCell(false); // new cell, same colors cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(3)); // 3 cm wide cell.SetText('Cell B', RedTextA); cell := cell.AppendNewCell(false); // new cell, same colors cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(3)); // 3 cm wide cell.SetText('Line 1', TextA); cell.AppendNewPar(true).SetText('Line 2',TextA); // and a second row row := row.AppendNewRow(true); // the first row cell := row.AppendNewCell; cell.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4); cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(9)); cell.SetText('second cell', HeadlineA); RTFMemo.DelayedReformat; end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 84. 78 WPTools Version 6 7.6.9 Tables WPTools Version 6 tables are very powerful: A table is handled like a paragraph object which contains multiple paragraphs as children. These are the rows. In turn, the rows contain multiple paragraphs which are the cells. Each cell paragraph can contain multiple paragraphs which are either text lines or tables: This makes WPTools tables very similar to HTML tables: <table> <tr> <td>Cell 1 in Row 1</td> <td>Cell 2 in Row 1</td></tr> <tr> <td>Cell 1 in Row 2</td> <td>Cell 2 in Row 2</td></tr></table> One possibility to create a table is to use the CreateTable API function: var aCell : TParagraph; with WPRichText1.Memo.DisplayedText.CreateTable(nil) d o begin ASet(WPAT_BorderFlags, WPBRD_DRAW_All4); with CreateRow(nil, true) d o begin InputCell.SetText('Cell 1') ; InputCell.SetText('Cell 2') ; EndRow(ThisRowStyle) end; with CreateRow(nil, true) d o begin InputCell.SetText('Cell 3') ; aCell := InputCell; with aCell d o begin // You could create more text ort a sub table ... © 2004-2008 WPCubed GmbH - Munich, Germany
  • 85. Guide 79 end; EndRow(ThisRowStyle) end; end; The table is created using the 'CreateTable' function of the TWPRTFDataBlock object. The parameter for this function is the paragraph after which the new table should be created. You can use 'nil' to create a table at the end of the document. The resulting value of this function is the TParagraph object which will contain all new rows. Use the CreateRow function of this paragraph to create a new row. The resulting value of the CreateRow function is a TWPTableRowStyle object, which serves as the default style for all cells created and also provides the function to create new cells. This object is deallocated by 'EndRow'. The other possibility is to use the API TableAdd() with a callback function to initialize the table cells. This is usually the more powerfull way to do it. Please see next chapter for various examples. 7.6.9.1 Set width in inch of a certain column Note: The function TParagraph._IsWidth_tw returns the current width of a cell in twips. Please note that this function requires the text to be formatted. Example 1) In this example we do not only set the width of a certain column but adjust the width of the parent table to fit in all columns: var cellwidth_tw, newwidth_tw : Integer; // Twip Values! par, cell, row : TParagraph; begin // cellwidth_tw := WPValueEdit1.Value; // Use a WPValueEdit to enter the number cellwidth_tw := WPInchToTwips(2.5) // use a fixed INCH value row := WPRichText1.TableRow; cell := WPRichText1.ActiveParagraph.Cell; i f (row=nil) o r (cell=nil) then ShowMessage('Please position the cursor in a cell!') else begin // Calculate current width of all columns newwidth_tw := 0; par := row.ChildPar; // this are the cells in this row while par<>nil d o begin i f par=cell then inc(newwidth_tw, cellwidth_tw ) else inc( newwidth_tw, par._IsWidthTw ); par := par.NextPar; // Sibling cell ! end; // Make sure we do not use % values ! row.ParentTable.FixAllCellWidths(0) ; // Assign TWIPS value to THIS column cell.ASetColumn (WPAT_COLWIDTH, cellwidth_tw); // And set the table width to fit all coluns row.ParentTable.ASet(WPAT_BoxWidth, newwidth_tw); // Reformat WPRichText1.DelayedReformat; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 86. 80 WPTools Version 6 end; end; Example 2) This extended example creates an array of TWPValueEdit controls in a scrollbox to let the user see and adjust the width of each individual column: // This is the UpdateGrid procedure procedure TForm1.UpdateWidthGridClick(Sender: TObject); var i: Integer; cell, row: TParagraph; ctrl: TWPValueEdit; begin // Empty the scrollbox for i := ScrollBox1.ControlCount - 1 downto 0 d o with ScrollBox1.Controls[i] d o begin Parent := nil; Free; end; // Fill the scrollbox row := WPRichText1.TableRow; cell := WPRichText1.ActiveParagraph.Cell; i f (row = nil) o r (cell = nil) then ShowMessage('Please position the cursor in a cell!') else begin // Make sure we do not use % values ! row.ParentTable.FixAllCellWidths(0) ; // Create ColCount edits: for i := 0 t o row.ColCount - 1 d o begin ctrl := TWPValueEdit.Create(ScrollBox1); ctrl.Left := i * 8 0; ctrl.Width := 7 8; ctrl.Parent := ScrollBox1; ctrl.Tag := i; // ColNr ctrl.UnitType := euInch; // euCm for Centimeters ctrl.Value := row.Cols[i]._IsWidthTw; ctrl.OnChange := CellValueEditChange; end; end; end; // OnChange event handler for each TWPValueEdit in array procedure TForm1.CellValueEditChange(Sender: TObject); var i, w: Integer; cell: TParagraph; begin i f WPRichText1.TableRow <> nil then cell := WPRichText1.TableRow.Cols[(Sender a s TWPValueEdit).Tag] else cell := nil; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 87. Guide 81 i f cell <> nil then begin // Calculate sum of all width w := 0; for i := 0 t o ScrollBox1.ControlCount - 1 d o inc(w, TWPValueEdit(ScrollBox1.Controls[i]).Value); // and apply to table cell.ParentTable.ASet(WPAT_BoxWidth, w); // and apply to column cell.ASetColumn(WPAT_COLWIDTH, (Sender a s TWPValueEdit).Value); // Reformat WPRichText1.DelayedReformat; end; end; 7.6.9.2 Work with % width WPTools Version 6 also has the ability to use % values for column widths. The procedure WPRichText1.TableMakeCellWidthPC converts all tables in the document to measure the column width in %. If the flag wpAlwaysColWidthPC was set in property EditOptionsEx this procedure is executed after a file was loaded and after each change to the column width using the mouse. The % column widtn is stored as property WPAT_ColWidthPC as %*100. // Set the width in 5, example 10% WPRichText1.ActivePar.ASetColumn(WPAT_COLWIDTH_PC, 1000) ; // Delete the fixed width since it has priority WPRichText1.ActivePar.ADelColumn(WPAT_ColWidth); // Reformat the text WPRichText1.DelayedReformat; 7.6.10 Create Table in Code Very often you will have to create a table, for example a calculation. This can be done best using the TableAdd procedure. This procedure requires only a few parameters, such as row cont and column count but can also work with a callback procedure which is executed for each created cell. Since the callback procedure receives information about the current column and row number it is easy to apply special properties to certain cells or preset the contents of the created cell. Note: You can also use the Rows[r].Cols[c] arrays as described in the second part of this chapter but then you have to take care that you work with the correct row index. Using this arrays is probably also a little slower. Please see reference for supported WPAT_ codes. a) Use TableAdd() with a callback function This code will append a new table to the end of the text: WPRichText1.TableAdd(7,7, [wptblActivateBorders,wptblAppendTableAtEnd],nil, InvoiceDemoCell); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 88. 82 WPTools Version 6 This is a screen shot of the created table: The callback procedure InvoiceDemoCell is implemented like this procedure TWPTableCalc.InvoiceDemoCell(RowNr, ColNr: Integer; par: TParagraph); const prods : array[1. .5] o f string = ( 'Cool', 'Master' 'Hummer' 'High Performace', 'Better' ); , , begin // Set the widths of the rows case ColNr o f 1 : par.ASet(WPAT_COLWIDTH_PC, 500); // % * 100 ! 2 : par.ASet(WPAT_COLWIDTH_PC, 2500) ; else begin par.ASet(WPAT_COLWIDTH_PC, 1400) ; par.ASet(WPAT_Alignment, Integer(paralRight)); end; end; // Set the text and the cell names and commands i f RowNr=1 then // Header Row ------------------------------ begin case ColNr o f 1 : ; 2 : par.SetText('Product' ; ) 3 : par.SetText('Price' ; ) 4 : par.SetText('Amount' ;) 5 : par.SetText('net') ; 6 : par.SetText('+VAT') ; 7 : par.SetText('total' ; ) end; par.ASetColor(WPAT_FGColor, $A0A0A0 ; ) par.ASet(WPAT_ParProtected,1) ; par.ASet(WPAT_Alignment, Integer(paralCenter)); end else i f RowNr=7 then // Footer Row ------------------------------ begin par.ADel(WPAT_BorderWidth); // Delete the border width for ALL linese par.ASet(WPAT_BorderWidthT, 4 0); // ANd set the top line to 40 twips par.ASetAdd( WPAT_BorderFlags, WPBRD_DRAW_Top); // Add a flag! // par.ParentRow.ASet(WPAT_BoxMinHeight, WPCentimeterToTwips(1.5)); par.ASet(WPAT_SpaceBefore, WPCentimeterToTwips(0.3)); par.ASet(WPAT_SpaceAfter, WPCentimeterToTwips(0.3)); par.ASet(WPAT_ParProtected,1) ; case ColNr o f 1 : ; 2 : ; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 89. Guide 83 3 : ; 4 : ; 5 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_NET' ; ) end; 6 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_VAT' ; ) end; 7 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'PAR_TOTAL' ; ) par.ASetCharStyle(true, WPSTY_BOLD); end; end; end else // Data Rows ------------------------------ begin case ColNr o f 1 : begin par.SetText(IntToStr(RowNr-1)); par.ASet(WPAT_ParProtected,1) ; end; 2 : par.SetText(prods[RowNr-1]); 3 : par.SetText(IntToStr(Random(1000) +1)); 4 : par.SetText(IntToStr(Random(3) +1)); 5 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)*left(1)' ; ) par.ASetStringProp(WPAT_PAR_NAME, 'PAR_NET' ; ) par.ASet(WPAT_ParProtected,1) ; end; 6 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'left(1)*0.16' ; ) par.ASetStringProp(WPAT_PAR_NAME, 'PAR_VAT' ; ) par.ASet(WPAT_ParProtected,1) ; end; 7 : begin par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)+left(1)' ; ) par.ASetStringProp(WPAT_PAR_NAME, 'PAR_TOTAL' ; ) par.ASet(WPAT_ParProtected,1) ; end; end; end; end; Note: The commands par.ASetStringProp(WPAT_PAR_COMMAND, 'left(2)+left(1)' ; ) par.ASetStringProp(WPAT_PAR_NAME, 'PAR_TOTAL' ; ) are only usable with WPTools Bundle. They are used to add calculation to a table. b) Use TableAdd() and the Rows[] and Cols[] arrays This example appends 2 rows to the current table (a new table is created if necessary) and loads an image in the second cell of the first row. Screen shot of the created table. (Only the first row is visible.) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 90. 84 WPTools Version 6 procedure TForm1.CreateTableWithImageClick(Sender: TObject); var tbl: TParagraph; obj: TWPTextObj; img: TWPOImage; imagefilename: string; rowoffset : Integer; begin // Select the image from file or use a local image imagefilename := ' '; i f SelectImageFile.Checked then begin i f OpenPictureDialog1.Execute then imagefilename := OpenPictureDialog1.FileName else exit; end; // Create the image object img := TWPOImage.Create(WPRichText1); // uses WPObj_Image try i f imagefilename = ' ' then img.Picture.Assign(Image2.Picture) else img.LoadFromFile(imagefilename); except img.Free; // We cannot load this image raise; end; // This code is required if we do *not* use the wptblAppendTableAtEnd option. // since than an existing table is enlarged tbl := WPRichText1.Table; i f tbl<>nil then begin rowoffset := tbl.RowCount; WPRichText1.ActiveParagraph := tbl.LastChild.ColFirst; end else rowoffset := 0; // Create the table and after that modify the cells // makes sure a new table is created at the end! tbl := WPRichText1.TableAdd(2, 1, [wptblActivateBorders],nil, nil) ; // Set text of first column tbl.Rows[rowoffset+0].Cols[ 0].SetText(imagefilename); // Create the TWPTextObj (which is the reference to image) obj := tbl.Rows[rowoffset+0].Cols[1].AppendNewObject(wpobjImage, false, false, 0 ); obj.ObjRef := img; obj.Frame := [wpframeFine]; // Set the size of the image obj.Width := img.ContentsWidth * 2; obj.Height := img.ContentsHeight * 2; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 91. Guide 85 // Empty row, no borders - move cursor to first cell WPRichText1.ActiveParagraph := tbl.ColFirst; tbl := WPRichText1.TableAdd(2, 1, [], nil, nil) ; WPRichText1.ActiveParagraph := tbl.ColFirst; // Format and display changed text WPRichText1.Refresh; end; c) Create a table with a header and footer row which are repeated on each page This feature is controlled by the flags paprIsFooter and paprIsHeader in the property TParagraph.par. The property must be set in the row paragraph which is the parent paragraph of a cell. The API TableAdd does this for you. We suggest to use this feature with the flag wpfDontBreakTableRows in FormatOptions. In any case please set the property wpDisableSpeedReformat. Example code: procedure TForm1.CreateTableCellCallBackHF(RowNr, ColNr: Integer; par: TParagraph); begin i f RowNr = - 1 then // THIS CELL IS IN THE HEADER © 2004-2008 WPCubed GmbH - Munich, Germany
  • 92. 86 WPTools Version 6 begin par.ASetColor(WPAT_BGColor, clBtnFace); i f ColNr = 1 then par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5) ) else par.SetText('HEADER' ; ) end else i f RowNr = - 2 then // THIS CELL IS IN THE FOOTER begin par.ASetColor(WPAT_BGColor, clBtnFace); i f ColNr = 1 then par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5) ) else par.SetText('FOOTER' ; ) end else begin i f (RowNr and 1) = 0 then par.ASetColor(WPAT_BGColor, clYellow); i f ColNr = 1 then begin par.ASetColor(WPAT_BGColor, clBtnFace); par.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1.5)); par.SetText(IntToStr(RowNr)); end else begin par.SetText(IntToStr(FCellNr)); inc(FCellNr); end; end; end; procedure TForm1.CreateTableWithHeaderFooterClick(Sender: TObject); begin WPRichText1.Clear; FRowCount := 200; // count of rows, excluding header and footer! WPRichText1.FormatOptions := [wpDisableSpeedReformat wpfDontBreakTableRows ; , ] WPRichText1.TableAdd ( 4, FRowCount, [wptblActivateBorders,wptblCreateHeaderRow,wptblCreateFooterRow nil, ], CreateTableCellCallBackHF; ) WPRichText1.Refresh; end; 7.6.11 Work with Styles and Stylesheets (in code) WPTools Version 6 has powerful possibilities to work with text styles. This one is one of the most important chapters of this manual since it explains how the styles - which are the heart of WPTools Version 6 - can be used and controlled. 1) What is a 'style'? A text style is a collection of text attributes which are used for a certain text unless the text itself overrides the attributes. So if you have a style which defines two properties, the font name and the font size and assign it to some text this text will be displayed in the select font in the selected size. If the text was created to use the font size, ie. 10, this font size will be used and not the font size defined in the style. Please note that borders can not be be defined in styles. Text styles usually have names, for example 'Headline' or 'Normal'. Using the names you can select a style from the list of styles and assign it to a paragraph. This assignment usually does not modify © 2004-2008 WPCubed GmbH - Munich, Germany
  • 93. Guide 87 the attributes of the text. (NOTE A) 2) The demo project (Demos/Tasks/ParStyle): This demo shows different ways to deal with the styles. You can play with the default attribute and the properties of one if the styles (FIRST) and immediately see the effect. 3) The default attribute This attribute (or elements of it) will be used for all the text which does not have an attribute ion its own. In this demo we initialize the default attribute using: WPRichText1.DefaultAttr.SetFontName(ComboBox1.Text); WPRichText1.DefaultAttr.SetFontSize(WPValueEdit2.Value / 2 0) ; While the demo is running you can change the defined values and immediately see the effect. So all the paragraph styles (FIRST and SECOND) set their own font size - changing the default will not change the display. But if you are changing the font name, you will see the change not only in the first line but also in the 3rd line: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 94. 88 WPTools Version 6 So how is text created which only uses the default attribute? par := WPRichText1.ActiveText.AppendPar; par.SetText('1) This line uses no style - It uses WPRichText1.DefaultAttr !') ; But in general, when you write text into the editor and no specific font was selected - that entry will be 'undefined' and the default will be used. 4) Creating a paragraph style In this demo we create a style (sty : TWPTextStyle;) like this: sty := WPRichText1.ParStyles.AddStyle('FIRST' ; ) and then assign properties using the ASet methods: sty.ASetAddCharStyle(WPSTY_BOLD); sty.ASetFontName('Verdana' ; ) sty.ASet(WPAT_CharFontSize, 1 3 * 100) ; Please see reference for supported WPAT_ codes. Many customers have asked why the styles do not have properties, such as sty.FontName? The reason for this is that using functions to read and write the properties we can support the <undefined> state. This means that if a font name was not set in a style we can react on that (by using the inherited font name). In general are the ASet... methods used to write a property while the AGet function are used to read it. They usually require a var parameter which will be changed. The result value of an AGet function is TRUE if the property was defined, otherwise it is FALSE. There is also the AGetDef() function which returns the property value itself, if it was not found it returns the default which was passed as parameter. (Read more about ASet) To use the paragraph style we can set the name par.ABaseStyleName := 'FIRST'; or the style: par.ABaseStyle := sty; Important: Only the attributes which are not overridden in the paragraph or the character attributes whill be retrieved from the attached style. This code will simply attach a style, it will not modify any properties of the paragraph or the text in this paragraph. So it is possible that the text does not use certain attributes of the style since they are overridden. a) To remove the attributes which are defined by a style you can use the method SetStyle which can be used with a style number, a style name or the reference to an item of the ParStyles collection. Two optional parameters control if the paragraph attributes and/or the character attributes should be adjusted to make all style attributes visible. par.SetStyle( 'FIRST' , true, true); b) If you are working with selected text, you can use the procedure SelectedTextAttr.ClearAttr(false, true) to remove all styles from the selected text, only the paragraph styles will be used. You can also use SelectedTextAttr.ClearAttrOverride - this will remove the attributes which are used in the paragraph styles. So the attributes which are not override attributes will be preserved, the attributes which will otherwise hide the paragraph style attributes will be removed. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 95. Guide 89 5) Saving and loading Save and restore style sheet in WPCSS format // Save: Memo1.Text := WPRichText1.ParStyles.GetWPCSS; //or WPRichText1.ParStyles.SaveToFile('c:stylesheet.wpcss' ; ) // Load: WPRichText1.ParStyles.SetWPCSS(Memo1.Text); WPRichText1.ReformatAll(true,true); //or WPRichText1.ParStyles.LoadFromFile('c:stylesheet.wpcss' ; ) WPRichText1.ReformatAll(true,true); Save and restore style sheet in CSS format (WPTools 6 only) You can save the paragraphs to a string using a_string := WPRichText1.SaveCSSheet; And load it using WPRichText1.LoadCSSheet( a_string ); 6) Creating embedded SPAN objects (Line 3) Especially to provide strong HTML support WPTools Version 6 can work with embedded SPAN styles. This are special objects which are embedded into the text. They are always used in pairs, one opening and one closing. The opening object can select a style and the closing object selects the previous settings again. If you are working with RTF you should not use SPAN objects. In this demo we create the objects right in the TParagraph object. If you need a less abstract way to work with the objects please check out the 'Code' procedures implemented in TWPRichText. They make it easy to create the objects, for example wrap selected text into a pair of SPAN tags. par := WPRichText1.ActiveText.AppendPar; pos := par.Insert(0, '3) SECOND STYLE - except for ',0) ; spanobj_open := par.InsertNewObject pos,wpobjSPANStyle, true, false) ; ( spanobj_open.StyleName := 'FIRST'; inc(pos); pos := par.Insert(pos, '<SPAN "FIRST">',0) ; spanobj_close := par.InsertNewObject(pos,wpobjSPANStyle, true, true) ; spanobj_close.SetTag(spanobj_open.NewTag); //<-- tags are used to link start with end! inc(pos); pos := par.Insert(pos, ' - END',0) ; par.ABaseStyleName := 'SECOND'; The variables spanobj _open and spanobj _close are of type TWPTextObj. They are created by InsertNewObject which requires four parameters: index: Integer; objtype TWPTextObjType; : HasClosing IsClosing Boolean , : Please note how the value for 'IsClosing' is alternated the the demo source code. "pos" is an integer © 2004-2008 WPCubed GmbH - Munich, Germany
  • 96. 90 WPTools Version 6 value which is the index into the paragraph. The insert() function always returns the position after the inserted text, so pos is always incremented. Please note, that for each open SPAN object the closing object must be on the same paragraph. If you need a linebreak you can use the code Char(10) to create a soft line break. Usually SPAN objects are not visible. They can be made visible using the flag wpShowSPANCodes in property Formatoptions. The display is controlled by property SPANObjectTextAttr, the text can be changed using SPANObjectTextAttr.CodeOpeningText and SPANObjectTextAttr.CodeClosingText (%Y inserts the StyleName). 7) Working with the Character Attributes (Line 4) In this demo we wanted to show how to use the low level methods. You can of course also create text using the procedure InputString and modify the current writing mode using the interface 'CurrAttr' - the demo GridMode uses the InputString technology. But this demo creates the text a bit differently. Please don't read on if you find this confusing. Using the AttrHelper interface ist usually much easier. First we need a buffer for our character attributes: ca : TWPCharAttr; Then we create the paragraph: par := WPRichText1.ActiveText.AppendPar; The buffer is initialized with FillChar(ca, SizeOf(ca), 0); If you are using Delphi 8 you can define another emptyca : TWPCharAttr and assign it to clear ca. Now we fill the paragraph by appending text. pos := par.Insert(0,'4) DEFAULT "FIRST" ',0) ; par.RTFProps.AttrInterface.SetCharStyles(ca, WPSTY_ITALIC, WPSTY_ITALIC); par.RTFProps.AttrInterface.SetFontSize(ca, 1 2) ; pos := par.Insert(pos,'12ptITALIC ',ca); "pos" is an integer value which is the index into the paragraph. The insert() function always returns the position after the inserted text, so pos is always incremented. The lines with par.RTFProps.AttrInterface.... used to modify ca - which in the end will be are used as parameter to insert(). AttrInterface is an object of class TWPCharAttrInterface. This class is not used to store attributes but to modify buffer variables of type TWPCharAttr! 8) The complete source of the "Init Text" procedure var par: TParagraph; sty: TWPTextStyle; pos: Integer; spanobj_open, spanobj_close: TWPTextObj; ca: TWPCharAttr; begin WPRichText1.DefaultAttr.SetFontName(ComboBox1.Text); WPRichText1.DefaultAttr.SetFontSize(WPValueEdit2.Value / 2 0) ; WPRichText1.Clear; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 97. Guide 91 // Set BODY WPRichText1.ActiveText := WPRichText1.BodyText; // ---------------------------------------------------- FIRST LINE ----------- // We use the DefaultAttr ---------------------------------------------------- par := WPRichText1.ActiveText.AppendPar; par.SetText('1) This line uses no style - It uses WPRichText1.DefaultAttr !') ; // ---------------------------------------------------- SECOND LINE ---------- // We use the default Style for the complete paragraph ----------------------- // Creates Style sty := WPRichText1.ParStyles.AddStyle('FIRST' ; ) // Create Paragraph par := WPRichText1.ActiveText.AppendPar; par.SetText('2) This line uses the FIRST style') ; // Assign Style par.ABaseStyle := sty; // Set Props sty.ASetAddCharStyle(WPSTY_BOLD); sty.ASetFontName('Verdana' ; ) sty.ASet(WPAT_CharFontSize, 1 3 * 100) ; // ---------------------------------------------------- THIRD LINE ----------- // We embedd a SPAN style ---------------------------------------------------- // Creates Style sty := WPRichText1.ParStyles.AddStyle('SECOND' ;) // Set Props sty.ASetAddCharStyle(WPSTY_ITALIC); sty.ASet(WPAT_CharFontSize, 1 0 * 100) ; // Create Paragraph par := WPRichText1.ActiveText.AppendPar; pos := par.Insert(0, '3) SECOND STYLE - except for ', 0) ; spanobj_open := par.InsertNewObject(pos, wpobjSPANStyle, true, false); spanobj_open.StyleName := 'FIRST' ; inc(pos); pos := par.Insert(pos, '<SPAN "FIRST">', 0) ; spanobj_close := par.InsertNewObject(pos, wpobjSPANStyle, true, true); spanobj_close.SetTag(spanobj_open.NewTag); //<-- tags are used to link start with end! inc(pos); par.Insert(pos, ' - END', 0) ; par.ABaseStyleName := 'SECOND' ; // ----------------------------------------------------- 4th LINE ------------ // We use character attributes ----------------------------------------------- // 'ca' is used as buffer to create a char attribute par := WPRichText1.ActiveText.AppendPar; FillChar(ca, SizeOf(ca), 0) ; pos := par.Insert(0, '4) DEFAULT "FIRST" ', 0) ; par.RTFProps.AttrInterface.SetCharStyles(ca, WPSTY_ITALIC, WPSTY_ITALIC); par.RTFProps.AttrInterface.SetFontSize(ca, 1 2) ; pos := par.Insert(pos, '12ptITALIC ', ca); FillChar(ca, SizeOf(ca), 0) ; par.RTFProps.AttrInterface.SetFontName(ca, 'Courier New') ; par.RTFProps.AttrInterface.SetFontSize(ca, 1 0) ; par.RTFProps.AttrInterface.SetColor(ca, clGreen); pos := par.Insert(pos, '10ptGreenCourier ', ca); FillChar(ca, SizeOf(ca), 0) ; par.RTFProps.AttrInterface.SetColor(ca, clBlue); par.Insert(pos, 'blue text', ca); // Assign the FIRST Style par.ABaseStyleName := 'FIRST'; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 98. 92 WPTools Version 6 // ----------------------------------------------------- last LINE -------- // We use a character style ----------------------------------------------- // 'ca' is used as buffer to create a char attribute par := WPRichText1.ActiveText.AppendPar; FillChar(ca, SizeOf(ca), 0) ; pos := par.Insert(0, '5) default ', 0) ; par.RTFProps.AttrInterface.SetCharStyleSheet(ca, par.RTFProps.ParStyles.GetID('FIRST')); pos := par.Insert(pos, 'with chararacter-style FIRST', ca); par.Insert(pos, ' default (RTF does not preserve character styles)', 0) ; end; 9) Working with CSS CSS means Cascading Style Sheet and is used to store any kind of paragraph and character attributes in HTML files. WPTools Version 6 was created keeping in mind the philosophy of both, CSS and RTF to provide the developer the best of both worlds. [>>] WPTools' TWPTextStyle class has the ability to dump its properties (to be exact: only the properties supported by CSS) as a CSS string: var sty : TWPTextStyle; begin sty := WPRichText1.ParStyles.FindTextStyle('FIRST' ; ) i f sty<>nil then CSS1.text := sty.AGet_CSS(true,false,true); end; [<<] To load a CSS string back into a TWPTextStyle you can use the TWPCSSParserStyleWP which is implemented in unit WPIOCSS: var sty : TWPTextStyle; parser : TWPCSSParserStyleWP; begin sty := WPRichText1.ParStyles.FindTextStyle('FIRST' ; ) i f sty<>nil then begin parser := TWPCSSParserStyleWP.Create; try parser.AsString := CSS1.text; parser.ApplyToStyle(sty); WPRichText1.ReformatAll(true); // Initialize all because we changed the font WPRichText1.Repaint; finally parser.Free; end; end; end; Please note that the TParagraph inherits from TWPTextStyle - so the above techniques can be also used for any paragraph object! 10) Working with WPCSS WPTools can work with string representation of property settings. Theses are called WPCSS strings due to their similarity to CSS. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 99. Guide 93 To read a WPCSS string use function TWPTextStyle.AGetWPSS( Names, CharAttr, TabAttr: Boolean; OnlyUsePTag: Boolean = FALSE; Abbreviated: Boolean = FALSE): AnsiString; To write it use procedure TWPTextStyle.ASetWPSS( const WPCSSString: AnsiString; Merge: Boolean = false; Abbreviated: Boolean = FALSE); If OnlyUsePTag is set to TRUE no style names are written. You should not use this feature if you want to store the created string. It will be invalid the next time the text is created. If Abbreviated is TRUE the short form for the property names will be used. 7.6.12 Numbering In WPTools Version 6 you can create paragraphs with bullets, simple numbering our outline numbering. The numbering is always controlled by the collection NumberStyles which is accessible by TWPRichText.NumberStyles. Each entry in this collection has a unique ID which is selected in each numbered paragraph using the WPAT_NumberStyle property. In case of outline numbering this style id only needs to select one style from the correct group. The engine will then use the outline level (WPAT_NumberLevel) to select the style within the same group. If a paragraph uses a paragraph style the NumberStyle defined in this style (if any) has priority. The number level of a paragraph has priority over the number level defined by a paragraph style! Please note: The properties WPAT_NumberMode, NumberTEXTB, NumberTEXTA etc should NOT be used for paragraphs or paragraph styles. They are only handled by the styles which are part of NumberStyles collection. Example: Initialize the NumberStyles to use legal numbering 1, 1.1, 1.2 ... © 2004-2008 WPCubed GmbH - Munich, Germany
  • 100. 94 WPTools Version 6 var i: Integer; begin i f WPRichText1 <> nil then for i := 1 t o 9 d o with WPRichText1.NumberStyles.AddOutlineStyle(1, i) d o begin Style := wp_1; TextB := ' '; TextA := '.'; Font := ' '; Indent := 360 * i; UsePrev := TRUE; end; WPRichText1.Refresh; end; Example using 'SelectedTextAttr': Assign simple 1,2,3 numbering to the selected text: var ind : Integer; begin ind := 360; WPRichText1.SelectAll; WPRichText1.SelectedTextAttr.ASet( WPAT_NumberStyle, WPRichText1.NumberStyles.AddNumberStyle( wp_1, // possible values: wp_bullet, wp_circle, // wp_1, wp_lg_i, wp_i, wp_lg_a, wp_a, Before1.Text, After1.Text, ' ', // Font, important for bullets ind, // default indent 0, // Fontsize or default false, // = legal numbering 0, // group, 1 for outline numbering 0 // level in group 1..10 )); end; If the selected numbering style is an outline style, you can use ASet(WPAT_NumberLevel, level) to select the style within this level. This example will apply the level one of the default outline group to either the current paragraph or the selected text if any selection has been made. var sty : TWPRTFNumberingStyle; begin // Locate level 1 in default outline group 1 sty := WPRichText1.NumberStyles.FindNumberStyle(-1,); // and assign the ID to the current paragraph or the selected // paragraphs WPRichText1.ASet(WPAT_NumberSTYLE, sty.I D) ; WPRichText1.ASet(WPAT_NumberLEVEL, 1) ; WPRichText1.Refresh; end; Like the paragraph styles the elements in "NumberStyles" have a property 'TextStyle'. This is a standard TWPTextStyle instance which holds the attributes for the numbering level. You can use it to set additional properties, such as the font color for the numbers. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 101. Guide 95 Example using 'CurrAttr': Assign simple 1,2,3 numbering to the selected text: var ind : Integer; begin ind := 360; WPRichText1.SelectAll; WPRichText1.CurrAttr.BeginUpdate; WPRichText1.CurrAttr.IndentLeft := ind; WPRichText1.CurrAttr.IndentFirst:= -ind; WPRichText1.CurrAttr.SetNumberStyle( Before1.Text, After1.Text, ' ', wp_1, ind ); WPRichText1.CurrAttr.EndUpdate; WPRichText1.HideSelection; end; Example using 'CurrAttr': Create several outline levels in the text var cp : Integer; i,l,m : Integer; begin cp := WPRichText1.TextCursor.DropMarker; // Remove numbers and indent WPRichText1.SelectAll; WPRichText1.CurrAttr.BeginUpdate; WPRichText1.CurrAttr.NumberStyle := 0; WPRichText1.CurrAttr.IndentLeft := 0; WPRichText1.CurrAttr.EndUpdate; WPRichText1.HideSelection; i := 0; l := 1; m := 1; // Move down and apply Outline Mode WPRichText1.CPPosition := 0; repeat WPRichText1.CurrAttr.BeginUpdate; WPRichText1.CurrAttr.OutlineLevel := l; WPRichText1.CurrAttr.IndentLeft := l * 360; WPRichText1.CurrAttr.IndentFirst := -360; WPRichText1.CurrAttr.EndUpdate; inc(i); i f i=3 then begin l := l+m; i f (l=4) o r (l=1) then m := -m; i := 0; end; until not WPRichText1.CPMoveDownPar; end; Note about CurrAttr: This is an interface which was introduced in WPTools 3. It is still supported and implemented in unit WPCTRRich. If you do not want to link unit WPCTRRich you cannot use CurrAttr. For new code we suggest to use ActiveParagraph, ASet or SelectTextAttr methods. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 102. 96 WPTools Version 6 7.6.13 Hyperlinks Certain texts can be interactive in WPTools - this means the text can be automatically highlighted when the mouse is moved over it (hover or "hot" effect) or an event can be triggered when the user clicks on it. The standard interactive texts are hyperlinks. Hyperlinks in WPTools Version 6 start with a hyperlink start tag <a> and end with a closing tag </a> . All these tags are represented by TWPTextObj instances. (These tags can be made visible using the 'FormatOptions'!) To read the hyperlinks URL use obj.Source, to modify the visible text change obj.EmbeddedText! This code can be used to create a hyperlink: WPRichText1.InputHyperlink( 'WPTOOLS' ,'BOOK1' . ) Since hyperlinks are marked with paired TWPTextObj instances it is also possible to create those tags directly by code. This is very useful if you are creating the text using the low level paragraph procedures: var par : TParagraph; link_tag : TWPTextObj; begin par := WPRichText1.ActiveText.AppendNewPar(); par.Append('This is a link: '); // Some Text // Create a link link_tag := par.AppendNewObjectPairwpobjHyperlink,'WPCubed GmbH'); ( link_tag.Source := 'http://www.wpcubed.com'; // to display: WPRichText1.Refresh; end; Note: The above code uses the function AppendNewObjectPair´. This function internally executes code similar to this example: startobj := par.AppendNewObject wpobjHyperlink,true,false); // Opening ( par.Append('WPCubed GmbH'); // some text endobj := par.AppendNewObject(wpobjHyperlink,true,true); // Closing endobj.SetTag(startobj.NewTag); // Link Opening<->Closing startobj.Source := 'http://www.wpcubed.com'; // The URL Hyperlink tags can have a style attached. This style can be a paragraph style: startobj.StyleName := ParStyleName; // set a reference to a paragraph style If no style name was specified the list of paragraph styles will be searched for a style with the name "A". Alternatively the style can be defined directly in the TWPTextObj instance: startobj.MakeStyle(true); startobj.Style.ASet(WPAT_CharFontSize, 2200); // create a large font startobj.Style.ASetColor(WPAT_CharColor, clRed); // as red text startobj.Style.ASetColor(WPAT_CharBGColor, clYellow); // on yellow background startobj.Style.ASetFontName('Courier New') ; Please note that these style definitions have a lower priority than the text attributes defined for the © 2004-2008 WPCubed GmbH - Munich, Germany
  • 103. Guide 97 enclosed characters (this are the attributes which have been assigned to the text) and the attributes defined in the property AutomaticTextAttr. They are only loaded and saved in the WPTOOLS format, not in RTF format. React on the click on hyperlinked text: Event OnClickHotText procedure TForm1.WPRichText1HyperLinkEvent(Sender: TObject; text, url: String; IgnoredNumber: Integer); begin i f Pos('http:',url)>0 then ShellExecute(Handle, 'open', PChar(url), ' ', ' ', SW_SHOW ) ; end; This event is executed after a dounble click on hyperlinked text. It will be triggered after a single click if the property 'OneClickHyperlink' has been set to true. React on the click on hyperlinked text: Event OnClickHotText procedure TForm1.WPRichText1ClickHotText(Sender: TObject; par: TParagraph; posinpar, X, Y: Integer; Button: TMouseButton; Shift: TShiftState; TxtObj: TWPTextObj); begin i f TxtObj.ObjType=wpobjHyperlink then begin WPRichText1.BookmarkMoveTo(TxtObj.Source); end; end; this bookmark was created with WPRichText1.BookmarkInput('BOOK1'); Which types of text objects are clickable is always controlled by property ClickableCodes. This means the event can be also created for text which has been wrapped by merge fileds, bookmarks or span codes. The event OnClickHotText is always triggered by a single click. Please note that in WPTools Version 6 hyperlinks are not represented by text with a certain attribute (asfHyperlink) followed by hidden text (afsHidden) as it was in WPTools 4 and before! How to display visited hyperlinks in a different color: We use the property WPRichText1.HyperlinkTextAttr.UseOnGetAttrColorEvent := TRUE; and a string list: FVisitedHyperlinks := TStringList.Create; In the hyperlink event we add URLs to the stringlist to know later if the link was already clicked: procedure TForm1.WPRichText1HyperLinkEvent(Sender: TObject; text, url: string; IgnoredNumber: Integer); begin FVisitedHyperlinks.Add(url); i f Pos('www', url) > 0 then ShellExecute(Handle, 'open', PChar(url), ' ', ' ', WM_SHOWWINDOW); end; Now we can use the OnGetAttributeColor event to modify the special text attribute 'on the fly': procedure TForm1.WPRichText1GetAttributeColor(Sender: TObject; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 104. 98 WPTools Version 6 var CharStyle: TCharacterAttr; par: TParagraph; posinpar: Integer); var txtobj : TWPTextObj; begin txtobj := WPRichText1.CodeInsideOf(par,posinpar,wpobjHyperlink); i f txtobj<>nil then begin i f FVisitedHyperlinks.IndexOf(txtobj.Source)>=0 then CharStyle.TextColor := clGreen; end; end; The reference CharStyle: TCharacterAttr which is passed to the event is a reference to a copy of the HyperlinkTextAttr property object. We can modify it without any sideffect to the other links in the text. But please do not modify the reference, just the properties of this object! This technique can be also used for other 'special texts' - but the property UseOnGetAttrColorEvent must be always set to true to activate the feature. 7.6.14 Bookmarks The bookmarks of WPTools Version 6 are very powerful. They can be nested and several functions make it easy to work with the marks. It is possible tio hide the bookmarks or to sow them. When they are displayed it is even possible to display themy through owner drawn code as in this example: This code creates a book mark WPRichText1.BookmarkInput( 'BM' + IntToStr(bm),true); The following functions deal with bookmarks //:: finds and selects a Bookmark function BookmarkSelect(const Name: string; OnlyText: Boolean): Boolean; //:: locates a bookmark and and moves Cursor function BookmarkMoveTo(const Name: string): Boolean; //:: locates a bookmark and and moves Cursor. Start at the current position function BookmarkMoveToNext(const Name: string): Boolean; // locates and moves Cursor to next .. //:: locates and returns position (or -1 iof not found) function BookmarkFind(const Name: string): Integer; {:: Creates a bookmark. If text is currently selected the selected text will be put iside of the new bookmark markers } function BookmarkInput(const Name: string; PlaceCursorBetweenTags: Boolean = FALSE):TWPTextObj; procedure BookmarkDeleteAllMarkers; {:: Deletes the bookmark markers with the given name. This procedure searches through all blocks of the current text } procedure BookmarkDeleteMarkers(const Name: string) ; procedure BookmarkDelete(const Name: string; Marks, Text: Boolean); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 105. Guide 99 function BookmarkDeleteInPar(const NameStart: string; par: TParagraph): Boolean; procedure BookmarkGetList(list: TStrings; FromAllBlock: Boolean = FALSE); overload; procedure BookmarkGetList(list: TWPTextObjList; FromAllBlock: Boolean = FALSE); overload; {:: This functions checks if the text at the given position is locate inside of a bookmark.<br> To check if there is a bookmark object under the mouse cursor use CodeAtXY(X,Y,Code)! } function BookmarkAtXY(x, y: Integer; var Bookmark: TWPTextObj): Boolean; {:: This functions checks if the cursor is inside of a bookmark.<br> To check for a text object, such a bookmark object at the cursor position use CPAttr.GetObject } function BookmarkAtCP: TWPTextObj; function BookmarkFirstInPar(par: TParagraph): string; function BookmarkAtParLin(par: TParagraph; pos_i n_par: Integer): TWPTextObj; function BookmarkForceInPar(par: TParagraph; const frmstr: string): string; / / reserved Example: This code in the event handler for OnTextObjGetTextEx is used to paint the bookmarks in the image above: procedure TForm1.WPRichText1TextObjGetTextEx(RefCanvas: TCanvas; TXTObject: TWPTextObj; var PrintString: WideString; var WidthInPix, HeightInPix: Integer; var PaintObject: TWPTextObj; Xres, YRes: Integer); begin i f not ShowBookmarkCodes.Checked then exit; i f TXTObject.ObjType=wpobjBookmark then begin // If you set PaintObject to anything <> nil PrintString will be ignored! // Here you can initialize an event for an owner draw object PaintObject := TXTObject; PaintObject.OnPaint := OnPaintObject; WidthInPix := RefCanvas.TextWidth(TXTObject.Name+'<'+#32) ; end; end; procedure TForm1.OnPaintObject(Sender : TWPTextObj; OutCanvas : TCanvas; XRes, YRes : Integer; X, Y, W, H, BASE: Integer ); var s : string; begin OutCanvas.Rectangle(x,y,x+w,y+h); OutCanvas.MoveTo(x+w,y+1) ; OutCanvas.LineTo(x+w,y+h); OutCanvas.LineTo(x+1,y+h); i f wpobjIsClosing i n Sender.Mode then s := '>' + Sender.Name else s := Sender.Name + '<'; OutCanvas.TextOut(x+2,y+BASE,s); end; Sometimes you will need to replace the text which is wrapped within bookmarks. This can be useful to process mailmerge forms which used to be processed using a word processor and OLE. The following code is fast and effective: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 106. 100 WPTools Version 6 procedure TForm1.ReplBookmarksClick(Sender: TObject); var allbm : TWPTextObjList; i : Integer; begin allbm := WPRichText1.CodeListTags(wpobjBookmark,'*ALL*' ,true); try for i:=0 t o allbm.Count-1 d o i f allbm[i].Name='sum' then // check the name! begin // simply assign text. You can even create new paragraphs // with #13 or #13+#10 sequences. allbm[i].EmbeddedText := '$134.39'+#13#10 +'$180.00'+#13#10 +'$200.00'+#13#10+'$272.00'; end; finally allbm.Free; end; WPRichText1.ReformatAll(false,true); end; 7.6.15 XML editor mode WPTools 6 supports a special XML editing mode. A loaded XML text will be displayed as: for this the XMLTAGS reader must be used. WPRichText1.LoadFromFile( filename , true, 'XMLTAGS-utf8' ); and the FormatOptions initialized as follows: WPRichText1.FormatOptions := WPRichText1.FormatOptions + [wpShowSPANCode WPRichText1.FormatOptionsEx2 := WPRichText1.FormatOptionsEx2 + [wpfCodeO wpfCodeObjectAsXMLTags creates the tag boxes shown above. wpfCodeObjectCheckParStyles makes the editor look up paragraph styles which have the same name as the tags which include the text. In this case the paragraph style collection uses the CSS definition © 2004-2008 WPCubed GmbH - Munich, Germany
  • 107. Guide 101 Lemma{font-family:'Courier New';font-weight:bold;color:red} Entsprechung{font-family:'Tahoma';font-size:13.00pt;} which was assigned to the editor using: WPRichText1.LoadCSSheet( css_string ); ... but there is more ... in case You have the WPTools 6 Premium edition, You can also work with XML schemas. from the tags in the XML schema it is possible to create a popup menu with items, which can be inserted at a certain position in the editor. To make this easy the premium edition includes the unit WPXMLSchema which implements the class TWPXMLSchmema. You need to create it like this: procedure TForm1.FormCreate(Sender: TObject); begin Schema := TWPXMLSchmema.Create(Self); Schema.OnPopupMenuClick := DoPopupMenuClick; end; procedure TForm1.FormDestroy(Sender: TObject); begin Schema.Free; end; DoPopupMenuClick is a method which should handle the click event on one popup menu item. procedure TForm1.DoPopupMenuClick(fMenu: TXMLMenuItem; fXMLSchema: TWPXMLSchmema; fXMLTag: TWPX var men: TXMLMenuItem; begin men := fMenu.XMLParent; while men <> nil d o begin WPRichText1.InputCode(wpobjCode, men.XMLTag.nameparam, ' ', [wpinpWrapSelectedText, wpinpNew men := men.XMLParent; end; WPRichText1.InputCode(wpobjCode, fXMLTag.nameparam, ' ', [wpinpWrapSelectedText, wpinpNewParag WPRichText1.SetFocus; end; The popup menu object is created on the form and assigned to the WPRichText PopupMenu property. Then in event PopupMenu1Popup this code is placed: var bb: Boolean; procedure TForm1.PopupMenu1Popup(Sender: TObject); var a: TWPXMLSchemaTag; pt: TPoint; begin i f not bb then try bb := true; PopupMenu1.Items.Clear; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 108. 102 WPTools Version 6 a := Schema.LocateContext( WPRichText1.ActivePar, WPRichText1.ActivePosInPar); i f a <> nil then a.FillPopupMenu(PopupMenu1, 0) ; WPRichText1.GetParXYBaselineScreen(WPRichText1.ActivePar, WPRichText1.ActivePosInPar, pt.x, pt.y); pt := WPRichText1.ClientToScreen(pt); PopupMenu1.Popup(PopupMenu1.PopupPoint.X, pt.y + 4) ; finally bb := false; end; end; Of course the menu can be also created a bit differently or other items can be added. In action the popup menu can look like this: 1) press the context menu key on the keyboard: 2) select the item and press enter © 2004-2008 WPCubed GmbH - Munich, Germany
  • 109. Guide 103 7.6.16 Printing - how to set printer properties WPTools Version 6 provides you with the possibility to easily change important printer options (such as paper tray) using an easy to use property PrintParameter. During the printing the "PrintParameter" are evaluated and applied to the DEVMODE structure which is used by the printer driver. There is also the event OnSetupPrinterEvent to let you change the DEVMODE structure yourself. This feature can be disabled using the flag wpDoNotChangePrinterDefaults in property PrintParameter.PrintOptions. The demo 'PrinterSet' shows how to: · change the orientation of a certain page · activate duplex mode (requires support of the printer!) · display the available paper trays · change the paper tray for the first and the rest of the pages · print the document · use BeginPrint/EndPrint to print the contents of two different editors into one printer cue - with a continuous page numbering. You can use the TWPRichText method Print to print the complete document or PrintPages to print a range of documents. If you first call BeginPrint(title, pagenumber) a new printing cue is opened. For best results it is necessary to provide this function with the number of the first page. This number is 0 based. (This is necessary since the printer properties for the first page must be set before Printer.BeginDoc is executed) If you print from different editors please make sure that the text in all this editors is formatted. If an editor is not visible call ReformatAll! To get the correct page numbering assign the total page count to WPRichText.Enviroment.CombinedPrintPageCount You will also need to set the flag . wpUsePrintPageNumberin the property PrintParameter.PrintOption of the editor which started the printing cue. The value of this -first- property will automatically be used by all the editors which are © 2004-2008 WPCubed GmbH - Munich, Germany
  • 110. 104 WPTools Version 6 printing into the same printing cue. When printing is finished don't forget to call EndPrint! Notes: · The property Printer.PageNumber is not updated as usual. · We recommend to add a possibility (i.e. INI entry) to your application to make it possible for the end user to set wpDoNotChangePrinterDefaults. · WPTools Version 6 selects the paper from the list of the available papers of this printer. Only if the paper is not found (by comparing the size) 'custom' is used. The list of papers is updated at printime, property PageDefs is not used. So it is possible to change the printer (using Printer. PrinterIndex) at any time! · Please also see the chapter about WYSIWYG · You will need to temporarily hide mail-merge markers using the propertry InsertPointTextAttr. Hidden if this flag is not true anyways. 7.6.17 Superprint: Print Booklets and Labels We've added a new component, TWPSuperPrint, that allows you to centrally manage a variety a WPTools printing features. Should you wish to, you also have the option of bypassing the Print Console, and controlling these aspects directly within your code, hidden from the user. This component includes the ability to control: · true "booklet-style" printing – the component has been optimized to automatically control "two up" (two pages per sheet) booklet printing · printing of labels (automatically tiled across the page! See other demo) · include a background image, selected via a subdirectory browser · tiling or stretching of the included background image · placement of the background image either vertically or horizontally centered, left, right, top, or bottom, and combinations of those (e.g., vertically centered and horizontally centered, horizontally centered on the bottom, etc.) As mentioned, almost all the power and flexibility of the TWPSuperPrint component can be centrally controlled from within a dialog box-type form. Please check out the LabelPrint demo to learn how to add simple label printing to your application. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 111. Guide 105 For an example of this, see the "SuperPrint" example off of DemosTasks. Please feel free to use as much of that code as you wish (or the entire Print Console itself) in your own application. The demo is written to be as generic as possible. Should you wish to customize the code, check out the assignments in FormCreate event (e.g., the EditBox and Preview properties), and tailor them to fit your particular case. Please note that the controls on the right hand side of the form could be easily copied and pasted into a different application. To print a test booklet, simply select File / Print, everything is already set up in the demo. Out comes the pages, and correctly ordered! Optionally, if you have the product wPDF, also a PDF file can be created. For the sake of simplicity, from here on we'll refer to the TWPSuperPrint component as WPSuperPrint1, or SuperPrint. Booklet Printing Let's talk about the booklet printing feature of this component. This is driven by a single procedure, WPSuperPrint1.SetTwoUpBooklet (). When called with first parameter set to true, and then the printed page width and height in twips, a number of adjustments required to print in a booklet format are made behind the scenes - so that you (or the person running the application) don't have to. They include: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 112. 106 WPTools Version 6 · setting the printer into Landscape · controls whether the page passed to it for printing is printed on the left or right half of the page · internally adjusts the page dimensions so that two pages can be printed on a sheet (more on this coming up) · sets the orientation of the TWPRichText component referred to by WPSuperPrint1. EditBox to Portrait (well, more accurately, it sets Landscape to False) · sets WPSuperPrint1's Columns property to 2, and its Rows property to 1 · sets WPSuperPrint1's Mode property to wpprPageColRows. This tells it how to calculate the page height and width · sets all of WPSuperPrint1's margins (left, right, top, and bottom) to 0, since we already have the margins in the text Note: be sure to set TwoUpBooklet to True p rior to executing a Printer.BeginDoc statement. If you don't, SuperPrint's code that automatically changes the printer's Orientation to Landscape will have no effect. One very important part of booklet printing is to determine the order that pages are sent to the printer. If we use as an example for this discussion a 12 page document, the pages would be ordered like this: The first sheet contains the highest and lowest numbered page. The second sheet contains the second highest and lowest numbered pages. Notice how on the first sheet, the even numbered page is positioned on the left half and the odd numbered page on the right . However, the second sheet reverses that – the odd page is on left, the even page on the right. WPSuperPrint1 automatically handles the left / right positioning, whichever is appropriate to the current sheet. Your code is responsible for supplying SuperPrint with the page number to print. WPSuperPrint1's OnCalcPageNumber should point to your procedure that calculates the page number ordering. For example: WPSuperPrint1.OnCalcPageNumber := DoCalcPage The DoCalcPage procedure in the SuperPrint demo is a good example of how to calculate the page numbers. As written, it will work with documents any number of pages. Another important part to using the TWPSuperPrint component is its Paint procedure. The © 2004-2008 WPCubed GmbH - Munich, Germany
  • 113. Guide 107 demo's StartPrint procedure is a good example of setting up the call to WPSuperPrint1's Paint procedure, and the parameters passed to it. A word about the call to RestoreValues in StartPrint. As mentioned above, SuperPrint internally adjusts page dimensions and orientation to print in booklet format. Therefore, you should store those properties somewhere (see the Demo's FormCreate event handler) so they can be restored after printing. And they should be saved p rior to setting WPSuperPrint1's TwoUpBooklet property True. In the demo, that's what RestoreValues is about. And although the code to store the values is in FormCreate, that code could just as easily have been moved to the top of StartPrint. Hint: By using a printer capable of supporting 11 inch x 17 inch paper, you can produce booklets with a page dimension of 8.5 inches by 11 inches (since the paper's orientation is switched to Landscape behind the scenes)! Labels To print labels, first, create the label (from within the TWPRichText component you assigned to the WPSuperPrint1.EditBox property), or import one into there. Then (in no particular order) · set TwoUpBooklet to False · include the line: WPSuperPrint1.Mode := wpprLabels (where WPSuperPrint1 is the TWPSuperPrint component), or add a checkbox that you use to assign/unassign the Mode property · set Columns to the number of labels you want across the page · set Rows to how many rows of labels you want across the page · set Copies to the product of Rows * Columns That's all you have to do to print labels! 7.6.18 Print Labels (TWPSuperPrint) We added an easy to understand demo which shows how to use the TWPSuperPrint component to add label printing to your application. Note: Please also see the new integrated label printing feature which was added to WPTools 6! The demo code has been created in a way which makes it easy to use it in your application. This is a screenshot of the main dialog - Page 1: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 114. 108 WPTools Version 6 This is a screenshot of the main dialog - Page 2: The code also implements loading and saving of the label definitions into one XML file which will be stored in the application root path. The format used inside this XML file is: <?xml version="1.0" encoding="windows-1250"?> © 2004-2008 WPCubed GmbH - Munich, Germany
  • 115. Guide 109 <Labels> <Def Name="2*5_on_Din_A4"> <TopMargin>238</TopMargin> <LeftMargin>238</LeftMargin> <RightMargin>238</RightMargin> <BottomMargin>238</BottomMargin> <HorzMargin>0</HorzMargin> <VertMargin>0</VertMargin> <ColCount>2</ColCount> <RowCount>5</RowCount> <PageWidth>11906</PageWidth> <PageHeight>16838</PageHeight> </Def> Note: The horizontal and vertical Margins are the small gaps BETWEEN labels - they are not the "pitch". To use this form you only have to create and show it. To load the first lines of the text into the label use the procedure LoadAddress. Example: procedure TForm1.Button1Click(Sender: TObject); begin WPLabelForm.LoadAddress( WPRichText1 ); WPLabelForm.Show; end; On the form the user can select a font, change the text and change the label definition. If any of values, such as the count of columns, is changed, this procedure is executed: procedure TWPLabelForm.ColCountChange(Sender: TObject); begin i f FLocked then exit; WPSuperPrint1.PageWidth := PageWidth.Value; WPSuperPrint1.PageHeight := PageHeight.Value; WPSuperPrint1.Rows := RowCount.IntValue; WPSuperPrint1.Columns := ColCount.IntValue; WPSuperPrint1.MarginTop := TopMargin.Value; WPSuperPrint1.MarginLeft := LeftMargin.Value; WPSuperPrint1.MarginRight := RightMargin.Value; WPSuperPrint1.MarginBottom := BottomMargin.Value; WPSuperPrint1.InbetweenHorz := HorzMargin.Value; WPSuperPrint1.InbetweenVert := VertMargin.Value; WPSuperPrint1.LabelStartRow := StartRow.Value; WPSuperPrint1.LabelStartColumn := StartCol.Value; WPSuperPrint1.Copies := Copies.Value; WPRichText1.Header.SetPageWH( WPSuperPrint1.Width, WPSuperPrint1.Height, 0, 0, 0, 0) ; WPRichText1.ReformatAll; end; It sets the properties of the SuperPrint component. After that the properties Width and Height which © 2004-2008 WPCubed GmbH - Munich, Germany
  • 116. 110 WPTools Version 6 reflect the current label size are applied to the TWPRichText - it holds the text of the label and is used for the printing process. The printing is started with this code: procedure TWPLabelForm.Button1Click(Sender: TObject); begin Printer.Title := 'Label' ; Printer.BeginDoc; WPSuperPrint1.Paint( Printer.Canvas, -GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX), // Offset in pixels -GetDeviceCaps(Printer.Handle, PHYSICALOFFSETy), // Offset in pixels GetDeviceCaps(Printer.Handle, LOGPIXELSY) / 1440, // Multiplicator for Parameters (twips->Canvas) [wpDoNotScalePage]); // Options Printer.EndDoc; end; It uses the Paint procedure of the SuperPrint component to render one page to the printer canvas. The physical offsets are passed as negative values to make sure the positions are acurate. Of course this offsets can be used to adjust the printing. 7.6.19 Print/Edit elements of TWPRTFDataCollection The demo DynAssignRTFData shows how to use the TWPPaintEngine to paint elements stored in a TWPRTFDataCollection on any Canvas. It also shows how to dynamically assign the RTFData object to an editor - so the editor can edit any of the elements in the collection! © 2004-2008 WPCubed GmbH - Munich, Germany
  • 117. Guide 111 This code is used to assign the text which should be edited: procedure TWPDynRTFData.DynDataListDblClick(Sender: TObject); begin // Remove link to this RTF Data Object WPRichText1.RemoveRTFData; // And add link to this one WPRichText1.SetRTFData( DynDataList.Items.Objects[DynDataList.ItemIndex] a s TWPRTFDataCollection); // Make sure the new text is shown WPRichText1.SetFocus; end; The boxes are painted using TWPPaintEngine components which have been created in code in "FormCreate". To change the RTFData which they are using this code is used after Drag&Drop: paint1.RTFData := DynDataList.Items.Objects[DynDataList.ItemIndex] a s TWPRTFDataCollection; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 118. 112 WPTools Version 6 7.6.20 Create Table from Database WPTools possibilities to create text and tables in code are extraordinary powerful. We created an example (DemosGridMode) which loads a BDE database and creates a table with all the rows. Optionally blobs can be loaded using the TParagraph.LoadFromStream method - this will preserve the formatting. The demo also shows how to change the background color using the ASetColor procedure. Optionally rows can be splitted on several pages (RowBreak) and, if you want to test the performance, the same data can be imported 100 times. This screen shot was taken after the well known BIOLIFE database was loaded - 100 times. This created 2800 rows and images on 400 pages in only 2.8 seconds! (P-M 1.6 GHZ) This is the main routine of the demo. It first cleares the text and sets the page size. Then a footer is created to show the page number. After that a new table paragraph is created (table) which will then host all rows. Please note that the CreateRow function creates an object of the class TWPTableRowStyle. This class inherits from TWPTextStyle (so does class TParagraph!) and is used as template for all cells which are created. So when you make changes to rowstyle, the new properties will be applied to all cells which are created afterwards using InputCell. The rowstyle object is deleted when the row is completed with EndRow. procedure TForm1.LoadFromDataSet(Data: TDataSet; aName: string; LoadBlobAsANSI: Boolean); var i, a, a_max, RowNr: Integer; table, cell, row: TParagraph; b: Boolean; obj: TWPTextObj; wpobj: TWPObject; bit: TBitmap; rowstyle: TWPTableRowStyle; tim: Cardinal; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 119. Guide 113 stream: TStream; begin WPRichText1.Clear; Caption := 'loading... - press ESCAPE to abort'; tim := GetTickCount; try WPRichText1.EditOptions := []; // Set Page Size WPRichText1.Header.PageSize := wp_DinA4; WPRichText1.Header.LeftMargin := WPCentimeterToTwips(2) ; WPRichText1.Header.RightMargin := WPCentimeterToTwips(1) ; WPRichText1.Header.TopMargin := WPCentimeterToTwips(1.5) ; WPRichText1.Header.BottomMargin := WPCentimeterToTwips(1.5) ; WPRichText1.Header.Landscape := TRUE; // WPRichText1.WordWrap := TRUE; // Create Footer WPRichText1.ActiveText := WPRichText1.HeaderFooter.Get( wpIsFooter, wpraOnAllPages); WPRichText1.InputString(aName + # 9) ; WPRichText1.InputTextField(wpoPageNumber); WPRichText1.ASet(WPAT_BorderFlags, WPBRD_DRAW_Top); WPRichText1.SetTabPos(MaxInt, tkRight); // Switch to BODY WPRichText1.ActiveText := WPRichText1.BodyText; RowNr := 0; i f StressTest.Checked then begin a_max := 100; ProgressBar1.Visible := TRUE; end else begin a_max := 1; ProgressBar1.Visible := FALSE; end; // Boolean to alternate the background b := FALSE; // Add all rows to this table table := WPRichText1.ActiveText.CreateTable (nil); table.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4); // now create the rows, a_max is used for stresstest for a := 1 t o a_max d o begin ProgressBar1.Position := a; ProgressBar1.Update; // Start at the beginning of database Data.First; // Repeat for all data rows repeat inc(RowNr); rowstyle := table.CreateRow(nil, true); i f rowstyle <> nil then © 2004-2008 WPCubed GmbH - Munich, Germany
  • 120. 114 WPTools Version 6 begin b := not b; rowstyle.ASetColor(WPAT_BGColor, clBlue); rowstyle.ASet(WPAT_ShadingValue, 3 0) ; // Create first Column with numbers cell := rowstyle.InputCell; cell.ASet(WPAT_BorderFlags, WPBRD_DRAW_Right); cell.ASet(WPAT_COLWIDTH, WPCentimeterToTwips(1)); cell.SetText(IntToStr(RowNr)); // Make sure every other row is *not* shaded: i f b then begin rowstyle.ADel(WPAT_BGColor); rowstyle.ADel(WPAT_ShadingValue); end; rowstyle.ASet(WPAT_IndentRight, 7 2) ; for i := 0 t o Data.Fields.Count - 1 d o begin cell := rowstyle.InputCell; i f Data.Fields[i] i s TGraphicField then begin bit := TBitmap.Create; bit.Assign(Data.Fields[i]); wpobj := TWPOImage.CreateImage (WPRichText1.Memo.RTFData, bit); obj := TWPTextObj.Create; cell.Insert(0, obj); obj.ObjRef := wpobj; obj._SetObjType(1 2); // = TWPTextObjType.wpobjImage obj.Width := wpobj.ContentsWidth div 3; obj.Height := wpobj.ContentsHeight div 3; bit.Free; end else i f Data.Fields[i] i s TBlobField then begin i f LoadBlobAsANSI then begin // The simple method which loads text into one paragraph cell.ASet(WPAT_CharFontSize, 600) ; cell.SetText(Copy(Data.Fields[i].AsString, 1, 400) + '...') ; end else begin // the "difficult" method which also loads formatted text stream := TBlobStream.Create(Data.Fields[i] a s TBlobField, bmRead); try cell.LoadFromStream stream, ( 'AUTO', ' ', [wploadpar_ClearShading]); finally stream.Free; end; end; end else cell.SetText(Data.Fields[i].AsString); cell.ASet(WPAT_BorderFlags, WPBRD_DRAW_Bottom); end; // Create the cells row := table.EndRow(rowstyle); i f not RowBreak.Checked then row.ASet(WPAT_ParKeep, 1) ; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 121. Guide 115 // Allow ESCAPE i f (GetAsyncKeyState(VK_ESCAPE) shr 1 5) <> 0 then begin i f MessageBox(Handle, 'Abort loading of data ?', 'ESCAPE', MB_YESNO) = IDYES then exit; end; end; Data.Next; until Data.EOF; end; // for a finally WPRichText1.Refresh; Caption := Format('WPTools5: Created %d rows in %.02f sec', [RowNr, (GetTickCount - tim) / 1000]); end; end; 7.6.21 Print Watermarks Watermarks are drawings which are printed before the actual contents of a page is printed. In WPTools Version 6 Watermarks have to be printed inside the event handler for OnPaintWatermark . This event gets this parameters: Sender a reference to the TWPRichText component which tiggered the event RTFEngine is the RTF Engine (= TWPRichText.Memo) toCanvas the drawing canvas for the output. During printtime this is the printer canvas. PageRect the bounding rectangle of the page. During printime the Top,Left coordinate is set to the negative physical offset to make it easy to print at exact positions. PaintPageNr the number of the page, 0 based RTFPageNr 0 or the number of the text page which is printed later over the watermark. You can access the definition object (class TWPVirtPage) of this page by reading RTFEngine.DisplayedText.Pages[RTFPageNr - 1]. WaterMarkRef reserved XRes and YRes define the current resolution. This is very important to convert real coordinates into coordinates on the virtual paper. You can use this functions to convert CM into pixles. The result value has to be added to PageRect.Left or PageRect.Top. function XP(cm: Double): Integer; begin Result := MulDiv(WPCentimeterToTwips(cm), Xres, 1440) ; end; function YP(cm: Double): Integer; begin Result := MulDiv(WPCentimeterToTwips(cm), Yres, 1440) ; end; CurrentZoom specifies the zooming the editor uses, at printtime it is 1 PaintMode the paint mode which is currently used. By checking for 'wppInPaintDesktop' you can write code which is not active at print time. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 122. 116 WPTools Version 6 Example: You can print the contents of one editor to the background of a different editor: (demo WaterM3) procedure TWPLetterHeadEdit.WPRichText1PaintWatermark(Sender: TObject; RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas; PageRect: TRect; PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject; XRes, YRes: Integer; CurrentZoom: Single; PaintMode: TWPPaintModes); begin // We are painting on a RTF-Engine surface so use the // PaintPageMode wpNoViewPortAPI since everything has been // set up already WPLetterhead.PaintPageOnCanvas(0, 0, 0, 0, 0, toCanvas, [], XRes, YRes, -1, -1, [wpNoViewPortAPI ); ] end; Other examples how Watermarks can be used (Project: DemosTasksWatermark) a) show a background pattern on the virtual paper - but do not print this pattern: var x,y : Integer; bit : TBitmap; begin i f wppInPaintDesktop i n PaintMode then begin x := PageRect.Left; bit := Image1.Picture.Bitmap; while x<PageRect.Right d o begin y := PageRect.Top; while y<PageRect.Bottom d o begin toCanvas.Draw(x,y,bit); inc(y, bit.Height); end; inc(x, bit.Width); end; end; end; b) Draw a 0.5 cm grid using light blue color, this grid is also printed var i,j : Integer; begin toCanvas.Pen.Width := 0; toCanvas.Pen.Color := $00FAD5AF ; toCanvas.Pen.Style := psSolid; for i:=1 t o 1000 d o begin j := PageRect.Left + MulDiv(WPCentimeterToTwips(0.5 * i), Xres, 1440) ; i f j>= PageRect.Right then break; toCanvas.MoveTo(j, PageRect.Top); toCanvas.LineTo(j, PageRect.Bottom); end; for i:=1 t o 1000 d o begin j := PageRect.Top + MulDiv(WPCentimeterToTwips(0.5 * i), Yres, 1440) ; i f j>= PageRect.Bottom then break; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 123. Guide 117 toCanvas.MoveTo(PageRect.Left, j); toCanvas.LineTo(PageRect.Right, j); end; end; c) Print a frame line around the text area (1) We are using the main page layout information: procedure TWaterM.WPRichText1PaintWatermark(Sender: TObject; RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas; PageRect: TRect; PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject; XRes, YRes: Integer; FCurrentZoom : Single; PaintMode: TWPPaintModes); var r: TRect; begin r.Left := PageRect.Left + MulDiv( RTFEngine.RTFData.Header .LeftMargin, XRes, 1440); r.Top := PageRect.Top + MulDiv( RTFEngine.RTFData.Header.TopMargin, YRes, 1440 ); r.Right := PageRect.Right - MulDiv( RTFEngine.RTFData.Header.RightMargin, XRes, 1440); r.Bottom := PageRect.Bottom - MulDiv( RTFEngine.RTFData.Header.BottomMargin, YRes, 1440); toCanvas.Pen.Color := clBtnShadow; toCanvas.Pen.Width := 0; toCanvas.Brush.Style := bsClear; toCanvas.Rectangle(r); end; (2) Now we are using the page layout information for the current page. i f RTFPageNr > 0 then begin r.Left := PageRect.Left + MulDiv( RTFEngine.DisplayedText.Pages[ RTFPageNr - 1].PageMarginLeft, XRes, 1440) ; r.Top := PageRect.Top + MulDiv( RTFEngine.DisplayedText.Pages[RTFPageNr - 1].PageMarginTop, YRes, 1440) ; r.Right := PageRect.Right - MulDiv( RTFEngine.DisplayedText.Pages[RTFPageNr - 1].PageMarginRight, XRes, 1440 ); r.Bottom := PageRect.Bottom - MulDiv( RTFEngine.DisplayedText.Pages[RTFPageNr - 1].PageMarginBottom, YRes, 1440 ); toCanvas.Pen.Color := clBtnShadow; toCanvas.Pen.Width := 0; toCanvas.Brush.Style := bsClear; toCanvas.Rectangle(r); end; Please note that the parameter RTFPageNr can be 0 if the page was inserted as "external page". d) Display a pre-printed form (such as a money transfer form) as part of the page. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 124. 118 WPTools Version 6 This example requires to use the event OnMeasurePage as well. In this event we reserve space at the bottom of the first page: const PR_Form_Height = 1 0.5; // Form Height in CM PR_Form_Width = 1 5.0; procedure TForm1.WPRichText1MeasureTextPage(Sender: TObject; PageInfo: TWPMeasurePageParam); begin // We want to make sure the first page has a bottom margin which is // large enough for our form i f PageInfo.pagenr = 1 then begin PageInfo.marginbottom := WPCentimeterToTwips(PR_Form_Height); PageInfo.changed := TRUE; end; end; The PaintWatermark code only draws on the first page: procedure TForm1.WPRichText1PaintWatermark(Sender: TObject; RTFEngine: TWPRTFEnginePaint; toCanvas: TCanvas; PageRect: TRect; PaintPageNr, RTFPageNr: Integer; WaterMarkRef: TObject; XRes, YRes: Integer; CurrentZoom: Single; PaintMode: TWPPaintModes); // ~~~~~~~~~~~~~~~~~~~~~ Convert CM values into pixel ~~~~~~~~~~~~~ function XP(cm: Double): Integer; begin Result := MulDiv(WPCentimeterToTwips(cm), Xres, 1440) ; end; function YP(cm: Double): Integer; begin Result := MulDiv(WPCentimeterToTwips(cm), Yres, 1440) ; end; // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ var r, r2: TRect; off, w: Integer; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 125. Guide 119 begin i f PaintPageNr = 0 then begin r := PageRect; r.Top := r.Bottom - YP(PR_Form_Height); toCanvas.Pen.Color := clBlack; toCanvas.Pen.Style := psDash; toCanvas.MoveTo(r.Left, r.Top); toCanvas.LineTo(r.Right, r.Top); // Draw the form at the right bottom border r.Left := r.Right - XP(PR_Form_Width); // Draw line toCanvas.MoveTo(r.Left, r.Top); toCanvas.LineTo(r.Left, r.Bottom); // Draw the sizzors toCanvas.Font.Name := 'WingDings' ; toCanvas.Font.Height := -YP(0.5) ; toCanvas.TextOut( PageRect.Left + XP(0.7), r.Top- toCanvas.TextHeight(#$22) div 2 , #$22 ); // This is background of the form, we do not draw this when // we are printing! i f wppInPaintDesktop i n PaintMode then begin r2 := r; inc(r2.Left,XP(0.1)); inc(r2.Top,YP(0.1)); toCanvas.Brush.Color := clYellow; toCanvas.FillRect(r2); end; // This are the form text toCanvas.Brush.Color := clWhite; toCanvas.Font.Name := 'Courier New'; toCanvas.Font.Height := -YP(0.5) ; toCanvas.Font.Style := [fsBold]; off := YP(0.1) ; // NAME r2.Left := r.Left + XP(1.0) ; r2.Top := r.Top + YP(2) ; r2.Right := r2.Left + XP(1 0) ; r2.Bottom := r2.Top + YP(0.7) ; toCanvas.FillRect(r2); toCanvas.TextOut(r2.Left + off, r2.Top + off, NameE.Text); // ADR r2.Left := r.Left + XP(1.0) ; r2.Top := r.Top + YP(5.5) ; r2.Right := r2.Left + XP(1 0) ; r2.Bottom := r2.Top + YP(0.7) ; toCanvas.FillRect(r2); toCanvas.TextOut(r2.Left + off, r2.Top + off, AdrE.Text); // COST, right aligned r2.Left := r.Left + XP(8.5) ; r2.Top := r.Top + YP(4.5) ; r2.Right := r2.Left + XP(5) ; r2.Bottom := r2.Top + YP(0.7) ; toCanvas.FillRect(r2); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 126. 120 WPTools Version 6 w := toCanvas.TextWidth(CostE.Text); toCanvas.TextOut(r2.Right - off - w, r2.Top + off, CostE.Text); // For Debugging // Draw a Line at 10,10 CM i f DrawDebugCross.Checked then begin toCanvas.TextOut( PageRect.Left+XP(1 0), PageRect.Top, '10') ; toCanvas.TextOut( PageRect.Left, PageRect.Top+YP(1 0), '10') ; toCanvas.MoveTo( PageRect.Left, PageRect.Top + YP(1 0)); toCanvas.LineTo( PageRect.Right, PageRect.Top + YP(1 0)); toCanvas.MoveTo( PageRect.Left+XP(1 0), PageRect.Top); toCanvas.LineTo( PageRect.Left+XP(1 0), r.Top); end; end; end; 7.6.22 Use "External Pages" What are "external pages" ? This are pages which are displayed by WPTools Version 6 before, after or within the regular text. In page layout mode the page will be displayed as if it was a text page. Why do I need it ? If you want to display the output of your favourite report generator and text in a powerful preview component. For example if you need to create a big report which contains of several parts, text and graphical report data. This feature will also help a lot if you need to combine the ANSI text (such as logging data) with formatted text. Since the external pages are rendered through an event it is possible to work with thousands of them - there is no need to initialize the graphical data at the beginning. Why can't I use watermarks for this? Actually you can - and this would be the second best way to implement it. But with the use of "external pages" no empty pages have to be inserted into the text, no place holders are required. The formatted text stays completely unaltered. Can I save the document with the additional pages ? No, this is not possible. The data which has been added as "external pages" will not be saved or loaded. The editor will only load and save (and edit) the regular text. The installed (TasksExternalPages) demo creates a list with dummy data. This list is displayed at the beginning of the formatted text: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 127. Guide 121 Methods to be used for external pages: (only in TWPRTFEnginePaint = WPRichText.Memo) Adds a reference 'ExternPageRef'. The returned TWPRTFExternPageRef contains variables to change the page size. function ExternPageRefAdd( mode: TWPRTFExternPageRefMode; PageNrX: Integer; Order: Integer; ExternPageRef: TObject; WatermarkRef: TObject): TWPRTFExternPageRef; procedure ExternPageRefClear - deletes all references and frees the data Events to be used with external pages: OnPaintExternPage (in TWPCustomRtfEdit and TWPRTFEnginePaint) Sender: TObject; RTFEngine: TWPRTFEnginePaint; prCanvas: TCanvas; xoff, yoff: Integer; r: TRect; PaintPageNr: Integer; ExternPageRef: TObject; DestXRes, DestYRes: Integer OnInitPage (only in TWPRTFEnginePaint = WPRichText.Memo) Sender: TObject; // The 'Parent' Object of the RTF - Engine, usually the TWPRichText RTFEngine: TWPRTFEnginePaint; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 128. 122 WPTools Version 6 paintpagenr: Integer; // the number of the paint page (this is not the RTF page) rtfpagenr: Integer; // the RTF page which will be used if ExternPageRef stayes to be nil var ExternPageRef: TObject; // assign an object here to disable RTF text for this page var WatermarkRef: TObject; // assign data required to paint a watermark var PaperColor: TColor; var pagewidth, pageheight, marginleft, margintop, marginright, marginbottom: Integer) o f object; Example: procedure TWPExternalP.UpdateBtnClick(Sender: TObject); var s : string; c,i : Integer; x,y,th,h: Integer; pw, ph : Integer; PageNr : Integer; aPage : TMetafile; aCanvas : TMetafileCanvas; procedure NewPage ; begin i f aPage = nil then begin aPage := TMetafile.Create; aPage.Width := pw; aPage.Height := ph; end; i f aCanvas=nil then begin aCanvas := TMetafileCanvas.Create( aPage, 0) ; aCanvas.Font.Name := 'Arial'; aCanvas.Font.Size := 1 1; h := ph - WPScreenPixelsPerInch; y := WPScreenPixelsPerInch div 2; th:= aCanvas.TextHeight('Ag') ; x := WPScreenPixelsPerInch div 2; end; PageCount.Caption := IntToStr(PageNr+1) + ' Extern Pages'; PageCount.Update; end; procedure PostPage ; var PageRef : TWPRTFExternPageRef; begin FreeAndNil(aCanvas); i f aPage<>nil then begin // We add a page at a certain location. The data object we added // Is freed automatically unless we set in the // returned TWPRTFExternPageRef object the property DontFreeExternPage // to true PageRef := WPRichText1.Memo.ExternPageRefAdd( wpAsPageX, PageNr, 0, aPage, nil ); // This values are optional PageRef.PageWidth := MulDiv( pw, 1440, WPScreenPixelsPerInch); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 129. Guide 123 PageRef.PageHeight := MulDiv( ph, 1440, WPScreenPixelsPerInch); inc(PageNr); aPage := nil; end; end; begin c := StrToInt(ACount.Text); // The count of lines to be printed s := ALine.Text; // the format string aPage := nil; aCanvas := nil; PageNr := 0; WPRichText1.Memo.ExternPageRefClear; // The page size for the external page in pixels pw := MulDiv( WPRichText1.Header.PageWidth, WPScreenPixelsPerInch, 1440) ; ph := MulDiv( WPRichText1.Header.PageHeight, WPScreenPixelsPerInch, 1440) ; // Try it: The external pages will be landscape! // ph := MulDiv( WPRichText1.Header.PageWidth, WPScreenPixelsPerInch, 1440); // pw := MulDiv( WPRichText1.Header.PageHeight, WPScreenPixelsPerInch, 1440); // Now create the lines for i:=1 t o c d o begin i f y>h then PostPage; NewPage; aCanvas.TextOut(x,y,Format(s,[i,Random(1000000)])); inc(y,th); end; PostPage; WPRichText1.DelayedReformat; end; Since we use simple metafiles as data for the external pages the painting is very easy. Of course we could also use a string list or a custom object and so avoid the overhead of metafiles. If you know in advance the count of pages but do not want to load the data in the beginning, this is possible, too. The data can be initializes when it is used first in the event OnPaintExternPage. procedure TWPExternalP.WPRichText1PaintExternPage(Sender: TObject; RTFEngine: TWPRTFEnginePaint; prCanvas: TCanvas; xoff, yoff: Integer; r: TRect; PaintPageNr: Integer; ExternPageRef: TObject; DestXRes, DestYRes: Integer); begin prCanvas.StretchDraw( r, ExternPageRef a s TGraphic ); end; 7.6.23 Images © 2004-2008 WPCubed GmbH - Munich, Germany
  • 130. 124 WPTools Version 6 (This screenshot shows text and a floating obj ect in WPTools Version 6.) Insert a graphic: procedure TForm1.InsertGraphicClick(Sender: TObject); var txtobj: TWPTextObj; begin i f OpenDialog2.Execute and (WPRichText1.ActiveParagraph <> nil) then begin WPRichText1.SetFocus; txtobj := WPRichText1.Memo.RTFData.TextObjects.Insert( WPLoadObjectFromFile( WPRichText1.Memo.RTFData, OpenDialog2.FileName), 1440, 1440) ; // Code to change the graphic, for example change width and height ot the 'PositionMode' i f txtobj <> nil then begin end; WPRichText1.Refresh; end; end; Note: If you need to work directly with a TParagraph you can use the method TParagraph. AppendNewObject to create a new TWPTextObj object. To the ObjRef property of this object you can assign the TWPObject instance created by WPLoadObjectFromFile. (See CreateTable demo) Modify selected object: procedure TForm1.ChangeObjectPositionAndWrapMode(Sender: TObject); begin i f WPRichText1.TextObjects.SelectedObj>nil then < begin WPRichText1.TextObjects.ChangePositionMode( WPRichText1.TextObjects.SelectedObj, wpotPar, wpwrBoth); end; end; Load new image into object: procedure TForm1.Loadimage1Click(Sender: TObject); begin i f (WPRichText1.TextObjects.SelectedObj<>nil) and (OpenPictureDialog1.Execute) then begin WPRichText1.TextObjects.SelectedObj.LoadObjFromFile ( OpenPictureDialog1.FileName); end; end; Replace text with a graphic file var GSFile: string; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 131. Guide 125 TextObject: TWPOImage; // from unit WPObj_Image begin GSFile := 'C:testfile.jpg' ; i f FileExists(GSFile) then with WPRichText1 d o begin Finder.ToStart; while Finder.Next('<<Graphic-Signature>>' d o ) begin TextObject := TWPOImage.Create(WPRichText1.Memo.RTFData); // ! TextObject.LoadFromFile(GSFile); SetSelPosLen(Finder.FoundPosition, Finder.FoundLength); TextObjects.Insert(TextObject); end; end; end; Alternative, using a graphic from an TImage object: WPRichText1.Finder.ToStart; while WPRichText1.Finder.Next('[sig]' d o ) begin WPRichText1.CPPosition := WPRichText1.Finder.FoundPosition; WPRichText1.Finder.FoundText := ' '; WPRichText1.TextObjects.InsertCopy(Image1.Picture.Graphic); end; WPRichText1.DelayedReformat; Hint: It would be also possible to use modify WPRichText1.TextObjects.SelectedObj.Wrap and WPRichText1.TextObjects.SelectedObj.PositionMode directly but this change is not logged for undo. 7.6.23.1 Provide a Graphic Popup Menu Please insert this popup menu ito your form: object GraphicPopupMenu: TPopupMenu Left = 675 Top = 443 object ascharacter1: TMenuItem Tag = 1 Caption = 'as character' end object reltoparautowrap1: TMenuItem Tag = 2 Caption = 'rel. to par - auto wrap left or right' end object reltoparwrapleftandright1: TMenuItem Tag = 3 Caption = 'rel to par - wrap left and right' end object reltopagenowrappng1: TMenuItem Tag = 4 Caption = 'rel. to page - no wrappng' end object reltopagewrapleftandright1: TMenuItem Tag = 5 Caption = 'rel. to page - wrap left and right' end end © 2004-2008 WPCubed GmbH - Munich, Germany
  • 132. 126 WPTools Version 6 Now select all items and create a one OnClick event for all menu items: In C++ Builder use this code: void __fastcall TForm1::GraphicOptionsClick(TObject *Sender) { i f (WPRichText1->SelectedObject) { switch ((((TComponent *)Sender)->Tag)) { case 1: WPRichText1->SelectedObject->PositionMode = wpotChar; break; case 2: WPRichText1->SelectedObject->Wrap = wpwrAutomatic; WPRichText1->SelectedObject->PositionMode = wpotPar; break; case 3: WPRichText1->SelectedObject->Wrap = wpwrBoth; WPRichText1->SelectedObject->PositionMode = wpotPar; break; case 4: WPRichText1->SelectedObject->Wrap = wpwrNone; WPRichText1->SelectedObject->PositionMode = wpotPage; break; case 5: WPRichText1->SelectedObject->Wrap = wpwrBoth; WPRichText1->SelectedObject->PositionMode = wpotPage; break; } } } In Delphi You can use this code: procedure TWPForm1.GraphicOptionsClick(Sender: TObject); begin i f (WPRichText1<>nil) and (WPRichText1.SelectedObject <> nil) then case (Sender a s TComponent).Tag o f 1: WPRichText1.SelectedObject.PositionMode := wpotChar; 2: begin WPRichText1.SelectedObject.Wrap := wpwrAutomatic; WPRichText1.SelectedObject.PositionMode := wpotPar; end; 3: begin WPRichText1.SelectedObject.Wrap := wpwrBoth; WPRichText1.SelectedObject.PositionMode := wpotPar; end; 4: begin WPRichText1.SelectedObject.Wrap := wpwrNone; WPRichText1.SelectedObject.PositionMode := wpotPage; end; 5: begin WPRichText1.SelectedObject.Wrap := wpwrBoth; WPRichText1.SelectedObject.PositionMode := wpotPage; end; end; end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 133. Guide 127 7.6.23.2 Linked Images Linked images use the string propetry StreamName to identify their contents. If this property is <>"" the binary image data will not be saved in a document fromat which othewise allows embedding, such as RTF and WPT. To HTML images can only be saved if a "StreamName" is provided. The event OnHTTPRequestImage is used to load the image data for images placed in HTML code and also for linked images loaded in RTF or WPT format. This event should be used to load images from a database which are only referenced in the text blob. Please read the FAQ at http://wpcubed.com/forum/viewtopic.php?p=3287#3287 The event OnPrepareImageforSavingcan be used to create image files (or database records) for images which are embedded. procedure TForm1.WPRichText1RequestHTTPImage(RTFData: TWPRTFDataCollection; Reader: TWPCustomTextReader; const LoadPath, URL: String; TextObject: TWPTextObj; var Ok: Boolean); var stream : TMemoryStream; loadurl : string; begin i f pos('http:',lowercase(URL))> then 0 loadurl := URL else loadurl := LoadPath + URL; stream := TMemoryStream.Create; try Panel2.Caption := URL; try Application.ProcessMessages; // this example uses INDY IdHTTP1.Get(loadurl,stream); except on e : Exception d o Panel2.Caption := URL + '-->' + e.Message; end; i f stream.Size>0 then try TextObject.LoadObjFromStream(URL,stream); except on e : Exception d o Panel2.Caption := URL + '-->' + e.Message ; end; ok := TRUE; i f ok then Panel2.Caption := ' '; Application.ProcessMessages; finally stream.Free; end; end; 7.6.23.3 Technical Information In previous versions of WPTools embedded objects were stored by using a list of references. A tag, which was required to identify a reference, was stored in the TAttr record which was used parallel to the character. WPTools Version 6 uses a similar method which is much more powerful and consumes less memory. Each paragraph can have a CharObjectIndex array. If no objects are used, this array is not allocated. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 134. 128 WPTools Version 6 The items in this array are the index values +1 in the FWPTextObjs array of the same paragraph. If a character is an embedded object the entry in the corresponding CharObjectIndex item is set to value <> 0. (Using this double reference makes it quicker to test whether a character is an object or not.) To check if a character is an embedded object, please use the IsObject function of the TParagraph object. 7.6.24 TWPTextObj with custom draw event Instances of the TWPTextObj class with ObjType set to wpobjTextObj are used to display page numbers, time and similar fields. Unlike mail merge fields those objects are represented using just one character. So it is impossible to have a line wrap in the text. Normally the objects are painted using an internal routine, so for objects with the name 'PAGE' the current page number is inserted. The text objects are created using WPRichText1.InputTextFieldName ('CHANGEME'); To have a different text you can provide an event handler for the OnTextObjGetTextEx event: procedure TForm1.WPRichText1TextObjGetTextEx(RefCanvas: TCanvas; TXTObject: TWPTextObj; var PrintString: WideString; var WidthInPix, HeightInPix: Integer; var PaintObject: TWPTextObj; Xres, YRes: Integer); begin i f TXTObject.Name='CHANGEME' then begin PrintString := 'more...' ; end; end; This will display the text object with the text "more..." using the attributes defined for that object. It is very easy to create a different background color: procedure TForm1.WPRichText1TextObjGetTextEx(RefCanvas: TCanvas; TXTObject: TWPTextObj; var PrintString: WideString; var WidthInPix, HeightInPix: Integer; var PaintObject: TWPTextObj; Xres, YRes: Integer); begin i f TXTObject.Name='CHANGEME' then begin PrintString := 'more...'; RefCanvas.Brush.Color := clYellow; end; end; Now, if you want to make that object clickable you can add an event handler to the OnTextObjectClick event: procedure TForm1.WPRichText1TextObjectClick(Sender: TWPCustomRtfEdit; pobj: TWPTextObj; obj: TWPObject; var ignore: Boolean); begin i f (pobj.ObjType=wpobjTextObject) and (pobj.Name='CHANGEME' then ) begin // locate next data record or similar ... ShowMessage('Object was clicked!' + #13 + pobj.AGetWPSS ); end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 135. Guide 129 end; Usually text objects can not be selected like images. This feature can be activated in EditOptionsEx, flag wpTextObjectSelecting. If you need to avoid the selection for certain objects add an event handler for the event BeforeObjectSelection. procedure TForm1.WPRichText1BeforeObjectSelection(Sender: TObject; txtobj: TWPTextObj; var Ignore: Boolean); begin // We only want images to be selectable Ignore := txtobj.ObjType <> wpobjImage; end; But what if you want to display some kind of graphic instead of the text? Do not use the OnTextObjectPaint event for this - this event is used to draw embedded images only. Instead create an event handler for the objects own paint event: procedure TForm1.OnPaintMarker(Sender : TWPTextObj; OutCanvas : TCanvas; XRes, YRes : Integer; X, Y, W, H, BASE: Integer ); Assign the address of this paint event to the property TXTObject.OnPaint in the event OnTextObjGetTextEx and don't forget to also specify a width. The width is only used if the variable PaintObject has been set since otherwise always the PrintString is evaluated. procedure TForm1.WPRichText1TextObjGetTextEx(RefCanvas: TCanvas; TXTObject: TWPTextObj; var PrintString: WideString; var WidthInPix, HeightInPix: Integer; var PaintObject: TWPTextObj; Xres, YRes: Integer); begin i f TXTObject.Name='CHANGEME' then begin WidthInPix := Xres div 5; TXTObject.OnPaint := OnPaintMarker; // This line is required: PaintObject := TXTObject; end; end; procedure TForm1.OnPaintMarker(Sender : TWPTextObj; OutCanvas : TCanvas; XRes, YRes : Integer; X, Y, W, H, BASE: Integer ); var o : Integer; begin OutCanvas.Brush.Color := clYellow; OutCanvas.RoundRect(x,y,x+w,y+h,XRes div 1 0, YRes div 1 0) ; OutCanvas.Pen.Color := clRed; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 136. 130 WPTools Version 6 o := XRes div 6 0; OutCanvas.Pen.Width := 0; OutCanvas.MoveTo(x + o*2, y + h div 2) ; OutCanvas.LineTo(x + w - o*3, y + h div 2) ; OutCanvas.MoveTo(x + w - o * 6, y + h div 2 - o * 3) ; OutCanvas.LineTo(x + w - o*3, y + h div 2) ; OutCanvas.LineTo(x + w - o * 6, y + h div 2 + o * 3) ; end; The example above will create the yellow maker: 7.6.25 Working with multiple threads Unlike many other editor components WPTools Version 6 can work threadsavely. This makes sense if you use WPTools to create documents. Since WPTools can be used to create and print documents without any window handle being required You can use WPTools as a powerful engine to created electronic documents. This includes RTF documents, HTML documents and, with our product wPDF, also PDF documents. The demo 'ThreadSave' shows how to create a seperate task to do merge text. The merge template is sent from the main thread to the sub thread. Each subthread merges the text 100 times and saves each resulting file as RTF FILE: The constructor is the most important part of the thread class: constructor TWPToolsThread.Create(const SomeText, DirName, Text: string; Count: Integer); begin inherited Create(false); ForceDirectories(DirName); RichText := TWPCustomRtfEdit.CreateDynamic; {$IFNDEF NOENVIROMENT} Enviroment := TWPToolsEnviroment.Create(nil) ; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 137. Guide 131 Enviroment.Assign(GlobalWPToolsCustomEnviroment); RichText.Memo.RTFData.RTFProps.Enviroment := Enviroment; {$ENDIF} RichText.OnMailMergeGetText := DoMailMergeGetText; RichText.AsString := Text; FCount := Count; FSomeText := SomeText; FDirName := DirName; end; With this line the editor which is used for the process is created: RichText := TWPCustomRtfEdit.CreateDynamic; TWPCustomRtfEdit is defined in unit WPCTRMEMO - it is the basic editor class. This class does not contain all features TWPRichTExt has, cannot be attached to a TWPRuler or a TWPToolBar but contains all procedures which are required to create text and tables, insert images and to do mail merge. The optional code Enviroment := TWPToolsEnviroment.Create(nil); Enviroment.Assign(GlobalWPToolsCustomEnviroment); RichText.Memo.RTFData.RTFProps.Enviroment := Enviroment; is only required if you need threadsave printing or if you need to add different object and file format handling classes to the enviroment. Example C++Builder code to work with dynamic WPTools editor TWPCustomRtfEdit *wp2; wp2 = new TWPCustomRtfEdit(); // = CreateDynamic wp2->_MakeDynamic(); wp2->InputString("Hello WorldrNext Line",0) ; // Insert the text into a differen editor WPRichText1->SelectionAsString = wp2->AsString; // If we need to print we need ReformatAll wp2->ReformatAll(false,false) ; wp2->PrintPages(1,1) ; // Delete the object delete wp2; Note: do not create editor windows which should work interactively using CreateDynamic ! 7.6.26 Create Text Paths To create text paths simply use the TWPRTFStorage component. In its property 'Links' you have to create an item for each TWPRichText in the chain. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 138. 132 WPTools Version 6 The following initialization is required: procedure TWPTextPathDemo.FormCreate(Sender: TObject); begin // All path objects need the window handle - otherwise we cannot // use our broadcasting system WPRichText1.HandleNeeded; WPRichText2.HandleNeeded; WPRichText3.HandleNeeded; WPRichText4.HandleNeeded; WPRichText1.InputString('This is a text path. Please create new pages with Ctrl +CR'+#13) ; WPRichText1.CPPosition := MaxInt; // Settings for all TWPRichText WPRichText1.EditBoxModes := [wpemLimitTextWidth,wpemLimitTextHeight]; WPRichText1.EditOptions := [wpNoHorzScrolling,wpNoVertScrolling]; WPRichText2.EditBoxModes := [wpemLimitTextWidth,wpemLimitTextHeight]; WPRichText2.EditOptions := [wpNoHorzScrolling,wpNoVertScrolling]; WPRichText3.EditBoxModes := [wpemLimitTextWidth,wpemLimitTextHeight]; WPRichText3.EditOptions := [wpNoHorzScrolling,wpNoVertScrolling]; WPRichText4.EditBoxModes := [wpemLimitTextWidth,wpemLimitTextHeight]; WPRichText4.EditOptions := [wpNoHorzScrolling,wpNoVertScrolling]; end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 139. Guide 133 In the BeforeEditBoxNeedFocus event we use this code: procedure TWPTextPathDemo.WPRichText1BeforeEditBoxNeedFocus(Sender: TObject; var Abort: Boolean); begin PageControl1.ActivePageIndex := 0; end; procedure TWPTextPathDemo.WPRichText3BeforeEditBoxNeedFocus(Sender: TObject; var Abort: Boolean); begin PageControl1.ActivePageIndex := 1; end; In the OnMouseDown event of the page control we remove the focus from the editors: procedure TWPTextPathDemo.PageControl1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin // The WPRichText must loose the focus - otherwise it is not possible // to switch to a different page PageControl1.SetFocus; end; 7.6.27 Syntax Highlighting Syntax highlighting is useful to avoid logical errors when the user is supposed to edit XML or HTML text in ANSI form or when she or he is editing programming code. WPTools 5 includes the class TWPSynEditHighlight which is used as interface to the syntax highlighters included in the open source project SynEdit. Since character attributes, such as "bold" and text color are permanently assigned to the text, it is not possible to deliberately choose text attributes for the text. WPTools 6 includes a new special syntax highlighting component which dynamically highlights the parts of the text which are detected to be "tokens". It is still possible to apply text attributes. Currently a syntax highlighter for XML and the special reporting and mail merge tokens are available. Syntax highlighers can apply character attributes to the text, or, and this is unique, work non destructive. Here the character attribute is calculated "on the fly", depending on the context. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 140. 134 WPTools Version 6 7.6.27.1 TWPSynEditHighlight The component TWPSynEditHighlight has been created to use the SynEdit (http://SynEdit. SourceForge.net) syntax highlighters (available for pascal, c++, java, SQL, XML and many many more) with WPTools Version 6. Please check out demo SynHighlight. TWPSynEditHighlight works in an optimized way - it updates the text attributes only when necessary and caches the text attribute ids. The relatively short sourcecode (WPSyntaxInterface) is really worth to be read. 7.6.27.2 TWPCustomSyntax (added to WPTools 6) This class, which is implemented in unit WPSyntaxHighlight implements a basics for a syntax highlighter. To apply syntax highlighting simply assign a TWPCustomSyntax instance to the property TWPRichText.CustomSyntax. The instance will be automatically freed by the editor. Example: uses WPSyntaxHighlight; HTMLText.CustomSyntax := TWPXMLSyntax.Create(nil); TWPCustomSyntax implements this interface: Initialize - receives a reference to the "Memo" object in a TWPRichText procedure Init(Engine: TWPRTFEngineBasis); override; Called for each paragraph at the start procedure StartPar(par: TParagraph); override; Called for each character. It has to update the variable FMode according to the syntax procedure NextChar(par: TParagraph; CPos: Integer); override; Called at the end of each paragraph procedure EndPar(par: TParagraph); override; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 141. Guide 135 Called before the complete text is processed procedure PreProcess(RTFData: TWPRTFDataBlock); override; Called after the complete text was processed procedure PostProcess(RTFData: TWPRTFDataBlock); override; Used to calculate the CharAttr index used at a certain position of a paragraph. function CalcAttr(attr: Cardinal; par: TParagraph): Cardinal; override; Reference to the RTFDataProps object property RTFProps: TWPRTFProps read FRTFProps; 7.6.27.3 TWPXMLSyntax The XML highlighter TWPXMLSyntax descends from TWPCustomSyntax. It is used to highlight XML and HTML code. It uses a fixed pitch fonts. It only overrides two methods: constructor TWPXMLSyntax.Create(aOwner: TComponent); begin inherited Create(aOwner); FReservedColor := clBlue; end; and NextChar which detects the meaning of certain parts of the text. The caller takes care that "FMode" is updated with the mode which was active when the previous paragraph ended. procedure TWPXMLSyntax.NextChar(par: TParagraph; CPos: Integer); var C: WideChar; function CC(i: Integer): WideChar; begin i f (CPos + i < 0) o r (CPos + i >= par.CharCount) then Result := # 0 else Result := par.C begin i f FRTFProps <> nil then begin C := par.CharItem[CPos]; i f not (FMode i n [wpsynMLComment, wpsynComment, wpsynReserved, wpsynString]) then begin i f (C = '&') then FMode := wpsynChar else i f (C = '<') then begin i f (CC(1) = '!') and (CC(2) = '-') and (CC(3) = '-') then FMode := wpsynMLComment else FMode := wpsynReserved; end; i f C = '>' then Ferror := true; end else begin i f (FMode = wpsynReserved) and (c = #32) then FMode := wpsynString else i f (FMode = wpsynString) and (c = '>') then FMode := wpsynReserved; i f C = '<' then Ferror := true; end; inherited NextChar(par, CPos); i f (FMode = wpsynMLComment) and (C = '>') and (CC(-1) = '-') then FMode := wpsynNormal else i f (FMode = wpsynReserved) and (C = '>') then FMode := wpsynNormal else i f (FMode = wpsynChar) and ((C = ';') o r (C = #32)) then FMode := wpsynNormal; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 142. 136 WPTools Version 6 Ferror := false; end; end; 7.6.27.4 TWPXMLRTFSyntax This class highlights XML tags in the text but does not apply permanent changes to the formatting. 7.6.27.5 TWPFieldSyntax This class highlights field tokens marked by certain strings. It does not apply permanent changes to the text. This class publishes the properties FieldStart and FieldEnd. They are initialized with '<<' and '>>'. 7.6.27.6 TWPFieldBandSyntax This class highlights field and band tokens marked by certain strings. It does not apply permanent changes to the text. It is inherited from TWPFieldSyntax. Band tokens start with the sign :, groups with #. Only groups may be nested. This class publishes the properties FieldStart and FieldEnd which are initialized with '<<' and '>>'. In addition to TWPFieldSyntax it also publishes BandChar and GroupChar which are initialized with ':' and '#'. 7.6.28 Auto capitalisation You can use the event BeforeInitializePar to update the current paragraph: procedure TForm1.WPRichText1BeforeInitializePar(Sender: TObject; RTFEngine: TWPRTFEngineBasis; RTFDataBlock: TWPRTFDataBlock; par: TParagraph); var pos_wstart, i : Integer; s : string; begin // Current paragraph // Current paragraph i f par = WPRichText1.ActivePar then begin i := WPRichText1.ActivePosInPar; // 1. Overread spaces to the left while (i>0) and par.IsSpace(i) d o dec(i); // 2. Overread a word pos_wstart := -1; i f not par.IsWordDelimiter(i) and (par.IsSpace(i+1)) then begin while (i>=0) and not par.IsWordDelimiter(i) d o begin pos_wstart := i; dec(i); end; // 3. Overread spaces while (i>0) and par.IsSpace(i) d o dec(i); // Now, if . ! ? or start of par uppercase it! i f (pos_wstart>=0) and © 2004-2008 WPCubed GmbH - Munich, Germany
  • 143. Guide 137 ((i<=0) o r (par.CharItem[i]='.') o r (par.CharItem[i]='!') o r (par.CharItem[i]='?') ) // Check for abbreviation (simplified - only check a..z and ((par.IsSpace(i-1) o r (par.CharItem[i]<>'.') o r ((par.CharItem[i-1]>='a') and (par.CharItem[i-1]<='z')))) then begin i f Integer(par.CharItem[pos_wstart])<256 then begin s := AnsiUpperCase(Char(par.CharItem[pos_wstart])); i f s<>' ' then par.CharItem[pos_wstart] := WideChar(s[1]); end else par.CharItem[pos_wstart] := WideUpperCase(par.CharItem[pos_wstart])[1] ; end; end; end; end; Note: WPTools 6 Feature: On popular demand the mode wpAutoCaptitalize has been added to property EditOptionsEx. If this mode is active the editor will automatically capitalize Words at the beginning of a sentence. 7.6.29 Search&Replace Text To search for text You can use the 'Finder'. The finder is a class which contains several properties to adjust how finding works. It is also able to find using a wildcard, but the found text always has to be in one paragraph. Overview TWPTextFinder: ds Method Clear - resets the attributes Method DropMarkerAtFoundPosition This function drops a cursor marker, see DropMarker. The optional parameter offset will be added to the 'position in paragraph'. Example - extract text in brackets [ ]: var startid, endid : Integer; with WPRichText1.Finder d o begin ToStart; while true d o begin i f not Next('[') then break; startid := DropMarkerAtFoundPosition(1) ; i f not WPRichText1.Finder.Next(']') then break; endid := DropMarkerAtFoundPosition(0) ; WPRichText1.TextCursor.SelectMarker(startid, endid); ShowMessage(WPRichText1.AsANSIString('ANSI', true)); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 144. 138 WPTools Version 6 WPRichText1.TextCursor.CollectAllMarker; end; end; Method FindAgain - uses the last search text Method MoveToFoundPositionEnd - moves cursor Method MoveToFoundPositionStart - moves cursor Method Next - searches a text - returns TRUE if successful. Method Prev - searches a text backwards - returns TRUE if successful. Method ReplaceAll - replaces text Method ReplaceAllW - replaces text using unicode strings Method SelectText - selects the text which was found Method SetFoundImage - replaces the found text with an image Property Position - current position where the search starts. Method ToEnd - current position - goto end Method ToStart - current position - goto start Property CaseSensitive - true or false Property CharAttr - If attributes have been defined in this property the attributes of the text which is found must contain this attributes. Please make sure you clear this property with CharAttr.Clear after your code has been processed! Property EndAtSpace This property restricts the wildcard search to stop when the next space or object is found. Also see EndAtWord. This example creates hyperlinks for all texts which start with http://: with WPRichText1.Finder d o begin ToStart; EndAtSpace := TRUE; while Next('http://*' d o ) begin SelectText; WPRichText1.InputHyperlink(FoundText); end; end; Property EndAtWord This property restricts the wildcard search to stop when the next word delimiter is found. Property Found This property is true after the Next found the text. It is not update by ReplaceAll. The method ToStart resets this value to FALSE. Property FoundLength - length of the found text © 2004-2008 WPCubed GmbH - Munich, Germany
  • 145. Guide 139 Property FoundParagraph - the paragraph wher the text was found Property FoundPosInPar - the position where the text was found in 'FoundParagraph' Property FoundPosition - The absolute character positiuon of the found text. Can be used to initialize the property WPRichText.CPPosition. Better use MoveToFoundPositionStart. Property FoundText - Reads and replaces the found text with new text. (Dont' forget WPRichText. DelayedReformat). Please note that it is not possible to insert new paragraphs using this property. If you need to insert paragraphs or formatted text use SelectText and assign the new text to TWPRichText. SelectionAsString. Property FoundAttr Reads and changes the attributes of the found text.. Property WholeWord - if true the found text must be within white spaces Property WildCard - the wild card character allowed in the search string, for example '*' Example: Replace the placeholder |NAME| with data using a bold font: WPRichText1.Finder.ToStart; while WPRichText1.Finder.Next('|NAME|' d o ) begin WPRichText1.Finder.FoundAttr.IncludeStyle(afsBold); WPRichText1.Finder.FoundText := 'Julian Ziersch'; end; WPRichText1.DelayedReformat; Example: Convert Hyperlink: The "Finder" demo project shows how to create hyperlinks and how to replace colored words. It also includes some demo code to change the attribute of text depending on their current attributes - not using the finder but the 'CurrentCharAttr' interface. (Note: The display of the hyperlink objects has been enabled in the property FormatOptions) with WPRichText1.Finder d o begin ToStart; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 146. 140 WPTools Version 6 EndAtSpace := TRUE; while Next('http://*' d o ) begin SelectText; WPRichText1.InputHyperlink(FoundText); end; EndAtSpace := FALSE; end; WPRichText1.HideSelection; Example: Replace red words var Finder: TWPTextFinder; begin Finder := WPRichText1.Finder; Finder.Clear; Finder.ToStart; Finder.CharAttr.SetColor(clRed); Finder.EndAtWord := TRUE; // "WholeWord" does not work Finder.WildCard := '*'; while Finder.Next('*') d o begin Finder.FoundText := 'Test'; Finder.FoundAttr.SetColor(clBlack); end; Finder.CharAttr.Clear; WPRichText1.Refresh; end; 7.6.30 CPChar, CPMoveNext, etc. WPTools makes it easy for you to loop through all the characters to check for attributes, change attributes or extract or modify text. (Also read about the cursor class TWPRTFDataCursor ) Example: Change color of bold text (from Finder demo) WPRichText1.AttrHelper.Clear; WPRichText1.AttrHelper.SetStyles([afsBold]); WPRichText1.CPPosition := 0; repeat i f WPRichText1.CurrentCharAttr.Contains( WPRichText1.AttrHelper) then WPRichText1.CurrentCharAttr.SetColor(clRed); until not WPRichText1.CPMoveNext; WPRichText1.Refresh; Example: Assign the bold attribute to the selected text var i : Integer; begin i := WPRichText1.SelLength; WPRichText1.CPPosition := WPRichText1.SelStart; while i>0 d o begin WPRichText1.CPAttr.BeginUpdate; WPRichText1.CPAttr.IncludeStyle(afsBold); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 147. Guide 141 // other changes ... WPRichText1.CPAttr.EndUpdate; i f not WPRichText1.CPMoveNext then break; Dec(i); end; end; Instead of this complicated code you can also use CurrAttr.AddStyle([afsBold]) but the above let you decide for each character which style has to be set. Upgrade notes: CPChar and CPAttr cannot be used as pointers anymore. Instead CPChar is a property and CPAttr is an object with properties to manipulate the corresponding TAttr value. 7.6.31 Share Styles between TWPRichText Sometimes you need to copy text and objects quickly between several editors. If you copy paragraph, table or table rows you can avoid using clipboard like operations by copying the TParagraph objects directly. To make this can work it is important that all TWPRichText use the same internal font, color and style tables. So, the TWPRichText must use the same TWPRTFProps object. 1) Only a few lines of code are required to initialize this prerequisite: a) add a variable of type WPGlobalRTFProps : TWPRTFProps; b) add the event OnInitializeRTFDataObject use code like this procedure TForm1.WPRichTextInitializeRTFDataObject( Sender: TObject; var RTFDataObject: TWPRTFDataCollection; var RTFPropsObject: TWPRTFProps); begin i f WPGlobalRTFProps=nil then begin WPGlobalRTFProps := TWPRTFProps.Create; WPGlobalRTFProps.Locked := true; end; RTFPropsObject := WPGlobalRTFProps; end; c) when the application closes you need to free the WPGlobalRTFProps object. 2) Copy current paragraph to a different TWPRichText var par : TParagraph; par := WPRichText1.ActiveParagraph.CreateCopyList(true, WPRichText1.ActiveParagraph); WPRichText2.ActiveParagraph.NextPar := par; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 148. 142 WPTools Version 6 WPRichText2.ReformatAll(false, true); 3) Copy current table row to a table in a different TWPRichText var par, aTable : TParagraph; // Copy this row par := WPRichText1.TableRow; par := par.CreateCopyList(true, par); // Insert a row - if necessary create a surrounding table object // Insert after current row i f WPRichText2.TableRow<>nil then WPRichText2.TableRow.NextPar := par else begin // Create a new table aTable := WPRichText2.ActiveParagraph.AppendNewTable(false); // and insert the row aTable.AppendChild(par); end; 7.6.32 Multiple Editors for the Same Text WPTools Version 6 allows the use of multiple editors which all work with the same text. This is also known as the split screen technique. Example: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 149. Guide 143 7.6.32.1 Use TWPRTFStorage The component TWPRTFStorage is used to host the TWPRTFDataCollection for a number of attached editor component. So if you place several editors on a form you can create Create items in the 'Links' collection and set wpDisplayTextStreamin property DisplayMode. The property AllowMultiView must be set to TRUE in all editors. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 150. 144 WPTools Version 6 7.6.32.2 Create Multi View in Code You need an event handler for the event OnInitializeRTFDataObject of the TWPRichText object. This event is executed when the text data is needed the first time. In the event handler you assign a RTFDataCollection which has been created 'outside'. You will need two variables in the TForm class: TForm1 = class(TForm) ... public RTFData: TWPRTFDataCollection; RTFDataProps: TWPRTFProps end; The event handler now initializes the variables and assigns them to any TWPRichText which is using this event handler. procedure TForm1.OnInitRTFData(Sender: TObject; var RTFDataObject: TWPRTFDataCollection; var RTFPropsObject: TWPRTFProps); begin i f RTFData = nil then begin RTFData := TWPRTFDataCollection.Create(TWPRTFDataBlock); RTFDataProps := TWPRTFProps.Create; RTFData.RTFProps := RTFDataProps; end; RTFDataObject := RTFData; end; 7.6.33 Work with sub paragragraphs WPTools Version 6 stores the text in a paragraph tree. The paragraphs are connected using the property 'NextPar'. Some paragraph types require that contents paragraphs are stored on a deeper level, as children paragraphs. For example tables are created that way. You can use this feature to separate the text into different sections. (Don't mix up with the text sections described here) These sections can be useful if you need to use one editor to edit or display the text which is stored in different locations, for example different database fields or even database records. It is even thinkabele to use WPTools similar to a database grid! © 2004-2008 WPCubed GmbH - Munich, Germany
  • 151. Guide 145 We created demo which showshow this can be done. You find this demo in the directory SubParagraphs. The demo shows how to use the paint line event to show the gray header bands. It also contains the code which moves the text from and to the main editor or the fields. This code is executed when '<<<<' is pressed: procedure TWPSubParDemo.LoadDataClick(Sender: TObject); var par: TParagraph; block: TWPRTFDataBlock; mem: TMemoryStream; s: string; charattr_for_ANSI: Cardinal; begin mem := TMemoryStream.Create; AllText.LockScreen; try AllText.Clear; // AFTER the clear we calculate our ANSI character property AllText.AttrHelper.Clear; AllText.AttrHelper.SetFontName('Courier New') ; AllText.AttrHelper.SetFontSize(1000) ; charattr_for_ANSI := AllText.AttrHelper.CharAttr; // and now create the text © 2004-2008 WPCubed GmbH - Munich, Germany
  • 152. 146 WPTools Version 6 AllText.CheckHasBody; block := AllText.ActiveText; par := block.FirstPar; par.ASet(WPAT_ParProtected, 1) ; par.Name := 'FieldA' ; par.ParagraphType := wpIsXMLTopLevel; s := FieldA.Text; // SetAllText creates a sub paragraph when the first #13#10 is found! i f s <> ' ' then par.SetAllText #13 + #10 + s, charattr_for_ANSI); // The first ( ANSI Text par.NextPar := TParagraph.Create(block); par := par.NextPar; par.ParagraphType := wpIsXMLTopLevel; par.ASet(WPAT_ParProtected, 1) ; par.Name := 'FieldB' ; par.ASet(WPAT_CharFontSize, 900) ; FieldB.SaveToStream(mem, 'WPTOOLS' ; ) mem.Position := 0; par.LoadFromStream mem, 'AUTO', ' ', [wploadpar_AsChildrenPar ( ]); // The formatted Text par.NextPar := TParagraph.Create(block); par := par.NextPar; par.ParagraphType := wpIsXMLTopLevel; par.ASet(WPAT_ParProtected, 1) ; par.Name := 'FieldC' ; s := FieldC.Text; i f s <> ' ' then par.SetAllText(#13 + #10 + s, charattr_for_ANSI); // The last ANSI Text finally mem.Free; AllText.UnLockScreen(true); end; end; This code is executed when '>>>>' is pressed: procedure TWPSubParDemo.PostDataClick(Sender: TObject); var par, cpar: TParagraph; mem: TMemoryStream; begin par := AllText.FirstPar; while par <> nil d o begin i f par.ParagraphType = wpIsXMLTopLevel then begin i f par.Name = 'FieldA' then begin FieldA.Text := par.GetAllText(false, false); end else i f par.Name = 'FieldB' then begin FieldB.LockScreen; try // This code uses AppendParCopy() to copy the text -------------------- FieldB.Clear; cpar := par.ChildPar; while cpar <> nil d o FieldB.BodyText.AppendParCopy(cpar); FieldB.CheckHasBody; // The code uses a stream to copy the text ---------------------------- © 2004-2008 WPCubed GmbH - Munich, Germany
  • 153. Guide 147 // this will be useful if you need to save to a blob field! {mem := TMemoryStream.Create; try if par.SaveToStream mem, true, 'WPTOOLS') then ( begin mem.Position := 0; FieldB.LoadFromStream(mem, 'WPTOOLS', true); end else FieldB.Clear; finally mem.Free; end;} finally FieldB.UnLockScreen(true); end; end else i f par.Name = 'FieldC' then begin FieldC.Text := par.GetAllText(false, false); end; end; par := par.NextPar; // do NOT use "next" here end; end; 7.7 BCB Notes Installation We added BPK files which can be compiled in C++Builder as packages. If there is a problem (Your setup is different than on the reference machine) you can install the file WPTools_Reg.PAS as a new component into a new package. You will have to add the vcl and vclx package - otherwise the message "filename.obj was not found" will be displayed. Please make sure the VCLJPG and DSNIDE packages are added. For database support VCLDB is also required. If you have BCB-Standard you can activate the switch NODB in the file WPINC.INC You will also need to make a change to the 'Option Source', the XML makefile for the package: When C++Builder compiles the RTFEngine it creates HPP files. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 154. 148 WPTools Version 6 Programming In general you can use the same techniques in BCB as you use in Delphi But please note that the dot '.' usually has to be replaced by the arrow '->' to access any objects. Instead of Txx.Create you usually use new. Procedures can be called without () in Delphi, for C++ please always add (). Speciality: Instead of TWPCustomRTFEdit.CreateDynamic use edit = new TWPCustomRTFEdit(nil); edit._MakeDynamic(); Troubleshooting: If you get a linker error 'unresolved external' please make sure the WPTools units are found, but only one time (no duplicates), in the library and in the include path. Please deactivate the use of runtime packages. 7.7.1 Example: Create dynamic TWPCustomRTFEdit TWPCustomRtfEdit *DynRTFText; DynRTFText = new TWPCustomRtfEdit(); DynRTFText->_MakeDynamic(); DynRTFText->Clear(); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 155. Guide 149 DynRTFText->Header->SetPageWH(WPCentimeterToTwips(2 1) , WPCentimeterToTwips(29.7) , WPCentimeterToTwips(2), //left Margin WPCentimeterToTwips(2), //right Margin WPCentimeterToTwips(2), //top Margin WPCentimeterToTwips(2)); //Bottom Margin DynRTFText->CheckHasBody(); DynRTFText->InputString("Some Textf") ; 7.7.2 Example: Create image object and insert TWPOImage *image = new TWPOImage(0) ; image->LoadFromFile( "logo.bmp" ); //image->PositionMode = wpotPage; WPRichText1->TextObjects->Insert(image->CreateCopy(0), 0, 0, " ", " " ); image->LoadFromFile( "logo1.bmp" ); WPRichText1->TextObjects->Insert(image, 0, 0, " ", " " ); 7.8 Label Priniting WPTools 6 introduces an exciting new feature. This is the integrated label design and printing. When label printing is activated, each logical page in the editor will be displayed and printed on an individual label. The user can freely edit the label sheet and mover the text cursor from label to label. This makes it very easy to preview the labels which are about to be printed and make last changes. The label printing is controlled by the interface WPRichText1.RTFData.LabelDef . Note: This feature is much more versatile than label printing using the demo Print Labels (TWPSuperPrint) since here the preview is editable. 7.8.1 LabelDef Using the new property LabelDef which was added to WPTools 6 You can quickly print labels. It is also possible to preview the label sheets just like they would be printed. It is even possible to edit the text on the label sheets. You can also specify the label num ber to start with. All param eters of a label can be specified, using centimeter or inch values, depending on UnitIsInch. A Label is either defined by the sheet size (width/height), colum count, rowcount and n the m argins (top, bottom ,left, right, horizontal and vertical) or, alternatively by the sheet size (width/height), the top, left, right and bottom margin and the specified label width and label height. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 156. 150 WPTools Version 6 Overview: Active : Switch Label display on / off AsText : Retrieve and set the label definition as text Bottom : Bottom Margin Caption : Caption of the label, displayed over text ColumnCount : Count of columns Horizontal : Horizontal margin between columns LabelHeight : Size of a label, if you set it you cannot change vertical margin and row count LabelWidth : Size of a label, if you set it you cannot change horizontal margin and row count Left : Left Margin Name : Name of this label definition (encoded into "AsText") Padding : Padding inside of the label Right : Right Margin © 2004-2008 WPCubed GmbH - Munich, Germany
  • 157. Guide 151 RowCount : Count of rows SheetHeight : Height of label sheet SheetWidth : Width of label sheet StartNr : Start nr for printing Top : Top Margin UnitIsInch : If true all floating point values are inch instead of CM Vertical : Margin between rows 7.8.1.1 Vertical Declaration Vertical : Single; Description The vertical margin between labels (in CM or inch). 7.8.1.2 UnitIsInch Declaration UnitIsInch : Boolean; Description If this value is true all floating point properties are interpreted as inch values, otherwise CM are expected. 7.8.1.3 Top Declaration Top : Single; Description The margin at the top of the label sheet. 7.8.1.4 StartNr Declaration StartNr : Integer; Description The num ber of the label on first page to start with. This property is useful if you work with half full label sheets. 7.8.1.5 SheetWidth Declaration SheetWidth : Single; Description © 2004-2008 WPCubed GmbH - Munich, Germany
  • 158. 152 WPTools Version 6 The width of the label sheet (cm or Inch, depending on UnitIsInch). 7.8.1.6 SheetHeight Declaration SheetHeight : Single; Description The height of the label sheet (cm or Inch, depending on UnitIsInch). 7.8.1.7 RowCount Declaration RowCount : Integer; Description The count of labe rows. 7.8.1.8 Right Declaration Right : Single; Description The margin to the right of the label sheet. 7.8.1.9 Padding Declaration Padding : Single; Description The m argin between text and label borders on all sides of the label. If this property is 0, the labels will be displayed in the preview as simple rectangles, if it is > a round 0 rectangle will be drawn. 7.8.1.10 Name Declaration Name : String; Description The nam of the label. Will be saved with property AsText. e © 2004-2008 WPCubed GmbH - Munich, Germany
  • 159. Guide 153 7.8.1.11 Left Declaration Left : Single; Description The margin on the left of the label sheet. 7.8.1.12 LabelWidth Declaration LabelWidth : Single; Description The width of the label. You can read this property to display the current width. If written, the properties ColumnCount and Horizontal are changed accordingly. 7.8.1.13 LabelHeight Declaration LabelHeight : Single; Description The height of the label. You can read this property to display the current height. If written, the properties RowCount and Vertical are changed accordingly. 7.8.1.14 Horizontal Declaration Horizontal : Single; Description The horizontal margin between labels (in CM or inch). 7.8.1.15 ColumnCount Declaration ColumnCount : Integer; Description The count of label colum on the sheet. ns 7.8.1.16 Caption Declaration Caption : string; Description © 2004-2008 WPCubed GmbH - Munich, Germany
  • 160. 154 WPTools Version 6 An optional caption for each label. This caption is printed on each label in a sm font all (Arial Narrow). You can use it to specify the return address. 7.8.1.17 Bottom Declaration Bottom : Single; Description The height of the bottom margin in cm or inch. 7.8.1.18 AsText Declaration AsText : string; Description Retrieves or sets all parameters except for Caption, Active and StartNr as string. This methods m akes it easy to load and save predefined label definitions. The form of the string is at N e= am xx with xx as the properties encoded into hexadecim values. If required the unit (cm or al inch) are converted as required. 7.8.1.19 Active Declaration Active : Boolean; Description When this property is set to true, the editor will display a label sheet. The page size which is currently defined in the editor is overridden when this m ode is on. The event OnMeasurePage is disabled. 7.8.2 Example Project The demo label design contains the preview/edit windows and a TWPValueEdit control for each of the properties. It also allows saving and loading the definition and manages the list of definitions in the Items list of a TComboBox. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 161. Guide 155 Please locate the Delphi project in directory DemosWPTools6LabelDesigner. Here w e quoted only most of the code. 7.8.2.1 Initialization procedure TForm1.FormCreate(Sender: TObject); begin UseInch := false; // Width of the sheet WPRichText1.RTFData.LabelDef.SheetWidth := 2 1; WPRichText1.RTFData.LabelDef.SheetHeight := 2 9.7; // Rows and columns WPRichText1.RTFData.LabelDef.ColumnCount := 2; WPRichText1.RTFData.LabelDef.RowCount := 7; // Margins WPRichText1.RTFData.LabelDef.Left := 0.5; WPRichText1.RTFData.LabelDef.Right := 0.5; WPRichText1.RTFData.LabelDef.Top := 1.5; WPRichText1.RTFData.LabelDef.Bottom := 1.5; // Start with first WPRichText1.RTFData.LabelDef.StartNr := 0; // Return Address WPRichText1.RTFData.LabelDef.Caption := ReturnAdress.Text; // And activate WPRichText1.RTFData.LabelDef.Active := true; ReadProps; end; 7.8.2.2 After changing sheet size and margins procedure TForm1.MargHorizontalChange(Sender: TObject); begin // UseInch ---- true: we work with inch, false: we work with CM WPRichText1.RTFData.LabelDef.UnitIsInch := UseInch; WPRichText1.RTFData.LabelDef.SheetWidth := SheetWidth.ValueAsInchOrCM(UseInch); WPRichText1.RTFData.LabelDef.SheetHeight := SheetHeight.ValueAsInchOrCM(UseInch); WPRichText1.RTFData.LabelDef.Top := MargTop.ValueAsInchOrCM(UseInch); WPRichText1.RTFData.LabelDef.Left := MargLeft.ValueAsInchOrCM(UseInch); WPRichText1.RTFData.LabelDef.Right := MargRight.ValueAsInchOrCM(UseInch); WPRichText1.RTFData.LabelDef.Bottom := MargBottom.ValueAsInchOrCM(UseInch); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 162. 156 WPTools Version 6 WPRichText1.RTFData.LabelDef.Horizontal := MargHorizontal.ValueAsInchOrCM(UseInch); WPRichText1.RTFData.LabelDef.Vertical := MargVertical.ValueAsInchOrCM(UseInch); // Read LabelWidth.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelWidth, UseInch); LabelHeight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelHeight, UseInch); StoreProps; WPRichText1.ReformatAll(true, true); end; 7.8.2.3 Change of column count or row count procedure TForm1.ColumnCountChange(Sender: TObject); begin WPRichText1.RTFData.LabelDef.ColumnCount := ColumnCount.Value; WPRichText1.RTFData.LabelDef.RowCount := RowCount.Value; // Read LabelWidth.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelWidth, UseInch); LabelHeight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelHeight, UseInch); StoreProps; WPRichText1.ReformatAll(true, true); end; 7.8.2.4 Change of label width and height Usually the labels are defined by the column count and row count property. But it is also possible to specify the width and height instead and the component will calculate the correct column and rowcount. procedure TForm1.LabelWidthChange(Sender: TObject); begin WPRichText1.RTFData.LabelDef.LabelWidth := LabelWidth.ValueAsInchOrCM(UseInch); WPRichText1.RTFData.LabelDef.LabelHeight := LabelHeight.ValueAsInchOrCM(UseInch); ColumnCount.SetValue( WPRichText1.RTFData.LabelDef.ColumnCount ); RowCount.SetValue ( WPRichText1.RTFData.LabelDef.RowCount ); StoreProps; WPRichText1.ReformatAll(true, true); end; 7.8.2.5 ReadProps and StoreProps ReadProps updates the visible controls procedure TForm1.ReadProps; begin SheetWidth.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.SheetWidth , UseInch); SheetHeight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.SheetHeight , UseInch); LabelWidth.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelWidth , UseInch); LabelHeight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.LabelHeight , UseInch); MargTop.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Top , UseInch); MargLeft.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Left , UseInch); MargRight.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Right , UseInch); MargBottom.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Bottom , UseInch); MargHorizontal.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Horizontal , UseInch); MargVertical.SetValueAsInchOrCM( WPRichText1.RTFData.LabelDef.Vertical , UseInch); ColumnCount.Value := WPRichText1.RTFData.LabelDef.ColumnCount; RowCount.Value := WPRichText1.RTFData.LabelDef.RowCount; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 163. Guide 157 LabelName.Text := WPRichText1.RTFData.LabelDef.Name; end; StoreProps saves the definition to the correct item in a string list. "Name" is used to identify the item. procedure TForm1.StoreProps; var i : Integer; begin i := LabelName.Items.IndexOfName(WPRichText1.RTFData.LabelDef.Name) ; i f i>=0 then LabelName.Items[i] := WPRichText1.RTFData.LabelDef.AsText else begin i := LabelName.Items.Count; LabelName.Items.Append(WPRichText1.RTFData.LabelDef.AsText); end; LabelName.ItemIndex := i; end; 7.9 HTTP Interface WPTools 6 includes the unit "wphttpget_unit", It implements a set of routines to load text, image data and style sheets over HTTP connections. The interface unit requires the powerful HTTP library Arart Synapse. It is not included. http://synapse.ararat.cz/ Info: The WPTools Demo does not include this unit. The interface is attached to the WPTools Kernel using function pointers. This makes it possible to separate the HTTP support from the rest of the application and is an effective mean to avoid any security risks through open HTTP connection points. In this demo (see directory DemosHTTPGet) we discuss how to implement a webbrowser like application, including history with forward and backwards buttons. The HTTP interface can be temporarily disabled by setting the boolean variable wphttp_Disable = true. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 164. 158 WPTools Version 6 7.9.1 Form Setup The Form is simple: Also required are 4 variables and 2 functions. Most of the code will be inserted into event handlers: public history: TStringList; historypos: Integer; pendingload: Boolean; procedure Load(url: string; Update: Boolean); procedure UpdateButtons; end; In the Form.OnCreate event we insert procedure TWPWebBrowser.FormCreate(Sender: TObject); begin history := TStringList.Create; WPRichText1.AsWebpage := [wpFormatAsWebpage]; WPRichText1.OneClickHyperlink := true; // No Table Resize WPRichText1.EditOptions := [wpActivateUndo, wpActivateUndoHotkey]; // Hot Hyperlinks WPRichText1.HyperlinkTextAttr.HotEffect := wpeffTextColor; WPRichText1.HyperlinkTextAttr.HotEffectColor := clBlue; // Limit the used fonts WPRichText1.RTFData.RTFProps.PreselectedFonts.Assign( Screen.Fonts ); WPRichText1.RTFData.RTFProps.PreselectedFonts.Add('sans-serif=Frutiger' ; ) end; The property PreselectedFonts is important for the CSS reader. It makes it possible to select one font alternative in cases multiple are offered in a comma separated list. In the Form.OnDestroy event we insert © 2004-2008 WPCubed GmbH - Munich, Germany
  • 165. Guide 159 procedure TWPWebBrowser.FormDestroy(Sender: TObject); begin history.Free; end; 7.9.2 Unit Initialization To update the status bar we need to create a global method. This method will be called when data is loaded over HTTP connections. It also initializes a timer on the form to update the screen and to clear the status bar. procedure do_wphttp_Notify(code: Integer; text: PAnsiChar); stdcall ; begin i f WPWebBrowser <> nil then begin i f code = 1 then //Load HTML begin WPWebBrowser.StatusBar1.Panels[1].Text := StrPas(text); i f WPWebBrowser.historypos < WPWebBrowser.history.count then WPWebBrowser.history[WPWebBrowser.historypos] := StrPas(text); end else i f code = 2 then // Called Synchronized ! begin WPWebBrowser.StatusBar1.Panels[2].Text := StrPas(text); WPWebBrowser.UpdateScreenTimer.Enabled := TRUE; WPWebBrowser.pendingload := TRUE; end; end; end; This is the timer method procedure TWPWebBrowser.UpdateScreenTimerTimer(Sender: TObject); begin i f not pendingload then begin WPWebBrowser.StatusBar1.Panels[2].Text := ' '; UpdateScreenTimer.Enabled := FALSE; end; WPRichText1.Repaint; pendingload := FALSE; end; The method do_wphttpNotify and the 4 methods from unit wphttpget_unit are attached to the WPTools engine using function pointers. The pointers are set in the initialization section of the unit: initialization // HTTP functions WPRTEDefs.wphttp_Init := @wphttpget_unit.wphttp_Init; WPRTEDefs.wphttp_Exit := @wphttpget_unit.wphttp_Exit; WPRTEDefs.wphttp_get := @wphttpget_unit.wphttp_get; WPRTEDefs.wphttp_copydata := @wphttpget_unit.wphttp_copydata; wphttp_Init_param := 'WPCubed_GmbH_HTTP1'; // Also initialize wphttp_Notify WPRTEDefs.wphttp_Notify := d o_wphttp_Notify; end. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 166. 160 WPTools Version 6 7.9.3 User Action and History Management The history uses a string list and an index into this list. Event for both buttons. procedure TWPWebBrowser.BackBtnClick(Sender: TObject); begin i f Sender = BackBtn then // Click on <-- dec(historypos) else inc(historypos); // Click on --> Load(history[historypos], false); end; and the method which updates the enabled state procedure TWPWebBrowser.UpdateButtons; begin BackBtn.Enabled := (historypos > 0) and (history.Count > 0) ; NextBtn.Enabled := (historypos < history.Count - 1) ; end; The Page is loaded when clicking "Refresh" or when clicking on a hyperlink or when pressing enter in the URL edit field. procedure TWPWebBrowser.RefershBtnClick(Sender: TObject); begin Load(URLEdit.Text, false); end; procedure TWPWebBrowser.WPRichText1HyperLinkEvent(Sender: TObject; text, url: string; IgnoredNumber: Integer); begin inc(historypos); Load(url, true); end; procedure TWPWebBrowser.URLEditKeyPress(Sender: TObject; var Key: Char); begin i f Key = #13 then begin Load(URLEdit.Text, true); Key := # 0; end; end; 7.9.4 Load Method The method load is responsible to load documents and also images. For unsupported file extensions it calls MessageBeep and exits. It does not yet preload the data and check it for errors. procedure TWPWebBrowser.Load(url: string; Update: Boolean); var s: string; obj: TWPOImage; load_the_text: Boolean; begin load_the_text := true; s := lowercase(ExtractFileExt(url)); i f (s = '.rtf') o r (s = '.txt') o r (s = '.doc') then begin // Standard Mode for Documents WPRichText1.AsWebpage := []; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 167. Guide 161 end else i f (s = '.jpg') o r (s = '.gif') o r (s = '.png') o r (s = '.jpeg' then ) begin // Mode for images obj := TWPOImage.Create(WPRichText1.RTFData); i f obj.LoadHTTPFromThread(nil, WPRichText1.RTFData, WPRichText1.RTFData.HTTPPrepareURL(ur begin WPRichText1.AsWebpage := []; WPRichText1.Clear; WPRichText1.InputObject(obj); load_the_text := false; end else begin obj.Free; MessageBeep(0) ; exit; end; end else // Ignore data right away i f (s = '.exe') o r (s = '.zip') o r (s = '.pdf') or (s = '.rar') o r (s = '.chm') o r (s = '.hlp') then begin // Unsupported extensions MessageBeep(0) ; exit; end else begin // Mode for websites // TODO - we should load now preload the data and check if valid WPRichText1.AsWebpage := [wpFormatAsWebpage]; end; // Update Statusbar URLEdit.Text := url; StatusBar1.Panels[1].Text := url; // Update History NOW - otherwise do_wphttp_Notify cannot update the filename correctly i f Update then begin while history.Count > historypos d o history.Delete(history.Count - 1) ; historypos := history.Count; history.Append(url); UpdateButtons; end; // Do we need to load text (maybe we loaded images) i f load_the_text then begin WPRichText1.Clear; WPRichText1.LoadFromFile(url); end; end; Notes: Most of the work is done in WPRichText.LoadFromFile - here WPTools 6 detects http urls and uses the http functions to load the data. Images are loaded multithreaded - so the page appears quickly. The new TWPObject class implements the method LoadHTTPFromThread (it will not work with threads though, if the last parameter is false). Here we also activate the special HTML formatting mode, or disable it for regular RTF documents. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 168. 162 WPTools Version 6 7.9.5 Webbrowser with WPTools Although WPTools 6 is not meant to replace a specialized HTML component, You can build a pretty decent HTML view er w ith it. 7.9.6 Source View It is possible to capture the HTML source code and display it in a second editor: Here w e have tw o tabs, the first show s the TWPRichText w hich displays the formatted text, the other show s the source code and uses the XML syntax highlighting. The editors are individual, edits in one w ill not update the other editor. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 169. Guide 163 The second editor is initialized like this: procedure TWPWebBrowser.FormCreate(Sender: TObject); begin ... // Update the Source view WPRichText1.RTFData.AfterLoadFromStream := WPRichText1LoadFromStream; // uses WPSyntaxHighlight: SourceView.CustomSyntax := TWPXMLSyntax.Create(nil) ; ... end; The text is assigned in the event TWPRTFDataCollection.AfterLoadFromStream The handler . uses this code: procedure TWPWebBrowser.WPRichText1LoadFromStream( RTFData: TWPRTFDataCollection; Stream: TStream; Reader: TWPCustomTextReader; OnlyBodyText: Boolean; var LoadedText: TWPRTFDataBlock); begin i f not OnlyBodyText then begin Stream.Position := 0; i f Reader.CopyOfBodyData<>nil then // HTML extracted from MIME data SourceView.LoadFromStream(Reader.CopyOfBodyData, 'ANSI', true) // Original Stream else SourceView.LoadFromStream(Stream, 'ANSI', true); Caption := WPRichText1.RTFVariables.Strings['Title' ; ] end; end; Here we use the property CopyOfBodyData. This memory stream is only filled by the MIME reader to capture the HTML body source. The normal stream would show the complete message text, including all header lines and attachments. 7.10 MIME Import / Export WPTools 6 includes the unit "WPIOMime", It implements a read and a writer for MIME encoded HTML Data. Info: The WPTools Demo does not include this unit. The interface unit requires the powerful HTTP library Arart Synapse. It is not included. http://synapse.ararat.cz/ © 2004-2008 WPCubed GmbH - Munich, Germany
  • 170. 164 WPTools Version 6 7.10.1 Reader / Writer To activate MIME support please add the unit WPIOMime to the uses clause. (C++Builder requires #pragma link). Now it is possible to load *.MHT, *.MSG and *.EML files. These file extensions automatically trigger the MIME reader and writer classes due to the class methods. class function TWPMimeReader.UseForFilterName(const Filtername: string): Boolean; begin Result := (CompareText(Filtername, 'TWPMimeReader' = 0) // not "inherited" ) o r (CompareText(Filtername, 'MIME') = 0) o r (CompareText(Filtername, 'MHT') = 0) o r (CompareText(Filtername, 'MSG') = 0) o r (CompareText(Filtername, 'EML') = 0) ; end; and class function TWPMimeWriter.UseForFilterName(const Filtername: string): Boolean; begin Result := (CompareText(Filtername, 'TWPMimeWriter' = 0) // not "inherited" ) o r (CompareText(Filtername, 'MIME') = 0) o r (CompareText(Filtername, 'MHT') = 0) o r (CompareText(Filtername, 'MSG') = 0) o r (CompareText(Filtername, 'EML') = 0) ; end; The writer supports the format options: -nohtml, do not save HTML text -noplain, do not save PLAIN text The MimeReader initializes and fills the property TWPCustomTextReader.CopyOfBodyData a with copy of the HTML text which is loaded as body. The data can be used to display the HTML source code (example). 7.10.2 Demo Instead of creating a new demo, we decided to enhance the WebBrowser application and add 2 buttons, "Load MIME" and "SaveMime". First we need to add WPIOMime to the uses clause: uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, WPRTEDefs, WPCTRMemo, WPCTRRich, ComCtrls, ExtCtrls, wphttpget_unit, wpobj_image, WPIOMime; To save a web archive or message file we use procedure TWPWebBrowser.SaveMIMEClick(Sender: TObject); begin with TSaveDialog.Create(self) d o try Filter := 'Webarchives (*.MHT)|*.MHT|Messages (*.MSG,*.EML)|*.MSG,*.EML'; DefaultExt := 'MHT'; Caption:= 'Save as MIME data'; i f Execute then © 2004-2008 WPCubed GmbH - Munich, Germany
  • 171. Guide 165 begin // Web Archive i f SameText( ExtractFileExt( FileName ), '.mht' ) then WPRichText1.SaveToFile(FileName, false, 'MIME-noplain' ) else WPRichText1.SaveToFile(FileName); end; finally Free; end; end; To load a MSG or MHT file we use procedure TWPWebBrowser.LoadMIMEClick(Sender: TObject); begin with TOpenDialog.Create(self) d o try Filter := 'Webarchives (*.MHT)|*.MHT|Messages (*.MSG,*.EML)|*.MSG,*.EML'; DefaultExt := 'MHT'; Caption:= 'Load MIME data'; i f Execute then begin WPRichText1.SaveToFile(FileName, true); end; finally Free; end; end; 7.11 PDF export with wPDF Used alone, with your own component or linked with WPTools, wPDF instantly creates PDF files at high speed. wPDF supports · Developer Express(tm EXPRESS PrintingSuite, (exam ) ple included) · ReportBuilder, (interface included) · ACE Reporter, (interface included) · RichEdit, (exam ple included) · RAVE Report, (interface included) · HTMLView, · FAST Report 2, (interface included) · FAST Report 3+ (interface included) 4, · QuickReport, (interface included) · WPTools 4 (incl. links and bookm arks, com ponent included) , · WPTools 5 (incl. links and bookm arks, com ponent included) , · WPTools 6 (incl. links, fields and bookm arks, component included) , · WPForm (exam , ple included) · List&Label and m ost other com ponents which can create a m etafile or draw to a HDC / Canvas. You always can com bine the output of different com ponents into one PDF file! The integration with WPTools extremely tight. So, other than just exporting text and images these features are supported: · Export hyperlinks · Export Bookm arks © 2004-2008 WPCubed GmbH - Munich, Germany
  • 172. 166 WPTools Version 6 · Export JPEG data without additional com pression · Create PDF tags (Also known as "m arked PDF" - this is a prerequisite for PDF/A com pliancy. Tagged PDF Docum ents can be better converted to form atted text. Our own "PDF to RTF" converter will even recreate table structures!) · new in WPTools 6: create edit fields (Exam ple ...) · new in WPTools 6: create checkbox fields (Exam ple ...) · new in WPTools 6: em bed data stored in a special object instance (Exam ple ...) 7.11.1 Export to PDF This is the most compact code to export the RTF or HTML text from a WPTools Editor to PDF: uses ..., WPPDFWP, WPRTEDefs, WPCTRMemo, WPCTRRich; procedure TForm1.ExportFromWPTools(Sender: TObject); var pdf : TWPPDFExport; begin pdf := TWPPDFExport.Create(nil); pdf.Source := WPRichText1; try pdf.FileName := 'c:wp5out.pdf'; pdf.Print; finally pdf.Free; end; end; The TWPPDFExport com ponent can be alternatively dropped on the form and the properties can be set in the IDE. Then only one line of code is required: WPPDfExport1. Print. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 173. Guide 167 7.11.2 Export using dialog You can use the provided PDF creation dialog to create a full featured PDF file with wPDF. To display it only these lines are required: uses WPToPDFDlg; var pdfcreate: TWPCreatePDF; begin pdfcreate := TWPCreatePDF.Create(Self); pdfcreate.EditBox := WPRichText1; try pdfcreate.ShowModal; finally pdfcreate.Free; end; end; 7.11.3 Export using PaintRTFPage() Alternatively this simple code can be used to export PDF files from WPTools Version 6. The drawing code used by WPTools Version 6 will makes sure that the hyperlinks and bookmarks are exported to PDF as they are with the 'old' WPPDFExport component. Please note that the component WPRichText1 is a TWPRichText component created on the form with the property Visible set to FALSE. All other properties have not been changed. // uses WPRTEPaint, WPPDFR1, WPPDFR2; procedure TForm1.ExportToPDF(Sender: TObject); var WPPDFPrinter1: TWPPDFPrinter; i,w,h : Integer; begin WPPDFPrinter1 := TWPPDFPrinter.Create(nil) ; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 174. 168 WPTools Version 6 WPPDFPrinter1.FileName :='c:wptools5demo.pdf' ; WPPDFPrinter1.CompressStreamMethod := wpCompressFastFlate; WPPDFPrinter1.AutoLaunch := TRUE; WPPDFPrinter1.BeginDoc; try i := 0; while i<WPRichText1.CountPages d o begin w := MulDiv(WPRichText1.Memo._PaintPages[i].WidthTw,WPScreenPixelsPerInch,1440); h := MulDiv(WPRichText1.Memo._PaintPages[i].HeightTw,WPScreenPixelsPerInch,1440); i f (w=0) o r (h=0) then begin w := Round( WPRichText1.Memo.PaintPageWidth[i] / WPRichText1.Memo.CurrentZooming ); h := Round( WPRichText1.Memo.PaintPageHeight[i] / WPRichText1.Memo.CurrentZooming ); end; WPPDFPrinter1.StartPage( w, h, Screen.PixelsPerInch, Screen.PixelsPerInch, 0) ; try // Use 0 as w and h to let the function calculate the width and height WPRichText1.Memo.PaintRTFPage(i,0,0,0,0,WPPDFPrinter1.Canvas, [wppInPaintForwPDF] ); finally WPPDFPrinter1.EndPage; end; inc(i); end; finally WPPDFPrinter1.EndDoc; WPPDFPrinter1.Free; end; end; To create watermarks simply add additional code which prints on the WPPDFPrinter1.Canvas. Or you can easily print 2 pages on the same PDF page, just make changes in 4 lines: var WPPDFPrinter1: TWPPDFPrinter; i, w, h : Integer; begin WPPDFPrinter1 := TWPPDFPrinter.Create(nil) ; WPPDFPrinter1.FileName :='c:wptools5demo.pdf' ; WPPDFPrinter1.CompressStreamMethod := wpCompressFastFlate; WPPDFPrinter1.AutoLaunch := TRUE; WPPDFPrinter1.BeginDoc; try i := 0; while i<WPRichText1.CountPages d o begin h := WPRichText1.Memo.PaintPageHeight[i]; w := WPRichText1.Memo.PaintPageWidth[i]; WPPDFPrinter1.StartPage(w, h div 2, Screen.PixelsPerInch, Screen.PixelsPerInch, 0) ; try // Use 0 as w and h to let the function calculate the width and height WPRichText1.Memo.PaintRTFPage(i,0,0,w div 2,h div 2,WPPDFPrinter1.Canvas, [] ); WPRichText1.Memo.PaintRTFPage(i+1,w div 2,0,w div 2,h div 2, WPPDFPrinter1.Canvas, [] ); finally WPPDFPrinter1.EndPage; end; inc(i,2); end; finally WPPDFPrinter1.EndDoc; WPPDFPrinter1.Free; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 175. Guide 169 end; end; 7.11.4 Create edit / memo fields Using WPTools 6 and wPDF V3 ist is now possible to create text fields in PDF files. Example: Create a simple edit field with WPRichText1.InputTextFieldName('FORMEDITFIELD') do begin Source := FieldName.Text; Params := SFieldText.Text + '@@HINT@@' + SHintText.Text; end; Create a edit field based on a TWPObject class: Here it is also possible to create multi line fields. var obj : TWPTextObj; begin i f Multiline.Checked then obj := WPRichText1.TextObjects.InsertClass('TWPOEditControl' 360*5, 260*5 ) , else obj := WPRichText1.TextObjects.InsertClass('TWPOEditControl' 360*5, 260 ); , i f obj.IsImage then begin obj.ObjRef.ObjName := AFieldName.Text; (obj.ObjRef a s TWPOEditControl).Text.Text := TextEdit.Text; (obj.ObjRef a s TWPOEditControl).Hint := HintEdit.Text; (obj.ObjRef a s TWPOEditControl).PDFFont := TWPOEditControlPDFFont( FontSelect.ItemIndex ); i f not AutoSize.Checked then (obj.ObjRef a s TWPOEditControl).PDFOptions := (obj.ObjRef a s TWPOEditControl).PDFOptions - [wpecAutosizeFont]; (obj.ObjRef a s TWPOEditControl).Multiline := Multiline.Checked; i f Multiline.Checked then (obj.ObjRef a s TWPOEditControl).FontSize := 1 0; end; end; 7.11.5 Create a check box field Using WPTools 6 and wPDF V3 ist is now possible to createcheck boxes in PDF files. Example: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 176. 170 WPTools Version 6 This box w as created w ith this code: with WPRichText1.InputTextFieldName('FORMCHECKBOX' d o ) begin Source := FieldName.Text; Params := 'true'; //'false' end; 7.11.6 Create embedded data objects Using WPTools 6 and wPDF V3 ist is now possible to add an object to the PDF file which holds embedded data. Example: This feature uses the class TWPODataContainer. It is a descendant of TWPOImage and so able to dis The embedded data is loaded by AddDataFile or AddDataStream. function AddDataFile(Filename: WideString; fsmode: TPDFEmbeddedFileElementFS = wpembDefault): string; function AddDataStream(data: TStream; fsmode: TPDFEmbeddedFileElementFS; compressmode: TPDFEmbeddedFileElementCompress; const ext_o r_subtype: string): string; Example code: var obj : TWPTextObj; begin obj := WPRichText1.TextObjects.InsertClass('TWPODataContainer' 360, 360 ); , i f obj.IsImage then begin obj.Mode := obj.Mode + [wpobjSizingDisabled]; // obj.ObjRef.LoadFromFile('c:a.bmp'); obj.ObjRef.AssignBitmap(Image1.Picture.Graphic); (obj.ObjRef as TWPODataContainer).AddDataFile(Edit1.Text,wpembDefault); (obj.ObjRef as TWPODataContainer).Icon := wpemTag; // wpemGraph; (obj.ObjRef as TWPODataContainer).AddParam('Contents','Dies ist eine Datei') ; (obj.ObjRef as TWPODataContainer).AddParam('Title' 'Julian Ziersch') ; , end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 177. Guide 171 7.12 Adding Spellcheck WPTools comes with an integrated spell check interface which can be used by the third party products Addict Spell and EDSSpell. (Please see latest partner links) Our own product WPSpell also uses this procedures and events. This screen shots show the spell-as-you-go feature with WPSpell and Addict Spell To activate the spell check interface all you have to do: · with Addict Spell: add unit WPTAddict to the project and use the WPTools spell check actions. · with EDSSpell: add unit eds_wptools to the project · with WPSpell (registered version. (order link: single, SITE) : 1. Drop the component TWPSpellController (activate symbol WPSEPLL in file WPINC.INC to compile it into the WPTools package) 2. Set the property WPSpellController1.Active to TRUE 3. Add the unit wpspell_link to the uses clause 4. Use the command WPRichText1.StartSpellCheck() to start/stop spellcheck · with WPSpell (demo version) : Just add the unit wpspell_link to the uses clause. You cannot create an instance of the spellcheck controller since it loaded at runtime from the demo DLL. Advantages of WPSpell · Spellcheck while typing · WPSpell has been esspecially tailored to work with WPTools. · Traditional spellcheck dialog · Support for spellcheck during input (curly underlines + popup dialog) · With WPTools Version 6: instant update of spellcheck markers when switching languages · Use multiple dictionaries · Low overhead - dictionaries are not completely loaded into memory (although this option exists, too) · Setup information automatically stored in INI file or registry · Dictionary compiler included · Optional compond word checking with German dictionary · Very fast dictionary routines © 2004-2008 WPCubed GmbH - Munich, Germany
  • 178. 172 WPTools Version 6 · Complete source code for spellcheck engine included with registered version. The engine has been rewritten to make best use of the latest compiler technology. In the editor two properties are of interest for spellchecking: SpellCheckStrategie possible values are wpspCheckInInit (default), wpspCheckInPaint and , wpspCheckInInitAndPaint. We recommend to use wpspCheckInInitAndPaint with WPSpell. ViewOption flag wpTraditionalMisspellMarkers: If this flag is active instead of the big underlines ( ) smaller lines are drawn under misspelled words: 7.12.1 Use WPSpell WPSpell is an addon to WPTools. 1) Please add the required units to the uses clause uses WPSpell_link, WPSpell_Controller, WPSpell_OptForm, WPSpell_StdForm 2) Create a TWPSpellController (you can also drop the component on the form) and set the properties. (Note: This step is not required if you are using the DEMO version since here the SpellController is provided by a DLL - the registered version does not use a DLL) in TForm we need a variable: FSpellControler : TWPSpellController; This variable is initialized in the event OnCreate procedure TForm1.FormCreate(Sender: TObject); begin FSpellControler := TWPSpellController.Create(self); FSpellControler.PersistencyMode := wpUseRegistry; FSpellControler.Active := TRUE; FSpellControler.LoadSetup(false); // UpdateLanguges; - this procedure fills a combobx end; procedure TForm1.FormDestroy(Sender: TObject); begin FSpellControler.AutoSaveSetup; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 179. Guide 173 FSpellControler.Free; end; 3) Switch SpellAsYouGo on and off (Spell is a checkbox in this example) procedure TForm1.SpellClick(Sender: TObject); begin if Spell.Checked then WPRichText1.StartSpellCheck(wpStartSpellAsYouGo) else WPRichText1.StartSpellCheck(wpStopSpellAsYouGo); end; 4) Add a configure button or menu item procedure TForm1.ConfigureClick(Sender: TObject); begin i f FSpellControler.Configure then begin // UpdateLanguges; - if we update a combobox i f Spell.Checked then begin WPRichText1.StartSpellCheck(wpStopSpellAsYouGo); WPRichText1.StartSpellCheck(wpStartSpellAsYouGo); end; end; end; alternatively you can also call: WPRichText1.StartSpellCheck(wpShowSpellCheckSetup); 5) If you want to show a combobox with the available dictionaries // This procedure updates the combobox procedure TForm1.UpdateLanguges; var i, j : Integer; begin // Checkbox Spell.Checked := (FSpellControler.OptionFlags and WPSPELLOPT_SPELLASYOUGO)<>0; // ComboBox SpellLanguages.Items.Clear; j := -1; for i:=0 t o FSpellControler.LanguageIDCount-1 d o begin i f FSpellControler.CurrentLanguage=FSpellControler.LanguageID[i] then j := SpellLanguages.Items.Count; SpellLanguages.Items.AddObject(FSpellControler.LanguageName[i], Pointer(FSpellControler.LanguageID[i])); end; SpellLanguages.ItemIndex := j; end; //this procedure applies a language change procedure TForm1.SpellLanguagesChange(Sender: TObject); begin i f SpellLanguages.ItemIndex>=0 then begin FSpellControler.CurrentLanguage := Integer(SpellLanguages.Items.Objects[SpellLanguages.ItemIndex]); i f Spell.Checked then begin WPRichText1.StartSpellCheck(wpStopSpellAsYouGo); WPRichText1.StartSpellCheck(wpStartSpellAsYouGo); end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 180. 174 WPTools Version 6 end; end; The property CurrentLanguage is used to select the current dictionary. You have to use one of the language or language-group IDs which are defined in file WPLanguages.INC Example: English General = 9, English UD= 1033, English British = 2057, French = 1036, German = 1031, Italian= 1040, Spanish = 1034 7.13 WPReporter Addon WPReporter is part of WPTools Bundle, WPTools Professional Bundle and WPTools Premium. With WPReporter you get a powerful reporting tool which is tightly integrated into the word processor. The resulting report is a text which can be edited. It creates the reports by merging data into a template with the ability to loop parts of the template (bands). In contrast to the the plenty reporting applications and tools available already, our reporting engine is based on a word processor. This m eans the reporting tem plate is just a text docum ent, so is the output. Also included is a component to add calculation to tables, also for dynamically calculated fields to display subtotals in headers, footers, header-rows and footer-rows. WPReporter is able to create tables with header and footer rows and sections if you need different page formats in a document. The following classes are included: TWPEvalEngine This class implements the support for formulas. TDBWPEvalEngine This class adds database access to TWPEvalEngine TWPFormulaInterface This class creates a link between an editor and an TWPEvalEngine to support calculation in text and tables TWPSuperMerge This is the main class of WPReporter. It implements the logic to create a new text from data and template texts. new: WPTools 6 includes powerful Token to Template Conversion. ReportTemplates can be editied using certain plain text tokens. Order link to the upgrade WPTools Standard or WPTools Standard PRO WPTools "Bundle" © 2004-2008 WPCubed GmbH - Munich, Germany
  • 181. Guide 175 7.13.1 Comparison to "usual" reporting 1) End user can modify templates Many reporting tools are very complicated to use or do not offer end user modifications at all. a) With WPReporter it is possible to load a regular docum ent with added tags for fields (i.e. <<name>>) and bands (i.e. <<#ORDERS>> .... <<#/ORDERS>> ) and WPReporter can convert such a docum ent into a reporting tem plate (=token to tem plate conversion). Syntax highlighting is possible while editing the reporting tem plate in text form. b) If the database structure is rather com plicated you can use the alternative tem plate architecture. Here the report logic has been split up into two parts (pre tem plate and tem plate architecture). One part is created and m aintained by the developer. It contains the outline of the report with bands which can but do not have to be used, fields which can be used and variables which are calculated while the report is being processed as XML data. The second part is the report tem plate. It can be edited by the end user (you can of course hide it, too) using the word processor. It is possible to insert fields and variables from the "repository". It is also possible to reset a selected group to its initial state in case it has been m essed up. It is saved as docum ent with added proprietary attributes to m aintain the bands. 2) No fixed page layouts Most reporting tools work with page layouts. This means you m place graphics at ay exact positions on a form and when the report is created it will exactly look as the designed form s. This approach is often very good, but is som cases you want the text created by the e reporter to be edit able. The m entioned approach has a problem here - while it is som etim possible to create RTF docum es ents with the reporting tool theses are not really "edit able" because the text has been broken up into the tiniest pieces - just single text boxes. Usually the RTF export is optimized to be best viewed in MS Word only. With the WPReporter a text file (RTF or WPT form at) is created which allows full editing, including changing of the page size, and other operations which m akes the re- pagination of the text necessary. This means that the reporting feature is optim if you need to create longer texts, al such as contracts. It will be suitable to print lists and invoices. If you need to print form which look like pre printed paper form (i.e. TAX form you cannot use the s s s) WPTools reporting. But in this case you will probably not need sophisticated form atted text. 3) Most RTF attributes usable © 2004-2008 WPCubed GmbH - Munich, Germany
  • 182. 176 WPTools Version 6 Usually the reporting tools only support very lim ited RTF features, sometim even es justified text is a problem not to speak of im , ages with text wrapping around, tables and m ore sophisticated tab stops which use fill signs. Since the WPTools reporting uses the sam text engine all the powerful word e processing features can be used in the created report. 4) No external installation Many reporting tools require to be installed separately, they can be quite cost intensive and the licensing can be restrictive. 7.13.2 Calculation in Text and Tables When you have licensed WPReporter you can use powerful calculation commands in WPTools. To use the calculation names and formulas add the component TWPFormulaInterface to the application. The calculation tool uses names and formulas. Names can be assigned to paragraphs or cells only. Formulas can be assigned to paragraphs (or cells) and also special TWPTextObj objects. When the text is calculated the paragraph text or the displayed text of the TWPTextObj will show the floating point result of the calculation. If a formula is just a name (assigned to one or many other paragraphs) the result is the sum of the numbers found in all the paragraph which use this name. This feature makes it easy to sum up values. Please see the demo TableCalc. This demo includes code to create a simple invoice. It also shows how to activate the optional display of paragraph names and formulas. Which this option activated you will see an output like this: You can see that the cells in each column use a different name (highlighted in red). The formula (in blue) uses a relative function left(N) which returns the value of the Nth cell to the left . The total row uses a formula (in blue) just the name used by the cells which should be summed up. Please note that this way to calculate is optimized for invoices and similar: The numbers will be always summed as displayed (rounded), not using possible additional decimal values. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 183. Guide 177 The text object which also displays the total is created as simple as: obj := par.AppendNewObject(wpobjTextObject,false, false); obj.Name := 'CALC'; // fixed name obj.Source := 'PAR_TOTAL' // display the sum of all par with this name ; obj.Params := '???'; // initial display text Note: the objects name is 'CALC' which is obligatory. If you need to create sub totals in header or footer texts You can use a TWPTextObject with the name PAINT_CALC. The 'Source' should be a + sign followed by the name of all paragraphs which should be summed up. Other formulas are not possible since the calculation is not performed by the WPEval unit. This simple calculation is the default action done for the OnTextObjectPaintCalc of the TWPFormulaInterface. Please also see below. Using HTML syntax such a footer can be created like this: WPRichText1.HeaderFooter.Get(wpIsFooter,wpraNotOnLastPage).RtfText.AsString := '<html><div align=right style="border-top-width:0.5pt">Subtotal: <TEXTOBJ name="PAINT_CALC source=" " +PAR_TOTAL">???</TEXTOBJ></div></html>'; This functions are created by the unit WPTblCalc and can be used in formulas: left(N, N2, ...Nn) : sum up the cells to the left right(N, N2, ...Nn) : sum up the cells to the right previous(N, N2, ...Nn) : sum up the cells in the same column but previous rows prior(N, N2, ...Nn) : synonym for previous() average(name) - calculate the average of all paragraphs with the give name valcount(name) - count the paragraphs with the give name The event TWPFormulaInterface.OnTextObjectPaintCalcmakes it possible to calculate the contents of fields at paint time. This is very useful for fields in header or footer texts or repeated table header or footer rows. These fields are not physically duplicated, they are just painted on several pages. So their contents must be calculated at paint time. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 184. 178 WPTools Version 6 The event OnTextObjectPaintCalc provides several parameters which make it possible to evaluate the text on the current page (the page they are painted upon). Please see the TableCalc demo. There we sum up all values which are in a certain mail merge field placed on a certain page. A total sum is simply retrieved from a value which is added to each row. We are searching for the last occurance of this value and use it. So if the page break changes and the last row becomes the first row of the next page we use the new last value instead. 7.13.3 Reporting with WPReporter The reporting creates a new text from a template by mixing in data or calculated text. A template consists of text which is sperated into different parts using bands and groups. Unlike groups, bands (data, header or footer) always end with the start of the next band or group. Groups end with the closing of the group - they can also be nested. Example for a template: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 185. Guide 179 (Hint: You can double-click on the to collapse any group) This report is created by this template in our demo application: Note that the table uses two footer rows. One is used at the end, the other is used only before a pagebreak. When the created report is saved to RTF MS-Word can use the repeated headers. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 186. 180 WPTools Version 6 Unfortunately it does not support repeated footers and hidden rows so both footers will be displayed at the end of the row. Note: Using the property ColumnWidthSnapValue You can control that the column widths which are very close (max. difference ColumnWidthSnapValue twips) are set to the same value. The default value 15 makes sure that one screen pixel difference does not count. This mode can be deactivated in the property "Options". If you have long field names and want to avoid word wrap in your template, You can either apply the property WPAT_NoWrap to the cells which should not wrap or you can shorten the fieldnames automatically using MergeText, event OnMaileMergeGetText. You can still show the complete fieldname in an hover event - please see chapter MailMerge. Note that WPAT_NoWordWrap must be enabled in property RichText.FormatOptionsEx. Please note that the word wrap is highly influenced by the way the font width is calculated by the screen driver. The property SuppressAutomaticHeaderFooter can be used to avoid that header and footers which cannot be properly used with MS Word are created. Please also see the event TWPFormulaInterface.OnTextObjectPaintCalc it can be used to - calculate subtotals for the repeated rows. (See demo TableCalc) WPReporter includes the band dialog which can be easily used to edit the template: This dialog is displayed by the TWPReportBandsDialog component. Please specify the editor and the SuperMerge component. Then use this code to show the dialog: WPReportBandsDialog1. Execute; The buttons "New Band" and "New Group" open popup menus to create new control bands. For groups cou can choose where the group should be created - ie. if the current group should be surrounded by the new one. Please note that while a group or band is selected, pressing ENTER © 2004-2008 WPCubed GmbH - Munich, Germany
  • 187. Guide 181 creates a new line at the beginning of the contained text. If a group is selected pressing INSERT creates a new line AFTER the group. Tip: When text and regular bands (no groups) are selected you can place this text into a new group using "create at the current position". (Hint: After a band has been added you can use the "Band Type" dialog to change its type. Please also activate one of the check boxes.) The SuperMerge component (TWPSuperMerge actually does all the work. It combines the text ) from the source component with the data with the data which was inserted using the OnMailMergeGextText event and sends it to the destination, another memo component of the class TWPRichText. To attach the two TWPRichText to the TWPSuperMerge please use one line of code to call the procedure SetSourceDest. (In WPTools 4 there were 2 properties for this task - they had to be removed due to the different architecture of the new WPReporter) procedure TForm1.FormCreate(Sender: TObject); begin WPSuperMerge1.SetSourceDest ( SourceText.Memo.RTFData, DestText.Memo.RTFData ); end; During the creation of the document (inside the destination control) the processing of each band can be switched off and each group can be repeated as often as required. After one paragraph of the template has been copied to the destination control the fields in this paragraphs are replaced by data values. This work is performed by the mail merge function which can be also used without WPReporter. The mailmerge function triggers the OnMaileMergeGetText event for each field which is found in the text. Inside the event the data can be assigned to the object which is used to transfer the data, an image can be inserted or the text format can be changed. 7.13.4 WPReporter - step by step In this chapter we show how to build an application which creates a certain report. (full source in directory "TasksWPReporter_MasterClient") 1) Create a form with a page control with 2 pages. The first page will be the template editor, the second page will display the complete report. You can easily hide the first page if you do not want to show your end user the editor. Also drop a TWPReportBandsDialog and a TWPSuperMerge component. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 188. 182 WPTools Version 6 2) Add a TWPToolBar, TWPRuler, a TWPRichText and also a TButton and connect the controls. The button is used to show the WPReportBandsDialog1 which is used to add and delete bands. 3) Now please add a second TWPRichText on TabSheet2. We will use this second editor to show the created report. You can also hide the form completely and a TWPPreviewDlg instead. (Property EditBox set to WPRichText2) 4) Now configure the TWPSuperMerge component. This must be done in the OnCreate event of the form. procedure TForm1.FormCreate(Sender: TObject); begin WPSuperMerge1.SetSourceDest( WPRichText1.Memo.RTFData, WPRichText2.Memo.RTFData ); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 189. Guide 183 WPReportBandsDialog1.EditBox := WPRichText1; end; Also configure the ReportBands dialog: The property DataBases holds a string list with names which can be selected for the group bands. This names are used select a certain data set or to create and reset a query. In our example we enter the strings CUSTOMERS and INVOICES. 5) now its time to create and attach the data bases. To do so we create a separate data module. (In a real application you would use your existing data module) For this demo we select the databases CUSTOMERS and ORDERS from the Borland demo database directory and set a master-detail relationship based on the field 'CustNo'. 6) In the event Form.OnShow we fill the field collection of the SuperMerge component. The field list is used to create the drop down menu for the InsertField menu. The collection can be also filled at design time. The field names can optionally use the syntax name=label_text. If the equation sign is used the part after it will be displayed in the insert-field menu of the report editor dialog. procedure TForm1.FormShow(Sender: TObject); var i : Integer; begin WPSuperMerge1.Fields.Clear; with WPSuperMerge1.Fields.Add d o begin ParentDatasetName := 'CUSTOMERS' ; ParentDatasetDescription := 'Customer Data'; RequiredParentGroup := ' '; for i:=0 t o DataModule1.CUSTOMER.Fields.Count-1 d o FieldNames.Add( DataModule1.CUSTOMER.Fields[i].FieldName + '=' + DataModule1.CUSTOMER.Fields[i].DisplayLabel ); end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 190. 184 WPTools Version 6 with WPSuperMerge1.Fields.Add d o begin ParentDatasetName := 'ORDERS' ; ParentDatasetDescription := 'Orders' ; RequiredParentGroup := 'ORDERS' ; for i:=0 t o DataModule1.CUSTOMER.Fields.Count-1 d o FieldNames.Add( DataModule1.ORDERS.Fields[i].FieldName + '=' + DataModule1.CUSTOMER.Fields[i].DisplayLabel ); end; end; 7) Now we want to implement a procedure which creates a generic template which works with our data. Was add a button: and attach this code: procedure TForm1.CreateGroupsClick(Sender: TObject); begin WPSuperMerge1.AddReportGroup('CUSTOMERS' , [wpCreateBorders,wpCreateDataRow ], nil, SetCellStyle, 2) ; WPSuperMerge1.AddReportGroup('ORDERS' , [wpCreateBorders,wpCreateSmallHeaderRow,wpCreateDataRow,wpCreateSmallFooterRow ], nil, SetCellStyle, 2) ; end; This code uses the procedure AddReportGroup which creates a group, optional with header and footer rows and with already inserted fields. It accepts a list of field names but can also collect the fields from the field names in the collection Field which we initialized in step (6). Similar to you can use a callback which will be executed for each created cell. In this callback you can change the text and set properties for the cell. We use this callback. procedure TForm1.SetCellStyle(RowNr, ColNr: Integer; par: TParagraph); begin i f (RowNr<0) and ((RowNr and 1) =1) then // Header Rows begin par.ASetColor(WPAT_FGColor, clBtnFace); i f ColNr>1 then include(par.prop, paprColMerge) else begin par.ASet(WPAT_Alignment, Integer(paralCenter)); par.SetText('Orders' ; ) end; end else i f (RowNr<0) and ((RowNr and 1) =0) then // Footer Rows begin par.ASetColor(WPAT_FGColor, clBtnFace); par.ASet(WPAT_SpaceBetween, -100) ; i f ColNr>1 then include(par.prop, paprColMerge); end; end; to get this report template as result: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 191. Guide 185 8) Now we can add the logic to actually create the report. We need an event handler for BeforeProcessGroup. Here we check if the 2 tables are at EOF and reset the client table. procedure TForm1.WPSuperMerge1BeforeProcessGroup(Sender: TWPSuperMerge; Band: TWPBand; Count: Integer; var CustomData: TObject; var ProcessGroup, IsLastRun: Boolean); begin i f Band.Alias='CUSTOMERS' then begin ProcessGroup := not DataModule1.CUSTOMER.Eof; i f ProcessGroup then DataModule1.ORDERS.First; end else i f Band.Alias='ORDERS' then begin ProcessGroup := not DataModule1.ORDERS.Eof; end; end; In AfterProcessGroup we move to the next record. procedure TForm1.WPSuperMerge1AfterProcessGroup(Sender: TWPSuperMerge; Band: TWPBand; var CustomData: TObject; var Abort: Boolean); begin i f Band.Alias='CUSTOMERS' then begin DataModule1.CUSTOMER.Next; Abort := FALSE; end else i f Band.Alias='ORDERS' then begin DataModule1.ORDERS.Next; Abort := FALSE; end; end; Now we need to merge in the data. We use the event OnMailMergGetText. In this event we locate the field in the sepecified dataset and assign the contents. Of course it would be possible to use calculated fields or variables and constants, too! © 2004-2008 WPCubed GmbH - Munich, Germany
  • 192. 186 WPTools Version 6 procedure TForm1.WPSuperMerge1MailMergeGetText(Sender: TObject; const inspname: String; Contents: TWPMMInsertTextContents); var f : TField; begin i f Contents.DatasetnamePart='ORDERS' then f := DataModule1.ORDERS.FindField(Contents.FieldnamePart) else f := DataModule1.CUSTOMER.FindField(Contents.FieldnamePart); i f f=nil then Contents.StringValue := ' ' // undefined! else Contents.StringValue := f.AsString; end; It is also possible to insert formatted text using the event OnMailMergGetText. For example if you have a letter stored in a database or a different editor. Simply assign RTF, WPTOOLS or HTML code to Contents.StringValue. If the inserted text starts with a table we recommend to set the mail merge option mmDeleteThisField With this option the fields are deleted in the destination editor. So no . paragraph has to be created above a table to store the field markers. procedure TWPRepForm.WPSuperMerge1MailMergeGetText(Sender: TObject; const inspname: string; Contents: TWPMMInsertTextContents); begin i f CompareText(inspname, 'RTFTEXT' = 0 then ) begin Contents.StringValue := ARTFTEXT.AsANSIString('RTF') ; Contents.Options := Contents.Options + [mmDeleteThisField ; ] end else .... end; 9) Almost complete - we want to show the update report when the active page in the page control is changed procedure TForm1.PageControl1Change(Sender: TObject); begin i f PageControl1.ActivePageIndex=1 then // Secod page then begin DataModule1.CUSTOMER.Open; DataModule1.ORDERS.Open; DataModule1.CUSTOMER.First; WPRichText2.Clear; WPRichText2.Header := WPRichText1.Header; // Assign page properties WPSuperMerge1.Execute; WPRichText2.DelayedReformat; end; end; 10) Improve the template At runtime you can change the reporting template, add fields and also header and footer bands. You can delete rows, move fields, merge cells. After some changes we got this template - still based on the automatic created template. Tip: You can save the template as WPT file and load into WPRichText1 when you click on it inside the IDE with right mouse button. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 193. Guide 187 The first, new header and footer bands create page header and footer. The page numbers have been inserted with WPRichText1.InputTextField(wpoPageNumber) - this function can be also selected from the InsertField dropdown in the report editor dialog. This is the created report: Advanced Techniques: Use the BeforeFormatTable event to focr certain tables to be on one page. Using the FormatOptions you can force all tables to be left intakt (unless they are too long for a © 2004-2008 WPCubed GmbH - Munich, Germany
  • 194. 188 WPTools Version 6 page). Using the RTFDataCollection event BeforeFormatTable you can enable this mode for certain tables: WPRichText2. HeaderFooter.BeforeFormatTable := BeforeFormatTable; procedure TWPRepTest.BeforeFormatTable(RTFData : TWPRTFDataCollection; tablepar: TParagraph; var KeepTogether : Boolean); begin i f tablepar.RowCount=2 then KeepTogether := TRUE; end; 7.13.5 WPReporter Events Reporting with WPReporter is controlled by events. This makes it possible to work with any database system, or also without a database, for example if load calculated data. Within the event code you can check the properties of the object WPSuperMerge.Stack to get information about the current position within the report template. The property Stack.Previous can be used to check the propeties of the parent group of bands. Other useful properties are Stack. GroupBand, Stack.Band and Stack.CurrentParagraph. This events are published by the class TWPSuperMerge: OnMailMergeGetText- the most important event, it is used to insert the data for certain data fields. This event uses the same parameters like the TWPRichText event OnMailMergeGetText. In the simplest case the event handler can be © 2004-2008 WPCubed GmbH - Munich, Germany
  • 195. Guide 189 procedure TForm1.DoMailMergGetTexte( Sender: TObject; const inspname: string; Contents: TWPMMInsertTextContents); begin Contents.StringValue := 'This is a test'; end; It is possible, for example, to use this field name to retrieve the text from a data set: Contents.StringValue := DataSet.FieldByName(inspname).AsString; You can also change the attribute of the inserted text using 'MergeAttr'. Contents.MergeAttr.SetColor(clRed); BeforeProcessGroup: This event is the second most important. It is used to control if a group should be processed or not. If the group should be processed set the parameter ProcessGroup to true, if it should be not processed set the parameter ProcessGroup to false. If you know that this would be the last time this group is being used set the parameter IsLastRun to true. When the template uses nested groups the BeforeProcessGroup will be triggered for the nested group before AfterProcessGroup is triggred for the outer group. Typically you test the DataSet for being at the end (EOF) and set the parameter ProcessGroup accordingly: i f Band.Alias = 'MAIN' then ProcessGroup := not MainDataSet.EOF; OnPrepareHeader : This event is triggered before a header band is being processed. You may set the parameter Abort to true to skip the band. OnPrepareText : This event is triggered before a text band is being processed. You may set the parameter Abort to true to skip the band. OnPrepareFooter : This event is triggered before a footer band is being processed. You may set the parameter Abort to true to skip the band. OnPostProcessBandData : This event makes it possible to modify a paragraph after it was created in the destination text buffer. It is triggered after the entire text for a band was created. The start and end paragraphs are passed to the event. The paragraph references can refer to normal paragraphs or table row paragraphs. You can use this event to add flags to paragraphs to mark certain areas in the report. AfterProcessGroupData : This event is processed after the data bands in a group have been processed. You can use © 2004-2008 WPCubed GmbH - Munich, Germany
  • 196. 190 WPTools Version 6 it to sum up values which should be used as totals in footers. AfterProcessGroupData will be triggered each round the group is used. You can set WPSuperMerge.Stack. PagebreakAtGroupEnd = true inside this event to force a pagebreak after the hroup data. AfterProcessGroup: This event is the triggered after a group has been processed. Typically you use this event to advance to the next record in the database. i f Band.Alias = 'MAIN' then MainDataSet.Next; 7.13.6 Convert text into template One unique strength of our WPReporter concept is the possibility to convert an existing report (maybe you used to create it using OLE before) quickly into a report template. You can use the procedure ConvertLetterIntoTemplate This procedure creates a report with . header and footer bands which are initialized to create the header and footer texts found in the original document. Around the body of the document a group is created which makes it easy to create many letters in a row. 1) All texts which are fixed have to remain in the template 2) All text blocks which depend on selected data must be replaced by mail merge fields. 3) Tables can be converted into groups with the utility function SuperMerge. ConvertTableIntoGroup This utility can be called from within the report editor dialog. The tool can . be used when the cursor is inside of a table, please do not select the table. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 197. Guide 191 Sometimes it is a good idea to simplify the table before you use "ConvertTableIntoGroup". Very useful will be the API 'SplitTable to split up a table which contains data from different logical ' elements. 4) Make text blocks conditional: Please add a possibility to the application to set the Name of a band. i.e. you can use a combo box or popup menu. The code would be basically: i f WPSuperMerge1.Bands.CurrentBand<>nil then WPSuperMerge1.Bands.CurrentBand.Alias := 'ANAME'; With the OnPrepareTextevent You can then check text bands (the green ones). If the band uses a certain Alias (alternatively You can use property Name) You can set the variable 'Abort' depending on a certain condition. procedure TWPRepTest.WPSuperMerge1PrepareText(Sender: TWPSuperMerge; Band: TWPBand; Count: Integer; var ParProps: TParagraphProperty; var Abort: Boolean); begin i f Band.Alias = 'ANAME' then begin Abort := TRUE; end; end; Now you can insert a data band and assign the 'Alias': Note: If you assign a string to property 'Name', this text will be displayed instead of 'Data' © 2004-2008 WPCubed GmbH - Munich, Germany
  • 198. 192 WPTools Version 6 7.13.7 Reporter and Bookmarks WPSuperMerge is able to create bookmarks around the text which was created in the destination document for a certain band or group. This bookmarks will be created after the text was entirely created if the property 'Bookmark' was set to a non empty string. Bookmarks (TWPTextObj objects) embedded in the template will also be copied to the destination, but since it is not possible to place bookmarks in band paragraphs the above mentioned functionality is the only way to do it. In this example template embedded bookmarks are used. The first group uses the bookmark property. Note: The bookmarks are usually invisible. They are displayed only if the flag wpShowBookmarkCodes was used in property FormatOptions. 7.13.8 Token to Template Conversion If you use the token to template conversion you can edit the reporting template with an editor such as MS Word. This feature has been added to WPTools 6 with the WPReporter addon. The tem plate is loaded into TWPRichText. In this control the template can be further edited with the additional convenience of syntax highlighting and on dem and converted into a "true" reporting template. (The latter uses nested paragraphs to represent groups and special paragraph types for bands. Fields are not text based but use objects instead.). Tip: The report templates can be used further in our .NET and OCX components TextDynam and TextDynam Server. ic ic © 2004-2008 WPCubed GmbH - Munich, Germany
  • 199. Guide 193 If you used the m m ail erge feature before and have docum ents with em bedded m erge fields those can be easily used a reporting templates as well! It is also possible to convert an existing report into a template. To activate syntax highlighting only one line of code is required: SourceText.CustomSyntax := TWPFieldBandSyntax.Create(nil); The created instance of TWPFieldBandSyntax will be freed automatically. To convert the text to a reporting template simply execute the method WPConvertReportScript from unit WPRTEReport. function WPConvertReportScript( Source: TWPRTFDataCollection; Mode: TWPConvertReportScriptMode = [wpClearErrorsAndWarning, wpConvertFields, wpConvertBands, wpConvertGroups]; // If this is nil the 'Body' will be converted DataBlock: TWPRTFDataBlock = nil; // Parameters used to detect fields and bands FieldStart: WideString = '<<'; FieldEnd: WideString = '>>'; BandChar: WideChar = ':'; GroupChar: WideChar = '#'): TWPConvertReportScriptResult; Example: procedure TWPRepForm.ConvertClick(Sender: TObject); begin WPConvertReportScript( SourceText.RTFData ); SourceText.ReformatAll(true,true); end; 7.13.8.1 General Syntax - Fields The token to template conversion uses special character combinations to separate the com ands from the text. Fields have to be em m bedded into the characters << and > >. (This codes < , > , : and # can be custom < > ized in TWPFieldBandSyntax for syntax highlighting. Other values can be passed to the m ethod WPConvertReportScript) Note: The parser expects that after the < and before the > characters no whitespace < > characters are typed. Otherwise the characters will be interpreted as text. Example for fields: <<name>> The nam of a field m contain space characters. e ay © 2004-2008 WPCubed GmbH - Munich, Germany
  • 200. 194 WPTools Version 6 Optionally the closing '/' character can be printed: < nam /> < e > Using such fields m m ail erge docum ents can be created. Such m erge docum ents only require fields to be filled with data. Using m m ail erge does not require the reporting extension so we decided to m ake the syntax highlighting and token to template conversion available in the basis edition. If you need repeated data rows in a docum ent you need groups and bands. Bands m ark certain text to be the header and footer of a docum ent or group while groups are used to loop certain parts of the template as long as data to fill in the fields is available. Groups can also be used to disable certain parts of the tem plate. While bands are not nested, groups can be nested and so consist of a start and end token. Note: The nam of a field will be passed to the event WPRichText.OnMailMergGetText e or WPSuperMerge.OnMailMergeGetTextwhile m erging the text or creating a report. This event can retrieve the text which should be inserted inside the field. 7.13.8.2 Syntax Highlighting WPTools includes a syntax highlighter for XML and also for the syntax described in this chapter (see TWPFieldBandSyntax) Using the syntax highlighting for report templates is easy - and - the highlighting works non destructive! Show highlighting: SourceText.Custom Syntax := TWPFieldBandSyntax.Create(nil); Remove highlighting: SourceText.CustomSyntax := nil Please note, how the original text attributes are restored - here the bold characters in the third line. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 201. Guide 195 7.13.8.3 Bands Bands are identified by a colon (':') after the opening < characters. < Example for header bands: <<:HEADER>> This starts a group header or, if used outside of any group a document header text. In the latter case the following variations are possible: HEADERF = header on first page only HEADERO = header on odd pages HEADERE = header on even pages HEADER_OFF = this header is disabled. Please note that bands are not im plemented using opening and closing tokens ("i.e. < ..> ...< /...> ") so optionally the closing '/' character can be typed: < :HEADER/ < > < > < >> Example for footer bands: <<:FOOTER>> This starts a group footer or, if used outside of any group a document footer text. In the latter case the following variations are possible: FOOTERF = footer on first page only FOOTERO = footer on odd pages FOOTERE = footer on even pages FOOTER_OFF = this footer is disabled. Inside header and footer bands fields, images and text is possible. A header and footer band ends where either a different header or footer band starts or a data band: <<:DATA/>> Bands m ust be the first non white space (white space= space or tab characters) in a paragraph. All text after the band token will be ignored and can be used to write com ents. m 7.13.8.4 Groups Groups are identified by a double cross ('#') after the opening < characters. While < bands < :.../> are not nested, groups can be nested and so are em < > bedded into a tag pairs <<#...>> <<#/....>. Unlike header and footer bands the nam of the group tags are not fixed. Practically e any nam can be used if it does not contain spaces. However the opening token m e ust match the closing token. For practical reasons the nam should m es atch the database which is referenced inside of the group. Example: <<#CUSTOMERS>> comment: we list all customers in this group © 2004-2008 WPCubed GmbH - Munich, Germany
  • 202. 196 WPTools Version 6 <<Customers.Name/>> <<Customers.Address/>> Ordered Items: <<#OR DER S>> comment: we list all items ordered by the current customer <<Orders.Name/>> <<#/OR DER S>> <<#/CUSTOMER S>> Note: The nam of a group will be passed to the band and group events while creating e a report. This event has to decide if a group should be processed (again) or not. It can create a sql query and calculate sub totals. 7.13.8.5 Parameters for Fields 1. Name - may contain spaces! (required) If first character is the @ sign, the complete text will be handled as formula. (no other options are possible) 2. Displayname in " " - must be second position ! 3. Options. +spc - this will add a space after the field if it was NOT empty. +spc/ - this will add a space before the field if it was NOT empty +nl - to add a new-line if it was not empty f "some text" - will be added after the field if it was NOT empty. Alias: + "..." b "some text" - will be added before the field if it was NOT empty. Alias: + "..."/ -"some text" - will be printed if it WAS empty r "some text" - will be printed instead of the field Special attributes remove - the field will be removed setattr - the paragraph attribute will be overwritten by field contents attributes autosetattr - if this is first field in line use the para attribute keepattr - protect the current paragraph attributes loadimage - interpret field value as file name of an image file loadtext - interpret field value as file name of a text file Supports Word Syntax: b before f after. Spaces are allowed after +, -, b, f ... 4. Format @"...." @ "%f" - uses this formatting code to format the field (usually floating point numbers) 5. Condition ?...=... ?fieldname=null - use this field if the specified field was null ?fieldname# null - use this field if the specified field is not null ?fieldname=zero - use this field if the specified field was zero ?fieldname#zero - use this field if the specified field is not zero Modify: Contents.IsNull to tell the engine that a field is null or zero. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 203. Guide 197 7.13.8.6 Parameters for Bands and Groups 1. Name - predefined header/footer names or one of the possible group names 2. Displayname name in " " - must be second position 3. Option +- +ff - start a new page after the band/group -ff - start a new page before the band/group Only header and footer: ("<<:HEADER>>) +afterstretch - header/footer used after a streched band +between - use band between records -start - don't use header at start -end - don't use footer at end Only Data Bands ("<<:DATA>>) -stretch - deactivate stretching (default = on) +keep - keep this paragraph together with next +newtable - start a new table 4. Condition ?...=... The following conditions to use a band are possible: =null - field must be null #null - field must not be null =zero - field must be zero #zero - field must not be zero ="..." - the field must have a certain value #"..." - the field must be different to a certain value Example: Modify: Contents.IsNull to tell the engine that a field is null or zero. 5. Formula - must be last option @.... It is used as start condition in a group start and a continue condition if used in a group end token. Any text in the paragraph after the closing '>>' will be ignored as comment! 7.13.8.7 Example Template <<:HEADERF "my header"/>> -- any text after the group will be ignored as comment This is the header on the first page <<:HEADER "my header"/>> -- HEADERF, HEADERO, HEADERE, HEADER This is the header on all pages © 2004-2008 WPCubed GmbH - Munich, Germany
  • 204. 198 WPTools Version 6 <<:TEXT>> -- start the regular text Dear Developer, This letter documents and demonstrates the reporting feature which is based on a template written in regular formatted text with additional tags: The "<<#" signs are expected as first non-space signs in a paragraph. Any text after the closing >> signs is ignored and can be used as comment. Fields are inserted between the signs << and >>. It is important that after the '<<' no white space or punctuation is written. Headers in groups are written using single, not open/closing tags. They cannot be nested anyway. The / before the closing >> signs should be added but is not required. Only groups are nestable. Groups are started using the code <<#. The name after the # sign will be the group name, so a database name can be used. An optional alias can be specified. It is possible to set up a list of possible group names. Now our list starts: <<#GROUP1 ?name#null "Invoice">> -- the table will be given the display name "invoice", the logical names remains "GROUP1". After the optional name a condition is expected. <<:HEADER/>> -- this header will be displayed at the start of the group Group Header. Fields are possible: <<fieldname +spc/>> <<:DATA ?"has orders"=null/>> -- this is the data row. Some data here - under condition that there are no orders. (Note that a field name may used spaces. In this case use " in the field name part as well.) <<:DATA ?hasorders#null/>> -- this is the data row. Some data here - under condition there are orders. <<:FOOTER/>> -- this footer will be displayed at the end of the group Group Footer. Fields are possible: <<fieldname/>> <<#/GROUP1>> -- close the group. This text comes after the group. When viewed with activated the syntax highlighting the document will look like © 2004-2008 WPCubed GmbH - Munich, Germany
  • 205. Guide 199 Note: The syntax highlighter does not m ake any m odifications to the attributes of the text. All highlighting is done just visual and is updated while the text is edited. After the conversion to the internal reporting template structure the document looks like this: 7.14 WPPremium Addon WPTools Premium adds the support for footnotes, text boxes and (soon) columns to the edition WPTools Professional Bundle. It comes with 100% Source code. If you have purchased WPTools Premium please see the dedicated WPTools Premium © 2004-2008 WPCubed GmbH - Munich, Germany
  • 206. 200 WPTools Version 6 manual (PDF) which also includes interesting technical information. For latest information about WPTools Premium please click here, orderpage. This text was created by the WPPremium demo. It also uses the "mirror margin" feature, the left and right margin are swapped on each second page. the footnote in edit mode: 7.14.1 Text boxes To insert a text box use this code: var obj: TWPORTFTextBox; txtobj: TWPTextObj; begin i f WPRichText1.CursorOnText.Kind <> wpIsBody then ShowMessage('Cannot insert object in Object') else begin obj := TWPORTFTextBox.Create(WPRichText1); obj.WidthTW := 3000; obj.HeightTW := 1000; obj.ObjName := '_AUTO_' + IntToStr(GetTickCount); obj.AsString := '<b>Textbox</b> text in HTML, ANSI or RTF format!'; txtobj := WPRichText1.TextObjects.InsertMovableImage(obj); i f txtobj <> nil then begin txtobj.Mode := txtobj.Mode + [ wpobjObjectUnderText, wpobjCreateAutoName ]; txtobj.RelX := 1440; txtobj.RelY := 0; // optional txtobj.Frame := [wpframe1pt,wpframeShadow]; WPRichText1.ReformatAll; obj.Edit; WPRichText1.SetFocus; end; end; end; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 207. Guide 201 This code in the OnTextObjectDblClick event makes the text box editable: i f pobj.ObjType = wpobjImage then begin i f pobj.ObjRef <> nil then pobj.ObjRef.Edit; ignore := TRUE; end; Screenshot of the created box in edit mode (after double click): Tip: To create a text box which is automatically positioned in the margin of the page use the modes wpobjLockedPos,wpobjPositionInMargin 7.14.2 Footnotes Please use the method InputFootnote(PlaceCursor: Boolean; CreateNumber: Boolean = TRUE; InitText: string = #32); to create a footnote. Like textboxes, headers and footers the footnotes are also "text layers". The text layers are all stored as collection items in the collection HeaderFooters. 7.14.3 Columns WPTools Version 6 "Premium" supports columns. Please note that "text balancing" is supported since WPTools Version 6.05.. This code starts a 2 column layout at the current paragraph with 0.5 cm margin inbetween. WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS, 2) ; WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS_X, WPCentimeterToTwips(0.5)); WPRichText1.Refresh; This code will ceate 3 columns WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS, 3) ; WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS_X, WPCentimeterToTwips(0.5)); WPRichText1.Refresh; With this code a column break is inserted so this paragraph will be moved to next column or page. The user will need this functionality if a column should not be extended to the end of the page. include(WPRichText1.ActiveParagraph.prop, paprNewColumn); WPRichText1.Refresh; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 208. 202 WPTools Version 6 To switch of column layout use WPRichText1.ActiveParagraph.ASet(WPAT_COLUMNS, 1) ; WPRichText1.ActiveParagraph.ADel(WPAT_COLUMNS_X); WPRichText1.Refresh; Column properties are loaded and saved in WPT and RTF format. 7.15 Trouble Shooting When creating a package with C++Builder 2007 Go to Project Options > Delphi Compiler > Other options In the 'Additional options' box, enter > -LUDesignIDE Leave the 'Use these packages when compiling' box empty. Compile. This is described in the CB2007 help system. Search in the Index for "Delphi packages (C++)" 8 Reference The registered version of WPTools 6 also includes an organized CMH file which can serve as reference. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 209. Reference 203 8.1 Reader and Writer WPTools makes it easy to add support for different file formats. The import and export is done through a reader and a writer class which must inherit from TWPCustomTextReader and TWPCustomTextWriter. This basic classes (defined in unit WPRTEDefs) already implement the necessary code for buffered reading and writing. To use a different reader or writer simple use its classname in the property TextLoadFormat or TextSaveFormat or use the alias names, RTF, HTML, ANSI and WPTOOLS. The reader class also includes a function to check for the format using the first 500 characters of a file, this makes it possible to implement auto detection. It is possible to select a certain reader or writer using a 'format string'. This string is passed to load and save methods, such as LoadFromFile and also in the properties TextLoadFormat and TextSaveFormat. To select a certain reader or writer simply name it in the format string. You can pass options to the reader or writer, too. This options are appended to the format string after a minus sign, i.e "HTML-onlybody". Multiple options are separated by comma. You can also set the code page for the loading and or saving operations. This can be useful with the data sensitive control DBWPRichText: Example: DBWPRichText1.TextLoadFormat := 'ANSI-codepage1251' // cyrillic ; DBWPRichText1.TextSaveFormat := 'ANSI-codepage1251' ; In general these options are supported but not all reader/writer can support all options: In our web based forum we have posted several FAQ topics and articles. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 210. 204 WPTools Version 6 The article "Compose an e-mail in HTML format / Save image to HTML" shows how to create a HTML e-mail. Overview For details please see table here: http: //www.wpcubed.com/manuals/formatstrings.htm onlybody - only write body part ignorefonts - do not load font information ignorefontsize - do not load font size information nostyles - do not load or save styles nonumstyles - do not load or save number styles noimages - do not load or save images basetext - only save text in WPTOOLS format, no styles or other info nomergefields - do not save merge fields, only contents nohyperlinks - do not save hyperlinks nobookmarks - don't save bookmarks novariables - dont save or load RTF variables nobinary - try to convert all binary to ASCII nopageinfo - do not save or load page size information ignorekeepn - don't load the keepn flag from RTF ignorerowmerge - do not load row merging from RTF ignorecollapsedpar - don't save table rows which are hidden by WPReporter codepage12xx - set the code page XY for loading. Default is 1252. complete - load header and footer information although we are inserting text alwaysembed - embed image data also for linked images For further reference please see the implementation of the reader and writer classes in the units WPIO*.PAS. All options are processed by the procedure "SetOptions". The reader and writer publish "Opt_name" properties which are set to true when an format option with the same name was used. 8.2 TParagraph API This object stores the text. It is organized in a linked list (NextPar/ PrevPar) starting from TRTFData.FirstPar. Paragraphs can also contain sub-paragraphs (ChildPar). Similar to WPTools Version 4 tables cells are handled as paragraphs. In contrast to previous versions, WPTools 5 handles child paragraphs to support multiple paragraphs in the one table cell. Even tables can be inside a table cell - (but they will always start under, and not beside the normal text since they always start on a new line.) Here we list the most important properties and methods. 8.2.1 TParagraph Properties _ActCellWidth AClass © 2004-2008 WPCubed GmbH - Munich, Germany
  • 211. Reference 205 align ANSIChr ANSIText Cell ChildPar Children ChildrenCount ColCount ColFirst ColLast ColLeft ColNext ColNr ColPrior ColRight Cols ColSpan CustomParameters EndSpanH EndSpanV FirstLine FirstSibling HasChildren Hidden id indentfirst indentleft indentright © 2004-2008 WPCubed GmbH - Munich, Germany
  • 212. 206 WPTools Version 6 IsFirstTextPar IsLastTextPar IsNewPage LastChild LastInnerChild LastLine LastSibling LineCount LoadedCharAttr LogNextPar LogPrevPar MinCHeight next NextPar nextpardown ObjectIndex ObjectRef ParagraphType ParentCell ParentGroup ParentPar ParentParentPar ParentParentRow ParentParentTable ParentRow ParentTable ParLength prev © 2004-2008 WPCubed GmbH - Munich, Germany
  • 213. Reference 207 PrevPar RowCount RowDown RowFirst RowLast RowLogNr RowNext RowNr RowPrior Rows RowSpan RowUp RTFData Sibling SiblingCount SiblingNr spaceafter spacebefore spacebetween StartSpan TableCount Tables 8.2.2 TParagraph Methods _FixAllCellWidths _IsWidthTw _SetMinMaxWidth AddFlagAttr ADelAllCharAttrDefinedIn © 2004-2008 WPCubed GmbH - Munich, Germany
  • 214. 208 WPTools Version 6 ADelColumn ADeleteEqualSettings AdjustTableRow AGetBaseAndSpan AGetFBBGCOlor AGetInherited AGetInheritedFromCell AGetInheritedFromPar ANeedUpdateProps Append AppendChar AppendChild AppendNewCell AppendNewObject AppendNewObjectPair AppendNewPar AppendNewRow AppendNewTable AppendTree AsChildOfPreviousPar ASetColumn ASetNeutral ASetRow Assign AUpdateProps CalcBorderLeftRightIndent CheckTable ClearCharAttr © 2004-2008 WPCubed GmbH - Munich, Germany
  • 215. Reference 209 ClearCharAttributes ClearProps ClearText Compare ComparePar CompareW Contains ContainsText CopyChar CPOfPos Create CreateCopy CreateCopyList CreateRow CreateTable CurrentSection DeleteChar DeleteChars DeleteMarkedChar DeleteParagraph DeleteParagraphEnd DeleteParagraphKeepChildren DeleteWPTextObj DelFlagAttr Depth Destroy Duplicate Empty © 2004-2008 WPCubed GmbH - Munich, Germany
  • 216. 210 WPTools Version 6 EndRow Exchange ExcludeProp ExcludeProps FirstLevelPar FixAllCellWidths FixAllRightCellWidths FontSizeAtPosition FreeObjectRefs GetAllText GetCell GetCharAttr GetCharAttrAt GetCharAttrIndexAt GetChildrenAsList GetDebugTreeString GetFirstCharAttr GetLineText GetNumberText GetObjList GetRowNext GetRowPrior GetRTLCursorPos GetSubText GetText GetWPTextObj globalnext globalNextPar © 2004-2008 WPCubed GmbH - Munich, Germany
  • 217. Reference 211 HasAttr HasObjects HasParent HasProp HasText HasTextW Height HeightTotal InbetweenObjects IncludeProp IncludeProps Insert InsertEx InsertNewObject IsCharObject IsEmpty IsFirstPar IsLastPar IsLowercase IsNonABC IsNonSpace IsNum IsPunctation IsRTL IsSpace IsTable IsUppercase IsWordDelimiter © 2004-2008 WPCubed GmbH - Munich, Germany
  • 218. 212 WPTools Version 6 LastChar LimitCPToLineLength LimitLines LineAllCount LineEndOffset LineHeight LineIsLast LineLength LineOffset LineOfPos LinePageNr LinePosFromX LineStartNr LineXFromPos LoadFromFile LoadFromStream LoadFromString LocateNextChar LocatePrevChar MakeLine MergeCell MoveChar NeedAttr NeedCharPos nextcell NextLine Optimize OptimizeObjectRefs © 2004-2008 WPCubed GmbH - Munich, Germany
  • 219. Reference 213 Overwrite paprIsLeftPar paprIsRightPar ParagraphLines ParagraphObjAdd ParagraphObjDel ParagraphObjFind ParentCellFromTable ParNr Position PositionOfObject PosOfCP prevcell PrevLine QuickFind Reformat Refresh Replace ReplaceW RowAppend SaveToStream SetAllText SetCapacity SetCharAttr SetChildrenFromList SetRTFData SetRTLCursorPos SetStyle © 2004-2008 WPCubed GmbH - Munich, Germany
  • 220. 214 WPTools Version 6 SetText SplitAt SplitCell SplitTable StartNewSection StartWith StartWithW SubPar SwapWithNextPar SwapWithPrevPar TableDepth TextAreaWidth TotalLength UnlinkParagraph UnlinkParagraphList UpdateMinMaxWidth ValidateTable 8.2.3 AppendParCopy If you need a low level routine to copy one paragraph and all the included paragraphs (this can be table rows or table cells) to the destination editor use: var par : TParagraph; begin // Get the reference to current paragraph par := WPRichText1.ActiveParagraph; // Append it to the active RTFDataBlock DestWP.ActiveText.AppendParCopy(par); // This moves to the next paragraph! Useful in a loop! WPRichText1.ActiveParagraph := par; // Format is required sometimes later DestWP.DelayedReformat; end; For better understanding here the source of the AppendParCopy method: function TWPRTFDataBlock.AppendParCopy(var SourcePar: TParagraph; SkipObjects: TWPTextObjTypes = []): TParagraph; var toPar : TParagraph; begin i f SourcePar = nil then Result := nil else © 2004-2008 WPCubed GmbH - Munich, Germany
  • 221. Reference 215 begin Result := SourcePar.CreateCopy(Self, SkipObjects); i f Result.ParagraphType = wpIsTableRow then begin i f Empty then toPar := CreateTable(nil) else begin toPar := LastPar; i f toPar.ParagraphType <> wpIsTable then toPar := CreateTable(nil) ; end; toPar.AppendChild(Result); end else AppendPar(Result); SourcePar := SourcePar.NextPar; end; end; You can see from this code that this routine tries to add new table rows to a table object which already exists in the text. So instead of moving the complete table you can also copy only selected rows. Since the result value of the AppendParCopy function is the new paragraph you can also do some pro-processing, for example apply certain attributes. You can also use the SET parameter SkipObjects to leave out certain object types, such as [wpobjMergeField] to ignore mail merge fields (the contained text will be copied of course). 8.3 TWPRTFDataCursor The cursor class is responsible for cursor movement, text selection and the assignment of properties to the selected or current text. It is owned by the TWPRTFDataCollection. This means if different editor components share the same RTFDataCollection they also share the same cursor. The class TWPRTFDataCursor has versatile methods to manage markers which are dropped in the text to be collected again later, for example to restore a cursor position or a selection. It also contains moving and selection methods. It offers access to the interfaces to change the attributes of the selected text or the current writing mode. 8.3.1 Drop-Markers The 'Drop Markers' are special markers which can be placed in the text. They are not really inserted in the text (such as bookmarks). They are simple flags which can be used to quickly return to a certain position in the text. They are not saved with the text. Many of the input routines automatically move the drop marker, this makes them much more powerful than simply storing the text position (CPPosition). function DropMarker: Integer; function DropMarkerAt(par: TParagraph; PosInPar: Integer): Integer; This functions drop a marker which can be collected later with CollectMarker.Text insertions and deletions - as long as no paragraphs are inserted or deleted - will will automatically modify the markers of the affacted paragraphs to make sure their logical position is not changed. This makes © 2004-2008 WPCubed GmbH - Munich, Germany
  • 222. 216 WPTools Version 6 markers much more powerful than cursor character offsets, such as 'CPPosition'. We suggest to delete all markers with CollectAllMarker when they are not required anymore. Note: · a) that markers are not saved with the text. · b) If the paragraph has been deleted which was used for a marker, the marker will be moved to the start of the following paragraph. Drops a marker at the start/end of the selected text: function DropMarkerAtSelStart: Integer; function DropMarkerAtSelEnd: Integer; Returns the text position of a certain marker. The result value will be -1 if the marker is not defined or if it is located in a RTFDataBlock which is currently not edited. (ActiveText) Please use GotoMarker to move the cursor to a certain position. function DropMarkerPosition(DroppMarkerID: Integer): Integer; Moves to a marker which was dropped by 'DropMarker'. If the parameter 'Collect' = TRUE this invalidates all markers which were dropped after the specified marker. You can use (true,-1) to collect the last marker or (true,X) to delete all markers including the marker X. (true,1) will collect all markers! If it is not possible to move to that marker the result value is FALSE. function GotoMarker(Collect: Boolean = TRUE; DroppMarkerID: Integer = -1): Boolean; function GotoMarker(DroppMarkerID: Integer): Boolean; Select the text between 2 markers. function SelectMarker(FromMarker, ToMarker: Integer): Boolean; Select text with a give length starting with a given marker. function SelectMarkerStartLen(FromMarker, Length: Integer): Boolean; Removes all markers from the text: procedure CollectAllMarker; Collects all markers including and after DroppMarkerID: procedure CollectMarker(DroppMarkerID: Integer); Example: This is the implementation of the ReplaceTokens procedure. It converts text which is wrapped by special characters such as "<<" and ">>" into mail merge fileds, It uses the DropMarkers and the Finder. It also uses some 'Code' methods to create the objects which are used to mark mail merge fields. function TWPCustomRtfEdit.ReplaceTokens(const opening, closing: string): Integer; var s, r: string; StartID, SelStartID, SelEndID, rl: Integer; RestoreSel: Boolean; startf, endf: TWPTextObj; begin StartID := 0; RestoreSel := FALSE; SelEndID := 0; SelStartID := 0; Result := 0; with TextCursor d o © 2004-2008 WPCubed GmbH - Munich, Germany
  • 223. Reference 217 try s := opening + '*' + closing; StartID := DropMarker; SelStartID := DropMarkerAtSelStart; SelEndID := DropMarkerAtSelEnd; RestoreSel := HideSelection; with Finder d o begin ToStart; while Next(s) d o begin r := FoundText; rl := FoundLength; CPPosition := FoundPosition + rl - Length(closing); DeleteChar(Length(closing)); r := Copy(r, Length(opening) + 1, Length(r) - Length(opening) - Length(closing)); endf := InputSingleCode(wpobjMergeField, r); endf.Mode := [wpobjUsedPairwise, wpobjIsClosing]; // Move the cursor to the found position CPPosition := FoundPosition; DeleteChar(Length(opening)); startf := InputSingleCode(wpobjMergeField, r); startf.Mode := [wpobjUsedPairwise, wpobjIsOpening]; endf.SetTag(startf.NewTag); MoveNext(Length(r)); inc(Result); end; end; finally HideSelection; i f RestoreSel then begin TextCursor.SelectMarker(SelEndID, SelStartID); end; TextCursor.GotoMarker(StartID); Refresh; end; end; 8.3.2 Attribute Interfaces The following references are accessible through the TWPRTFDataCursor class: The interface to change the selected text. It is also available as WPRichText.SelectedTextAttr . property SelectedTextAttr: TWPSelectedTextAttrInterface; The interface to change the current writing mode. It is also available as WPRichText.WritingAttr . property WritingTextAttr: TWPCurrentWritingmodeAttrInterface; This interfaces changes the character atr the cursor position, similar to WPRichText.CPAttr . property CurrentCharAttr: TWPCursorCharAttrInterface; This function returns SelectedTextAttr if text is selected, otherwise WritingTextAttr: function CurrAttribute: TWPSelectedTextAttrInterface; Also available is an interface in the finder class to modify the found text. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 224. 218 WPTools Version 6 property Finder.FoundAttr: TWPFoundTextAttrInterface. The TWPAttrInterface group contains classes to change attributes of different text parts. This chart shows which classes there are and how you can access each of them. The most important interface is TWPAbstractCharParAttrInterface. It defines the methods which are implemented by TWPSelectedTextAttrInterface and TWPCursorCharAttrInterface. It also inherits of TWPAbstractCharAttrInterface. Please note that the 'Get' functions return a boolean value. This value will be false if the property was not set. In this case the passed variable will not be modified. If you work with colors you need to know that colors are saved as index values in the TextColors array. The methods with "Color" in their names automatically do the conversion. In TWPAbstractCharAttrInterface the following methods are available to access the attributes of a character: procedure Clear; procedure Clear(const FontName: string; FontSize: Single; FontColor: TColor = clBlack); overload; procedure BeginUpdate; { Saves the font name, color and background color and all other character attributes. Use AttrLoad to load. Note: The stored information survives a RTFProps.Clear! } procedure AttrSave(var store: TWPAbstractCharAttrStore); { Loads the font name, color and background color and all other character attributes which were stored with AttrSave. If there are no stored attributes the result value is FALSE. } function AttrLoad(var store: TWPAbstractCharAttrStore): Boolean; { This procedure assigns the character attributes stored in a certain text style or TParagraph to this attribute interface } procedure Assign(SourceStyle: TWPTextStyle); function EndUpdate: Boolean; { Applies style flags (such as WPSTY_BOLD..) to the character style. It is possible to switch a style explizietly off by setting the style bit in the "mask" and unsetting it in the "on" parameters. } The following mask bits are available: © 2004-2008 WPCubed GmbH - Munich, Germany
  • 225. Reference 219 WPSTY_BOLD = 1; // Bit 1 bold WPSTY_ITALIC = 2; // Bit 2 italic WPSTY_UNDERLINE = 4; // Bit 3 underlined (solod) WPSTY_STRIKEOUT = 8; // Bit 4 strikeout WPSTY_SUPERSCRIPT = 16; // Bit 5 superscript WPSTY_SUBSCRIPT = 32; // Bit 6 subscript WPSTY_HIDDEN = 64; // Bit 7 hidden text WPSTY_UPPERCASE = 128; // Bit 8 all uppercase WPSTY_SMALLCAPS = 256; // Bit 9 all uppercase but non-captitals are 20% larger WPSTY_LOWERCASE = 512; // Bit 10 all lowercase xxx = 1024; // reserved bit WPSTY_DBLSTRIKEOUT = 2048; // Bit 12 strikeout - double solid line xxx = 4096; // reserved bit WPSTY_PROTECTED = 8192; // protected text procedure SetCharStyles(WPSTY_mask, WPSTY_on: Integer); // switches a style on and off procedure ToggleCharstyle(WPSTY_code: Integer); { TOneWrtStyle is an enum which can be used to identify character styles. The following values are defined: afsBold, afsItalic,afsUnderline, afsStrikeOut, afsSuper,afsSub,afsHidden,afsUppercaseStyle, afsSmallCaps,afsLowercaseStyle, afsNoProof, afsDoubleStrikeOut, afsButton, afsProtected, afsUserdefine. Note: afsNoProof and afsButton are reserved for future versions. WrtStyle = set of TOneWrtStyle. } function GetStyles(var styles: WrtStyle): Boolean; procedure SetStyles(Value: WrtStyle); procedure IncludeStyle(Element: TOneWrtStyle); procedure ExcludeStyle(Element: TOneWrtStyle); procedure UndefineStyle(Element: TOneWrtStyle); procedure IncludeStyles(Elements: WrtStyle); procedure ExcludeStyles(Elements: WrtStyle); function HasStyle(Element: TOneWrtStyle; var Yes: Boolean): Boolean; function HasAStyle(Element: TOneWrtStyle): Boolean; procedure SetFont(const FontNr: Integer); procedure SetFontName(const FontName: string) ; { reads the font name as index in the FontNames arra yof the TWPRTFdataProps } function GetFont(var FontNr: Integer): Boolean; function GetFontName(var FontName: TFontName): Boolean; function GetFontCharset(var Charset: Integer): Boolean; { Assign the VCL style font flags. Better use IncludeStyle() and ExcludeStyle() } procedure SetFontStyle(const FontStyle: TFontStyles); { Read the VCL style font flags. } function GetFontStyle(var FontStyle: TFontStyles): Boolean; procedure SetFontCharSet(const Charset: Integer); function GetCharSpacing(var DistanceTW: Integer): Boolean; procedure SetCharSpacing(const DistanceTW: Integer); function GetCharLevel(var CharlevelPC: Integer): Boolean; procedure SetCharLevel(const CharlevelPC: Integer); function GetCharWidth(var CharwidthPC: Integer): Boolean; procedure SetCharWidth(const CharwidthPC: Integer); procedure SetFontSize(Size: Single); function GetFontSize(var FontSize: Single): Boolean; procedure SetColorNr(const ColorNr: Integer); procedure SetColor(const Color: TColor); procedure SetColorString(const ColorName: string) ; function GetColorNr(var ColorNr: Integer): Boolean; function GetColor(var Color: TColor): Boolean; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 226. 220 WPTools Version 6 procedure SetBGColorNr(const ColorNr: Integer); procedure SetBGColor(const Color: TColor); procedure SetBGColorString(const ColorName: string) ; function GetBGColorNr(var ColorNr: Integer): Boolean; function GetBGColor(var Color: TColor): Boolean; function GetTextLanguage(var Mode: Integer): Boolean; procedure SetTextLanguage(const Mode: Integer); function GetHighlightMode(var Mode: Integer): Boolean; procedure SetHighlightMode(const mode: Integer); function GetTextEffect(var Mode: Integer): Boolean; procedure SetTextEffect(const mode: Integer); function GetUnderlineMode(var Mode: Integer): Boolean; procedure SetUnderlineMode(const mode: Integer); procedure SetUnderlineColorNr(const ColorNr: Integer); procedure SetUnderlineColor(const Color: TColor); function GetUnderlineColorNr(var ColorNr: Integer): Boolean; function GetUnderlineColor(var Color: TColor): Boolean; function GetCharEffect(var Effect: Integer): Boolean; procedure SetCharEffect(const Effect: Integer); function GetCharStyleSheet(var StyleNr: Integer): Boolean; { WPTools can assign paragraph styles also to character attributes } procedure SetCharStyleSheet(const StyleNr: Integer); { This function creates a CSS like style sheet using wptools special names. <br>If 'OnlyUsePTag' is set to true, only generic 'P' tags are created: The created string can then only be used for text which uses the same RTFProps object in the same instance of the application. } function AGetWPSS(OnlyUsePTag: Boolean = FALSE; Abbreviated: Boolean = FALSE): AnsiString; { This procedure applies the properties defined in the given string. They must have been created using the AGetWPSS function. Please note that white space characters are not expected in the string.<br> If the optional parameter "Merge" is set to TRUE no properties in the style are initialized before the new properties are applied. } procedure ASetWPSS(const WPCSSString: AnsiString; Merge: Boolean = false; Abbreviated: Boolean = FALSE); { This function returns true if the provided character attributes are contained completely in this character attributes.} function Contains(var OtherCA: TWPCharAttr): Boolean; function Contains(CharAttrInterface: TWPStoredCharAttrInterface): Boolean; { This function returns true if the provided character attributes containes all attributes which are defined here. } function ContainedIn(var OtherCA: TWPCharAttr): Boolean; function ContainedIn(CharAttrInterface: TWPStoredCharAttrInterface): Boolean; TWPAbstractCharParAttrInterface defines this methods: { This procedure is used to set the paragraph style for all paragraphs } function AGetBaseStyle(var StyleNr: Integer): Boolean; { This procedure is used to set the paragraph style for all paragraphs } procedure ASetBaseStyle(StyleNr: Integer); { Increments a property (with offset>0) or decrements a property (with offset<0). In any case the value is checked for the minimum value } procedure AInc(WPAT_Code: Byte; Offset: Integer; MinValue: Integer = 0); {:: Assigns a color value - to reset to default use clNone } procedure ASetColor(WPAT_Code: Byte; Value: TColor); { Executes a bitwise OR operation with the current value and the passed value and assign the result } procedure ASetAdd(WPAT_Code: Byte; Value: Cardinal); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 227. Reference 221 { Executes a bitwise AND NOT operation with the current value and the passed value and assign the result } procedure ASetDel(WPAT_Code: Byte; Value: Cardinal); { This procedure is used to write most of the paragraph properties If the value is 0 it will delete an existing entry unless the 0 value is required to override an inherited value. Please note that you may only use 23 bits of Value } procedure ASetNeutral(WPAT_Code: Byte; Value: Integer); { This procedure is used to reset a property to the default value } procedure ADel(WPAT_Code: Byte); { This function returns the count of defined TabStops } function TabstopCount: Integer; { This function returns all defined tabstops one by one } procedure TabstopGet(nr: Integer; var Value: Integer; var Kind: TTabKind; var FillMode: TTabFill; var FillColor: Integer); { Adds a tabstop to the style. The value has to be specified in twips. If the function returns TRUE the tab was added, if it is false an existing was modified. } function TabstopAdd(Value: Integer; Kind: TTabKind; Fill: TTabFill; ColorNr: Integer): Boolean; { Deletes the tabstop with the giben value in twips + - the value RTFProps. TabPlusMinus) } function TabstopDelete(Value: Integer): Boolean; { Moves a tabstop specified by position } procedure TabstopMove(OldValue, NewValue: Integer); { Deletes all defined tabstops } procedure TabstopClear; { Selects a base style for this paragraph. } procedure SetStyle(ParStyleNr: Integer; ClearParStyles: Boolean = FALSE; ClearCharStyles: Boolean = FALSE); { Retrieves the number of the base style for this paragraph } function GetStyle: Integer; { If this property is true all paragraph manipulations (ASet, AGet, ASetAdd, ASetDel, ASetColor, SetStyle, GetStyle but NOT the tabstop procedures) will be executed with the current cell instead of the current or selected paragraph. This makes it easier to change the color and border attributes in table cells. The class TWPSelectedTextAttrInterface does not use this property, only TWPCursorCharAttrInterface. } property ModifyCellsOnly: Boolean; Examples: a) Create formatted text under program control: WPRichText1.AttrHelper.Clear; WPRichText1.AttrHelper.SetFontName( 'Courier New') ; WPRichText1.AttrHelper.SetColor(clGreen); WPRichText1.ActiveParagraph.SetText( 'Some green text', WPRichText1.AttrHelper.CharAttr); WPRichText1.DelayedReformat; b) Set the default writing font of a DBWPRichText. We use the OnClear event: procedure TForm1.DBWPRichText1Clear(Sender: TObject); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 228. 222 WPTools Version 6 begin DBWPRichText1.WritingAttr.Clear; DBWPRichText1.WritingAttr.SetFontName('Courier New') ; DBWPRichText1.WritingAttr.SetFontSize(1 8) ; end; c) Implement the hotkeys Ctrl+B, I and U to toggle the bold, italic and underline character style in the current writing mode or, if text is selected, the selected text. We use the OnKeyPress event. procedure TForm1.WPRichText1KeyPress(Sender: TObject; var Key: Char); begin i f Integer(Key) = Integer('B') - 6 4 then begin WPRichText1.TextCursor.CurrAttribute.ToggleCharstyle WPSTY_BOLD); ( Key := # 0; end else i f Integer(Key) = Integer('I') - 6 4 then begin WPRichText1.TextCursor.CurrAttribute.ToggleCharstyle(WPSTY_ITALIC); Key := # 0; end else i f Integer(Key) = Integer('U') - 6 4 then begin WPRichText1.TextCursor.CurrAttribute.ToggleCharstyle(WPSTY_UNDERLINE); Key := # 0; end; end; d) Change font size of one paragraph: WPRichText1. SelectParagraph ); // You can pass a 'par' here! ( i f WPRichText1.SelectedTextAttr.GetFontSize(aSize) and (aSize<1 1) then WPRichText1.SelectedTextAttr.SetFontSize(1 2) else WPRichText1.SelectedTextAttr.SetFontSize(9) ; WPRichText1.HideSelection; e) Show all supported underline modes: procedure TForm1.ShowPossibleULClick(Sender: TObject); const cnames: array[1. .1 8] o f string = ( 'WPUND_Standard' , 'WPUND_Dotted' , 'WPUND_Dashed' , 'WPUND_Dashdotted' , 'WPUND_Dashdotdotted' , 'WPUND_Double' , 'WPUND_Heavywave' , 'WPUND_Longdashed' , 'WPUND_Thick' , 'WPUND_Thickdotted' , 'WPUND_Thickdashed' , 'WPUND_Thickdashdotted' , 'WPUND_Thickdashdotdotted' , 'WPUND_Thicklongdashed' , 'WPUND_Doublewave' , 'WPUND_WordUnderline' , 'WPUND_wave' , 'WPUND_curlyunderline'; ) var i: Integer; begin WPRichText1.Clear; WPRichText1.CheckHasBody; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 229. Reference 223 WPRichText1.WritingAttr.Clear('Verdana' 1 0) ; , WPRichText1.InputString('The modes are applied with' + #10 + 'WPRichText1.WritingAttr.SetUnderlineMode(x)' #13 + #13) ; + WPRichText1.WritingAttr.ASet(WPAT_BorderFlags, WPBRD_DRAW_All4); WPRichText1.WritingAttr.LockBorder; WPRichText1.WritingAttr.ASet(WPAT_IndentLeft, 720) ; WPRichText1.WritingAttr.ASet(WPAT_IndentFirst, 288) ; WPRichText1.WritingAttr.ASet(WPAT_Indentright, 3600) ; WPRichText1.InputString(#13) ; WPRichText1.WritingAttr.SetColor(clGray); WPRichText1.WritingAttr.SetUnderlineColor(clRed); for i := 1 t o 1 8 d o begin WPRichText1.WritingAttr.SetUnderlineMode(i); WPRichText1.InputString(cnames[i] + #13) ; end; WPRichText1.WritingAttr.SetUnderlineMode(-1) ; WPRichText1.WritingAttr.SetUnderlineColor(clNone); // After UnlockBorder the border will be closed with the next // new paragraph WPRichText1.WritingAttr.UnlockBorder; WPRichText1.InputString(#13) ; WPRichText1.WritingAttr.ADel(WPAT_IndentLeft); WPRichText1.WritingAttr.ADel(WPAT_IndentFirst); WPRichText1.WritingAttr.ADel(WPAT_Indentright); WPRichText1.WritingAttr.SetColor(clBlack); WPRichText1.InputString(#13 + 'The colors have been changed with' + #10 + 'WPRichText1.WritingAttr.SetColor(clGray);' #10 + + 'WPRichText1.WritingAttr.SetUnderlineColor(clRed);' #13 + #13) ; + end; 8.4 Manage Style Properties Most paragraph properties are managed by the functions which are introduced by the TWPTextStyle class. Please note the inheritance chart of the TParagraph class: Note: The RTF engine also provides powerful interfaces to manipulate the paragraph and/or character attributes of the current text or the selected text. Both interfaces are part of the © 2004-2008 WPCubed GmbH - Munich, Germany
  • 230. 224 WPTools Version 6 TWPRTFDataCursor . The attributes of the TWPTextStyle/TParagraph objects are managed by the 'A' methods. Most important is the function AGet which reads a value. This method TWPTextStyle.AGet(WPAT_code : Integer; var Value : Integer) is a function which returns a boolean value. The return code is false if the property with the ID WPAT_code was not defined. In this case the variable "Value" will not be modified! Please make sure you initialized the variable Value! 8.4.1 List of 'A' methods The most important 'A' function is: Method ASet(WPAT_Code: Byte; Value: Integer); Set the value of a certain property element. Value may be an integer value in the range -8388607 .. +8388607. (24 bits) Note: If you need to set a color value you can use ASetColor Reference: Method ABorderEqual Method ABorderHash Method AClearCharAttr Method ACopy Method ADel This procedure is used to reset a property to the default value. Method ADelAllFromTo Deletes all properties from/to certain WPAT_values. Method ADelAllIn Delete all properties which are included in this array. Method ADelAttr Deletes groups of attributes attributes. Method ADeleteDifferentSettings This method deletes all properties from this paragraph or style which are not defined in the style which was passed as the parameter. Please also see ADeleteEqualSettings. Method ADeleteEqualSettings This method deletes all properties from this paragraph or style which are also set in the style which is passed as the parameter. . Please also see ADeleteDifferentSettings. Method AGet This procedure is used to read most of the paragraph properties. It returns as true if the value was found. Method AGetAsINI © 2004-2008 WPCubed GmbH - Munich, Germany
  • 231. Reference 225 Method AGetBorder Initialize the border record with the setting in this paragraph. When Init=TRUE all values will be initialized. Method AGetCharProps This procedure fills a TCharAttr record with character properties which are defined here. If Overwrite=FALSE, then it will not overwrite values which are marked as "used" in the mask except for the CharStyle value which is assigned using the 'or' operator. Method AGetCharStyle Method AGetColor Method AGetDef This procedure is used to read most of the paragraph properties. Method AGetDefInherited This function reads the attributes defined in this style or paragraph by following the inheritence order. The definition which was made last is used. (See AGetDef) Method AGetFontName This function retrieves the font name defined for this style or its basestyle (= the inherited WPAT_CharFont property). If no font is defined, the result value is an empty string. Method AGetInherited This function reads the attributes defined in this style or paragraph by following the inheritence order. The definition which was made last is used. (See AGet) Method AGetStringProp Reads a property which is a string. Strings are stored as index values into a global string list. Method AGetStyleCharAttr Method AGetWPSS This function creates a CSS-like style sheet using WPTools special names. Note: All position values are measured in twips. If 'OnlyUsePTag' is set to true, only generic 'P' and 'Tab' tags are created: The string created can then only be used for text which uses the same RTFProps object in the same instance of the application. Method AGet_CSS Method AInc Increments which increase a property (with offset>0) or decrease a property (with offset<0). In either case the value is checked for the minimum value. Method AMerge Merges Attributes Method ASet Set the value of a certain property element. Value may an integer value within the range -8388607 .. +8388607. (24 bits) Method ASetAdd Executes a bitwise OR operation with the current value and the passed value and assigns the result. Method ASetAddCharStyle Adds a character style attribute (WPSTY_BOLD...) to the paragraph or style. Method ASetAsINI © 2004-2008 WPCubed GmbH - Munich, Germany
  • 232. 226 WPTools Version 6 Set the propertyies in the WPTools 4 INI format used by the style collection Method ASetBaseStyle ASetBaseStyle sets the number of the base style for this element. The number is the ID (not the index!) of a style which is stored in the ParStyles property of the TWPRTFProps object. Method ASetBorder Define the borders using the given border record. Don't forget to set blEnabled in LineType, otherwise all borders will be disabled. This function overwrites all defined borders in these paragraphs and, if all borders are the same or 0, removes existing definitions. Method ASetBorderFlags Method ASetCharStyle Method ASetCharStyle Method ASetColor Assigns a color value;to reset to default use clNone. Method ASetColorString Assigns a color string; to reset to default use an empty string. Method ASetDel Executes a bitwise AND NOT operation with the current value and the passed value and assigns the result. Method ASetDelCharStyle Removes a character style attribute (WPSTY_BOLD...) from the paragraph or style. This actually adds a negative style attribute, this means it also deletes an inherited value. Method ASetFontName This method sets the font used by this style. If an empty string is passed, it deletes the current setting. It cannot be used to set an inherited value which is reported by AGetFontName. Method ASetNeutral This procedure is used to write most of the paragraph properties. If the value is 0, it will delete an existing entry unless the 0 value is required to override an inherited value. Please note that you may only use 23 bits of Value Method ASetStringProp Method ASetWPSS This procedure applies the properties defined in the given string. They must have been created using the AGetWPSS function. Please note that white space characters are not expected in the string. If the optional parameter "Merge" is set to TRUE, the name and the base style parameter are not changed (even if they are included in the string) and no properties in the style are initialized before the new properties are applied. Method AStringToNumber AStringToNumber saves a string to a global list and returns the number to identify the string. This feature is required for style properties which require string variables. 8.4.2 ASet/GetBorder function AGetBorder(var Border: TBorder; IsTableBord, Init, Overwrite: Boolean): Boolean; Initialize the border record with the setting in this paragraph. When Init=TRUE all values will be initialized. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 233. Reference 227 procedure ASetBorder(const Border: TBorder); Define the borders using the given border record. Don't forget to set blEnabled in LineType otherwise all borders will be disabled. This function overwrites all defined borders in these paragraphs and, if all borders are the same or 0, removes existing definitions. TBorder is defined as: TBorderType = set o f (BlLeft, BlTop, BlRight, BLBottom, BlInsideV, BlInsideH, BlDiagLB, BlDiagRB, BLBar, BlFinish, BLBox, BlEnabled ); TWPBrdLine = (brdLeft, brdTop, brdRight, brdBottom, brdInsideV, brdInsideH, brdDiagLB, brdDiagRB, brdBar); TBorder = record LineType: TBorderType; // Switch On certain Borders BorderType: array[BlLeft..BLBar] o f Integer; // Properties of this border BorderColor: array[BlLeft..BLBar] o f Integer; BorderWidth: array[BlLeft..BLBar] o f Integer; // If This values are <>0 or if "UseAllBorder=true" they // are used instead the above arrays UseAllBorder: Boolean; AllBorderType: Integer; AllBorderColor: Integer; AllBorderWidth: Integer; end; The TBorder record is not saved with the text style. Only the non-default values are stored as regular attributes, using the ASet and AGet procedures using the WPAT_codes. 8.5 WPAT_codes WPAT_codes are used to set and retrieve paragraph and style attributes. Not all codes which are defined are already used in WPTools Version 6. The reserved codes are printed in gray color. The method TWPTextStyle.AGet(WPAT_code : Integer; var Value : Integer) is mainly used to read a property. Please make sure you initialized the variable "Value"! 8.5.1 Character Attributes WPAT_CharFont = 1; // the index of the font WPAT_CharCharset = 2; // the CharSet of the font WPAT_CharFontSize = 3; // FontSize in pt*100 WPAT_CharWidth = 4; // Character scaling value (display similar to WPAT_CharSpacing) WPAT_CharEffect = 5; // Special character effects and character styles FLAG: WPEFF_CUSTOM1 = 1; // wpcustN - 63 Custom tags for whatever fixed styles you want to develop FLAG: WPEFF_CUSTOMMASK = 63; // The following are bits FLAG: WPEFF_SHADOW = 64; // shad FLAG: WPEFF_INSET = 128; // embo FLAG: WPEFF_OUTSET = 256; // impr FLAG: WPEFF_OUTLINE = 512; // outl FLAG: WPEFF_FRAME = 1024; // chbrdr - only default brdrsbrdrw10 © 2004-2008 WPCubed GmbH - Munich, Germany
  • 234. 228 WPTools Version 6 FLAG: WPEFF_ANIMbit1 = 2048; // animtext1 FLAG: WPEFF_ANIMbit2 = 4096; // animtext2 FLAG: WPEFF_ANIMbit3 = 8192; // animtext4 FLAG: WPEFF_ANIMMask = 8192 + 2048 + 4096; WPAT_CharStyleMask = 6; // always used with WPAT_CharStyleON to allow the combination of styles WPAT_CharStyleON = 7; // Switch one or multiple of the following Styles on (WPSTY_BOLD ... ) FLAG: WPSTY_BOLD = 1; // Bit 1 bold FLAG: WPSTY_ITALIC = 2; // Bit 2 italic FLAG: WPSTY_UNDERLINE = 4; // Bit 3 underlined (solod) FLAG: WPSTY_STRIKEOUT = 8; // Bit 4 strikeout FLAG: WPSTY_SUPERSCRIPT = 16; // Bit 5 superscript FLAG: WPSTY_SUBSCRIPT = 32; // Bit 6 subscript FLAG: WPSTY_HIDDEN = 64; // Bit 7 hidden text FLAG: WPSTY_UPPERCASE = 128; // Bit 8 all uppercase FLAG: WPSTY_SMALLCAPS = 256; // Bit 9 all uppercase but non-captitals are 20% larger FLAG: WPSTY_LOWERCASE = 512; // Bit 10 all lowercase FLAG: WPSTY_NOPROOF = 1024; // Bit 11 noproof - disable spellcheck for this FLAG: WPSTY_DBLSTRIKEOUT = 2048; // Bit 12 strikeout - double solid line FLAG: WPSTY_BUTTON = 4096; // button (use background color) - with frame FLAG: WPSTY_PROTECTED = 8192; // protected text - can be optionally handled as shaded text FLAG: WPSTY_USERDEFINED = 16384; // Bit 15 user defined flag {* bit 16 must be unused } // The following 'styles' are stored as bits in the highest byte of the CharAttr[x] integer. // They are usually applied and removed dynamically FLAG: cafsHyphen = $01000000; // assigned by reader or Ctrl+minus, break here FLAG: cafsWasChecked = $02000000; // used by spellcheck routine - don't check again FLAG: cafsMisSpelled = $04000000; // used by spellcheck routine - red line FLAG: cafsMisSpelled2 = $08000000; // used by spellcheck routine - green line FLAG: cafsInsertedText = $10000000; // WPTOOLS PREMIUM: Revision Marks FLAG: cafsDeletedText = $20000000; // WPTOOLS PREMIUM: Revision Marks FLAG: cafsWordHighlight = $40000000; // highlighted by Find Routine FLAG: cafsDelete = $80000000; // Text is marked for deletion FLAG: cafsALL = $FF000000; FLAG: cafsNONE = $00FFFFFF; WPAT_CharColor = 8; // The text color (as index in palette) WPAT_CharBGColor = 9; // The text background color (as index in palette) WPAT_CharSpacing = 10; // "Letter-Spacing" in twips, 0..$8000 = EXPAND, $8001- $FFFF = COMPRESS WPAT_CharLevel = 11; // Move Character up or down - in half points (RTF: up dn } // 0..$8000 = UP, $8001- $FFFF = down WPAT_CharHighlight = 12; // {reserved} Highlight mode (different styles and colors) WPAT_UnderlineMode = 13; // {reserved} Underlining mode, 0=off, 1=solid, 2=double, 3= dotted ... FLAG: WPUND_Standard = 1; // Underline Style 1 FLAG: WPUND_Dotted = 2; FLAG: WPUND_Dashed = 3; FLAG: WPUND_Dashdotted = 4; FLAG: WPUND_Dashdotdotted = 5; FLAG: WPUND_Double = 6; FLAG: WPUND_Heavywave = 7; FLAG: WPUND_Longdashed = 8; FLAG: WPUND_Thick = 9; FLAG: WPUND_Thickdotted = 10; FLAG: WPUND_Thickdashed = 11; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 235. Reference 229 FLAG: WPUND_Thickdashdotted = 12; FLAG: WPUND_Thickdashdotdotted = 13; FLAG: WPUND_Thicklongdashed = 14; FLAG: WPUND_Doublewave = 15; FLAG: WPUND_WordUnderline = 16; FLAG: WPUND_wave = 17; FLAG: WPUND_curlyunderline = 18; // only used for spellcheck FLAG: WPUND_NoLine = 200; // Dont draw line !!!! When imported from RTF! WPAT_UnderlineColor = 14; // Underlining color, 0=text color, otherwise colorindex +1 WPAT_TextLanguage = 15; // {reserved} Language of the text WPAT_CharStyleSheet = 16; // CharacterStyle (index in ParStyles) NOTE: gray symbols are reserved for future versions of WPTools! 8.5.2 Paragraph Attributes // Margins WPAT_IndentLeft = 17; // Indent Left (CSS = margin) WPAT_IndentRight = 18; // Indent Right (CSS = margin) WPAT_IndentFirst = 19; // Indent First (CSS = text-indent) WPAT_SpaceBefore = 20; // Space Before (CSS = margin) WPAT_SpaceAfter = 21; // Space After (CSS = margin) WPAT_LineHeight = 22; // LineHeight in in % ( Has priority over WPAT_SpaceBetween) WPAT_SpaceBetween = 23; // Space Between (CSS = margin) - negative : Absolute, Positive minimum // padding, only in tables: WPAT_PaddingLeft = 24; // Distance from Border to Text (CSS = padding) tscellpaddt / trpaddl WPAT_PaddingRight = 25; // Distance from Border to Text (CSS = padding) WPAT_PaddingTop = 26; // Distance from Border to Text (CSS = padding) WPAT_PaddingBottom = 27; // Distance from Border to Text (CSS = padding) // Alignment WPAT_WordSpacing = 28; // Value = 0 for default or % of EM (ignored for justifed text) WPAT_Alignment = 29; // paralLeft, ... WPAT_VertAlignment = 30; // Cells: paralVertTop, paralVertCenter, paralVertBottom // Colors and background WPAT_BGColor = 50; // Background Color WPAT_FGColor = 51; // Foreground Shading Color WPAT_ShadingValue = 52; // Background Shading Percentage in % WPAT_ShadingType = 53; // Background Shading Type VALUE: WPSHAD_solidbg = 0; // Solid Background - use WPAT_BGColor and WPAT_ShadingValue VALUE: WPSHAD_solidfg = 1; // Solid Background - use WPAT_FGColor and WPAT_ShadingValue VALUE: WPSHAD_clear = 2; // Clear Background VALUE: WPSHAD_bdiag = 3; // Backward diagonal pattern. VALUE: WPSHAD_cross = 4; // Cross pattern. VALUE: WPSHAD_dcross = 5; // Diagonal cross pattern. VALUE: WPSHAD_dkbdiag = 6; // Dark backward diagonal pattern. VALUE: WPSHAD_dkcross = 7; // Dark cross pattern. VALUE: WPSHAD_dkdcross = 8; // Dark diagonal cross pattern. VALUE: WPSHAD_dkfdiag = 9; // Dark forward diagonal pattern. VALUE: WPSHAD_dkhor = 10; // Dark horizontal pattern. VALUE: WPSHAD_dkvert = 11; // Dark vertical pattern. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 236. 230 WPTools Version 6 VALUE: WPSHAD_fdiag = 12; // Forward diagonal pattern. VALUE: WPSHAD_horiz = 13; // Horizontal pattern. VALUE: WPSHAD_vert = 14; // Vertical pattern. WPAT_BGBitMap = 54; // Background Image. WPAT_BGBitMapMode = 55; // Bitfield for scroll, center, center, repeat Special Flags: WPAT_ParProtected = 92; // 1=protect, 0=not protected WPAT_ParKeep = 93; // 1=no page break WPAT_ParKeepN = 94; // 1=keep paragraphs together WPAT_ParIsOutline = 160; // Is Outline (used by PDF Export and for TOC) - value = level! NOTE: gray symbols are reserved for future versions of WPTools! 8.5.3 Numbering Attributes WPAT_NumberSTYLE = 31; // Reference to a different Style. It can be a single style or // a style which is part of an outline style sheet. In the letter case the correct // style will be be located inside this group using the WPAT_NumberLEVEL parameter. WPAT_NumberLEVEL = 32; // Numbering Level // The following styles are used for simple paragraph numbering and also inside // numbering styles. Numbering styles can also use all other paragraph attributes! // Please also note that 'WPAT_NumberLEVEL' on its own does NOT activate numbering. // WPAT_NumberSTYLE or WPAT_NumberMODE must be also specified. // If only WPAT_NumberLEVEL is used this just specifies the current outline level. WPAT_OUTLINELEVEL = 32; // synonym for WPAT_NumberLEVEL WPAT_NumberMODE = 33; // Supported elements are: (levelnfcN) {*}WPNUM_ARABIC = 1; // Arabic (1, 2, 3) {*}WPNUM_UP_ROMAN = 2; // Uppercase Roman numeral (I, II, III) {*}WPNUM_LO_ROMAN = 3; // Lowercase Roman numeral (i, ii, iii) {*}WPNUM_UP_LETTER = 4; // Uppercase letter (A, B, C) {*}WPNUM_LO_LETTER = 5; // Lowercase letter (a, b, c) {*}WPNUM_LO_ORDINAL = 6; // Lowercase Ordinal number (1st, 2nd, 3rd) {*}WPNUM_Text = 7; // Cardinal text number (One, Two Three) {*}WPNUM_ORDINAL_TEXT = 8; // Ordinal text number (First, Second, Third) {*}WPNUM_WIDECHAR = 15; // Double-byte character {*}WPNUM_CHAR = 16; // Single-byte character {*}WPNUM_CIRCLE = 19; // Circle numbering (*circlenum) {*}WPNUM_ARABIC0 = 23; // Arabic with leading zero (01, 02, 03, ..., 10, 11) {*}WPNUM_BULLET = 24; // Bullet (no number at all) WPAT_NumberTEXTB = 34; // Text Before (index in stringlist of RTFFProps) (obsolete) WPAT_NumberTEXTA = 35; // Text After (index in stringlist of RTFFProps) (obsolete) WPAT_NumberTEXT = 36; // Char #1..#10 are the level placeholders, the rest is the surrounding text WPAT_Number_STARTAT = 37; // Start Numbering if this is first in level WPAT_Number_ALIGN = 38; // 0=Left, 1=Center, 2=Right WPAT_Number_SPACE = 39; // Minimum distance from the right edge of the number to the start of the paragraph text WPAT_NumberFONT = 40; // Optional: Font for the text WPAT_NumberFONTSIZE = 41; // Optional: FontSize (pnfs) in pt * 100 WPAT_NumberFONTCOLOR = 42; // Optional: FontColor (pncf) WPAT_NumberFONTSTYLES = 43; // Optional: CharStyles bitfield WPAT_NumberINDENT = 44; // Old Style Indent - NumberStyles may also use the INDENTFIRST/ INDENTLEFT props! WPAT_NumberFLAGS = 45; // © 2004-2008 WPCubed GmbH - Munich, Germany
  • 237. Reference 231 {*}WPNUM_FLAGS_COMPAT = 1; // Compatibility to old RTF {*}WPNUM_FLAGS_USEPREV = 2; // Use text from previous level ( pnprev) {*}WPNUM_FLAGS_USEINDENT = 4; // Use Indent from previous level {*}WPNUM_FLAGS_FOLLOW_SPACE = 8; // A space follows the number, Default = TAB! {*}WPNUM_FLAGS_FOLLOW_NOTHING = 16; // nothing follows the number {*}WPNUM_FLAGS_LEGAL = 32; // convert previous levels to arabic {*}WPNUM_FLAGS_NORESTART = 64; // if this level does not restart its count each time a number of a higher level is reached {*}WPNUM_FLAGS_ONCE = 128; // Number each cell only once in a table {*}WPNUM_FLAGS_ACROSS = 256; // Number across rows (the default is to number down columns) {*}WPNUM_FLAGS_HANG = 512; // Paragraph uses a hanging indent {*}WPNUM_NONumberING = 1024; // DO NOT NumberATE! {*}WPNUM_NumberSKIP = 2048; // Increase number but do not display WPAT_NumberPICTURE = 46; // Reserved for number pictures WPAT_Number_RES1 = 47; WPAT_Number_RES2 = 48; WPAT_Number_RES3 = 49; 8.5.4 Border Attributes The TBorder record is not saved with the text style, only the non-default values are stored as regular attributes, using the ASet and AGet procedures. The WPAT_ codes used for border parameters are: WPAT_BorderTypeL = 6 0; // Border Mode Left(no, single, double etc) WPAT_BorderTypeT = 6 1; // Border Mode Top (no, single, double etc) WPAT_BorderTypeR = 6 2; // Border Mode Right(no, single, double etc) WPAT_BorderTypeB = 6 3; // Border Mode Bottom (no, single, double etc) WPAT_BorderTypeDiaTLBR = 6 4; // Diagonal Line - TopLeft/BottomRight ( cldglu ) WPAT_BorderTypeDiaTRBL = 6 5; // Diagonal Line - TopRight/BottomLeft The following constants are used as values for the 'Type' attribute {*}WPBRD_SINGLE = 0; // brdrs Single-thickness border. (=Default) {*}WPBRD_NONE = 1; // brdrnil brdrtbl No Border {*}WPBRD_DOUBLEW = 2; // brdrth Double-thickness border. {*}WPBRD_SHADOW = 3; // brdrsh Shadowed border. {*}WPBRD_DOUBLE = 4; // brdrdb Double border. {*}WPBRD_DOTTED = 5; // brdrdot Dotted border. {*}WPBRD_DASHED = 6; // brdrdash Dashed border. {*}WPBRD_HAIRLINE = 7; // brdrhair Hairline border. {*}WPBRD_INSET = 8; // brdrinset Inset border. {*}WPBRD_DASHEDS = 9; // brdrdashsm Dashed border (small). {*}WPBRD_DOTDASH = 10; // brdrdashd Dot-dashed border. {*}WPBRD_DOTDOTDASH = 11; // brdrdashdd Dot-dot-dashed border. {*}WPBRD_OUTSET = 12; // brdroutset Outset border. {*}WPBRD_TRIPPLE = 13; // brdrtriple Triple border. {*}WPBRD_THIKTHINS = 14; // brdrtnthsg Thick-thin border (small). {*}WPBRD_THINTHICKS = 15; // brdrthtnsg Thin-thick border (small). {*}WPBRD_THINTHICKTHINS = 16; // brdrtnthtnsg Thin-thick thin border (small). {*}WPBRD_THICKTHIN = 17; // brdrtnthmg Thick-thin border (medium). {*}WPBRD_THINTHIK = 18; // brdrthtnmg Thin-thick border (medium). {*}WPBRD_THINTHICKTHIN = 19; // brdrtnthtnmg Thin-thick thin border (medium). {*}WPBRD_THICKTHINL = 20; // brdrtnthlg Thick-thin border (large). {*}WPBRD_THINTHICKL = 21; // brdrthtnlg Thin-thick border (large). {*}WPBRD_THINTHICKTHINL = 22; // brdrtnthtnlg Thin-thick-thin border (large). © 2004-2008 WPCubed GmbH - Munich, Germany
  • 238. 232 WPTools Version 6 {*}WPBRD_WAVY = 23; // brdrwavy Wavy border. {*}WPBRD_DBLWAVY = 24; // brdrwavydb Double wavy border. {*}WPBRD_STRIPED = 25; // brdrdashdotstr Striped border. {*}WPBRD_EMBOSSED = 26; // brdremboss Embossed border. (CSS=ridge) {*}WPBRD_ENGRAVE = 27; // brdrengrave Engraved border. (CSS=groove) {*}WPBRD_FRAME = 28; // brdrframe Border resembles a "Frame." The following properties store the width in twips: WPAT_BorderWidthL = 6 6; // Thickness left inner Line WPAT_BorderWidthT = 6 7; // Thickness top inner Line WPAT_BorderWidthR = 6 8; // Thickness right inner Line WPAT_BorderWidthB = 6 9; // Thickness bottom inner Line WPAT_BorderWidthDiaTLBR = 7 0; // Diagonal Line - TopLeft/BottomRight WPAT_BorderWidthDiaTRBL = 7 1; // Diagonal Line - TopRight/BottomLeft These values store the color of the borders: WPAT_BorderColorL = 7 2; // Color left inner Line WPAT_BorderColorT = 7 3; // Color top inner Line WPAT_BorderColorR = 7 4; // Color right inner Line WPAT_BorderColorB = 7 5; // Color bottom inner Line WPAT_BorderColorDiaTLBR = 76; // Diagonal Line - TopLeft/BottomRight WPAT_BorderColorDiaTRBL = 77; // Diagonal Line - TopRight/BottomLeft If the values of all borders are the same, these codes can be used as a shortcut to set the value for a whole group: // Shortcut - set width and color of ALL lines. - Use Flags to switch on/off WPAT_BorderType = 8 7; // Border Mode ALL LINES AROUND BOX WPAT_BorderWidth = 8 8; // Thickness ALL LINES WPAT_BorderColor = 8 9; // Color ALL LINES This is the most important code. By setting a single bit a border is switched on. // Border Flags - switch borders on/off WPAT_BorderFlags = 9 0; {The following flags switch on certain borders. The type can be defined or inherited} {*}WPBRD_DRAW_Left = 1; // Left Border (Default = Single Line = Mode 0) = BlLeft {*}WPBRD_DRAW_Top = 2; // Top Border {*}WPBRD_DRAW_Right = 4; // Right Border {*}WPBRD_DRAW_Bottom = 8; // Bottom Border {*}WPBRD_DRAW_All4 = 1 5; // left + Top+ Right + Bottom {*}WPBRD_DRAW_DiagLB = 16; // Cells: Diagonal Top-Left -> Bottom-Right {*}WPBRD_DRAW_DiagRB = 32; // Cells: Diagonal Top-Right-> Bottom-Left {*}WPBRD_DRAW_Bar = 64; // Border outside (right side of odd-numbered pages, // left side of even-numbered pages) {*}WPBRD_DRAW_InsideV = 128; // Rows: Inside Vertical {*}WPBRD_DRAW_InsideH = 256; // Rows: Inside Horizontal {*}WPBRD_DRAW_Box = 512; // Draw Box around paragraph {*}WPBRD_DRAW_Finish = 1024; // Draw bottom border here, even if next paragraph has same border properties © 2004-2008 WPCubed GmbH - Munich, Germany
  • 239. Reference 233 8.5.5 Table Size and Position A table usually uses the complete text area, this is the page width minus the left and right margins. Property to set the width in twips: WPAT_BoxWidth Property to set the width in percent * 100 of the page width WPAT_BoxWidth_PC Offset from the left margin. Can be negative to be to the lefgt of the text area. WPAT_BoxMarginLeft Offset from the left margin. If negative the table is extended into the margin area WPAT_BoxMarginRight Horizontal Alignment of the table: WPAT_Box_Align: possible values are WPBOXALIGN_RIGHT and WPBOXALIGN_HCENTERTEXT The column width is defined by the properties WPAT_ColWidth and WPAT_ColWidth_PC. The first is the width in twips, the latter is the width in percent * 10 (Example: 1000 sets a width of 10%). WPAT_ColWidth has priority over WPAT_ColWidth_PC. You will need to delete the WPAT_ColWidth flag if you need to set the width in percent. Cell.ADel(WPAT_ColWidth) Cell.ASet(WPAT_ColWidth_PC,1000); // 10% You can read the current width of a cell using the method cell.IsWidthTW. The text must be formatted. Once the user resizes columns in a table all widths which are defined by a percent value will be converted into exact WPAT_ColWidth values. You can force this conversion for the complete text using the function WPRichText.TableFixAllCellWidths. This method can also round the width values suing a 'snap value'. The method TableAdjustCellWidth can be used to recalculate the width of all columns to keep them visible. The property WPAT_BoxMinHeight can be used with table rows to set the minium height of a table row. WPAT_BoxMaxHeight is used to set the maximum width. Both properties will be ignored in cells which are merged vertically. They can be used together. You can use reference Cell.ParentRow to set or read a property in a row. The editor allows the modification of row heights if this mode has been enabled in the property EditOptions. Example Apply row height to all rows in current table : var par : TParagraph; i f WPRichText1.Table<>nil then begin par := wp.Table.ChildPar; while par<>nil d o begin par.ASet( WPAT_BoxMinHeight, twips_value ); par.ASet( WPAT_BoxMaxHeight, twips_value ); par := par.NextPar; end; end; Example Apply row height to selected rows only : © 2004-2008 WPCubed GmbH - Munich, Germany
  • 240. 234 WPTools Version 6 var par : TParagraph; i f WPRichText1.Table<>nil then begin par := wp.Table.ChildPar; while par<>nil d o begin i f par.HasProp( paprCellIsSelected ) then begin par.ASet( WPAT_BoxMinHeight, twips_value ); par.ASet( WPAT_BoxMaxHeight, twips_value ); end; par := par.NextPar; end; end; 9 Notes for Upgraders ... from WPTools Version 5 The RTF-Engine of WPTools 6 is based on WPTools 5. We are even able to create a WPTools 5 build from WPTools 6 since all addons in WPTools 6 are activated by conditional compiling. If the compiler symbol WP6 ($DEFINE WP6) is not active, a Project can be compiled as if it was WPTools 5. So upgrading should be extremely smooth. The major changes will come up when You upgrade to Delphi 2009. This new version is based on WideStrings instead of AnsiString and WPTools 6 honors this. Where it makes sense the API still uses ANSI String. At present time the Delphi 2009 support is not 100% tested. .... from WPTools Version 4 As emphasized before WPTools Version 6 is based on a new RTF Engine. (We call this RTF engine although it internally works with data structures which are much more similar to HTML/CSS than to RichText-Format) This means that if you have modified the RTF engine before or use undocumented features the affected parts of the code must be updated. We will assist you here to make the transition easier. WPTools Version 6 contains so many new features and possibilities that it is very likely that a very elegant way to solve the problem can be found. Please check out the FAQ web forums FAQ: Questions when upgrading FAQ: General Important: WPTools Version 6 uses 'delayed reformat'. This means the formatting of the text is delayed until the next idle phase. Therefore, If you are using InputString or similar it is not required to use BeginUpdate/EndUpdate to speed up the application. On the other hand, if you want to print the text (or convert it to PDF) right after loading or creation, it it is required to execute the procedure ReformatAll; The same is required if you want to print or create a PDF file right after the use of © 2004-2008 WPCubed GmbH - Munich, Germany
  • 241. Notes for Upgraders 235 LoadFromFile. If you used to create an editor at runtime using TWPRichText.Create(nil) please change the code to use the constructor CreateDynamic; (C++Users call the method _MakeDynamic() after the new) This way the editor knows it is invisible and has no parent. You need to execute ReformatAll whenever you need the text to be formatted for printing or export to PDF. Do not create editor windows which should work interactively using this method! Please note that the property WorkOnText used to select a completely different text (the header/ footer text) in WPTools 4. In WPTools Version 6 it will simply move the cursor to that text. Esspecially the function MergeText works normally works with the body text, the property WorkOnText will not make any difference. But the MergeText function to select the modification of all text parts. (See Mailmerge and forms) WPTools Version 6 works with text attributes which can be undefined. So it is possible that the current font has no name. In this case the font used for the text will be defined by the paragraph style or the default attributes. To set the default font for an editor use the OnClear event: procedure TForm1.DBWPRichText1Clear(Sender: TObject); begin DBWPRichText1.WritingAttr.Clear; DBWPRichText1.WritingAttr.SetFontName('Arial' ; ) DBWPRichText1.WritingAttr.SetFontSize(1 1) ; end; Please note that the properties of the reader and writer (LoadOptions, StoreOptions) are nbow defined by format strings. These format strings can be used with all IO methods. To retrieve the text as RTF string you can simply use str := WPRichText.AsANSIString('RTF'); Overview When you convert older projects you will at least have to modify the uses clauses remove: WPDefs, WPObj, WPRTF*, WPPrint, WPRich, WPWinCTR add: WPRTEDefs, WPRTEPaint, WPCtrMemo, WPCtrRich, WPObj_Image, WPIO Please note that code which works with pointers (lin : PTLine, pa : PTAttr) cannot be easily converted to work with WPTools Version 6 so please do not try to update the old logic to work with WPTools Version 6. It is better to find a way to do it using the new, advanced API of WPTools. Please don't hesitate to post a question in the forum: Many problems which required hundred lines of code were converted into a few lines with "WPTools Version 6" code. Style handling is now done inside the RTF-Engine. The WPStyleCollection is still there but it is only a container for template styles. WPReporter works differently in V5 - please see WPReporter © 2004-2008 WPCubed GmbH - Munich, Germany
  • 242. 236 WPTools Version 6 9.1 Updated Rendering and Formatting WPTools Version 6 formats as close to MS Word(tm) as possible. So it ignores the paragraph spacing on top of pages. You can enable the old behavior in property FormatOptionsEx by adding flag wpDontIgnoreSpacebeforeOnTopOfPage. Please also see the other options in FormatOptions and FormatOptionsEx. 9.2 Changed Unit Names One of the first things you might realize when you try to compile a WPTools V4 project with WPTools Version 6, is that some unit names no longer exist. This is because we decided to create new units for program code which is entirely new. At the same time obsolete units were deleted. We recommend to delete all wp* units from the uses clause of each unit, add units WPRTEPaint and WPObj _Imageand let Delphi add the other required units. The following changes are required: Change WPDefs, WPObj, WPRtfTXT, WPRTFIO all to W PRTEDefs Change WPRtfIO, WPRtfInp to W PRTEPaint Change WPEmOBJ to WPObj _Image WPRTEDefs and WPRTEPaint are the main units of the "RTF-Engine". Their pascal code is only included in WPTools Professional and WPTools PREMIUM. Change WPPrint, WPWinCtr to W PCTRMemo The unit WPCTRMemo contains the editor control and the preview, making unit WPPreVw obsolete. Change WPRich to W PCTRRich The unit WPCtrRich contains the procedures, objects and properties which were mainly added to provide compatibility to older WPTools versions. It is required by the TWPToolBar, TWPRuler and TWPAction classes. The unit WPStat2 is not included. Please use a standard status bar (Win32 tab). The old WPTools 1 status bar has been discontinued. The HTML support is included in unit WPIOHTML, the units WPReadHT, WPWrtHT and WPXMLFile are obsolete. WPTools Version 6 will always use CSS in the created HTML code. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 243. Notes for Upgraders 237 The RTF reader is implemented in unit WPIOReadRTF, the RTF writer in WPIoWriteRTF. (WPreader and WPWrtRTF is obsolete) The ANSI reader and writer are implemented in WPIoANSI, not WPWrite2. Important: You need to use "FormatStrings" instead of the properties LoadOptions and StoreOptions! unit WPPapBin always was nothing more than an example unit. The old version will still work. Also see demo: "PrinterSetup" The main WPReporter class TWPSuperMerge is now located in WPRTEReport, not in wpmerge. pas. The component WPFiler is not supported anymore. Quickreport support has been discontinued. 9.3 Changed Classes RTF-Engine The RTF Engine concept has been changed greatly. It is no longer possible to use a RTF-Engine object, such as "TWPRtfTextPaint" in WPTools 4, to identify certain text or text properties - In WPTools Version 6 the text objects are accessed directly, not through the 'RTF-Engine': The TWPRTFProps are now used for text properties, such as colors and styles. For text either the TWPRTFDataCollection or the TWPRTFDataBlock is used. An exception of this rule is the cursor class, also accessible through TWPRichText.TextCursor. It contains many variables and procedures which used to be in the TWPRtfTextPaint object.(see Data Structures) Usually code does not require a reference to the RTF-Engine since this reference is provided by the editor control (TWPCustomRichText, TWPCustomRtfEdit). Thus, in general it is possible to replace something like "RtfText : TWPRtfTextPaint" with a reference to a TWPCustomRtfEdit. Editor The TWPCustomRtfEdit class is defined in the unit WPCtrMemo. It contains access to the RTF engine (Memo), the TWPRTFData object (Memo.RTFData) and the possibility to change attributes (through Memo.Cursor). However, it does not contain the 'CurrAttr' property, which has been defined under the unit WPCTRRich, in the class TWPCustomRichText. 9.4 Changed Pointers To make compilation with Delphi8 for .NET possible, WPTools Version 6 no longer makes use of pointers (exception: some optimized conversion code). As a result, all pointers have been replaced. The PTParagraph pointers have all been changed to references to a TParagraph object. Since references and pointers can be used in a very similar manner, you can compile your code by simply removing the ^ sign (Delphi) or changing -> into . (c+ +) The RTF-Engine paragraph pointers (WPRichText1.Memo.active_paragraphand others) have been moved. The references which represent the cursor position are now in WPRichText.Memo. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 244. 238 WPTools Version 6 Cursor or, if no editor is used, in RTFDataCollection.Cursor. Please note that in WPTools Version 6 the reference active_paragraph can be undefined (nil). The same is true for the 'FirstPar' reference of a TWPRTFDataBlock - although the code will create a first paragraph as soon as this property is read. The pointer for the TLine record of WPTools Version 6 is no longer supported. The TLine record has been completely replaced, a position in a paragraph is now described solely by the position, posinpar. The cursor object still supports a property called active_line. It is an integer value which can be used to access the wrapped lines. Pointers to border descriptions (TBorder) can no longer be used. The border definitions are now stored in the regular properties of a TParagraph or TWPTextStyle class. But to provide compatibility to WPTools 4 it is possible to fill a TBorder record 'on the fly' with values calculated from the stored properties. This means that if you have a procedure which expects a TBorder record or pointer it is necessary to pass a reference to a TWPTextStyle class and calculate the border record inside of this procedure using the TWPTextStyle procedure AGetBorder(). Please see the next chapter for further information. 9.5 Changed GUI elements TWPToolCtrol In WPTools 4 the control TWPToolCtrol was used to create the link between a TWPComboBox and the editor. This class is not supported anymore since it was not compatible to modern 3rd party toolbar controls. This means that it is not possible to use any TPanel as a toolbar by simply dropping a TWPToolCtrl on its surface. We recommend to use the TWPToolPanel instead. The best approach is to use the wptools standard actions to link to buttons and menu items and the new TWPToolsCustomEditContolAction. The latter class can be also added to any TActionList and is used to create a link to the TWPComboBox class. (property AttachedControl) Please read more about actions and Use WPTools5 with TBX (Toolbar2000 Extension) TWPEdit The component TWPEdit (the single line RTF object) is not available anymore. You can use a standard TWPRichText and set certain properties to replace it. object WPRichText1: TWPRichText LayoutMode = wplayNormal ScrollBars = ssNone EditOptions = [wpActivateUndo, wpActivateUndoHotkey, wpNoVertScrolling] XOffset = 1 5 Width = 300 Height = 2 2 end © 2004-2008 WPCubed GmbH - Munich, Germany
  • 245. Notes for Upgraders 239 Now add an event handler for OnKeyDown to suppress the Return key: procedure TForm1.WPRichText1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin i f Key = VK_RETURN then key := 0; end; 9.6 New Border Handling Border definitions are now stored in the regular properties of a TParagraph or TWPTextStyle class. These properties are usually read by the AGet function and written using the ASet procedure. For your convenience all border properties can be saved in and restored from a TBorder record. This record is written by the ASetBorder procedure. The TBorder record is similar to the one used by WPTools 4, but has been improved to hold different modes, colors and widths for each line by using arrays for the values BorderType, BorderColor and BorderWidth. Notes: a) The blDouble and blDot LineType no longer exist. Instead the 'type' must be used to choose a different border line style. So code such as Ndouble.Checked := blDouble i n Border.LineType; must be changed to Ndouble.Checked := Border.AllBorderType = WPBRD_DOUBLE; Please note that this is using the AllBorderType item which contains the type of all borders, if they are the same. To read or set a single style for one of the possible borders (left, right ...) use the array Border.BorderType[BlLeft..BLBar]. b) The value 'FUse256Colors' or 'Use256Colors' no longer exists. WPTools always uses at least 256 colors. c) The elements HColor, HColorR, VColor, VColorB have been replaced by the array BorderColor: array[BlLeft..BLBar] of Integer; So please change code such as btnLColor.Tag := Border.HColor; btnRColor.Tag := Border.HColorR; btnTColor.Tag := Border.VColor; btnBColor.Tag := Border.VColorB; to btnLColor.Tag := Border.BorderColor[blLeft]; btnRColor.Tag := Border.BorderColor[blRight]; btnTColor.Tag := Border.BorderColor[blTop]; © 2004-2008 WPCubed GmbH - Munich, Germany
  • 246. 240 WPTools Version 6 btnBColor.Tag := Border.BorderColor[blBottom]; d) The Thickness value no longer exists. Please use either the AllBorderWidth or the BorderWidth[] elements. Please note that the width is stored as twip value, not as 1/2 pt. e) The Space value is no longer used. The styles now support padding values which are defined by the WPAT_ codes WPAT_PaddingLeft, WPAT_PaddingRight, WPAT_PaddingTop and WPAT_PaddingBottom. These values cannot be set in the TBorder record. f) The function Memo.Set_ParBorder no longer exists. Instead you can use CurrAttr.SetBorders( LineSelection: TBorderType = [blLeft,blTop,blRight,blBottom]; WPBRD_mode: Integer = -1; ThicknessTW : Integer = -1; LeftColor : Integer = -1; RightColor : Integer = -1; TopColor : Integer = -1; BottomColor : Integer = -1; AllPadding : Integer = -1; DeleteDefaultSettings: Boolean = TRUE). A value of -1 is used to select the default value. By default using -1 will delete the corresponding attribute from the list of attributes which causes the inherited values to be used. 9.7 Changed Style Handling In WPToois 4 the style handling was performed by the TWPStyleCollection component. This is not the case anymore. This component can be optionally used to store the style in their non-binary representation (which is a string list with name, value pairs) and assign this style to one or more TWPRichText when required. This can help to synchronize the style sheet to provide a default sheet. Please read here about how to use the paragraph styles in a native way. 9.8 BackgroundImage WPTools Version 6 does not have the property "background image" anymore. Instead you can draw the image using the water mark event - see Demo 'WaterM2'. You can create a different tiled background on each page and it is also possible to show a form in the background. WPTools Version 6 takes care about the necessary buffering so no flickering will be visible. We recommend to use RTFVariables to store the file name of the background image which should be used with a document. 10 Release Notes - WPTools 6 WPTools 6 is based on the code of WPTools 5. While we develop WPTools 6 further we also integrate improvements into WPTools 5 (see WPTools 5 Release Notes). When you have the PRO or PREMIUM version you can also compile WPTools Version 6 as if it was © 2004-2008 WPCubed GmbH - Munich, Germany
  • 247. Release Notes - WPTools 6 241 Version 5 if you un-define the compiler symbol WP6 in the file WPINC.INC. Syntax: defined symbol: {$DEFINE WP6} = Compile WPTools 6 undefined symbol: {.$DEFINE WP6} = Compile WPTools 5 Release Notes: 15.7.2009 - WPTools 6.05 + Scroll with middle mouse button + new XML editing mode (see XML editor mode ) + TParagraph.Trim method to remove white spaces at start and end + Vertical Scrolling by pressing the middle mouse button now works. + improved auto thumbnail mode * enhancement to HTML reader / writer to handle embedded SPAN objects + new method: ApplySPANStyles(and_remove : Boolean=false; ignore_charattr : Boolean = false); can be used to apply SPAN styles to the text which it embeds + The function InputSpanObjects( Attributes : TWPAbstractCharAttrInterface ) : TWPTextObj; can be used to wrap the selected text into SPAN objects + method LoadCSSheet can be used to load paragraph styles in CSS format from a string. There is also SaveCSSheet. + new even OnTextObjectMovePosition (move event) - OnTextObjectMove is still used for resize (unchanged) * several improvements in editor - fix problem with Wordrwap and centered text 28.6.2009 - WPTools 6.04 + WPTools Premium: Column Balancing * many improvements in RTF reader. Word documents are now understood better * Improvement in check for protected text (ppMergedText) + new ViewOptionsEx property - auto hyperlinks were not working + TWPComboBox has an event OnUpdateItems which will be triggered after the items had been automatically assigned. 24.6.2009 - WPTools 6.03.6 * thinner page borders in thumbnail mode. ViewOptionsEx: wpAutoThumbnailMode will show pagenumbers only when in thubmbnail mode (= wpShowPageNRinGap in ViewOptions) + property ColorDesktop and DeskGradientHorizontal to render the background with a gradient fill * fix for protected text handling (CR after a field) * fix for text alignment near a movable image - EditOption AutoDetectHyperlinks was not working anymore * WPReporter: SuperMerge.Stack.PageBreakAFterGroup := true was ot working when footers were used © 2004-2008 WPCubed GmbH - Munich, Germany
  • 248. 242 WPTools Version 6 1.6.2009 - WPTools 6.03.5 - fix problem with display of character attributes when attributes were inherited from paragraph styles - fix problems with selection deletion in single column, single row tables - improvement of RTF writer when writing sections 11.5.2009 - WPTools 6.03.3 - improved report band dialog, new ShowOptions property - fix in RTF reader to load header/footer - change in HTML writer to save SPAN instead of FONT tag - several fixes in editor * WPTools Premium: better column support. Fixed column height now splits correctly on 2 pages. 28.4.2009 - WPTools 6.03.2 - fix problem with justified text in PDF 21.4.2009 - WPTools 6.03.1 - fix problem with images when used in Delphi 2009 - better support for header/footer in RTF files created by word. (Ignore bogus header/footer) - some stability fixes 25.3.2009 - WPTools 6.03 + improved text rendering - optimation for character distances on screen to provide better display + improvement on ShowMergeFieldNames to improve cursor movement and drag and drop + automatic disable dragging of fields inside of fields + improved merge field selection. TextObject.SelectedObject now returns the mergefield if it was completely selected + change in HTML saving code to save src in <img> after width adn height (for outlook) * various bugfixes 17.1.2009 - WPTools 6.01.5 - WPPREMIUM: Text after Columns initialized with WPAT_COLUMNS_Y is now allowed + TWPToolBar FontName drop down now lists fonts used by document first - fix for tables which use a fixed row height and are splitted on different pages + improvements necessary for Delphi 2009 - the Locaization demo now works + EditOptionEx wpDontPreserveObjectsAgainstDeletion - fix problem in ImageObject LoadFromStream when GraphicEx is used - fix problem with Delphi 2009 when loading WPReporter templates - fix problem with HTML reader with paragraph style of first paragraph 26.10.2008 - WPTools 6.01 * updated HTTP Demo, now with "Source View" + DELETE/BACKSPC at start of line removes right/center alignment + loads background images for paragraphs, tables and styles * improvement to text protection (empty lines) - improvements to HTML and CSS reader - improved HTML format routine - improved MIME loading - now supports binary data despite Synapse does not) + MIME reader capturesHTML body for SourceVIew * DataProvider now uses MergeText('',true) instead of MergeText + boolean wphttp_Disable to disconnect HTTP temporarily * several changes to improve compatibility with Delphi 2009 17.10.2008 - WPTools 6.00.1 - several changes to fix problems which occured with use of Delphi 2009 © 2004-2008 WPCubed GmbH - Munich, Germany
  • 249. Release Notes - WPTools 6 243 * update to WPIO_MIME to also load binary encoded GIFS and JPEGS from EML files 11 Release Notes - WPTools 5 WPTools 6 is based on the WPTools Source files plus several additions and optimations. We include the WPTools 5 release notes here to provide You with hints to interesting changes and improvements. 26.9.2008 V5.0 Release 43 - WPTools PRO / PREMIUM can be now compiled with Delphi 2009 (several changes) - fix bug in InsertClass method - GetPageOfBookmark works for all bookmarks - Code to move images has been updated 24.9.2008 V5.0 Release 42 * updated manual topic "Mailmerge and forms" - ANSI writer: Separates cells by TABS and rows by CRNL - DB Control now switches to readonly when dataset does not use AutoEdit - Fix in preview dialog property DisabledDialogs - PREMIUM: improvement to TextBox selekting - improvement to MeasurePage event * some enhancements to API 10.8.2008 V5.0 Release 40.1 * some minor bugfixes 15.7.2008 V5.0 Release 40 * WPREMIUM: tables are handled in columns better * RTF did not save foreign characters in current codepage correctly when <> cp1252 * WPReporter - a group with "always hidden" will never be processed * Better Landscape setting when printing - there was a problem with tables in sections 30.5.2008 V5.0 Release 39 * small improvement to CSS reader - some stability improvements - PNG objects were sometimes not freed. - fixed problem with EURO character 4.4.2008 V5.0 Release 38 - some small fixes in editor - better text box positioning with WPPremium - HTML reader - apply paragraph style to first paragraph as well - fix when saving a single selected cell * Changed attribute detection for selected text - should work much better now. This can be deactivated using const DefaultAttrAlsoForSelectedText = false in WPCtrRich but should be on for better editing possibilities. - fix for missing bottom border before page break - MoveToTable does not look for non-table paragraphs + RTFDataBlock.FindParByNameEx locates a paragraph with a given name and a given type 12.3.2008 V5.0 Release 37 + LoadFromString procedure (more intuitive than property SelectionAsString) * apply bottom border when last row was deleted © 2004-2008 WPCubed GmbH - Munich, Germany
  • 250. 244 WPTools Version 6 22.1.2008 V5.0 Release 36 - fix of broken drag&drop support - quicker desletion of text when clicking near text - some fixes in rendering engine + detect PNG, GIF and JPEG automatically in TWPImageObj.LoadFromStream (solves GIF saving problem) * improved Compress method in WPObj_Image.pas * change in WPIOHTML to not save empty header texts 20.12.2007 V5.0 Release 35 - fix to not draw border around table objects - fix problem when pasting text in form completion mode - fix problem is two DFM files - fix problem with double grid lines (around tables) * improved update of GUI methods - now using inherited style properties (Use CUrrAttr) + When printing all colors can be set to black - see PrintParameter.PrintOptionbs: wpAllColorsAreBlack - improved padding saving for table cells * the code dealing with reading attributes of the selected text now also reads attributes of attched styles. This can be switched off using the EditOptionEx: wpDontInitSelTextAttrWithDefaultFont If a character attribute was not defined in a style the document default is retrieved This only works for character attributes, not for paragraph attributes. Those can be read using ActiveParagraph.AGetInherited in case SelectecTexAttr reports an undefined attributesx * Font "System" is now mapped to "Arial" since the cursor advance does not work otherwise 27.11.2007 V5.0 Release 34 + WPRichText1.TextCursor.CurrAttribute.AInc(WPAT_CharFontSize, pt*100, 300) can now also be used to increment/decrement font size of text w hich is controlled by a style sheet. * in normal layout modes borders are not draw n betw een virtual pages * Update to WPReporter table calculation. When the functions left() and previous() refer to non-existing cell The result of the function w ill be undefined and "[ERR]" w ill be displayed. * Some updates to RTF reader and HTML w riter + ANSI text w riter understand option "-nolinefeed" to use CR instead of CR+LF * some savety checks to avoid AVs w ehn paragraphs are deleted + HTML reader loads <sup> * w hen in ppAllE xceptForE ditFields Mode the not editable merge fields w ill not be accessed by the TAB keys anymore. (can be sw itched off by compiler symbol MOVE TO_ALL_FIE LDS) - fix in RTF reader for better import of text w ith several nested tables in one table cell + new format string for WPTools w riter: -allnumberstyles, forces also the unused styles to be saved * WPRichText.Assign( Source ) w ill also copy the number styles - fix problem introduced by "fix AV w hen resizing table". Adding additional fix. + new flag ppIsHyperlink in property ProtectedPro - fix of problem w ith w pShow InvisibleText + w hen pasting ANSI text (or one RTF line) the inserted text w ill inherit current paragraph attributes, except that the new flag w pcoPastedANSIDoesNotInheritParAttr has been set in ClipbordOptions - fix AV w hen resizing table an deleting a row at the same time - fix problem w ith space_before and invisible merge fields start tags at beginning of line + function Print(PageRange): Boolean now also supports @@ODD@@ and @@E N@@ as page range short cuts VE 11.09.2007 V5.0 Release 30 + SplitCells now includes a bollen parameter "before" (default=false) *E ditHyperlink w ill insert the link as text if no linktext w as provided in procedure call or as text selection + function WP.Printing to check if currently printing text * the TWPPreview w ill not paint itself w hile the attached editor is printing * ReformatAll(true, true) now clears all know n character w idth (important for toggling visiblity of fields!) * RTF reader loads infocompany and infomanager + infohlinkbase + new method: SplitCellsVertically - fix in ReplaceTokens. Tokens not seperated by spaces w ere not recognized * w hen pasting RTF text into an empty numberd paragraph the number property is retained. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 251. Release Notes - WPTools 5 245 + new format string: IgnoreSpan for HTML reader + IgnoreSpan is automatically used for pasted HTML text (better for pasting from e-mails) - fix in CodeLocate - compare ObjType 27.07.2007 V5.0 Release 25 + Object (par or page relative) cannot be moved w hen w pobjLockedPos is used in the TWPTextObj.Modes + TP aragraph.IsUpperCase + TParagraph.IsLow ercase - fields w ith background color w ere displayed char by char w hich reduced display quality - some small tw eaks in engine 5.07.2007 V5.0 Release 24.4 * changed virtual method DoUpdateE ditState to DoUpdateEditStateEx + added event: OnE ditStateChanged (replaces V4 E ditChangeE vent) * image loading checks for empty stream - fixed AV w ith ppNoE ditAfterProtection 2.07.2007 V5.0 Release 24.3 * updated OnToolBarIconSelection - removed "except end" w hen pressing "Open" - some fixes to undo handling and tables - some fixes to image handling (can be selected w hen outside page) * improved HTML reader (better handles non "X" HTML) 04.06.2007 V5.0 Release 24.1 - fix for dropped character problem (w hen first paragraph of all w as longer than page) - sect w hich does not define section break in RTF code now inserts paragraph - w hen deleting a table w hich w as follow ed by another table UNDO w ill not insert the next table * paprIsHidden flag now saved to WPT format + new property: WP.RTFData.InsertTextIntoNew Row - copy in table alw ays insert into new row s *E ditBox mode checked after paste from clipboard + HTML reader loads UTF8 - use formatstring '-utf8' - KeyPress does not check GetAsyncKeyState for space key - selection w as not removed sometimes on click - fix in SetOuterCellBorders - cell split could cause AV w hen UNDO w as active - pasting ignores merged cells + Support for Delphi 7 - Win32 - solves problem in Paragraph.Reformat w hen inserting tabs - Shift+Delete is now handled (CutToClipboard) - Ctrl+Left handling improved (problem w ith single char w ords) - suppress bottom border in layout mode w hen outside of page area - better handling of undo for page break added inside table - 2 units in PRO version w ere w rong in V5.22 - WPWordDelimiterArray['-'] := true w ill disable w ord w rap in w ords w ith - sign - paste ANSI w as disabled - DeleteFieldAtCP now w orks w ith protected fields, too - end of page border line is not printed in normal layout mode - fix in BulletStyleDlg - EditStyleNums - don't position cursor in empty line under text box * change variable "new " to "new nr" to avoid C++ problem - centered text w ith bullets now paints bullet besideds the text, not at start of line - WP REP MIUM - improved column reading/w riting code (RTF format) 1.03.2007 V5.0 Release 23 + WPPremium: Load&Save of column properties in RTF format + TParagraph.E xchange method to exchange tw o characters in the text * automatic hyperlink creation (w pAutoDetectHyperlinks) now moves trailing dots after the link - table borders after long headers w ere painted w rongly - w hen inserting a paragraph in a table cell the border attributes is not copied - WPPremium: TextBoxes w ere sometimes not loaded at correct position - WPPremium: Second Column w as started one line higher - WPPremium: Column break now starts a new column BE FORE the paragraph (expected behaviour) * updated Section reading from RTF (non breaking mode w as checked too early) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 252. 246 WPTools Version 6 - KeepN did now w ork correctly w hen space-after w as defined + NumberStyles can now be loaded and saved (using GetWPCSS, SaveToFile) * updated unit WPIOWPTools: When loading numberstyles the ids are mapped and duplicates are removed. + FormatOptionsE new flag w pfNumberingControlledByStyles x: If defined numbering modes are directly stored and used in paragraph styles. Please note that this w ill only w ork w hen you use "WPT" format for load&save - HTML w riter created unnecessary open/close attribute tags before and after text objects 24.01.2007 V5.0 Release 22 + improved auto indet code when numbering styles are used. (Can be switched off in EditOptionsEx wpDontUseNumberIndents) + alignment now updated for header/footer before paint code to provide propper alignment when fields such as "page number" was used. Can be switched off using Memo. _DontUpdateObjInHeaderFooter := true + property RTFDataCollection.RTFViewOptions with flag wpLockDATEandTIME to lock the value of DATE and TIME fields - improved drag&drop detection - when RTF is loaded and text uses the charset 1 automatically the sysetm default code page is used * several improvements to HTML reader and writer using the format string "-WriteAllColWidths" all table cells with be written with a width param "-DontWriteStyleParam" will switch off the saving of the inline styles style="" -csspath:"..." can be used to specify a CSS style for loading and saving - fix for ine height problem when fields or bookmarks were used at the start of a line * several small stability improvements 26.11.2006 V5.0 Release 21.1 + when saving HTML files embedded images will always be written as files in same directory as HTML file + new format option: -imgpath:"xxx" - embedded HTML images will be written to the path xxx use -imgpath:"" to switch off saving of embedded HTML graphics. + HTML reader now detects ISO charsets - improvement to RTF reader to better handle corrupt RTF files - some improvements to engine - fix to render engine to set font attribute of mailmerge tags (sometimes inherited attribute was used) - better detection of black-on-black text * the optional ReportBuilder (9/10) support was rewritten and enhanced. + optionally FastReport support is now available 9.11.2006 V5.0 Release 21 + new EditOptionEx: wpZoomWithMouseWheel to zoom with mouse wheel + Control - invisible chars, such as bookmarks are now handled like spaces (ghost cursor bug) - reactivated Ctrl+C - code was deleted by mistake - some fixes to make upgrade form V4 easier (additions to finder, added functions GetSelTextBuf, InsertParText, ChangeAttr, GetParText) activated by compiler symbol V4COMAPT) - removed reference to TransparentBitBlt in unit WPObj_image since not supported under Windows NT - TWPTextStyle.AGet_CSS has additional parameter "IgnoreMargins" to suppress the writing of margin and indent attribute (useful when writing <li> tag * some improvements to HTML reader and writer * HTML reader will allign tables in the middle by default (like IE) This can be switched off by undefining HTML_CELLS_VALIGN_MIDDLE in WPIOHTML + new option for HTML reader: -onlyinbodytag, text outside <body> tags is always ignored. 15.10.2006 V5.0 Release 20.9 + unless compiler symbol DONTREQ_SHIFT_FOR_UNDER_TEXT_OBJ has been set, images which are under the text require the SHIFT key to be pressed to become selected * tabstops wrapped to next line were ignored (width=0) - now they will be used to jump to first tab. (can be switched off in PRO version using compiler symbol DONT_USE_TAB_IN_NEXT_LINE) * improved response time after mouse click © 2004-2008 WPCubed GmbH - Munich, Germany
  • 253. Release Notes - WPTools 5 247 + the ANSI text reader will convert #12 chars (form feed code) into page breakes. (switch off with DONTUSEFF) - changes to improve the usage of inhereited font and font size information - fix for line draw problem for table cells which span a page * several small changes to fix stability issues - fix of problem in conversion of unicode to ANSI - fix in HTML reader: alignment in DIV was applied to previous paragraph + load and save to unicode strings: GetUNICODE and SetUNICODE. (Internally the UNICODE reader/writer are used) + new: ruler properties IntervallStepsInch and IntervallStepsCM 11.8.2006 V5.0 Release 20.8 + property WPRichText.Memo.TextColor - this color is used for the text which uses the default color. It is initialized from the global variable wpClWindowText which has the default value clBlack. Note: To set the color of the editor window use property DeskColor and PaperColor + new flags in ProtectedProp: ppBookmarkKeepStructure and ppInsertpointKeepStructure --> if text is deleted the contained bookmark or field objects can be recreated. + new method: SetOuterCellBorders(Activate : Boolean; BorderWidth : Integer = -1); It is now used by the "outer border" standard action * StartSpellcheck automatically positions cursor before current word. - Some improvements to further improve stability + if compiler symbol TOTALREADONLY is active (see WPINC.INC) no table or object resizing is possible when the Readonly property is true + new ClipboardOption wpcoAlsoCopyHTML to also create a HTML block when copying text. This solves a problem when the text is pasted into Outlook express which seem to not handle RTF correctly. * numbering action will now continue numbering after bulleted paragraphs The numbering will restart, unless the CTRL key is pressed. 17.7.2006 V5.0 Release 20.7 + new event: OnLeaveRTFDataBlock * improved HTML reader - assign border attributes from styles - InputCode automatically moves to first cell if currently in table ot table row object - some secuity checks (GetPosition, SetPosition) + improved RTF reader (reading nested tables) * fix for wrong headerr tag in WPWord written files * ignore wrong textb code in TX written RTF files * under some circumstances paragraphs were appended - WPPREMIUM: KeepN was broken - some stability issues 13.6.2006 V5.0 Release 20.6 + new quick start chapter in manual * don't color paragraph symbol when merge field at end of line - fix in DeleteMarkeredChar API - change in RTF reader to handle table rows with no cells - added load formatstring option: -overwriteparattr to always use attributes of first paragraph + added REDO hot key Shift+Ctrl+Z (in addition to Ctrl+Y) * modified numbering action - http://wpcubed.com/forum/viewtopic.php?t=2148 with changes to make it also work with selected text added similar code for bullet button * Table dialog now allows wpDefaultTableInTable if option wpAllowTableInTable was not set new: default Option wpNestingAsInEditOptions to use wpAllowCreateTableInTable of TWPRichText. EditOptions - improvement of cursor position restore when applying UNDO 17.5.2006 V5.0 RELEASE 20.5 + TIME and DATE text object now handle the data format string correctly + w hen using the tab key to navigate through a table the destination cell w ill be automatically selected unless you have specified w pDontSelectCellOnSpreadsheetMovement in E ditOptionEx * The interface SelTextAttr w ill now report the default attributes if no other attributes are © 2004-2008 WPCubed GmbH - Munich, Germany
  • 254. 248 WPTools Version 6 defined by the selected text. This behavoir can be disabled w ith E ditOptionE w pDontInitSelTextAttrWithDefaultFont x * Punctation chars are now handled as 'w ords' w hen using Ctrl+Cursor left/right - several fixes in engine * the save dialog can create a default extension if the extension does not match HTM, HTML, TXT, WPT, RTF or DOC (this must be enabled using compiler define CRE ATE _AUTOE XTE NSION. By default the extension w ill be appended if it is just a number. Now the selected format (filterindex) w ill be passed to the save procedure. - fix range check in cursor up/dow n (w as introduced by XPosLineUpDow n) - better bullets in right aligned text - StyleDialog hides TAB option unless compiler symbol STY_DONTHIDE TAB w as defined 18.4.2006 V5.0 RELEASE 20.3 + new pow erful function FieldLocate w hich can be used to enumerate the fields in the document to read or w rite their contents. It w as created to offer an alternative to Mergetext w hich does not require the use of a callback. * Cursor Up/Dow n now tries to retain the horizontal cursor position (can be sw itched of in E ditOptionsEx) + MailMerge(name) now allow s ONE w ildchars chaaracter '*' in the name parameter + MailMergeE x(name, command) also compares the command property of the fields. Also allow s w ildcard + WPRichText.Memo.DisableBackgroundOnBWPrinter can be set to TRUE if (and only if!) there are problems w ith the printer printing colored text. Some old printers seem to "think" they should print the text using w hite color if the background style is clear. (doesn't make much sense) * other changes and stability fixes 01.3.2006 V5.0 RELEASE 20.2 + new event PaintPageHint: Customize the canvas properties or paint the page number in your ow n code (then set "Ignore" to true) + new E ditOptionsE w pAlw aysColWidthPC w hen changine a column w idth all w idth w ill be calculated in %. x: + new global variables WP HTMLUL_ListI mageURL_circle and WP HTMLUL_ListImageURL_bullet to set an image name for the HTML export to be used for <ul> items + CSS now understands the color 'transparent' + new options for Contents.Options in OnMailMergeGetText: mmIgnoreLoadedFonts and mmIgnoreLoadedFontSize to ignore fonts w hen loading RTF - some fixes in engine - (!) fix in RTF reader to w ork w hen correctly w hen Czech list sorting is active + new event: OnTestForLinkE vent to detect hyperlinks in plain text. + new : [Ctrl+D LE ] deletes w ord or w hite space to the right E TE + CSS format now supports the MS Office elements: mso-style-parent and mso-style-parent * better detetection of symbol fonts * function IsSelected returns FALSE if text is selected but the length of the selection is 0 character + new demo: PrintOnBMP - for those w ho w ant to FAX pages + new demo: PlainTextLinks - have hyperlinks in plain text (w ithout having <a> tags in text) + new procedure ScrollLinePos(par, posinpar) makes this text line first of screen (w hen text long enough) - paste of tables in RTF code w orks better - improved automatic field selection * better display of selection of paragraph breaks * also show manual pagebreak (dashed line) w hen property WordWrap=true + Display hint w ith "Page/ PageCount" w hen the text is scrolled. Can be sw itched off using compiler symbol NOP AGE NHINT or View Option 'w pDontDisplayScrollP ageHint' also see event: OnPaintPageHint + OnPaint event now allow s flicker free painting - several fixes to RTF reader (i.e. linepar in header) - fix for default tabstops in WordWrap mode + New EditOption: w pSelectCompleteFieldAlsoWhenInside - even w ehn selection is done w ithin a field the complete field w ill be selected. + EditOption: w pDontSelectCompleteField - unless activated, alw ays select a complete fields w hen the selection contains part of a field - fix for default tabstops in WordWrap mode + new ClipboardOption: w pcoDontCopyProtectedAttribute, dont copy the protected attr (RTF, WPTOOLS) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 255. Release Notes - WPTools 5 249 * better support for the WordWrap mode (w hen page LayoutMode is selected) + support for context menu key. The event OnMouseDow nWord w ill be triggered w hen the context menu key w as pressed. If you use the new E ditOptionE w pDontTriggerPopupInContextE x: vent the old behavior is established, the event w ill be then only triggered in OnMouseDow n. * some fixes to improve stability 31.1.2006 V5.0 RELEASE 19.7 + the WPTools Version 6 Delphi setup now also includes the Package WPTools5_BCB10_W32 for the C++ Personality. It uses the pascal compiler symbol "NODB" since the linker error 'cannot find DB.OBJ' w as persistent * Delphi 2006 files now compiled w ith D2006 - Update 1 + DevE xpressBars support (define USE XP SSBARS) E RE + DoubleClick w ord selection now excludes ()[] signs. When clicked on this signs the matching character is found + ruler now show s page size and margins w hich w ere assigned in OnMeasurePage event - better operation of rulers in normal layout mode - better handling of tabs w ith justified text - problem w ith spacebefore has been fixed (w as sometimes used at start of page) - RTF reader did not handle tables at the start of a file correctly (w hen importing from Word). + compiler symbol: NUMBE RACTION_SIMPLE if defined the number button w ill create a simple list, not an outline! + for Version 4 compatibility: new methods SelectPages, PagesAsString * improved table header-row and footer-row handling. - some additional checks to improve stability * improved RTF reader to better handle charsets 12.1.2006 V5.0 RELEASE 19.6 + added support for Delphi 2006 * character styles w ill not applied to the symbols of bulleted lines + negative tabs are now possible * the RTF reader w ill now apply the maximum column w idth to a table. That produces output as seen in Word. To sw itch it off globally use compiler define ALWAYS_IgnoreTableWidth or the reader format string "-IgnoreTableWidth" * The horizontal Ruler now allow s it to move the right indent into the right page margin - several improvements w hen reading RTF tables, better nested tables due to table start/end tags + Drag&Drop now supports auto scroll (move mouse close to, but not over the border) - fixed problem w ith 'space_after' - WPReporter: fix of editing bug in - WPReporter: no par is appended after table w hen loading RTF text template (w e suggest to use WPT) - Preview Form now updates page number in scroll event * if in SinglePageMode TWPPreview .PageCount now retuns the PageCount in attached TWPRichText. Also: Scrollbar w ill be updated according to pagecount if AutoZoom = fullpage + new FormatoptionsE w pfNoTableHeaderRow s and w pfNoTableFooterRow s to sw itch off the duplicate display of x: table header and footer row s. - automatic decimal tabs in tables w ork better (w ord w rap bug) and automatically use ',' or '.' if the respective other char is not present 3.1.2006 V5.0 RELEASE 19.5 - InputEditField returns reference of *first* marker - fixed problem w ith text in first cell of table w hich extends over left page margin * show empty "size" combobox w he selected text uses different font sizes (WPAction.PAS) - WPPRE MIUM: fixed problem w hen a footnote w as first char on a page 22.12.2005 V5.0 RELEASE 19.4 - fix for w rongly aligned images in header - WPReporter copies tabstops - RTFDataCollection.Clear did not clear numberstyles - compiler define 'SAVE _ALL_NUMSTYLE S_WP w as set in unit WP T' IOWP TOOLS - avoid one pixel padding for regular texts lines - improvements to RTF reader - AutoScrollFeature now disables itself w hen text cannot be scrolled any further * resizing of really small images now w orks + procedure PrintPages can now print in reverse order (to value < from value!) + support for double, tripple and quadro click to select w ord, sentence and paragraph + new E ditOptionsE w pDblClickCreateHeaderFooter x © 2004-2008 WPCubed GmbH - Munich, Germany
  • 256. 250 WPTools Version 6 + new event OnClickCreateHeaderFooter (create header/footer after double click in margins) + textobj.Name and txtobj.Sourece is now saved w ith image objects to RTF * some changes to make WPTools PRO and PRE MIUM w ork w ith Delphi 2006 * load black character background color from RTF 07.11.2005 V5.0 RELEASE 19 + Ruler now have OnChanging and OnChanged events + If there is just one decimal tab in a table cell the text w ill be formatted as if it starts w ith a tabstop (can be sw itched off using FormatOptionE w pfNoAutoDecTabInTable) x * in paragraphs w ith borders the padding betw een paragraphs w hich use the same borderflags is now ignored * CodeInsideOf checks if cursor is on the closing object and then also returns the start object - RTF reader had problems w ith WPReporter templates w hen groups w ere empty - avoid w rap of last char w hen right tabstop is near right border - fixed misplacement of cursor after first char in a w rapped paragraph (happened sometimes during typing) - fixes in HTML reader/w riter to better support <li> tag - WPTOOLS w riter now w rites the the tag <StandardFont/> correctly. Reader repairs previously saved tag. 28.10.2005 V5.0 RELEASE 18.10 + faster initialization of the text (loading+pagination+display of test document "RTF Spec 1.8" = 220 pages, 8MB RTF in about 7 sec on 1.6 GHZ Test PC.) + faster typing in texts w hich very long paragraphs (1 par=40 pages!). This mode can be sw itched off in EditOptionsE w pDisableFastInitOnTyping - w hich should not be necessary. x: * change of 'DelayedInvalidate' logic in unit WPCTRME MO now using a timer. This avoids problems in MDI applications w hen a form w as destroyed w hich uses a TWPPreview control - MoveToField moved the cursor in E ditFields one char to far. - field 'NEXTPAGE w as not w orking ' - w hen RTF w as loaded merge fields removed the KeepN property from their paragraph - fixed handling of the automatic tab to indent first (did only w ork w hen first indent w as on left page margin) - highlight of current field did not w ork (E ditField demo) + FormatOptionE w pfKeepNUsesParImages - keepN also check for paragraph aligned images. x: + RTF reader/w riter now supports the sbknone, sbkpage tags for sections * much improved performance w hen w orking w ith files w hich use SPAN styles * some improvements to paragraph border dialog - Save section starts also before tables to RTF - w hen loading sections saved w ith w ord not automatically page breaks are created - fix small problem im HTML w riter w hich caused </td> to be saved for merged columns - Fix to KeepN support (only one block w as supported per page) - it w as not possible to edit an 'undefined' value in the value editbox by typing. It stayed grayed. * some improvements to HTML reader/w riter 17.10.2005 V5.0 RELEASE 18.8 + new function GetImageAtXY - to locate all images in MouseMove event * revised UNICODE copy&paste * format routine now handles nagative left/first indents + The format routine w ill *not* ignore empty paragraphs at the end of the footer. If your Application needs this behaviour use the flag FormatOptionsE : w pfIgnoreTrailingE x mptyParAtFooter - fixed 'ghost image' problem - fixed problem of center alignment of images in table cells w hen combined w ith new line characters - fixed problem w ith section header/footer w hen section started w ith a table - improvements to KeepN support. (note: KeepN requires 2 reformat runs) * ParProp dialog now show s inherited values in gray color 27.9.2005 V5.0 RELEASE 18.7 * WP Reporter w ill create long documents faster * in event OnTextObjGetTextE the property TXTObject.ParentRTFPage can no be x used to know the page the object is painted. (Useful in header/footer) - Paste in header/footer w hen displayed text is not the body does not create ghost RTFDatablock ('DoubleVision bug') + new event: RTF.BeforeFormatTableRow to sw itch on KeepRow Togethere for certain row s + new ClipboardOption w pcoDontCopyProtectedText - do not copy / cut protected text + WP Tools P ium HTML export: footnotes w ith hyperlinks, textboxes as aligned tables rem 12.9.2005 V5.0 RELEASE 18.6 * collection RTFProps.CharStyles is disabled - it w as not used. Now ParStyles is consistently used for © 2004-2008 WPCubed GmbH - Munich, Germany
  • 257. Release Notes - WPTools 5 251 characterstylesheets, too * better support for character styles load&save in WPTOOLS format - fixed format problem w ith space_betw een + RTF reader can now load RTF texts and use the existing style sheets w ith option "-dontoverw ritestyles" - improved handling of inc-indent action 6.9.2005 V5.0 RELEASE 18.5 + new E ditOptionsE w pAllow Draw DropBetw eenTextBlocks - for Drag&Drop into/from header + footer texts x: + new AddCopy function in the paragraph style collection. Copys a style w ith all base styles from a different collection + WPReporter templates print much better since a left margin of 1/2inch is respected - group arrow s are now visible. * improved nested tables: If a nested table is only cell content no padding w ill be used. - bug fixes in RTF reader: Read styles w ith pn group, nested tables - WPReporter now w orks w ith paragraph styles even if Source/Dest does not use shared TWPRTFDataProps - Save dialogs now w orks for TXT files - fixed problems w ith NL in table cells and tabstops - fixed problem w ith cursor positioning in right aligned paragraphs * better display of highlighted text (background color) w ith certain printer drivers and w PDF * TParagraph.CreateCopy now also copies style sheets w hich are used by this paragraph * images now belong to the TWPRTFDataCollection and not the TWPRTFProps. This avoids problems w hen w hen several RTFDataCollections used the same RTFDataProps. Using the new FormatOptionsE x w pfStoreWPObjectsInRTFDataProps the TWPObject can be still stored in the RTFProps - they w ill be only deleted if RTFDataProps.ClearAllWPObjects is executed. * improved cursor movement, also in forms * WPTOOLS format now uses <StandardFont/> tag to save the current default font. + new procedure InsertRow Above + w hen using the InsertRow action or toolbutton press CTRL to insert ABOVE of current row * TWPPreview Dlg now automatically uses events (w atermarks) from attached editbox. (assigned using code: dia. WP reView 1.AssignP P rintProperties(FEditBox);) 27.8.2005 V5.0 RELEASE 18.3 - RTF reader: unlock default font also in paragraphs w hich use a style - fixed clipping problem (under rare circumstances the first line w as not displayed) - HTML reader/w riter supports ID property (<p id="...">) + The HTML reader w ill create a page break after tag <pagebreak/> (useful for on the fly created HTML code) + The HTML reader w ill create a page reference to a certain bookmark w ith tag <pageref name="bookmarkname"/> + Reference as HTML-Help (.cmh) file is now available (see registered dow nloads) + CurrAttr Style, GetStyleE COlor and BGColor now also report paragraph, paragraph style and Default Attr x, + FormatOptionsE w pDontAddE x: xternalFontLeading - render lines smaller (more like WPTools 4) + new API: TWPOw nedCharAttrInterface.LockChanging, UnlockChanging - any attempts to change the attributes w ill be ignored. * loading RTF w ill now modify the RTFData.ANSITextAttr to reflect the default font defined in the RTF. (Use WPRichText.DefaultAttr.LockChanging to disable!) This is an important chage since otherw ise the standard font is alw ays used. - RTF-Reader: handle codepage in reader stack * disable drag and drop w hen multiple cells are selected (except for complete table!) * HTML reader: now allow s <ul>, <ol> tags w ithin <P> or <DIV> tags * Print() and PrintDialog functions automatically disable WordWrap property for the time of printing. You can define the symbol ALLOWWORDWRAP RI to disable this change P NT - padding-right in table cells w as sometimes duplicated by format routine - fixed paint problem w ith TWPRichTextLable w hich is using AutoZoom - fixed problem w ith property View Options: w pNoE ndOfDocumentLine - fixed problem 'clipdebug' not anymore $defined in unit WPCtrMemo - some small bug fixes in Preview Dlg + scrollbars 18.8.2005 V5.0 RELEASE 18.1 + new IDE dialog (click right on TWPRichText control) to pre configure format- and edit options. * WPPRE MIUM: InputFootnote now expects instead of the 'CreateNumber' boolean a new parameter a 'mode' Using 'w pNumberInFootnoteIsSuperScript' the number in the created footnote w ill be super script. * RE PORTBUILDE R(tm) Support units have been updated, now w ith metafile cache for faster display * improved RTF style handling: all redundant character and paragraph attributes are removed automatically (can be sw itched doff using FormatOption : "-DontFixAttr") + CurrAttr.FontName and Size w ill now report the default/style attributes. Can be sw itched off using $define DONT_RE PORT_DE FAULT_ATTR + updated DefaultAttr handling. Using this property you can set the default font © 2004-2008 WPCubed GmbH - Munich, Germany
  • 258. 252 WPTools Version 6 + new E ditOptionsE w pDontResetPagesizeInNew - the "New " action w ill not reset the page size! x: + new E ditOptionsE w pSetDefaultAttrInNew - the "New " action w ill reset the w riting mode to the default x: + new method: ClearE x(DontClearStyles,DontResetP ageSize,ResetWritingAttr : Boolean); * updated function Draw () * if EditOptionsE flag 'w pClearAttrOnStyleChange' is used assigning a style w ill remove the redundant x information first. This is not required w ith WPTOOLS format and RTF unless "-DontFixAttr" w as used. + new property: AcceptFilesOptions. Create movable images or linked images w ith drag&drop! + new event: AfterLoadText - preprocess the text before after load operations + much improved Par.SplitCell method and new property E ditOptionsE w pAllow SplitOfCombinedCellsOnly x (Disables a function w hich allow s the creation of tables w ith different coloumn count per row ) - PageProp dialog w ill not report custom size anymore - fix of drag&drop of text and images betw een pages in multi column layout * RTF reader now appends an empty paragraph after tables. This can be disabled using the compiler define DONT_AP E P ND_P AR_AFTE R_TABLE but should be better for the usability. S + PrintParamameter.PageSides now w orks w ith the Print() function + The print dialog now also allow s printing of selected text. This can be disabled using PrintOption 'w pDontAllow SelectionP rinting' + speed optimation of the RTF reader (especially for files w ith images) * removed the unused state element from record: TLine - fixed spacing problem for paragraphs w hich w ere follow ing a table - some other small bug fixes and improved handling. 3.8.2005 V5.0 RELEASE 18 * support for UNICODE copy&paste - better support for UNDO in DeleteColumn * CombineColumns does not anymore combine cells in tables w hich are embedded in the selected cells + support for vertical alignment also in vertically merged cells + new property FormatOptionsE x + w pClearDoesNotDelete in the attribute 'locked' of paragraph styles and numbering styles is now w orking This property makes it easy to set up a standard set of styles w hich is available in new texts. * HTML reader/w riter uses "w idth" element in style strings for images, tables and cells + new property: TWPStyleDlg.SaveCSSAsWPCSS. If true the WP-CSS format w ill be created w hen the user selects to saves to CSS format. WPCSS supports all properties. WPCSS w ill also be saved w hen the file extension is w pcss. When the extension is INI or STY the INI format w ill be saved. This format also contains all properties. STY file created by WPTools 4 are now imported better. + new event: BeforePasteImage - possibility to change the embedded object. + new method: GetParXYBaselineScreen can be used to calculate the baseline of certain text, for example to set the position of a drop dow n menu. + TWPSelectedTextAttrInterface now supports: ToggleCharstyle E xample: Implement Hotkey CTRL+B in OnKeyP ress event: if (Key=#2) then begin WPRichText1.TextCursor.CurrAttribute.ToggleCharstyle(WPSTY_BOLD); Key := #0; end; * changed property WriteObjectMode in 'default editor' to w obRTF. It w as 'Standard' * improved TParagraph.SetStyle method w hich can remove properties w hich are defined in style - several smal bug fixes in RTF engine * Additions to this manual, see Table Attributes, Mailmerge and forms, TWP TFDataCursor R 15.7.2005 V5.0 RELEASE 17.4 + new PrintParameter.PrintOption: w pAlw aysHideFieldmarkers - to hid field markers in Print; and PrintDialog; + new edit functionality: w hen resizing a table w hile pressing CTRL key the w idth of each column w ill be adjusted by preserving the aspect-ratio of the column w idth to the table w idth * editor improvements: better protection against unw anted change of column -w idth and -height. + improvements to HTML reader to display certain new sletter a lot better + WPReporter: new property ColumnWidthSnapValue- make sure table columns use same w idth (the default value 15 maps column lines w hich are not further aw ay than one screen pixel) + WPReporter: new Option flag "w pFixAllColumnWidth" - converts variable w idth columns into fixed w idth columns + TOCs can now be also created from the first line in a table cell using the new mode flag [w ptocAlsoProcessTables] for the CreateTableOfContents method. + WPAT_NoWrap can be used to sw itch off the w ord w rap in one paragraph. This mode has to be specifically actived if property FormatOptionsE X * updated RTF load metafile routine * border dialog now displays state of current paragraph - fix: draw paragraph border at end of page - fix: additional hyphen draw n at end of line © 2004-2008 WPCubed GmbH - Munich, Germany
  • 259. Release Notes - WPTools 5 253 - fix: Paragraph.MergeCell procedure improved 10.7.2005 V5.0 RELEASE 17.3 + new localizable strings. See file "WP Tools_EN_ADDE D.XML" in DemosTasksLocalisation + new procedure TWPOImage.Compress - automatically used after paste from clipboard. R equires $D FI ECOM R SSBI AP E N PE TM ASJP G E + RTF reader now supports vietnamese charset + WPRE PORTE the option w ppNew PageAfter can now be used for report groups R: + WP PRE ORTE new utility functions in WP R: SuperMerge: FindGroup, FindBand: Locate bands and groups ConvertLetterIntoTemplate : Create a banded report template from a text w ith header/footer (also see: ConvertTableIntoGroup: Convert a table into a report group w ith header, data and footer bands) + WP E OR R band.Bookm R P TE : ark to automatically w rap the text w hich w as created by a band or group into bookmarks. The bookmarks are applied after all text w as copied! + WPRE PORTE new event: AfterCopyParagraph - triggered after new par w as appended but before the data is R: merged + new component: TWPManageHeaderFooterDlg opens the dialog to create and delete header+footer, now localizable! * improved XMLE ditor for WP LanguageControl + new flag for Contents.Options in OnMailMergeGetText: mmDeleteThisField deletes the field markers! + WP PRE ORTE Option 'w pDeleteFieldsInDestination' deletes the fields in destination. (uses mmDeleteThisField) R: + ReplaceAll through the replace dialog now a) uses UNDO b) w ill w ork w ithin current selection only + Replacement in TParagraph.Replace now supports UNDO Bugfixes: - Select Word Procedure - DB control automatically uses '-nobinary', - HTML reader and w riter improvements - RTF reader now creates OnRequestHTTPImage event of embedded TWPObject (import from V4 files) and ignores next I C D I AGE N LU EM - RTF reader: Ignore rn after unicode u tag - RTF reader: apply subtrative properties - Fixes in WP TOOLS reader - some improvements to format and paint routine + new event: AfterCopyToClipboard makes it possible to add custom objects to clipboard + CombineCells now removes empty paragraphs - inputbuffer for fast w riteres (unit WOCtrMemo) optimized 14.6.2005 V5.0 RELEASE 17.2 [** IMPORTANT **] The LayoutMode "playLayout" did not hide header/footer before (as intended and described in manual) This has now been fixed. Header and footer w ill be hidden. Please make sure you use __playFullLayout__ to also show header/footer - automatic header+footer row s: improved alignment w ith other row s * new property "DefaultNumberIndent" (must be changed in code) w hich sets the default indentiation for bullets and numbers applied by bullet dialog and bullet button - page numbers are grayed in header/footer * the HTML w riter can now create simple UL and OL lists. This feature can be deactivated defining the compiler symbol DONT_WRITE _SIMP _LISTS LE + new event: OnCalcPageNr makes it easy to change the displayed page nr. - some improvements of formatting function for merged table row s - improvement of paint procedure (selected text and background colors) + new SelectedTextAttr.ClearAttrOverride + new View Option: w pDraw HeaderFooterLines + new FormatOption: w pNoMinimumCellP adding + new : TWP TextStyle.ADelAllDefinedIn - fixed memory leak w ith the 'StoreComplete' undo object * Copy text from single table cell does not copy borders and table structure anymore * removed unused interfaces from RTFE ngine * CountPages, CountLines, CountParagraphs now reports '1' for empty documents (better for GUI since that first line w ill be automatically created w hen the editor gets the focus) They count the body text if the cursor is not set to any other RTFDataBlock 30.5.2005 V5.0 RELEASE 17 © 2004-2008 WPCubed GmbH - Munich, Germany
  • 260. 254 WPTools Version 6 + added new 'categories' to online help + WPPRE MIUM + WPRE PORTE You can now use text boxes in report templates (fields can be used) R: + WPPRE MIUM + WPRE PORTE You can now use foor notes in report templates (fields can also be used) R: * Create table button alw ays disabled w hen in table (unless w pAllow CreateTableInTable is used in EditOptions) * WPRE PORTE the StartCode of a group is now processed before the event BeforeProcessGroup! R: + new FormatOption: w pDontAdjustFloatingImagePosition - do not modify the position of relative objects to keep on page + new FormatOption: w pDontAdjustFloatingImagePosition - do not modify x,y of floating images automatically to avoid that they are outside of page + new option for TParagraph.LoadFromStream: "w ploadpar_UseWritingAttr". Now the current attributes w ill be applied to the loaded text. + new : TParagraph.LoadFromString - makes it easy to set formated text in a parabgraph. (RTF or HTML commands are understood!) - fixed problem w ith WPReporter template editing w hen layout mode w as set to normal - improved case insensitive search in finder - several improvements to editor handling 12.5.2005 V5.0 RELEASE 16 - IMPORTANT: fixed problem w ith tabs in ruler w hich only occured w ith Delphi 5. * some important improvements to cursor handling w ith WPReporter + keep properties of images w hen pasting (or TextObj.Insert) image w hile other image is selected + several improvements to WPReporter and Report-Band Dialog (see new demo! ) * improved w riting of stylesheets in RTF code * improved saving of stylesheets in RTF code * the procedure ParStyle.LoadFromFile now has a parameter 'Merge' to merge in the new styles * improved stylesheet dialog (show focus in Listbox) * paint selection-background for selected text objects w hich use OnPaint event * the TWPRichText now publishes the event OnPrepareImageforSaving (used by the TWPRTFDataCollection) to make it easier to use in applications w hich do not use the "MultiView " feature. This event can be used to preprocess an image before it is saved, for example save it as GIF/JPE file G and store the file name in the property TextObj.Source + new function: TParagraph.InsertE - makes it possible to insert text w ith r signs (new pars w ill be created) x This is internally used by TextObj.E mbeddedText := 'new text' - so multiline text in bookmarks can be replaced + FORMTE fields are now converted to w ptools edit fields XT + changed behaviour of FormatOption: w pfHangingIndentWithTab - the left indent w ill be handled as first tabstop not only if the tab is the first character but also if the text before the tab fits into the first indent. * OnTextObjectMouseUp, OnTextObjectMouseMove and OnTextObjectMouseDow n are now also triggered for non-image TWPTextObj. (See editBox demo for a checkbox example) Only w ith image objects the x and y parameters are relative to the objects coordinates! 26.4.2005 - V5.0 RELEASE 15 + WPRichText.ParStyles.SaveToFile / LoadFromFile to make it easy to load/save style sheet in WPCSS format + WPRichText.ParStyle.SetWPCSS(s) applieas a string w hich w as created by GetWPCSS * protected text is now also locked for attribute changes (unless ppDontProtectAttributes is used in ProtectedProp) * updated demo P arStyles * updated RTF font/charset w riting. The resulting file w ill be a lot smaller + New procedure DeletePage - deletes the text on a certain page. This is a very complicated function w hich also handles multipage table row s! + new view option: w pDraw PageMarginLines to draw a doted line round the text area + function 'CodeListTags', w orks like 'GetCodeTags' but creates a TWPTextObjList * cleaner display of text selection (visible w ith italic text) * improved paragraph-border draw ing (respects indent-left/right) + RTL support can be activated by setting the flag paprRightToLeft in TParagraph.prop or for all paragraphs w ith WPRichText1.Memo._RTLSupport := TRUE * improvement to HTML w riter for better tables + WPFORM SUPPORT: now operational in WPForm V2.50 - only text rotation is not possible + ALL underline modes and the underline color feature are now w orking * automatic update of filter index for load/save dialogs + property TextLoadSaveOptions. Makes it possible to set a format string for Load, Save and SaveAs operations. + The attribute interfaces (such as WPRichText1.WritingAttr) now have a overloaded Clear procedure w hich allow s it to set the fontname and -size, + color right aw ay: WP RichText1.WritingAttr.Clear('Verdana',10); © 2004-2008 WPCubed GmbH - Munich, Germany
  • 261. Release Notes - WPTools 5 255 7.4.2005 - V5.0 RELEASE 14 * improve import of V4 mail merge templates. In RTF reader (w pioreadrtf.pas) the $DE FINE FIXUP _V4_FIELDS enables that trailing >> and ] are automatically removed. + WPPremium: cursor movement w ithin ootnote blocks using cursor up/dow n + "image under text" option in graphics menu of default actions + cursor movement w ithin visible header/footer blocks using cursor up/dow n and mouse click + improvements to the handling of forms (see new demo: E ditFields ) * Revised border dialog. (All properties are undefined by default, can be changed individually) * LoadFromFile, LoadFromStream now loads header/footer even if there is a body text defined (the function IsE ,mpty) has been updated + the property WPAT_ProtectedPar is now also checking attached styles and parent table/row s * copy&paste, Drag&drop now automatically tries to not create orphan field opening/close tags + added support for IME editor + the ruler now alow s it to change the left indent only * better update of WPComboBox * possibility to have a tabstop before the left indent * new handling of font names in RTFPros object (list instead of array) * changed logic of Ctrl+Left/Right to jump to start of w ord instead of end of w ord + font charset load&save in RTF format * several improvements to cursor positioning in forms (ProtectedProp=[ppAllE xceptForE ditFields]) + new RTF w riter option: "-nonumberprops" - in RTF the numbers are saved as regular text + new w riter option: "-nomergefields," - merge fields are not saved, just the embedded text + new w riter option: "-nohyperlinks" - hyperlinks are not saved + new w riter option: "-nobookmarks" - Bookmarks are not saved + new RTF reader option: "-ignorerow merge" - ignore the combine row s RTF tag + procedure 'FastAppendText' is now a function. If the optional parameter 'AsNew Section' is true this function w ill return the reference to a new section property object. * linked images are now saved w ith w idth/height (Word still ignores the w h parameters) + the follow ing functions have been added, they now include table cell handling: function DeleteP arWithCondition(Condition: TWPCheckP aragraph) : Boolean; function DeleteParWithE mptyFields : Boolean; function DeleteParWithText(const FindText: string) : Boolean; function DeleteTrailingSpace(E mptyFieldsToo: Boolean): Boolean; function DeleteLeadingSpace(E mptyFieldsToo: Boolean;InFirstP : Boolean = TRUE Boolean; ar ): - ... lots of small fixes to improve overall perfomance and reliability V5.0 - Release 13 (11.3.2005) - solved problem w hich occured under w indow s 98 (critical fix) + new IDE context menu for the TWPRichText 'Change Page Size' + new auto zoom mode: w pAutoZoomAsManyAsPossibleInRow + new demo: AppendAsSection: Create a big text out of several texts incl header + footer + enhanced the WPTOOLS format reader to understand the <new section/> tag. This makes it possible to create multi section texts w ithout loading them into an editor! +E nhanced API to w ork w ith sub paragraphs. Plese see the new demo "SubP aragraphs "! * InputTextField/InputTextFieldName are now functions returning the created TWP TextObj + new event: BeforeDropText to abort drop operation + property WideStringValue : WideString of 'Contents' in OnMailMergeGetText + new format string option: '-codepageXXXX' to set code page for ANSI reader/w riter + property Text and SelText now use the current keyboard codepage (internally uses '-codepage' !) + possibility to create repeated table header and footer row s. See updated demo: CreateTable + possibility to use the TWPFormulaInterface to calculate the value for repeated fields in header/footer(OnTextObjectPaintCalc) See TableCalc demo. + WP Reporter : added the possibility to have repeated header/footer w ith WP Reporter V5.0 - Release - 12.2 (22.2.2005) * improved code to size table row s (requires E ditOption w pTableRow Resizing) + possibility to set a fixed table row height in editor (press CTRL) + vertical alignment in table cells is now handled + page up/dow n key is now handled differently to avoid deadlock * better handling of merged row s - now the last column can be alw ays merged even if the column count in the row s is different + option: "-nobinary" to save RTF code w ith hex encoded data + save binary RTF variables * improvement of scroll function: Scroll to selected object instead of anchor © 2004-2008 WPCubed GmbH - Munich, Germany
  • 262. 256 WPTools Version 6 * The footer now alw ays starts at the bottom of the page w ith MarginFooter distance. If you need the old behavior w ith the footer to start at the beginning of the footer use FormatOption w pFooterMinimumDistanceToText * started implementation of character styles * the RTF w riter interpreted OptOnlyBody incorrectly and so didn't w rite some RTF tags * improvement to E ditOption w pAutoDetectHyperlinks to automatically exit a link w hen space or ')' is typed. V5.0 - Release - 12 (3.2.2005) + the E ditBoxModes w pemAutoSizeWidth and w pemAutoSizeHeight and the events OnChangeE ditBoxWidth and OnChangeE ditBoxHeight are now w orking. New demo: "EditBoxModes" + format option: w pfKeepOutlineWithNext to keep headline w ith chapter text even if seperated by empty lines + PrinterParameter are w orking now . Please check out the new demo "PrinterSet " * updated chapter 'M erge ' ailm * new chapter TWPTextObj w ith custom draw event * save non standard RTF-Variables as 'userprops' to RTF + format option: w pfKeepOutlineWithNext to keep headline w ith chapter text even if separated by empty lines - paragraphs longer than 2 pages w ere not formatted correctly. - better sizing + movement of images in "normal" layout mode * sizing rectangles are not any longer shrinked w hen zooming out * save and load new page starts before a table row in a Word compatible w ay V5.0 - Release - 11.1 (23.1.2005) + Readonly property for header/footer (TWPRTFDataBlock class) - if true they cannot be selected in page layout mode *E ditOptions spreadsheetcursormovement now w orks (jump to next cell w ith TAB) + TWP VirtPageP aintParam w hich is parameter of event: CustomLineP aintBefore now has new boolean property: PaintingInE ditor + unit WPSyntaxInterface to use the SYNTAX HIGHLIGHTING modules w hich are part of SynE w ith WPTools Version 6. (See demo SynHighlight ) dit + SP EE DRE FORMAT (can be disabled in FormatOptions): During regular text editing only the current and the next page is formatted, the rest of the text is untouched until the next time CR or Ctrl+CR is pressed or the user scroll the text. The delay betw een keystrokes w hich w as noticeable w ith very long texts is so minimized. + new component: TWP aintEP ngine . Used to paint the text from a TWPRTFDataCollection. See demo: TasksDynAssignRTFData + KeepN support activated * Widow /Orphan control revised (--> property FormatOptions) * improved handling of double buffer. Now the creation of 1000+ editors at a time is possible + Hyphenation (manual, use Ctrl + '-' to mark a character to go into next line) + Support for BB codes in the HTML reader. Must be enabled w ith -useBBCodes in format string. Use -ignorehtml to ignore regular HTML tags + use #13 code to create new paragraphs in HTML. Must be enabled w ith -useCRin format string * the DefaultAttr and the WritingAttr didn't survive a Clear of the text. This has been fixed. * better line number display in WPGutter - now start w ith 1 instead of 0 * LoadFromFile now uses the FormatString parameter V5.0 - Release - 10.5 (22.12.2004) * faster paint routine * new E vent: OnNew RTFBlock: Makes it easy to apply a default font/style/text (see online HLP) * TWPObject.Paint() function now receives TWPTextObj and Mode paremeter to adjust painting for different devices - several bugfixes (see history.txt) V5.0 - Release 10 (7.12.2004) * new unit WPCreateDemoText - must read chapter: Set Attributes in code * new demo LabelP rint w hich implements an easy to use form to print labels. * new demo E xternalP ages to show how to mix custom printed pages w itn text * new demo Find Text * updated demo: CreateTable * update demo: GlobalStyle (includes self running demo) * updated section in this manual: Header and Footer * updated manual section and VCL functionality: Interactive Text * far improved RTF reading and w riting * improved WPTOOLS format reader and w riter * improved HTML format reader and w riter © 2004-2008 WPCubed GmbH - Munich, Germany
  • 263. Release Notes - WPTools 5 257 + support for legal outlines + updated CreateTableOfContents procedure * many fixes and additions to programing API V5.0 - Release 9 (26.10.2004) * better handling for PageWidth/P ageHeight actions * better handling of the tables w ith WordWrap set to TRUE + added demo "ThreadSave" to show how to do threadsave mailmerge + added procedure: DeleteFields + now possible: colors and sizes for bullets + added FormatOption: w pfAlw aysFormatWithScreenRes - for better display w hen you only display on screen but do not print + added event: OnCustomLinePaintAfter - print borders around paragraphs or group of paragraphs + added event: OnCustomLinePaintBefore- print background of paragraphs or group of paragraphs + added event: BeforeInitializePar - syntax highlighting, dynamic hiding of pars etc + new : pow erful TWP SuperP rint component to print labels, multiople pages on one page and booklets + WPReporter: added TWPFormulaInterface - calculation in tables, paragraphs and "CALC" fields - fixed format routine: centered and right aligned text w as not handled correctly w hen indents w ere used. + added localization NEW and updated Demos: * CreateTable - show s how to modify an existing table! + SuperPrint - print labels and booklets using a new pow erful component: TWPSuperPrint + ThreadSave - merge letters in a several threads +M ini - create a compact w ptools editor w indow w ith split screen in code + WPReporter_Calc - requires WPTools bundle: pow erful calculation in text and tables V5.0 - Release 8 (6.10.2004) - fix to GetXPositionTw and GetYPositionTw to w ork w ith zooming and XOffset properly + new procedure: Memo.GetXYP ositionAtRTFTW * improved unit WP Obj_Image to save compatible RTF images in BMP WMF, JP G and P format , E NG (see property WriteObjectMode. It must be set to w obRTF for this) * improved image saving code for PNG files - they are now saved compressed in WPT format - improved painting of bullets created w ith WPTools 4 + added support for BCB6 and BCB5 (WPTools Standard E dition) + added events to TRTFDataCollection to modify reader and w riter (BeforeSaveToStream etc) V5.0 - Release 7.5 (30.9.2004) + new MDI Demo - show s how to use DefActions w ith MDI form + new "Lines" property for E ditor and RTFDataBlock * improved DefAction Module * revised RTF saving code: style and table handling improved. Fixed problem w ith nested tables. - RTFw riter: In landscape mode the non-sw apped page size values w ere w ritten + new FormatOption: XMLOutline - show s the text as HTML outline * revised HTML reading logic * support for hyperlinks and bookmarks w hen printed w ith w PDF - improved draw ing of tables in header or footer * added support for E DSSP LL E V5.0 - Release 7 (13.9.2004) + added reusable data module WPDefAct - it contains main menu, image list and actions + added new popup editor WPDefE ditor - it can be used in your applications (read more) + new procedure SetZoomMode to change layout mode and zooming quickly + improved performance of MergeText and FastAppendText V5.0 - Release 6.5 (8.9.2004) + Redo support (activated in EditOptions!) - bugfixes to cursor movement procedure - improvement of formatting procedure * added property Draw Options to rulers * added OnPaint event to rulers V5.0 - Release 6.5 (4.9.2004) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 264. 258 WPTools Version 6 + completely rew ritten TWPRuler (many properties need to be ignored w hen the form is loaded in the IDE ) The ruler now supports undefined, inherited indents and grays out tabstops w hich are not active in al selected paragraphs. The height / w idth is now fixed to 24 pixel. This is important for a clear display. + completely rew ritten TWPVertRuler . + Page relative images are now supported : PositionMode w potPage + added autoscroll (w ith variable speed) - can be sw itched off in EditOptions * improved selection across page borders - fixed problem in spellcheck interface - fixed problem w hen saving tab stops * added E ditField demo - several bugfixes and additions to API V5.0 - Release 6 (24.8.2004) - renamed unit WP OBJI mage to WP OBJ_I age to avoid conflict w ith TWPObjType: w pobjImage m + new Demo 'WaterM ' show s how to draw a form or image tiles in the background 2 * updated Demo 'P arStyles ' - to also show how to w ork w ith style combo box and dialogs * The PRO version is now compatible to BCB5 and BCB6 (see BCB notes) - renamed unit WP OBJImage to WP OBJ_Image to avoid conflict w ith TWPObjType: w pobjImage * improved deletion of selected tables row s + added support for references (reference: display page number of page w ith bookmark) * improvement to bullet handling + reformat optimized for best screen and print quality (see WYSI WYG) * WPTools format handles Numberstyles, complete style table and RTFVariables + improvement to function Draw () - now also w ork w hen SetWindow Org API is active - bug fix in SaveToFile() - parameter Format w as ignored + procedure ParStylePaint to paint a style name into a listbox or combo + added: StyleDialog + modernized text selection w ith mouse (selects w ords automatically) * updated drag&drop code, now also betw een different TWPRichText + added: StyleSheetDialog * finished: TWPStyleCollection (please note: You don't need it for the paragraph style support. It is only a container. The dialogs are attached best to an editor using property 'EditBox' + added style saving to RTF - improved style loading from RTF + optimized WPReporter draw ing code * added popups to WPReporter E ditor Dialog V5.0 - Release 5.5 (11.8.2004) + new function: WPRichText.Assign - copies the text and the view options + special text attr. * updated TWPStyleCollection. This class stores the style templates + new Demo 'P arStyles ' - this show s how to w ork paragraph and span styles - natively and fast * many improvments to HTML loading and saving, esspecially the CSS support has been updated + several improvements to the programming API to make it more consistent - solved problem w ith tabstops * extended TBX demo (also see Use WPTools5 w ith TBX) V5.0 - Release 5.1 (6.8.2004) +E ditor sw itches off numbering on Return in empty line + new demo: GridM ode - create a table from text and images loaded from database + loading and saving of numbering (complete new code to w rite list styles) © 2004-2008 WPCubed GmbH - Munich, Germany
  • 265. Release Notes - WPTools 5 259 - bugfix for property CPColNr - better handling of TWPRichText.DefaultAttr (it w as only partly used) - fix to property 'Readonly' - w as also declared also in unit WPCtrRich - improvement to SpellAsYouGo: do not check w ord during w riting - fix to OnDblClick. The last parameter 'Ignore' now is passed as 'var' V5.0 - Release 5 (2.8.2004) * All Layout Modes are now operational - see Layoutmodes * All View Options now w ork (Show CR etc) * new table resizing code * hyperlink support in RTF label * added: OnP ageGapGetText - improved RTF and WPTOOLS reader and w riter classes - improved loading of RTF text w hich contains charsets - improved loading of tables - improved HTML w riting: saving of <font> and <span> tags - improved HTML w riting: saving of <br> tag * added OnChange event - removed LayoutModes 'w playFullLayoutColumns' and 'w pThumbNailView Nr' (redundant) V5.0 - Release 4.5 (25.7.2004) - improved handling of soft line breaks = Char(10) - improved action handling - new pseudo action: 'TWPToolsCustomE ditContolAction' w hich is used to replace the TWPToolControl - added TBX demo (also see Use WPTools5 w ith TBX) V5.0 - Release 4 (16. July 2004) * many improvements to RTF reader (load header/footer for sections) - improvement to rendering of tabstops - improvement to formatting of justified text + new method: HyperlinkConvertOldWPT3Links to convert the old WPTools hyperlink syntax - sw itch off unw anted painting of paragraph borders * increased performance of InputString() + Support for overw rite mode: new property Inserting and TextCursor.Inserting + added funtion GetPar(parindex) : TParagraph + added property ProtectedProp and event OnCheckProtection. * improved "editfield" protection and edit code, also added edit-field events * improvement to HTML w riting code to reduce file size - WPRuler now handles tabstops - fixed bug w hich SetCharAttr used by the ChangeAttr demo V5.0 - Release 3 (2. July 2004) - undo for image moving + resizing - undo for Drag&Drop and Copy&Paste - improvement to format routine to better support text w rapping around images * save header and footer to RTF - now also the optional names of header and footer are saved! - improvement to selection + cursor placement - fix to avoid unw anted drag&drop - revised loading and saving of fields and objects from and to RTF - Image handling, resizing and moving - highly improved for character and paragraph dependent images - now supported: different w rap mode (TWPTextObj.WRAP) - bugfix: format routine: w ord w rap around images did not w ork at start of paragraph + WPReporter 2 - beta 1 - now w ith new group folding function. Currently only 'IgnorePageHeight' operation supported + WPReporter: added WPE E val ngine and created functions to make it possible w ith WPReporter to change text styles in scrips (= band commands) + WPReporter: added improved band dialog, now w ith insert/delete band buttons + added unit WP WordConv + added unit w pManHeadFoot - improvements to the handling of property 'WorkOnText' - property "ScrollBars" w orks as expected - added undo support (70% complete) + new View Option: w pDontPaintPageFrame © 2004-2008 WPCubed GmbH - Munich, Germany
  • 266. 260 WPTools Version 6 + new View Option: w pCenterPaintPages - to center the pages automatically in the preview dialog + new property for TWPPreview : SinglePageMode. If true only one row of pages are displayed (1 or 2) V5.0 - Release 2 (17. June 2004) - The HTML loading has been improved. - The function Draw () is now w orking. Please note the new demo project FunctionDRAW. Draw w ill render the text using the same w ord w rap as it is used in the editor. It is used to fill rectangles vertically w ith text. A new rectangle can be started w hen the text w as not completely printed. V5.0 - Release 1 (14. June 2004) This first release includes the pow erful new RTF engine w ith its versatile capabilities to use paragraph and character attributes. This versatility does not only come from the amount of possible attributes, but how the attributes can be stored - attached to a paragraph or a style or inherited. The GUI controls have been taken from WPTools 4 and adapted as far as possible. The look and feel w as not changed - on purpose. Later new property dialogs w ill be delivered. © 2004-2008 WPCubed GmbH - Munich, Germany
  • 267. Index 261 LoadImageFromFile 34 Index LoadImageFromStream 34 Localization 14 -M- -A- Mailmerge 27 Actions 49 Merge Images 34 Attributes 74, 81 Multithreading 130 AutomaticTextAttr 31 - B- -O- OnMailMergeGetText 33 Bookmarks 98 -C- - P- PDF Export 9, 165 C++Builder 147 PDF View 9 Custom Draw 115, 120, 128 Printing 103, 104, 107, 110 -D- - R- Default Editor 47 RTF2PDF 1 DevExpessBars 70 -F- -S- Sections 66 FastAppendText 39 ShowMergeFieldNames 31 FieldLocate 38 Splitscreen 142 Format Strings 203 Styles 86 Forms 41 -T- - H- Tables 78, 81, 112 Hyperlinks 96 TBX 70 TextDynamic 1 -I- Token Conversion 192 ToolBar 2000 70 Images 123 TParagraph 20 InsertPointAttr 31 Translation 14 -L- TWPRTFDataBlock 20 LabelPrinting 149 -W- Language 14 Watermarks 115 License 7 wPDF 165 Load & Save 203 WYSIWYG 25 © 2004-2008 WPCubed GmbH - Munich, Germany