Using XFF files
Converting reports to XFF files
To create a XFF file, send "XFF" as the target parameter and the name of the file as the output name parameter of the SetParams().
Example: Creating a XFF file
LOCAL m.loSession m.loSession= xfrx("XFRX#INIT") IF m.loSession.SetParams("output.xff",,,,,,"XFF") = 0 m.loSession.ProcessReport("report") m.loSession.finalize() ENDIF
LOCAL m.loObj m.loObj = xfrx("XFRX#LISTENER") iF m.loObj.SetParams("output.xff",,,,,,"XFF") = 0 REPORT FORM myreport OBJECT m.loObj ENDIF
By default, .XFF extension (XFrx File) is added to the output file. The XFF file is internally stored as a normal DBF file, and because Memo fields are used for some of its columns, another file with the same name and .FPT extension is created.
Initializing the XFRX#DRAW class instance
(Please see the XFRX#DRAW class reference).
XFRX methods do not work with the XFF file directly, but always via the XFRX#DRAW class, which represents a wrapper around the XFF file. To create an instance of this class, call XFRX with “XFRX#DRAW” parameter. Then call openDocument(tcXFFFileName) to attach the XFRX#DRAW object to an existing XFF file:
LOCAL m.loXFF m.loXFF = xfrx("XFRX#DRAW") IF m.loXFF.openDocument("output.xff") ELSE ? "XFF file cannot be open" ENDIF
You can also create an empty XFF file by calling CreateDocument(tcXFFFileName) method.
Creating temporary XFF files
Sometimes you may want to create the XFF file just in memory, use it in your application (e.g. for report previewing and printing) and release it afterwards.
To do this, leave the XFF file name empty. In this case a temporary XFF file will be created and you will be able to access its XFRX#DRAW class instance. The way how to access the instance differs in VFP 8.0 and VFP 9.0.
VFP 8.0 approach
In VFP 8.0, the instance is returned by the Finalize() method of the XFRXSession class:
LOCAL m.loSession, m.loXFF m.loSession= xfrx("XFRX#INIT") IF m.loSession.SetParams(,,,,,,"XFF") = 0 m.loSession.ProcessReport("report") m.loXFF = m.loSession.finalize() ENDIF * * now the loXFF instance can be used as if the XFF file was opened * with the openDocument method call *
VFP 9.0 approach
In VFP 9.0, the instance is stored in oxfDocument property of the XFRXListener class:
LOCAL m.loObj, m.loXFF m.loObj = xfrx("XFRX#LISTENER") m.loObj.targetType = "XFF" m.loObj.targetFileName = "" && output to a temporary file REPORT FORM report OBJECT m.loObj m.loXFF = m.loObj.oxfDocument
Converting XFF files to other output formats
To process the stored report, you need to initialize a XFRX#DRAW object, link it to the stored file and send it as a parameter of TransformReport method of XFRXListener class (in VFP 9.0) or XFRXSession class (in VFP 8.0) instance.
Example: Transforming a stored XFF file to a PDF document.
VFP 8 approach:
LOCAL m.loSession, m.loXFF, m.lnRetVal m.loSession= xfrx("XFRX#INIT") m.loXFF = xfrx("XFRX#DRAW") IF m.loXFF.openDocument("output.xff") m.lnRetVal = m.loSession.SetParams("output.pdf",,,,,,"PDF") IF m.lnRetVal = 0 m.loSession.TransformReport(m.loXFF) ENDIF ENDIF
VFP 9 approach:
LOCAL m.loSession, m.loXFF, m.lnRetVal m.loObj = xfrx("XFRX#LISTENER") m.loXFF = xfrx("XFRX#DRAW") IF m.loXFF.openDocument("output.xff") m.lnRetVal = m.loObj.SetParams("output.pdf",,,,,,"PDF") IF m.lnRetVal = 0 m.loObj.transformReport(m.loXFF) ENDIF ENDIF
Printing XFF files
To send the content of a XFF file to a printer, call printDocument method of the XFRX#DRAW class instance. The name of the printer, job name and page range can be sent as parameters.
Please see the full parameter list and further details in the XFRX#DRAW class reference.
Example: Printing an XFF file
m.loXFF.printDocument(getprinter(),"xfrx – invoice", "1,2,4-10")
Displaying printer properties dialog
A printer properties dialog for a given printer can be invoked via _xfPrinterProperties function, returning the printer properties structure as a string.
This string can be saved as a user preference and sent to XFRX as the 5th parameter of PrintDocument method when printing. This functionality is similar to SYS(1037) introduced in VFP 9.0, with two differences/improvements:
- The page setup and printer selection dialogs are skipped, which saves two clicks for the users and preempts confusions in case the printer has already been selected. (Very often, there is a printer selection box in the "main" form and a button to invoke printer properties).
- This implementation works in earlier versions of Visual FoxPro, too (from VFP 5.0)
The _xfPrinterProperties method takes 3 parameters:
tcPrinterName - the printer name
tcTag2 - the DEVMODE structure to use as a default (if not specified, the default printer settings will be used)
tlShowProperties - if set to .T., the printer properties dialog box will show up. If OK button is clicked, the DEVMODE structure with selected printer settings will be returned. If Cancel button is clicked, an empty string will be returned.
If this parameter is set to .F., the dialog will not be displayed and the default printer setting will be returned.
by ref tnRetVal - Value indicate a problém (since XFRX 15.7)
- -3 Printer name is not valid
- -2 Cannot get DEVMODE size for specified printer
- -1 Cannot get DEVMODE for specified printer
Example:
SET PROCEDURE TO xfrx ADDITIVE && this is required as the function is implemented inside XFRX.FXP LOCAL m.lnRetVal, m.lcPrinter, m.lcTag2 m.lcPrinter = GETPRINTER() && select a printer m.lcTag2 = _xfPrinterProperties(m.lcPrinter, "", .F.) && do not show the dialog, return the default settings m.lcTag2 = _xfPrinterProperties(m.lcPrinter, m.lcTag2, .T.) && show the dialog box now m.lcTag2 = _xfPrinterProperties(m.lcPrinter, m.lcTag2, .T.,,@m.lnRetVal) && show the dialog box now DO CASE CASE EMPTY(m.lcTag2) AND m.lnRetVal=0 && CANCEL button was clicked CASE EMPTY(m.lcTag2) AND m.lnRetVal<0 && Some error OTHERWISE && OK button was clicked ENDCASE
Using custom printer settings when printing
The printer settings structure can be sent to PrintDocument method as the fifth parameter. If this parameter is empty, the default printer settings are used.
The printer settings structure can be retrieved by _xfPrinterProperties procedure (see the previous chapter), or, if the printer settings are saved with the report, it is stored in Tag2 field in the first record of the FRX file.
Example:
m.loXFF.printDocument(lcPrinter, "job name", 1, 3, lcTag2)
Changing custom printer settings
Since XFRX 17.0 you can use class _XFRX_DEVMODE_WRITER for changing some printer properties.
Example:
LOCAL m.loDEVMODE, m.lcTAG2, m.lcPrinter m.lcPrinter=SET("PRINTER",2) m.lcTAG2 = _xfPrinterProperties(m.lcPrinter, "", .F.) && do not show the dialog, return the default printer settings m.loDEVMODE=CREATEOBJECT("_XFRX_DEVMODE_WRITER",m.lcTAG2) && read DEVMODE structure m.loDEVMODE.SetField("DM_ORIENTATION",2) && set some field - orientation landscape =m.loDEVMODE.Write() && recreate DEVMODE structure m.lcTAG2 =m.loDEVMODE.cDEVMODE m.loXFF.printDocument(m.lcPrinter, "job name", 1, 3, m.lcTAG2)
Previewing XFF files
Please see chapter Previewing XFF files for more information about previewing XFF files in the advanced report previewer that comes with XFRX.