Using GDI+ in Reports
Visual FoxPro 9's object-assisted reporting mode leverages Microsoft Windows GDI+ to render to output devices. GDI+ offers new opportunities for high-quality, extensible output, and also mandates some changes in native output behavior. This topic describes some aspects of creating output associated with use of GDI+.
GDI+ Features in Visual FoxPro Object-Assisted Output
When you use Visual FoxPro's object-assisted reporting mode, output is rendered by a ReportListener-derived object. The following table lists ways in which ReportListener's features and native behavior are affected by GDI+.
Device-independent and resolution-independent rendering
GDI+ provides a graphics object, an extra layer of abstraction beyond the device context of GDI. The graphics object is capable of rendering output identically to disparate devices such as screens and printers.You can expect a high degree of consistency between preview and print output in Visual FoxPro's object-assisted reporting mode. The graphics object's methods for laying out text and graphics are resolution-independent, so Visual FoxPro can render pages to printers at different resolutions, according to the capabilities of each printer.
Note
Because Visual FoxPro respects the print resolutions available on each printer, you may see some changed behavior in reports with saved printer environments. If the printer setup with which the report was saved during report design had a different resolution than the printer you specify when running the report, the page may not scale properly on the page. In Visual FoxPro 9, you can override printer setup instructions with explicit instructions in a separate field, including explicit instructions to use a particular print resolution regardless of printer (assuming the printer supports the resolution you set). However, in most cases, you have no need to do so; simply removing the printer environment from the report provides better results.
Tip
In Visual FoxPro 9, unlike previous versions, the printer environment is not saved to the report or label definition by default. For more information about using override settings for printer environments, see Understanding and Extending Report Structure. For more information about printer environments in reports, see How to: Save the Printer Environment for Reports.
Differences in kerning and text widths from output in earlier versions
GDI+'s device- and resolution- independent methods of drawing text ensure that a specific string will fit into the same rectangular space in a layout when it is rendered on different devices. However, the algorithms in GDI+ that measure strings, handle kerning (or spacing) of individual letters in strings, and align strings in the layout rectangle are significantly different from the Report Engine's original algorithms used for this purpose.If you have defined the width for expressions very exactly in an existing report, in some cases the same data will no longer fit. You may be able to widen the expressions appropriately by adding just a few pixels. You can use the Report Builder's Size and position in layout options convenient for this purpose. For more information, see General Tab, Report Control Properties Dialog Box (Report Builder).
Tip
As in earlier versions of Visual FoxPro, numeric expressions that do not fit in their assigned layout rectangle are represented by asterisks in report output, to avoid providing a number that looks correct but is actually truncated. If you see asterisks in an expression when you switch a report to object-assisted mode, and if you think that the number should fit into the space, check to see if it has a picture template assigned. All versions of Visual FoxPro use the picture template to determine how much space the number needs for display. If you used a template such as
99,999.99
, for example, your output may display as asterisks even if the actual number has fewer digits. To ensure that the output displays properly in object-assisted mode, you can widen the layout element enough to display99,999.99
with the element's designated font attributes. However, if the picture template has more digits than your anticipated data results, you may only need to remove a digit from the template. For more information, see Format Expressions for Field Controls.When strings do not fit in their assigned layout rectangle, GDI+ provides a way to let the user know that the entire output is not displayed. The ReportListener class takes advantage of this GDI+ feature for output that does not represent numbers, with its StringTrimming options, described in the next section.
Note
Visual FoxPro's Report System, in all versions, ignores the layout rectangle when displaying calculated fields that have picture templates. As a result, the differences between object-assisted output and backward-compatible output described here do not apply to calculated fields. For example, a field set to Sum and given a picture template of
999,999,999
in a layout rectangle that is too small to fit all the characters in the template will display its full text; it will not be truncated. For more information, see How to: Perform Calculations in Field Controls and Format Expressions for Field Controls.
StringTrimming Options
GDI+ provides multiple ways for you to handle text that does not fit in its assigned layout rectangle. The ReportListener class exposes its various options as described in the table below. When you are designing a report or label, the Report Builder allows you to pick from these options in the Report Control Properties dialog box. For additional information about selecting one of the available options while designing a report, see Format Tab, Report Control Properties Dialog Box (Report Builder).Value StringTrimming Type 0
Not specified, default will be used.
1
StringTrimmingCharacter
Trims strings that do not fit at the nearest character.
2
StringTrimmingWord
Trims strings that do not fit at the nearest word.
3
StringTrimmingEllipsisCharacter
Trims strings that do not fit at the nearest character and adds an ellipsis (…).
4
StringTrimmingEllipsisWord (Visual FoxPro default)
Trims strings that do not fit at the nearest word and adds an ellipsis (…).
Note
Trimming the string based on the word rather than character level most closely emulates the trimming behavior of Visual FoxPro when it runs reports and is not in object-assisted mode. Adding the ellipsis allows users to see when some content is missing. Because GDI+ requires slightly more space for text expressions than GDI did, this setting allows you to check older reports for expressions that require widening for GDI+ rendering to handle their contents.
5
StringTrimmingEllipsisPath
Replaces an inner portion of strings that do not fit with an ellipsis (…).
Note
This value is useful for path- and file- names. For example, the string
C:\PROGRAM FILES\MICROSOFT VISUAL FOXPRO 9\REPORTOUTPUT.APP
can render asC:\PROGRAM FILES\
…\REPORTOUTPUT.APP
.
DynamicLineHeight feature
GDI+ line spacing is the default method of handling line spacing for ReportListener objects that render multi-line text. GDI+ line spacing allows for a more polished appearance, faster performance, and fewer pages for the same report content than the Report Engine's original line-spacing algorithms. However, GDI+ line spacing changes the amount of space your text takes up in the layout when you compare the rendered results to previous versions of Visual FoxPro.ReportListener's rendering strategy for text spanning multiple lines changes according to the value of its DynamicLineHeight property. This value determines whether the ReportListener uses GDI+ standard (dynamic) line spacing according to font characteristics, or the backward-compatible fixed line spacing used by Visual FoxPro when it runs reports and labels but is not in object-assisted mode. For more information, see DynamicLineHeight Property.
- Availability of output page images
When an application renders to a particular drawing surface using GDI+, GDI+ provides methods to save the contents of the drawing surface to various image file types. Visual FoxPro exposes this capability in the ReportListener's OutputPage method. For more information, see OutputPage Method.
- Availability of transparency values in color settings
GDI+ specifies colors using ARGB (alpha or transparency, red, green, and blue) components. Visual FoxPro report and label definition files do not have a way of storing the transparency value, so colors stored in .frx and .lbx tables are always completely opaque or transparent. However, Visual FoxPro exposes the transparency values to ReportListener code at run time, in the EvaluateContents event. You can use this event dynamically set text and text background colors to different degrees of transparency, and cause blends to occur in overlaid, semi-transparent layout elements. For more information, see EvaluateContents Event.
Using GDI+ in User Code during Report Runs
Your code can take advantage of GDI+ capabilities in reports. Visual FoxPro 9 ships with a suite of wrapper classes for the GDI+ API to facilitate your use of these features. For more information, see GDI Plus API Wrapper Foundation Classes.
Your use of GDI+ during a report run takes one of two forms:
You use GDI+ to render to the drawing surface the ReportListener uses for native output. In this scenario, you can dynamically place new output elements or alter existing ones directly into the running report. The ReportListener class exposes a handle to its own graphics object, during a report run, for this purpose. For more information, see GDIPlusGraphics Property. As explained in that topic, and as shown in the topic's sample code, to use the native ReportListener's graphics object, you must use functions based in the same file copy of GDIPLUS.DLL that the product uses in native code. To ensure that you use the correct copy of GDIPLUS.DLL, use the syntax IN GDIPLUS.DLL with no explicit path in your DECLARE DLL statements. For more information, see DECLARE - DLL Command.
You supply the ReportListener object with a handle to a separate graphics object, and ask it to draw an output page to this additional graphics object. In this scenario, you do not accomplish your goal by temporarily assigning a different handle to the ReportListener's GDIPlusGraphics property; for safety reasons, that handle is read-only. Instead, you supply the ReportListener with the additional handle as one of the parameters to the OutputPage method. The ReportListener's GDIPlusGraphics handle, and the native output stream, remain undisturbed by this process. For more information, see OutputPage Method.