XFRX

Developer’s guide

 

© 2007 Martin Haluza

EQEUS.COM

 

 

 

 

 

 

 

XFRX version: 12.3

Last update:  16:34, June 5, 2007


The latest version of this document is available at: http://www.eqeus.com.

 

 

 

 

Trademarks: Microsoft, Visual FoxPro, .NET, Visual C#, ASP.NET, Word, Excel and ActiveX are either trademarks or registered trademarks of Microsoft Corporation.

1      Contents

 

1        Contents. 2

2        What’s new in this document. 5

3        Introduction.. 7

4        Architecture of XFRX.. 8

5        Installation.. 10

5.1          How XFRX handles different version of Visual FoxPro. 10

5.2         Differences between XFRX for VFP 8.0 and XFRX for VFP 9.0.. 11

5.3         Distributing XFRX with other applications. 11

5.4         Two versions of XFRXLIB.FLL.. 12

6        Running XFRX.. 13

6.1         Running XFRX in VFP 5.0, 6.0, 7.0 and 8.0.. 13

6.2         Running XFRX in VFP 9.0.. 14

6.3         Using THISFORM and THIS references. 15

6.4         Displaying progress bar in VFP 8.0.. 16

6.5         Displaying progress bar in VFP 9.0.. 16

6.6         Canceling report generation in progress. 17

6.7         Printing page ranges. 17

6.8        User-defined page size. 17

6.9         Zipping the generated files. 18

7        Interactive features. 19

7.1          Hyperlinks. 19

7.2         Bookmarks. 20

7.3         Document properties. 21

8       PDF specific features. 22

8.1         PDF Encryption.. 22

8.2        PDF Font Embedding. 22

8.3        Object rotation.. 23

8.4        Appending generated output to existing PDF Documents. 23

9        Word specific features. 24

9.1         Password protection.. 24

9.2         Word document splitting. 24

10     Flow layout document option.. 25

10.1       Running the conversion.. 25

10.2      How it works. 25

10.3      Page headers and footers. 27

10.4      Deficiencies. 27

11      Generating XPS documents. 29

12     Generating OpenOffice documents (ODF). 30

13     HTML specific features. 31

13.1       HTML page size adjustment. 31

14     Excel specific features. 32

14.1       General notes. 32

14.2      How it works. 32

14.3      Handling page breaks. 32

14.3.1     Generating sheet per page. 32

14.3.2          Generating sheet per start-each-group-on-a-new-page groups. 33

14.4      Defining sheet names. 33

14.5       Hiding the Excel sheet grid. 33

14.6      Leaving the fields content in Excel cells. 33

14.7       How to invoke the XLS output. 33

14.8      XLS cells adjustment. 34

14.9      How to achieve the best results. 34

14.10         Numeric field picture format in Excel 36

15      Converting reports to plain text. 38

15.1       Limitations. 38

15.2       How it works. 38

15.3       Horizontal lines. 39

15.4       Characters per inch setting. 39

16     Using XFF files. 41

16.1       Converting reports to XFF files. 41

16.2      Initializing the XFRX#DRAW class instance. 41

16.3      Creating temporary XFF files. 42

16.4      Converting XFF files to other output formats. 43

16.5       Printing XFF files. 43

16.5.1      Displaying printer properties dialog. 43

16.5.2          Using custom printer settings when printing. 44

16.6      Previewing XFF files. 44

17      Drawing custom objects with XFRX#DRAW... 45

17.1       Drawing custom objects to existing XFF files. 45

17.2       Drawing custom objects during report generation process. 45

17.2.1      Page-bound scripts. 45

17.2.2          Rectangle-bound scripts. 46

17.3       XFRX#DRAW functions. 49

17.3.1      XFF document navigation.. 49

17.3.2          Adding pages. 49

17.3.3     Coordinates units. 49

17.3.4          Drawing functions. 49

17.3.5     Tooltips, hyperlinks and bookmarks. 50

18     XFRX previewer. 51

18.1       Setting up the XFRX previewer. 51

18.1.1      Common methods and properties. 52

18.1.2     Using frmMPPreviewer class. 59

18.1.3     Using cntXFRXMultiPage class. 59

18.1.4     Using XFCont class. 60

18.2      Printing from the previewer. 62

18.3      Exporting reports from the previewer. 62

18.4      Previewer localization.. 63

19     Implementing custom event hyperlinks (drilldown) in the XFRX previewer. 65

19.1       Setting up custom event hyperlinks. 65

19.2      Accessing the calling previewer. 66

19.3      Drilldown solution example. 66

20          Converting reports to pictures. 70

21     Chaining listeners in VFP 9.0.. 71

22          Running XFRX in a web-based environment. 72

23          Reference. 73

23.1      XFRX Output Target Types. 73

23.2      Properties and methods common in XFRXListener and XFRXSession classes. 74

23.3      XFRXListener class. 84

23.4      XFRXSession class. 85

23.5      XFRX#DRAW class. 86

23.6      XFCont class. 95

24          XFRX License. 97

2      What’s new in this document

 

Date

XFRX version

Document modifications

May 24, 2007

12.3

New chapter:

Generating XPS documents (page 29)

Updated chapters:

Registering an extension handler (page 54)

Using cntXFRXMultiPage class (page 59)
[new property – cntXFRXMultiPage]

XFRX Output Target Types (page 73)

 

August 15, 2006

12.0

Updated chapters:

XFRX Output Target Types (page 73)

Flow layout document option (page 25)

Generating OpenOffice documents (ODF) (page 29)

 

February 1, 2006

11.3

New chapters:

Implementing custom event hyperlinks (drilldown) in XFRX previewer (page 65)

Installation / Two versions of XFRXLIB.FLL (page 12)

 

Updated chapters:
XFRX previewer (page 51)

Properties and methods common in XFRXListener and XFRXSession classes (page 74) [new properties: PictureDPI and DefaultPictureFormat]

 

December 2, 2005

11.2

New chapter:

OpenOffice Writer document option (page 29)

 

Updated chapter:

XFRX Output Target Types (page 73)

 

August 24, 2005

11.1

New chapters:

Showing / hiding previewer toolbars (page 52)

Displaying printer properties dialog (page 43)

Using custom printer settings when printing (page 44)

 

June 2, 2005

11.0

New chapters:

Architecture of XFRX (page 8)

Drawing custom objects with XFRX#DRAW (page 45)

 

March 28, 2005

10.2

New chapters:

Defining sheet names in XLS documents (page 33)

Hiding the Excel sheet grid (page 33)

Leaving the fields content in Excel cells (page 33)

Printing XFF files, chapter Printing XFF files (page 43)

 

Updated chapters:

Handling page breaks in XLS output (page 32)

Using XFF files (page 41)

XFRX previewer (page 45)

XFFWriter class reference  (page 86)

 

December 29, 2004

10.1

New chapters:

Appending generated output to existing PDF Documents na stránce 23.

 

3      Introduction

XFRX is a tool for transforming Visual FoxPro reports to electronic formats. It can be incorporated into Visual FoxPro applications to provide the following functionality:

 

XFRX is a royalty-free product. It can be added to Visual FoxPro applications without any additional costs. Please read the License chapter for more details.

 

XFRX is available for Visual FoxPro 5.0, 6.0, 7.0, 8.0 and 9.0. XFRX contains its own report engine which is used in VFP 8.0 and earlier. In VFP 9.0, XFRX plugs into the new reporting architecture of the native report engine.

The differences between XFRX for VFP 5.0, 6.0, 7.0 and 8.0 and XFRX for VFP 9.0 are described in detail in this document.

Please note: To make the text easier to read, these differences are described as differences between VFP 8.0 and VFP 9.0. If VFP 8.0 is mentioned further in the text, it applies for VFP 5.0, 6.0 and 7.0 as well.

 

4      Architecture of XFRX

The basic architecture is described in the following schema:

 

FoxPro report – The FoxPro report definition, stored in .FRX, .FRT files

Report engine – The reporting engine that processes the report definition. XFRX for VFP 8.0 and earlier contains its own report engine. In VFP 9.0, XFRX plugs into the new reporting architecture and the native report engine is used.

Scripts – Methods or code snippets written in VFP. The scripts call methods of XFRX#DRAW class to “draw” to the generated document.

You can find more information about using scripts in Drawing custom objects with XFRX#DRAW chapter on page 45.

Custom object scripts – scripts linked to a rectangle object on a report. When the rectangle is being processed, the script is invoked instead of rendering the actual rectangle. The custom object scripts can alternatively be converted to pictures.

When these scripts are processed, the controlling table of the report is available, so these scripts are ideal for generating graphs or other data based graphics objects.

Page bound scripts – scripts invoked on each page, drawing either “above” of “below” the page content. These scripts are suited for watermarks.

Custom scripts – you can modify the generated reports, too. You can add text, graphics, new pages, hyperlinks, bookmarks, etc. You can even create new documents from scratch, bypassing the report engine altogether.

XFF File – an internal file that stores the generated reports. These files can be modified, stored to disk, previewed on screen, printed or converted to any of the target formats. You can find more information about XFF files in Using XFF files chapter on page 41.

XFRX#DRAW class – the class that wraps XFF files.

XFRX previewer – The XFF files can be previewed in an advanced report previewer that comes with XFRX. The previewer can be localized and allows for search the document and supports hyperlinks and bookmarks.

You can find more information about using the previewer in XFRX previewer chapter on page 51.

Printer – XFRX is also able to print the XFF files. Please find more information about printing in Printing XFF files chapter on page 43.

 

 

 

5      Installation

 

Evaluation version quick tip: For a quick preview of the capabilities of XFRX, unpack the whole zip archive to an empty directory and run DEMO.SCX.

 

XFRX consist of the following parts:

 

The installation is very easy: simply unpack the zip archive and make sure the files are accessible from VFP (they can either be placed in a local directory or the path can be set via the SET PATH command).

 

5.1     How XFRX handles different version of Visual FoxPro

XFRX for VFP 8 contains its own report engine that mimics the behavior of the native Visual FoxPro report engine.

XFRX for VFP 9 is implemented as an XFRXListener class, a descendant of UtilityReportListener class (please see _REPORTLISTENER.VCX in FFC for more information about the basic report listener classes provided by FFC). The XFRXListener class complies with the object-assisted reporting standards introduced in VFP 9 and perfectly fits into the new open architecture. You can use it alone or in combination with other report listeners provided with the product or by third parties.

About 95% of XFRX is written in Visual FoxPro and, to make the deployment as easy as possible, all its source code (without the visual classes for the report previewer container) is in one PRG file, both for VFP 8.0 and VFP 9.0: XFRX.PRG. This PRG file is the same for all VFP versions.

If you purchase XFRX without source codes, you will be able to download XFRX.FXP compiled in the VFP version you are using.

If you purchase the source code, before you add XFRX.PRG into your project and compile it, you need to enable (uncomment) one of the #DEFINE commands at the beginning of XFRX.H, which determines the VFP version you are using.

Example: If XFRX is used in VFP 8.0, the beginning of XFRX.H would look like this:

*#DEFINE VFP5

*#DEFINE VFP6

#DEFINE VFP8

*#DEFINE VFP9

 

(Please note there is not a constant for VFP 7.0. If you are using VFP 7.0, uncomment the VFP6 constant).

5.2     Differences between XFRX for VFP 8.0 and XFRX for VFP 9.0

As written in the previous paragraph, XFRX for VFP 9.0 uses the native report engine, which results in the following advantages:

  1. The layout of the documents produced by XFRX for VFP 9.0 should generally be more exact as the same engine is used both for printing and for document generation.
  2. XFRX for VFP 9.0 is approximately twice as fast as XFRX for VFP 8.0.
  3. Variables declared as LOCAL are not visible in XFRX for VFP 8.0.
  4. XFRX for VFP 8.0 has some restrictions in handling the data environment. It is able to set up the data environment, open tables, setup relations and fire the data environment methods, but the data environment instance itself is not available. This restriction does not apply to VFP 9.0.
  5. XFRX for VFP 9.0 is able to display any content of general fields, including ActiveX components. XFRX for VFP 8.0 is able to extract just BMP and JPEG pictures from the general fields.
  6. XFRX for VFP 8.0 does not support multicolumn layout where records are laid from left to right (rather than from top to bottom). This limitation does not apply for VFP 9.0.

 

5.3     Distributing XFRX with other applications

The best way to distribute XFRX is to include XFRX.FXP (or XFRX.PRG, if you purchased the source code option) into the target application’s exe (add it to your project, to the section where your PRGs are). This way, you won’t have to distribute this file and, more importantly, XFRX will be able to access the reports and other resource files (pictures, tables, etc.) built into the exe as well.

If you are using the XFRX previewer, add the appropriate files from the XFRXLIB directory to your project as well.

The support libraries (XFRXLIB.FLL, HNDLIB.DLL and ZLIB.DLL) cannot be included in the exe and need to be distributed along with the application. They need to be located either in the same directory where the main EXE is or in a directory defined in SET PATH command.

5.4     Two versions of XFRXLIB.FLL

There are two versions of XFRXLIB.FLL available that you can use with XFRX. The reason of this is that the “normal” XFRXLIB.FLL version requires three other DLL libraries from Microsoft to be installed on the target computers: gdiplus.dll, msvcr71.dll and msvcp71.dll. If you try to use XFRX with XFRXLIB.FLL without these DLLs installed, SetParams method will return -6, “xfrxlib.fll cannot be loaded (it is missing or invalid)”.

 

All of these dll libraries can be downloaded from Eqeus or Microsoft website:

 

These libraries can be distributed with your application (they are also distributed with VFP 9.0), but sometimes you may not need the gdiplus features in XFRXLIB.FLL and it may be easier to use a no-gdi+ version of XFRXLIB.FLL. This library is located in the NOGDIP subdirectory in the evaluation as well as commercial version package.

 

The following table indicates features not available in the no-GDI+ version if XFRXLIB:

 

 

GDI+ version

No-GDI+ version

Exporting reports as pictures

Yes

No

Printing

Yes

No

Supporting BMP and JPG pictures in PDF

Yes

Yes

Supporting other picture formats in PDF

Yes

No

Converting report pictures to defined DPI

Yes

No

Exporting contents of general fields in VFP 9

Yes

No

Exporting BMP and JPG pictures from general fields in VFP 8

Yes

Yes

Binary comparison of images to reduce the size of PDF documents

Yes

Yes

 

 

 

6      Running XFRX

When XFRX is run, it returns an instance of one of three classes, depending on a parameter passed. The available parameters are:

  1. “XFRX#INIT”
    Running XFRX with this parameter will return the XFRXSession class instance, which is the main class that controls the behavior of XFRX in VFP 5, 6, 7 and 8.
  2. “XFRX#LISTENER”
    This option is available in Visual FoxPro 9 only and returns an instance of XFRXListener class.
  3. “XFRX#DRAW”
    This option returns an instance of XFRX#DRAW class. This class is used for working with XFF files. Please see Initializing the XFRX#DRAW class instance chapter
    na stránce 41 for more information.

 

Important note: The evaluation version of XFRX cannot be included into VFP projects, it makes VFP crash. To avoid this please invoke XFRX via macro substitution:

 

loSession = EVALUATE("xfrx('XFRX#INIT')")

 

This way XFRX.APP does not get into the project and you will be able to compile your application without problems.

 

6.1     Running XFRX in VFP 5.0, 6.0, 7.0 and 8.0


Please note:
To make the text easier to read, the differences between XFRX for VFP 5.0, 6.0, 7.0, 8.0 and XFRX for VFP 9.0 are further in the text described as differences between VFP 8.0 and VFP 9.0. If VFP 8.0 is mentioned, the described feature applies for VFP 5.0, 6.0 and 7.0 as well.

 

  1. Call XFRX with "XFRX#INIT" as a parameter to obtain the XFRXSession object:

    loSession=XFRX("XFRX#INIT")

  2. Call SetParams method to set the document generation parameters. (Please see page 74 for details and full parameter list).
  3. If SetParams return 0 (zero), call ProcessReport method for each report to process. (Please see page 85 for details and full parameter list).
  4. After all reports are processed, call Finalize method to finish the document generation process.
  5. You can also call ResetPageNo() method if you need to reset the page number in between reports.

 

Example 1:

This code merges two reports –  report1 and report2 – into a single PDF document, output.pdf

 

use demoreps\invoices order customer

local loSession, lnRetval

loSession= xfrx("XFRX#INIT")

lnRetVal = loSession.SetParams("output.pdf",,,,,,"PDF")

If lnRetVal = 0

            loSession.ProcessReport("report1")

            loSession.ProcessReport("report2")            

            loSession.finalize()

Else

            ? lnRetVal

Endif

 

6.2     Running XFRX in VFP 9.0

In VFP 9.0, the standard object-assisted mode is used to run XFRX:

  1. Call XFRX.APP with "XFRX#INIT" as a parameter to obtain the XFRXListener object:

    loListener=XFRX("XFRX#LISTENER")

  2. Now there are two options you can choose from:
    1. Call loListener’s SetParams method that has exactly the same parameters and return values as the one in XFRXSession class. (Please see page 74 for details and full parameter list).
    2. Or, you can fill in individual properties of loListener and run SetParams method without any parameters to make sure you can proceed to the next step. (Please see page 84 for full list of properties available).
  3. Call the native REPORT FORM command with the new OBJECT clause for each report to process. If more reports are merged, include NOPAGEEJECT clause with each REPORT FORM call but the last one.
  4. Alternatively, you can leave the NOPAGEEJECT clause in the last REPORT FORM command as well (which may be useful is some scenarios) and call loListener.finalize() to finish the document generation.

 

Note: Even in VFP 9.0, you can initialize the XFRXSession class via “XFRX#INIT” parameter and use the XFRX’s own engine, rather than the native one.

 

The following examples all do exactly the same (and they also do exactly the same as the example 1 above), showing various ways of calling XFRX in VFP 9.0:

Example 2:

 

use demoreps\invoices order customer

local loSession, lnRetval

loxfrx = XFRX("XFRX#LISTENER")

lnRetval = loxfrx.SetParams("output.pdf",,,,,,"PDF")

IF lnRetval = 0

            REPORT FORM report1 OBJECT loxfrx NOPAGEEJECT

            REPORT FORM report2 OBJECT loxfrx

ELSE

            ? lnRetval

endif

 

Example 3:

 

use demoreps\invoices order customer

local loSession, lnRetval

loxfrx = XFRX("XFRX#LISTENER")

lnRetval = loxfrx.SetParams("output.pdf",,,,,,"PDF")

IF lnRetval = 0

            REPORT FORM report1 OBJECT loxfrx NOPAGEEJECT

            REPORT FORM report2 OBJECT loxfrx NOPAGEEJECT

            Loxfrx.finalize()

ELSE

            ? lnRetval

endif

 

Example 4:

 

use demoreps\invoices order customer

local loSession, lnRetval

loxfrx = XFRX("XFRX#LISTENER")

loxfrx.targetType = "PDF"

loxfrx.targetFileName = "output.pdf"

lnRetval = loxfrx.SetParams()

IF lnRetval = 0

            REPORT FORM report1 OBJECT loxfrx NOPAGEEJECT

            REPORT FORM report2 OBJECT loxfrx

ELSE

            ? lnRetval

endif

 

6.3     Using THISFORM and THIS references

Note: This paragraph applies to VFP 8.0 only. THISFORM and THIS references are handled properly by the native report engine in VFP 9.0.

XFRX supports using THISFORM and THIS in the expressions of the report fields. However, being normal VFP application, XFRX cannot access THISFORM and THIS objects directly. Instead, THISFORM object has to be explicitly sent to XFRX via setThisform() method, THIS needs to be sent via setThis() method. The use is very simple.

If you have THISFORM in your report, call xfrxSession.setThisform(THISFORM) before calling ProcessReport(). If you are using THIS, call xfrxSession.setThis(THIS).

6.4     Displaying progress bar in VFP 8.0

XFRX provides a simple hook so that any progress bar tool could be used for displaying the progress during the document generation process. All you have to do is to create an object which contains updateProgress() method and pass it to XFRX. During the generation process, XFRX calls updateProgress() method either after each page or after each record is processed.

This is a simple example of displaying the generation progress in a wait window:

 

loSession=xfrx("XFRX#Init")
loProgress = createobject("progress")
lnRetVal = loSession.SetParams("document",,,,,,"PDF")
if lnRetVal = 0
   loSession.setProgressObj(loProgress,2)
   loSession.ProcessReport("myReport")
   loSession.finalize()
endif

define class progress as custom
   procedure updateProgress
      lpara ta,tb, tc
      wait window nowait "Page #: "+allt(str(tb))+" Report #: "+allt(str(ta))+" ("+allt(str(tc))+"%)"
enddef

The progress object is attached to XFRX with setProgressObj() method. This method takes two parameteres - the first one is the progress object, the second defines the information the updateProgress() will be getting. It can contain two values: 1 - only page number and report number will be provided in updateProgress() method, or 2 - page number, report number and percentage progress within the current report will be provided. Using the percentage progress information is more accurate and more suitable for progress bar visualization, but to provide this, XFRX has to calculate the number of records in the processed table, which, sometimes, can be very time demanding. In this cases, 1 can be used not to calculate the number of records.
The updateProgress method takes three parameteres: current report number, current page number and actual percentage progress within the current report.

 

6.5     Displaying progress bar in VFP 9.0

In VFP 9.0, the XFRXListener object can be chained together with another listener which would take care of the progress bar displaying. One of the possible ways to do this is to use the UpdateListener class, which is shipped with VFP 9.0, in FFC.

 

Example:

This sample code creates an instance of the UpdateListener class and chains it with XFRXListener:

 

loxfrx = XFRX("XFRX#LISTENER")

SET CLASSLIB TO (HOME()+"FFC\_reportlistener.vcx")

loUpdate = CREATEOBJECT("updatelistener")

loUpdate.thermFormCaption = "Report in progress ..."

loxfrx.successor = loUpdate

lnRetval = loxfrx.setparams("output.pdf",,,,,,"PDF")

IF lnRetval == 0

            REPORT FORM (lcReportName) OBJECT loxfrx NOPAGEEJECT

            loxfrx.finalize()

ELSE

            ? lnRetval

endif

 

6.6     Canceling report generation in progress

Note: This paragraph applies both to VFP 9.0 and VFP 8.0

The report generation process in progress can be canceled by setting the global variable gnStopXFRX to 1. For example, you can, for example, use it this way:

 

ON KEY LABEL Ctrl+C gnStopXFRX = 1

 

6.7     Printing page ranges

Note: This paragraph applies to VFP 8 only. In VFP 9.0, please use the RANGE clause of the REPORT FORM command to achieve the same.

To define the page range, call setPageRange() method before calling calling ProcessReport(). There are two possible ways how to call the setPageRange() method:

loSession.setPageRange(5,10)

loSession.setPageRange("1,4,10-20,25")

 

6.8     User-defined page size

Note: This paragraph applies both to VFP 80. and VFP 9.0

You can define the page size of the generated document. The user-defined page size will override the page size stored in the report. To define the user-defined page size, call setPaperSize() method with paper width and paper height as parameters:

 

setPaperSize(nUDPaperWidth, nUDPaperHeight)

 

The unit is Inch * 10000.

 

See also: HTML page size adjustment na stránce 31.

6.9