What is the Mind's Eye Report Engine?

What is the Mind's Eye Report Engine? (Updated 02/19/2009)

 Top Next

The Mind's Eye Report Engine (MERE) is an ActiveX control that can be used in your applications to generate reports at runtime without limitations as to where objects can be placed onto report pages as well as to what the Page Size and/or Orientation of those pages are within a single report. MERE is most noted for it's built in high performance PDF Engine that can generate PDF documents without the need to install or use a printer driver. The MERE PDF Engine can write a one hundred page PDF document in a second or two depending on the performance of your system. Even though the MERE ActiveX control has a great preview engine, it can also be used without any User Interface to Print, Email or generate PDF files of your reports from a web server or a background service. If your application doesn't require any User Interface, check out out LITE Version of the product. The MERE LITE version is an ActiveX control without any GUI and can be instantiated on the fly or dropped onto a Form or Object Container and used to generate PDF documents programmatically. The LITE version works great for web applications where you simply need to render a PDF document on demand and send the document to the browser. The LITE version and the PRO version both have a PDFStream() method that facilitates being able to generate a PDF to a memory stream without creating a temporary file on disk. This is a major plus in that you don't have to worry about cleaning up any temporary files after generating your PDF document.

The Mind's Eye Report Engine ActiveX control can be placed onto a Form in Visual FoxPro, VB, C#, Delphi or even on a web page to Preview reports generated by your program. The Report Engine is data independent and using the Methods built into the Report Engine, gives you the ability to create reports or documents quickly and easily by reading data from your database in different development languages and placing that data onto pages within the Report Engine. The data placed onto pages at runtime are persisted in memory and until the report engine object is released or the Clear method is used to clear the contents of the Report Engine.

The amount of data and pages in the report is only limited by the amount of memory/disk space on the system running the Report Engine. Multiple instances of the Report Engine can coexist simultaneously which allows for running multiple Top Level Form Reports as well.

WHAT'S NEW

The new Version 4.0 release of MERE has a much smaller memory footprint and eliminates a lot of methods that are no longer needed for use with Visual FoxPro 9.0. Additionally, the MERE V 4.0 ActiveX control WILL NOT work with the older VFP 8 and below MindsEyeReportEngine.VCX Class Library. So, if you are using the MERE 4.0 control, be sure and use the MERE_ReportListener.VCX Class Library. The VFP 9 usage and sample code is included in the help file starting here.

In addition, the new MERE 4.0 control can be used with VB6 as it has a much shorter PROGID. VB6 has a 38 character limit on the PROGID name and the older 3.X version of MERE could not be instantiated by name. Please be sure to use the MERE 3.X version of the ActiveX control when using the MindsEyeReportEngine.VCX Class Library which IS ONLY intended for use with VFP 8 and below.

For more information check out the What's New! section of this Help File.

COMPARISON CHART BETWEEN LITE and PRO Versions

Features | LITE | PRO
Save to PDF | ü | ü
AddText() Method | ü | ü
AddShape() Method | ü | ü
AddPicture() Method | ü | ü
AddLine() Method | ü | ü
Compress PDF | ü | ü
SaveToPDF() Method | ü | ü
PDFStream() Method | ü | ü
AddChart() Method |  | ü
AddBarcode() Method |  | ü
AddFromClipboard() Method |  | ü
AddWordDocument() Method |  | ü
CopyPageToClipboard() Method |  | ü
SaveToBitmap() Method |  | ü
SaveToJPEG() Method |  | ü
SaveToMetafile() Method |  | ü
SaveToPNG() Method |  | ü
SaveToTIFF() Method |  | ü
SaveToWord() Method |  | ü
SendMail() Method (SMTP or MAPI) |  | ü
GUI Interface |  | ü
PrintReport() Method |  | ü
Print Report from User Interface |  | ü
Print Preview / Display Report |  | ü

See the Feature List

Click Here for to view a Screen Shot of the Report Engine

Built in Chart Engine Support

To learn more about the control's PEMs click on the following links:

Properties

Events

Methods

Visual FoxPro 9.0 Usage and Examples

MERE Version 4.0 and the MERE LITE control both use the new VFP 9 ReportListener class and are intended to be used with the included MERE_ReportListener.VCX Class Library which is a subclass of the VFP 9 ReportListener Class designed to output the VFP Rendered Reports into the MERE ActiveX control in the RENDER() method of the RL Class.

Visual FoxPro 8.0 and Below Usage and Examples

The MERE control also has special support built into it to help it in processing and running unmodified Visual FoxPro FRX Reports along with the included Visual FoxPro Class Libraries.

Visual FoxPro Support

Mind's Eye, Inc.

support@mindseyeinc.com

http://www.mindseyeinc.com/ReportEngine

(636) 282-2102


Feature List

Mind's Eye Report Engine ActiveX Control Feature List

 Top Previous Next

Report Engine/Preview Features

It's a programmable Desktop Publishing Tool!

· Add Rotated Text to pages anywhere, anytime.
· Add Images, Shapes and Lines to pages anywhere, anytime.
· Add Charts to pages anywhere, anytime programmatically.
· Add Barcodes to pages anytime, anywhere and at any angle.

Built in PDF Engine

· No PDF Printer Driver or 3rd party software is required to generate PDF documents using the Mind's Eye Report Engine.
· Lightning Fast PDF Engine generates the PDF document based upon the objects in the Report Engine.
· A page range can be specified when saving pages to a PDF document.
· Stream PDF document output to a variable using the PDFStream Method.

Enhanced Printing Capabilities

· Shrink To Fit option so pages will print within the Printable Area on each page. This includes printing an 11x17 page onto an 8.5x11 page.
· PaperBin assignments for each and every page
· MediaType assignments for each and every page
· The ability to print All Pages, Range of Pages and Current Page without closing Window
· Print Even and Odd Pages, Odd Pages Only or Even Pages Only
· Print pages in Reverse Order for outputting to Ink jets so the pages are ordered correctly in the stack
· Print Multiple copies with or without collation without specific printer support
· Set the Caption of the Printing dialog box to your choosing
· Suppress the Printing dialog box
· Specify the name of your Print Jobs via a Property
· Easily Print your output to a Printer File

Built with Developer's in Mind

· Royalty FREE Per Developer License
· Add Pages programmatically at runtime specifying both Size and Orientation anywhere within the document meaning you can now insert a page at the beginning of the report at anytime.
· Nearly Unlimited Zoom
· Append multiple Reports into a Single Report or Report Preview
· Data independent control
· Watermark Object for each individual page specifying the Text, Font, Size, Style and Rotation Angle
· Support Multiple Page Sizes in a Single Report
· Dynamically Add Objects and Pages to the Report at run time.
· Navigate pages programmatically or using the toolbar.
· Control the look and feel of the control via Properties at Runtime.
· Enable, Disable or Hide various Toolbar Buttons and/or the entire Toolbar
· Overlay a calendar on report pages to print a calendar or photo calendar. The calendar automatically increments the month for each additional page on the report.

Built In Barcode Engine

· MERE has it's own built in Barcode engine and renders the Barcodes onto the page as an image at runtime.
· Barcodes are also rendered as scalable PDF graphics path objects in PDF documents as well using much less memory than embedding barcode fonts into a PDF document.
· NO Barcode Fonts Required on the system in order to print Barcodes or generate them into a PDF document.
· Over 20 Barcode styles supported
· Barcodes can be rotated to any angle on the page.

Built In Charting Engine

· Add multiple charts to any page within your report and easily assign different data to each chart on the page.
· Place Charts onto Report Pages and change the chart type at runtime.
· Each chart contains it's own unique data points and can also contain multiple datasets within the same chart.

Built in Email Engine

· SMTP engine is built into the control
· MAPI requires the MAPI drivers installed on the PC.
· Single SendMail Method generates a PDF document and emails it at once.
· Support for Multiple Email Attachments

Save Pages to Image Files

· Individual Report Pages can be saved as image files in BITMAP, JPEG, PNG, TIFF or METAFILE format.
· Specify the maximum dimension of an image file to produce thumbnail images of any page.

Clipboard Support

· Copy Report Pages to the Clipboard to be pasted into other applications interactively or programmatically.
· Paste Enhanced Metafile Objects onto Report Pages from other applications interactively or programmatically.

Clipboard Screen Shot


What's New!

02/19/2009

New Version of the MERE ActiveX control and rendering fixes

· Version 4.0 of the MERE ActiveX control eliminated all of the methods that were no longer being called when using the MERE_ReportListener Class in Visual FoxPro 9.0. This reduced the memory size of the ActiveX control as well as the number of Methods.
· The new Version 4.0 control has a new PROGID and CLASSID and can now be instantiated in VB 6.0.
· New MEREPRO4PreviewForms.VCX Class Library created for use with the new MERE 4.0 ActiveX control.
· Updated the Mind's Eye Report Engine Control Help File to better document using the control with Visual FoxPro 9 as well as using the new MEREPro4PreviewForms Class Library which is used to host the new MERE Version 4.0 control.
· Updated the MANIFEST FILE Examples for using the MERE ActiveX controls (PRO and LITE versions) with a Manifest File instead of having to register the control using REGSVR32.
· Minor changes made to the MERE_ReportListener Class to work with both the new MEREPRO4PreviewForms.VCX Class Library and the older MindsEyeReportPreviewForms.VCX Class Library.
· Minor rendering fixes and improvements were made to the Version 3.X ActiveX control.

06/05/2008

Speed Improvements, Lower Memory Usage and Corrections made to Rotated Text (PRO V3.5)

· Refactoring of rendering code and modifying internal memory structure of Report Objects improved both rendering performance and lower the amount of memory used when creating reports. Not that memory improvements needed to be made but every little bit helps.
· Corrections were made to the rendering of Rotated Text for Preview, Print, Image Output and PDF Output.
· VFP 9 support added for the NOCONSOLE option into the MERE_ReportListener Class for the REPORT FORM command to be used as a flag to NOT DISPLAY the Mind's Eye Report Preview Form when running the report. This functions the same as setting the MERE_ReportListener.lDoNotShow Property to TRUE before running the report. Therefore the following 3 ways can now be used to suppress the displaying of the MERE Report Preview form. This can be used to run reports and generate a PDF file without displaying the Preview Form. The NODIALOG option will OVERRIDE the MERE_ReportListener.lDoNotShow property if it has been set to FALSE which is the default.
REPORT FORM SomeReport OBJECT oMERE NODIALOG
m.oMERE = CREATEOBJECT('MERE_ReportListener',oRPT,.T.)
oMERE.lDoNotShow = .T.

05/15/2008

Enhanced and made corrections to the SMTP Email Support (PRO Version)

· Added a new property to better support sending HTML emails via SMTP by adding an EMAILBodyHTML property. The EMAILBodyHTML property can be used to specify the HTML content for an HTML email separate from the Plain Text portion of the email. Set the EMAILBody property to the text you wish to display as the Plain Text portion of the email.
· Made improvements to the SendMail() method so that attachments show up as attachments when sending HTML SMTP emails instead of having them embedded into the email itself. So, you can now send HTML Emails using the SendMail() method with attachments.
· Fixed an issue in the SMTP portion of the SendMail() method that was not using the EMAILSMTPPort value set via the property for sending the EMAIL causing it to fail if you were using a non-standard port number.

04/27/2008

MERE Lite PDF Rendering Engine released.

The MERE Lite PDF Rendering Engine is a lightweight version of the MERE Report Engine Professional. It only outputs PDF documents using a subset of the rendering methods that the Professional version supports such as AddText(), AddLine(), AddShape(), AddPicture(), NewPage. The Lite version does not have any User Interface and therefore does not support previewing reports. The reports must be rendered to a PDF document for review.

Features | LITE | PRO
Save to PDF | ü | ü
AddText() Method | ü | ü
AddShape() Method | ü | ü
AddPicture() Method | ü | ü
AddLine() Method | ü | ü
Compress PDF | ü | ü
SaveToPDF() Method | ü | ü
PDFStream() Method | ü | ü
AddChart() Method |  | ü
AddBarcode() Method |  | ü
AddFromClipboard() Method |  | ü
AddWordDocument() Method |  | ü
CopyPageToClipboard() Method |  | ü
SaveToBitmap() Method |  | ü
SaveToJPEG() Method |  | ü
SaveToMetafile() Method |  | ü
SaveToPNG() Method |  | ü
SaveToTIFF() Method |  | ü
SaveToWord() Method |  | ü
SendMail() Method (SMTP or MAPI) |  | ü
GUI Interface |  | ü
PrintReport() Method |  | ü
Print Report from User Interface |  | ü
Print Preview / Display Report |  | ü

Fixed issue with OLE Error when calling AddText() Method and PRINTER FONTS

· Fixed an issue causing OLE Errors when PRINTER FONTS were used when calling the AddText() Method. Found that GDI+'s MeasureString() function does not support PRINTER FONTS. Who would have thought!

05/31/2005

Added Save As Image support from the MERE Toolbar allowing end user saving of report pages while previewing a report without additional coding.

· The Current Page, All Report Pages or a Range of Report Pages can be saved to BMP, EMF, GIF, JPEG, PNG and TIFF from the MERE Preview Toolbar. The Current Page is the page displayed in the Preview. The page in the preview can be changed by moving the scrollbar position.
· Multi-Page TIFF is now supported both from the Save As Image Dialog and from the SaveToTIFF() Method.
· Multiple page Save As Image will render each page to a separate file and autonames each image file by adding "-00X" to the base file name for individual pages where X matches the physical page number within the report. The page number is padded with leading zeroes and the padding size is based upon the page count within the report engine.
· Saving Pages as Images can be scaled to 400% from the Save As Image Dialog. Some file outputs will not be fully scaleable to 400% and may generate an error due to memory requirements. Therefore scale down to say 300% and try again.

Save As Image Dialog

Added Page Previews to the Print Dialog, Save To PDF Dialog and Save As Image Dialog Forms.

You can now quickly preview all of the pages in an entire report while preparing to Print, Save as a PDF or Save as Image.

Save To PDF Dialog

Print Report Dialog

MERE_ReportListener.VCX Updated

Modified the MERE_ReportListener Class to detect any Stretch With Overflow Report Expressions on TwoPassProcess reports after finding out that the VFP ReportListener RENDER() Method is passing an Empty String in the cContentsToBeRendered Parameter on the first pass. The optimization code introduced in the previous release was bypassing the 2nd pass of a TwoPassProcess report since the MERE ActiveX control can dynamically render _PAGENO and _PAGETOTAL values with one pass. The modification made can still process reports with one pass when VFP indicates it is a TwoPassProcess report when there aren't any SWO objects in the report. When an SWO object is detected in a TwoPassProcess, the first pass will be ignored and the output is rendered on the 2nd pass now.

05/14/2005

Created an XML Manifest File for the MERE ActiveX Control that supports using the ActiveX control on systems without having to register the control.

The XML Manifest File is now installed into the DOCS folder when the setup is ran. An XML Manifest File can be used to run the ActiveX control on "locked down" systems where the registry cannot be updated due to security restrictions on the system. The XML Manifest File can be used on Windows XP SP1 and Windows 2003 server systems. For more information on the XML Manifest File see the Registering the MERE ActiveX Control section in the Help File.

Updated MERE ActiveX Control and MERE_ReportListener.VCX

Update the MERE ActiveX control to check for Font names being used while rendering a report to see that they were installed on the current system before attempting to use them. Any Fonts that are not found are automatically converted to ARIAL. Previously, this was causing an OLE Exception error when a font in a report was defined that was not on the current system. Also, made changes to the processing of the AddText() method for the handling of RIGHT ALIGNED text that was incorrectly trimming some text during Report Preview.

Updated the MERE_ReportListener Class which exits out of TwoPassProcess reports after the first pass which improves performance since the MERE ActiveX control supports "real time" rendering of _PAGENO and _PAGETOTAL values used in VFP reports. Also eliminated a GO TOP call in the BEFOREREPORT Method that was incorrectly setting the current datasession to the first record.

04/26/2005

Updated MERE_ReportListener.VCX and OCX

Updated the MERE_ReportListener class to add support for most of the Dynamic Property Expressions to support modifying size and colors of Shapes on the fly and other DPE capabilities while running Visual FoxPro reports.

Corrected a Vertical Text Alignment rendering issue in the new MERE OCX when using it with the older MindsEyeReportEngine.VCX Class Library which has most of the VFP Report Writer replacement engine code written in Delphi inside the OCX. The new GDI+ rendering code in the new OCX already handled moving the vertical placement of text to the baseline which was causing the older engine to render text vertically down by the height of the font.

Updated the MindsEyeReportEngineTestForm.SCX to support switching between running the new MERE_ReportListener Class and the older MindsEyeReportEngine Class when using Visual FoxPro 9 to make it easy to compare the new rendering engine and the old rendering engine and help in making improvements to the older rendering engine to match the native Visual FoxPro Report Writer Engine.

04/22/2005

MERE_ReportListener Class released for Visual FoxPro 9

Released the MERE_ReportListener Class for processing Visual FoxPro Reports using the Visual FoxPro 9 object-assisted report engine based on the Visual FoxPro 9 ReportListener baseclass. Visual FoxPro 9 report processing speed using the MERE_ReportListener in combination with the Mind's Eye Report Engine ActiveX control is nearly as fast and sometimes faster than using the native Visual FoxPro 9 Report Preview Engine. Additionally, using the MERE ActiveX control allows for Page Numbers to be properly displayed in real time as multiple reports are appended/chained to create a single report without requiring any modifications to your Visual FoxPro reports.

12/16/2004

Support for VFP 5.0 Added

Modifications to the MindsEyeReportEngine Class Library was made to allow for compiling and use with VFP 5.0. Runtime compile is not supported under VFP 5.0, therefore execution of code stored within the DataEnvironment of an FRX is not supported.

12/07/2004

Dynamic PaperBin Expression Support for VFP FRX Reports Added

Now the PaperBin for each page of a report can be set while rendering VFP FRX reports using the new PAPERBIN Dynamic Property Expression. VFP functions can be used to dynamically set the PaperBin property of each page in the report. For more information see the VFP Dynamic Report Object Properties Expression Support Topic.

11/19/2004

Improved Text Search

The Text Search has been improved to support Find Next and Find Previous as well as Highlighting all occurrences. The new Find Text uses a toolbar to place the Find text box and search buttons when the Find Button is pressed on the main toolbar. The Find Next and Find Previous automatically scrolls the page so that the text found is within the viewable area of the preview.

PDF Font Embedding Support Added

True Type fonts that allow embedding can now be embedded into PDF documents. See the PDFFontMetric Method to embed individual fonts.

New Properties Added

· DisplayFindToolbar - Used to Hide or Show the Find Toolbar in the Preview window for use with the new Text Search.
· DisplayPopupMenu - Used to control the display of the Popup Menu of the Report Preview window.
· EMAILSMTPHostDisplayStyle - Used to control whether the SMTP HOST field on the Email Dialog box is set to Edit, Read Only or Hidden when EMAILMessagingType = 0.
· EMAILFromDisplayStyle - Used to control whether the FROM field on the Email Dialog box is set to Edit, Read Only or Hidden when EMAILMessagingType = 0.
· PDFFontCount - Indicates the number of unique Fonts that will be used when creating a PDF document containing all pages in the report. This is a Read Only property and can be used in conjunction with the new PDFFontMetric Method to set or read Embedded Font settings.
· PrintDuplex - Used to Enable or Disable Duplex printing. This flag controls the preset of the Duplex check box on the Print Dialog as well.

New Methods Added

· DeletePage Method to support programmatically deleting pages from the current report. A single page or a range of pages can be deleted. If all pages are deleted, then the report is cleared and a single page will be displayed.
· PDFFontMetric Method can be used to read the names of the unique PDF Fonts in the current report or to Set or Read the Embedded Font Settings for each font that will be generated when creating a PDF document.

08/25/2004

Updated Printing Support

Printing support has been changed to support using a printer driver's Multiple Copy support if the printer supports printing multiple copies rather than printing multiple copies in an internal loop by MERE. This change was made to help speed up performance on printer's that use RIP Engines to generate output such as copiers/printers where ripping a single page can take a minute or more. A Property may be added in the future to override the printer driver's multi-copy support and use the original MERE method for printing multiple copies. The original method was written to support printing multiple copies where the printer driver did not support multiple copies by itself.

Improvements made to VFP WHITE SPACE Rendering

Improvements were made to more closely match the "white space" between detail bands where PRINT WHEN and REMOVE LINE IF BLANK options were set while rendering VFP Reports. Sometimes, MERE would not produce as large of a "white space" between bands.

AddText Method now supports Translucent Text

The AddText Method now accepts a negative value for the NBACKSTYLE Parameter and will then render the text in the PREVIEW and while PRINTING with a translucent mapping. PDF output has not been enhanced yet to support the translucent coloring.

BUG Fixes

· Fixed a problem with rendering PDF documents when an image file specified on a page was not found on disk would cause an OLE EXCEPTION. The missing image file is now ignored the same as it is in the PREVIEW and PRINTING methods.
· Fixes where made in the OCX which corrected an issue with the original 2.0 release of MERE that caused objects using a PRINT WHEN clause to print although it was flagged to not print using the PRINT WHEN Expression.
· Improvements were made to more closely match the "white space" between detail bands where PRINT WHEN and REMOVE LINE IF BLANK options were set while rendering VFP Reports. Sometimes, MERE would not produce as large of a "white space" between bands.

07/28/2004

Added Support for embedding Hyperlinks into PDF Documents

PDF Hyperlink support has been added to the Dynamic Property Expression Engine. This allows a DPE directive to embed a Hyperlink into a PDF document whenever the PDF Document is rendered by the Report Engine. The HYPERLINK information is stored in the Report Engine Object during the rendering of a Visual FoxPro Report. See the Dynamic Report Object Property Expression Details for more information.

06/09/2004

New PDFStream Method for returning a PDF Document as a String

The new PDFStream Method can be used render PDF Documents to memory without having any files being written to disk that would require subsequent cleanup. Thus, the new PDFStream Method can be used to easily send a PDF Document to a web server in a Response.Write() Command from in COM Object or it can be used to easily copy a PDF document into a Memo Field in a Visual FoxPro Table.

04/22/2004

New Dynamic Report Object Property Expression Support for Visual FoxPro Reports

Dynamic Property Expressions (DPE) can be used to override Static VFP FRX Report Object Properties set at Design Time as a Report is rendered using the Mind's Eye Report Engine by simply entering Dynamic Property Expressions for Report Objects using Visual FoxPro Expressions. This makes it very easy to change Font Colors, Font Styles, Shape Colors, Widths and more on an FRX Report at runtime according to the values returned by the DPEs.

Dynamic Report Object Property Expression Details

Use the MindsEyeReportTestSuite.APP to run the following example reports using the Test Mind's Eye Engine button on the Test Suite Form and then selecting one of the two examples located in the REPORTS folder during the install:

Dynamic Font and Shape Property Expression Example.FRX

Dynamic Shape Width Property Expression Example.FRX

Dynamic Shape Width Property Expression Screen Shot

Chart Engine Enhancements

More Properties were added to the control enhancing the Chart Engine even further. It is now possible to turn the 3-D effect On or Off as well as the Depth of the 3-D effect as well as being able to turn off the axes on the chart. For more information look at the Chart Engine Properties.

04/05/2004

EMAIL Now supports Sending Multiple File Attachments

EMAIL now supports sending multiple attachments while using the SendMail Method using the new EMAILAddAttachment Method and the new EMAILAttachmentCount Property to see how many attachments are currently assigned. Setting the EMAILAttachmentCount Property to Zero will clear all attachments.

03/28/2004

Added MindsEyeReportTestSuite.APP

The MindsEyeReportTestSuite.APP has been added to the install and can also be downloaded separately to help test out Visual FoxPro FRX Reports using the Mind's Eye Report Engine as well as provide a little analysis of the FRX and allow you to Browse an FRX while running or modifying an FRX report. The MindsEyeReportTestSuite is a single Form that can run in the VFP IDE while working with and testing reports. Suggestions for additional features is always welcome. In order to run VFP Reports using the test suite, you must either have the tables already open or you must have code in the DataEnvironment's INIT to generate cursors on the fly or to open tables. Otherwise, you will receive a TABLE NOT OPEN error. When you test a VFP report and the Auto Analyze and Browse Before Running option is checked, the FRX will be copied into a separate cursor for browsing in the BROWSE Tab and the Analysis will generate a text report of some of the Properties of the FRX Report for review.

This tool is also helpful, in providing a basic idea of some of the Properties and capabilities of the Mind's Eye Report Engine ActiveX control from a programmatic use, independently of running Visual FoxPro FRX reports. There are several programmatic examples on the DEMOS tab of the form.

The Mind's Eye Report Test Suite makes it easy to check for updates on the website by clicking on the Check For Updates link on the lower right corner of the Form if you have a current internet connection without sending any information to the website.

MindsEyeReportTestSuite App Screen Shot

ACTIVEX REPORT ENGINE ENHANCEMENTS

Report Engine Preview Enhancements

· Added Up and Down Arrow Key press support to the Page Number field on the Toolbar to change pages. By pressing the Up or Down Arrow Keys will move to the previous or next page in the Report. Holding down the SHIFT, CTRL or SHIFT+CTRL while pressing the arrow keys will cause the page change to occur in increments of 5, 10 or 25 pages at a time instead of a single page for rapid movement through a report.
· Improvements to the User Interface
· Added new Popup Menu over the Toolbar to support choosing Toolbar Display Style, Language and Unit of Measure at runtime.
· Bitmaps on Toolbar are now properly displayed with transparent colors.
· Toolbar shows background color properly in VFP 8
· Added DisplayToolbarStyle Property to support switching the toolbar icons between Standard or New Style icons.
· Added DisplayUnitOfMeasure Property to support changing the Units of Measure used to display the Page Size.
· Added the AddToolbarButton Method to support adding Custom Toolbar buttons programmatically at runtime.

Printing Engine Enhancements

· Rendered Report Memory Usage Reduced by over 30% per object.
· Print To File capability has been added for generating printed output to a File. This allows a print job to be printed to a file to be printed at a later time to the printer specified at the time of the print job. For example, a document can be printed to a generic Postscript Printer Driver with the output sent to a File rather than directly to the printer. This file can then be emailed or copied to another system where it can then be copied to the printer port where the printer is located. See the PrintReport Method detailing the new cFilename Parameter.
· The PrinterID Property and SetPrinterTo() Method now accept both Printer Names and Numbers. So, the printer can be specified using either a number such as 1, 2, 3, etc. or using a name such as 'HP 720C' or '//SERVER/HP LASERJET 4'.
· The PrinterID Property and SetPrinterTo() Method now accept -1 as a value which will select the Default Printer for the Report Engine.
· Added PrintShrinkToFit Property to support the ability to shrink any page size to the page size being printed to.
· Added a PaperBin Property which allows for assigning each report page to print from a different paper bin.
· Added PrinterAddForm and PrinterDeleteForm Methods to support Adding and Deleting CUSTOM FORM sizes in Windows NT/2K/XP.
· Added the ability to display the Printable area of the page in the Report Engine Preview. When PrintShrinkToFit is set to TRUE, report pages will automatically be scaled to print within the Printable area of the page regardless of paper size.
· Solved problem with some printer drivers that were causing the Report Engine to error. This problem was found to be in the Delphi TPrinter Class caching Printer Device Handles.
· Now supports Duplex printing of Documents.

PDF Export Engine Enhancements

· PDFXOffset and PDFYOffset Properties added to for adjusting position of report pages when saved to a PDF Document.

Report Generation Enhancements

· Insert Report Pages feature added to support inserting pages into a report ahead of existing pages. This feature was used to help support inserting an entire FRX Report into the current report. This allows for things like adding a Table of Contents to a report after rendering a report or several reports into the Report Engine.
· Added a SETALL Method to support quickly assigning some Report Engine Properties to all or a range of pages that are page specific such as the WatermarkText or WatermarkRotation Properties.

Report Export Enhancements

· Added SaveToWord Method which uses OLE Automation to export a Report to a Word Document as a Enhanced Metafile images.
· Added the ability to Save Report Pages to Image files as JPEG, BMP, PNG, TIFF and METAFILE images.

VISUAL FOXPRO REPORT RENDERING IMPROVEMENTS AND ENHANCEMENTS

· Refactored Visual FoxPro Class library which greatly improved speed another 5 to 10 fold over what was already fast in comparison to other VFP 3rd Party Report Engines
· Stretch With Overflow and Float algorithms have been greatly improved to more closely render Visual FoxPro reports
· Remove Line If Blank algorithms have been improved for both speed and accuracy.
· Added NBOTTOMMARGIN Property to the VCX to control rendering height of pages.


Report Engine Screen Shot

The following is a screen shot of the Mind's Eye Report Engine control being hosted in a Visual FoxPro Form.


Quick Start to Using the Report Engine Control

The Mind's Eye Report Engine Control can be placed onto a Visual FoxPro Form or Container or placed onto a .NET Form as to easily generate reports programmatically and then print them, save them to PDF documents or email them as PDF documents in your application. The Report Engine Control was orginally written to get around the limitations encountered with the Visual FoxPro Report Writer that would allow objects to easily be placed onto report pages at runtime anywhere or anytime programmatically rather than having to jump through hoops and performing all kinds of tricks to make the Visual FoxPro Report Writer do what we wanted. After several thousand hours of writing code to emulate the Visual FoxPro Report Writer and run Visual FoxPro FRX Reports using Visual FoxPro 8 and below without change, Microsoft introduced Visual FoxPro 9's object-assisted report engine which allows MERE to really shine when running Visual FoxPro Reports. More than 15,000 lines of Delphi code are no longer used in the MERE ActiveX control when running reports using the MERE_ReportListener in Visual FoxPro 9. Additionally, the entire MindsEyeReportEngine.VCX Class library is no longer needed as well which was at least a couple of thousand lines of VFP code or more.

To state it mildly, Visual FoxPro 9 now has an awesome report engine that allow 3rd party tools like MERE do what they do best and not have to worry about how or where report objects are rendered by Visual FoxPro with all of its "features". With less than a few hundred lines of code in a ReportListener class, the Mind's Eye Report Engine is able to render reports nearly as fast as the native Visual FoxPro engine and at the same time work around some of the issues that are still found in the latest native Visual FoxPro Report Engine with ease such as Page Numbering and switching Paper Trays on the fly while printing reports.

Most of the examples under this topic simply instantiate an instance of the MindsEyeReportPreviewForm and then generate reports programmatically using Visual FoxPro. The same type of programmatic reporting can easily be done using JavaScript or .NET with the MERE ActiveX control placed on a web page or on a .NET form.

Quick Start to Running Visual FoxPro Reports using the Mind's Eye Report Engine

With the release of Visual FoxPro 9, usage of the Mind's Eye Report Engine (MERE) with Visual FoxPro has changed significantly for the better. There is much less VFP code to maintain and debug and running reports using the MERE ReportListener are rendered almost as fast as native VFP and will usually render faster than native VFP when images are included in your reports.

Depending on the version of Visual FoxPro you intend to use, please refer to the appropriate section of the Help File for specific examples for use with the particular version of Visual FoxPro.

Visual FoxPro 9

Visual FoxPro 8 and Below

Mind's Eye Report Engine Testing Tool

You will find the MindsEyeReportEngineTestForm.SCX Form file installed into the FORMS subfolder of the folder in which you installed the Minds Eye Report Engine files. This Visual FoxPro FORM is a very handy tool and will even show off some of the capabilities of the Mind's Eye Report Engine. The easiest way to see a Demo of the MERE control is to click on the DEMOS Tab and then click on some of the Demo Buttons on the left side of the form. For more information please refer to the Mind's Eye Report Engine Testing Tool section of the Help File. Below is the main tab of the Testing Tool Form.

Minds Eye Report Engine Testing Tool Screen Shot

Minds Eye Report Engine Testing Tool Demos Tab Screen Shot


Mind's Eye Report Engine Testing Tool

The Mind's Eye Report Engine Testing Tool can be ran from the Visual FoxPro Command Window anytime. It is a great tool for learning more about your report's FRX structure as well as a place to demo the MERE product.

Launching the Mind's Eye Report Engine Testing Tool from the Command Window. If your path or current directory is the MindsEyeReportEngine, you can type the following command into the VFP Command Window:

DO FORM FORMS\MindsEyeReportTestTool.SCX

The MERE Testing Tool should display and look similar to the screen shot shown below.

Report Engine Options Tab

The Report Engine Options tab has several options for configuring how the Testing Tool functions. Some of the options at the top of the tab allow for selecting which Visual FoxPro REPORTBEHAVIOR to use when calling the Native VFP Report Engine. It also allows for selecting between the new MERE PRO 4.0 Version and the MERE PRO 3.0 version of the control when launching the Report Preview Form or Testing the Mind's Eye Engine. There is also a checkbox to allow for testing using the older MindsEyeReportEngine.VCX Class Library which is dated and should only be used with Visual FoxPro 8.0 and below. It is highly suggested that you upgrade to Visual FoxPro 9.0 and use the newer MERE_ReportListener Class to run VFP Reports. It is much Faster and Renders more accurately than the older MindsEyeReportEngine Class.

Minds Eye Report Engine Testing Tool Screen Shot

Demos Tab

The Demos tab contains buttons that will quickly run code that demonstrates the various features of using the Mind's Eye Report Engine. Click on the buttons displayed on the left side of the form to run the demos as defined on the buttons. The Chart Demo allows for clicking on the button several times and it will automatically add another page with another chart type drawn when it is clicked on to the current report. When a chart is displayed on the MERE ActiveX control in the Demo Form, you can click on the various settings under the Chart Properties section to dynamically change the chart on the current page in the MERE Preview Form.

Minds Eye Report Engine Testing Tool Demos Tab Screen Shot

Report Analysis Results Tab

The Report Analysis Results tab contains an analysis of the most recent loaded and/or ran FRX report and displays it in an informational Edit Box. You may find this information helpful when debugging issues with a report.

Minds Eye Report Engine Testing Tool Report Analysis Tab

Browse Report Tab

The Browse Report tab contains a cursor copy of the most recently loaded and/or ran FRX report. Using the Drop Down List box on this tab, you can filter the various records by data type within the report to help debug issues with a report and or study the field values.

Minds Eye Report Engine Testing Tool Browse Report Tab


Manifest File for MERE ActiveX Control

Registering the MERE ActiveX Control and Manifest File Alternative Method

 Top Previous Next

In order to use the Mind's Eye Report Engine ActiveX control on your system for development or in a distributed application, it must first be registered like any other ActiveX control unless you are using Windows XP SP1 or Server 2003 and above with an associated XML Manifest File.

Using the MERE ActiveX Control without Registering the Control

In Windows XP SP1 and Server 2003 and above, you can use a manifest file that allows the use of COM objects with your application without creating any entries in the system registry, which may be the case where IT departments have the user's systems "locked down" so to speak. Using an XML Manifest File, allows you to use a specific copy of an OCX or DLL for your application on a system that has multiple copies of the same OCX or DLL file. The manifest file contains the registration data that would normally reside in the system registry that are used to locate and run the associated OCX or DLL program. This method also helps resolve "DLL HELL" situations that might occur when another application installs a newer or older version of the same OCX or DLL file on the same system.

In order to use an XML Manifest File, you must name the manifest file the same name as your client application with the addition of .manifest after the name. The manifest file must then be placed into the same folder as your application. Then when your application is loaded the OS will look for a manifest file in the same folder and if it is found it will be used to load any instances of DLL or OCX programs named in the manifest file. Example application and associated manifest filenames are shown below:

Application Filename: MyApplication.exe

Application Manifest Filename: MyApplication.exe.manifest

Below is the XML text that must be in the manifest file for properly using the MERE ActiveX control with your application or development environment. Once you have the text in the manifest file save the text file with the naming convention described above into the same folder as your application or development tool and also place a copy of the MERE ActiveX control file into the same folder to load and run the control without registering the control in the system's registry. Please note the subtle differences in the CLSID in the document. The CLSID value is a GUID which is generated when the control is created. This must be correct for the correct control or it will not work.

Manifest File for the MERE Version 4.X ActiveX Control

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<file name="MindsEyeReportEnginePro4.ocx">

<comClass description="Mind's Eye Report Engine ActiveX Control"

clsid="{39EF81FF-7DE3-4C46-8E62-DEAA2FEF7CF4}"

progid="MEREPro4.MEREPRO"

threadingModel="apartment" />

</file>

</assembly>

Manifest File for the MERE Version 3.X ActiveX Control

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<file name="MindsEyeReportEnginePro1.ocx">

<comClass description="Mind's Eye Report Engine ActiveX Control"

clsid="{7FEC6DA5-DA92-4F95-9F7E-0CAB77F61DC4}"

progid="MindsEyeReportEnginePro1.MindsEyeReportEnginePro"

threadingModel="apartment" />

</file>

</assembly>

Manifest File for the MERE LITE Version ActiveX Control

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<file name="MERELite1.ocx">

<comClass description="Mind's Eye Report Engine ActiveX Control"

clsid="{F173298F-4587-42EC-91FE-18327A456C2D}"

progid="MERELite1.MERELite"

threadingModel="apartment" />

</file>

</assembly>

Registering the MERE ActiveX control using REGSVR32

The MindsEyeReportEngineSetup.EXE program should have registered the control on your system during installation. However, if the control is not loading properly, you can manually register the control using the REGSVR32 program from the command line supplied with your operating system. The same is registration is required when distributing your application unless you use the Manifest File method described above. When an ActiveX control is registered, an entry is made into the System Registry using the control's name and GUID. When an ActiveX control is instantiated in an application or in a development environment, the name of the control is located in the registry and then the associated file name used by the control is read from the registry. If you own a developer's license for the Mind's Eye Report Engine, you must make sure that your License File is located in the same folder as the registered MindsEyeReportEnginePro1.OCX file on your system before embedding your license.

If you are having trouble with using the control, make sure that there are not multiple copies of the control on your system and make sure that the latest version is the registered version of the control.

An Example Registering the control using REGSVR32:

REGSVR32 C:\MindsEyeReportEngine\MindsEyeReportEnginePro1.OCX

See Also:


Demonstration of Report Engine Speed

Report Engine Object Speed

The following example demonstrates using the Mind's Eye Report Engine without using an FRX Report. This example adds 1000 pages into the Report Engine using the NewPageByPaperSize() Method and sets the WatermarkText and WatermarkRotationAngle Properties for each of those pages. Then after it has created the 1000 pages and set the Watermark Properties, it uses the GoToPage() Method to display all of the pages in the Report Engine.

SET CLASSLIB TO MEREPro4PreviewForms && MindsEyeReportPreviewForms (if using the MERE Version 3.x OCX)

PUBLIC oRPT

oRPT = CREATEOBJECT('MindsEyeReportPreviewForm')

FOR i = 1 TO 999

WITH oRPT.oReportEngine

.WatermarkText = 'Draft Copy'

.WatermarkRotationAngle = i

.NewPageByPaperSize(1)

ENDWITH

ENDFOR

oRPT.oReportEngine.WatermarkText = 'Draft Copy'

oRPT.SHOW()

* Now just for fun demonstrate that each page actually has it's own Watermark Properties

FOR i = 1 TO oRPT.oReportEngine.nTotalPages

oRPT.oReportEngine.GotoPage(i)

ENDFOR

See Also:


Placing Charts into a Report

Placing Charts into the Report Engine

The Mind's Eye Report Engine has a built in Charting Engine, so that charts can be added to your reports to be printed or saved to PDF files. The following example demonstrates how to programmatically generate a Chart within the Report Engine using the AddChart Method and the other Chart related Methods and Properties to give you total control over your Charts.

SET CLASSLIB TO MEREPro4PreviewForms && MindsEyeReportPreviewForms (if using the MERE Version 3.x OCX)

PUBLIC oRPT

oRPT = CREATEOBJECT('mindseyereportpreviewform')

oRPT.Top = 10

oRPT.Left = 20

oRPT.Width = 600

oRPT.Height = 800

WITH oRPT.oReportEngine

.AddChart('',1,1,1,6,5)

.ChartSeriesTitle = 'Portfolio 1'

.ChartSeriesColor = 16744576

.ChartAddXYData(4.8,0,'Sep 02',16744576)

.ChartAddXYData(4.1,0,'Dec 02',16744576)

.ChartAddXYData(3.8,0,'Mar 03',16744576)

.ChartAddXYData(3.4,0,'Jun 03',16744576)

.ChartAddSeries(1,'Portfolio 2',4194432)

.ChartAddXYData(4.2,0,'Sep 02',4194432)

.ChartAddXYData(3.8,0,'Dec 02',4194432)

.ChartAddXYData(3.5,0,'Mar 03',4194432)

.ChartAddXYData(3.1,0,'Jun 03',4194432)

.ChartAddSeries(1,'Portfolio 3',14089977)

.ChartAddXYData(3.6,0,'Sep 02',14089977)

.ChartAddXYData(3.2,0,'Dec 02',14089977)

.ChartAddXYData(2.7,0,'Mar 03',14089977)

.ChartAddXYData(2.5,0,'Jun 03',14089977)

.ChartTitle = 'Portfolio VS Benchmark'

.ChartXAxisTitle = 'Period'

.ChartXAxisFontSize = 16

.ChartYAxisTitle = 'Return'

.ChartYAxisFontSize = 16

.ChartSeriesMarksVisible = .f.

ENDWITH

oRPT.Show()

See Also:

AddChart | ChartAddXYData | ChartAddSeries | ChartSelect | Chart Properties

Example Code to Create Charts


Displaying Real Time Page X of Y

The following example demonstrates how the "Real Time" Page X of Y processing is done. It also demonstrates how to use the SetPageNumberToOne Method.

The following example will instantiate an instance of the Report Engine and then add 100 pages to the Report Engine along with some Report Field Objects using the AddReportField Method. It also uses the SetPageNumberToOne Method to reset the page number on the 10th page throughout the report. After running the example below you will be able to see the text output in the lower right corner of each page with the resulting Page X of Y information being displayed with the virtual page number being reset to one.

SET CLASSLIB TO MEREPro4PreviewForms && MindsEyeReportPreviewForms (if using the MERE Version 3.x OCX)

PUBLIC oRPT

oRPT = CREATEOBJECT('MindsEyeReportPreviewForm')

nHPos = 6

nVPos = 10

lcReportFieldExpr = ['Page: '+ALLTRIM(STR(_PAGENO))+' of '+ALLTRIM(STR(_PAGETOTAL))]

FOR i = 1 TO 100

WITH oRPT.oReportEngine

.AddReportField('',lcReportFieldExpr,nHPos,nVPos,0,0,'','','Arial',14)

.NewPageByPaperSize(1)

IF MOD(i,10) = 0 THEN

.SetPageNumberToOne(i)

ENDIF

ENDWITH

ENDFOR

oRPT.oReportEngine.AddReportField('',lcReportFieldExpr,nHPos,nVPos,0,0,'','','Arial',14)

oRPT.SHOW()

oRPT.oReportEngine.FirstPage()

See Also:


Printing Reports To a File

Reports can be printed to a Printer Output File by using the PrintReport Method which supports an optional parameter the name of a file to print to.

When the PrintReport Method is called using the optional filename, the Report Engine will create an output file using the printer driver of the passed printer by name or number or the default printer if none is specified. The resulting output file will contain all of the printer commands that would have normally been sent to the printer. This file can then be copied directly to a printer to print the report from the file at a later time.

One area where this is useful is in generating Postscript Files that are to be later processed by a postscript distiller tool or postscript converter. You can download and install a Generic Postscript Printer Driver for Windows from the Adobe website:

http://www.adobe.com

For Example:

SET CLASSLIB TO MEREPro4PreviewForms && MindsEyeReportPreviewForms (if using the MERE Version 3.x OCX)

PUBLIC oRPT

oRPT = CREATEOBJECT('MindsEyeReportPreviewForm')

WITH oRPT.oReportEngine

.WatermarkText = 'LOWER TRAY'

.PAPERBIN = 2 && DMBIN_LOWER

.NewPageByPaperSize(1)

.WatermarkText = 'DEFAULT TRAY'

.NewPageByPaperSize(1)

.WatermarkText = 'MANUAL FEED'

.PAPERBIN = 4 && DMBIN_MANUAL

.FirstPage()

.PrintPromptForPrint = .F. && Turn off Prompt for a Printer Dialog

ENDWITH

oRPT.SHOW()

* Now call the PrintReport Method to print the pages using the

* Postscript Printer driver to a File

oRPT.oReportEngine.PrintReport('Generic Postscript Printer',1,3,0,'Postscript Printout File.ps')

See Also:

PrintReport


Specifying the Paper Bin for Report Pages

Specifying the Printer Tray for Individual Pages

Each page in the Report Engine can be pulled from a different tray automatically while printing by assigning the PAPERBIN Property to a specific bin number. The PAPERBIN values are the same as those described in the WINDOWS.H Header File. The following example demonstrates how to assign the Printer Tray for each individual page in a Report using the PAPERBIN Property. Please note that not all printers support all of the values since each printer may not have all the trays that can possibly be specified by the values below. However, you can loop through the pages in the report engine and assign the PAPERBIN property for each and every page. For example, if you wanted the first page to be printed onto Letterhead that is placed in the LOWER TRAY, then set the PAPERBIN Property to 2 for the first page in the report engine. All other PAPERBIN values will be set to 0 and will be pulled from the AUTO tray unless specified otherwise.

NOTE:

As of 12/17/2004, support has been added to the Dynamic Property Expression evaluations to allow for the PaperBin value to be modified during rendering of a VFP FRX report. By placing the PAPERBIN Keyword into the DPE expression of the COMMENT field for a report, the VFP expression will be evaluated and used to set the PAPERBIN Property for the page currently being rendered. The DPE expression can be placed anywhere on the report page other than the TITLE and SUMMARY BANDS as they only print once per report.

DMBIN_UPPER = 1

DMBIN_FIRST = DMBIN_UPPER

DMBIN_ONLYONE = 1

DMBIN_LOWER = 2

DMBIN_MIDDLE = 3

DMBIN_MANUAL = 4

DMBIN_ENVELOPE = 5

DMBIN_ENVMANUAL = 6

DMBIN_AUTO = 7

DMBIN_TRACTOR = 8

DMBIN_SMALLFMT = 9

DMBIN_LARGEFMT = 10

DMBIN_LARGECAPACITY = 11

DMBIN_CASSETTE = 14

DMBIN_LAST = DMBIN_CASSETTE

DMBIN_USER = 256 (Values that are 256 and above are User Defined and vary by printer)

SET CLASSLIB TO MEREPro4PreviewForms && MindsEyeReportPreviewForms (if using the MERE Version 3.x OCX)

PUBLIC oRPT

oRPT = CREATEOBJECT('MindsEyeReportPreviewForm')

WITH oRPT.oReportEngine

.WatermarkText = 'LOWER TRAY'

.PAPERBIN = 2 && DMBIN_LOWER

.NewPageByPaperSize(1)

.WatermarkText = 'DEFAULT TRAY'

.NewPageByPaperSize(1)

.WatermarkText = 'MANUAL FEED'

.PAPERBIN = 4 && DMBIN_MANUAL

.FirstPage()

ENDWITH

oRPT.SHOW()

* Now call the PrintReport Method to print the pages.

oRPT.oReportEngine.PrintReport()

See Also:


Pasting Images or Clipboard Objects onto a Report Page

Using the Clipboard Support in MERE, you can easily add an Image or a Clipboard object such as a paragraph from a document or a piece of a spreadsheet as an Enhanced Metafile object onto a Report Page at Runtime both interactively or programmatically.

Possible Uses

· Quickly generate a Photo Collage and email it as a PDF
· Quickly send a chunk of a spreadsheet as a PDF document that is not changeable to a colleague for review.

Steps to paste an Image onto a Report Page:

SET CLASSLIB TO MEREPro4PreviewForms && MindsEyeReportPreviewForms (if using the MERE Version 3.x OCX)

PUBLIC oRPT

oRPT = CREATEOBJECT('mindseyereportpreviewform')

oRPT.SHOW()

1. Run the code above from the Command Window in Visual FoxPro
2. Now open up your web browser and navigate to a page with a photo on the page and right click over the image and select COPY from the menu.
3. Now switch back to the Visual FoxPro and move the mouse over the Mind's Eye Report Engine report page in the MindsEyeReportPreviewForm and hold down the SHIFT, CTRL or SHIFT+CTRL key while dragging your mouse to draw a bounding box for placing the image onto the report page and then release the mouse.
4. The image will now be placed onto the current page as an object where you drew the bounding box.

You can use the same technique to paste in selected text from a word processing document or a chart from an spreadsheet. All objects that are placed onto the report page are stored in a temporary EMF file on disk until the ActiveX control is released. MERE keeps track of each unique file name as it adds new objects onto report pages. The objects will scale with the page since they are Enhanced Metafile objects.

NOTES:

Holding down the SHIFT key while dragging the mouse will ensure that the image maintains it's aspect ratio. Holding down the CTRL key while dragging the mouse will allow the image to size to the bounding box and disregards it's aspect ratio.

See Also:


Installing Your License Key

ActiveX control licensing implementation varies between development environments and therefore requires different methods of installing or using your license file. In Visual FoxPro, ActiveX license files are embedded into a Form, Form Class or Container Class whenever an ActiveX control is placed on the Form or Container. Therefore, in order to distribute an application in Visual FoxPro using the Mind's Eye Report Engine ActiveX control, you must first remove the MERE ActiveX control from the MindsEyeReportPreviewForm Form Class and then add the ActiveX control back onto the Form Class. You must do this once your license file has been copied into the same folder where the MERE ActiveX control is registered. If the LIC file cannot be found, the copy protection watermark will still appear on the ActiveX control.

Steps to Installing Your License in Visual FoxPro

Adding the MERE ActiveX control to the VFP ActiveX Controls.

First, you must add the Mind's Eye Report Engine ActiveX Control to your ActiveX controls in the VFP Controls Tab in the Tools | Options Setup Form. With the release of MERE 4.0, there are now 2 different versions of the ActiveX control and so you can add simply the Version 4.0 control or both of them. Both the Version 4.X and 3.X versions of the control can exist on a single system both development and runtime and will not conflict with each other as they have a unique ClassID and ProgID.

1. Select Tools from the Visual FoxPro System Menu.
2. Select Options from the Tools menu.
3. Select the Controls Tab in the Options form.
4. Click on the ActiveX controls radio button on the Controls Tab.
5. Click on the Add button and then navigate to the folder that contains the MindsEyeReportEnginePro4.OCX or MindsEyeReportEnginePro1.OCX file.
6. Click on the MindsEyeReportEnginePro4.OCX or MindsEyeReportEnginePro1.OCX file to select it and then click OK. This will add the Control to the list of ActiveX controls.
7. Navigate down the list of ActiveX controls until you find the control labeled, Mind's Eye Report Engine Professional and then click on the Check Box to mark the control as active in Visual FoxPro. If you have installed both version 4.0 and 3.X of the control, check both boxes.
8. Click on the Set as Default button at the bottom of the Options form.
9. Close the Options form.

The MERE ActiveX control will now be available on your list of ActiveX controls in the Form Controls Toolbar in Visual FoxPro when ActiveX Controls are selected.

Embedding your developer's license into the MindsEyeReportPreviewForm Form Class.

1. Modify the MindsEyeReportPreviewForm Form Class located in either the MEREPRO4PreviewForms.VCX Class Library if using the MERE 4.X Version of the ActiveX Control or the the MindsEyeReportPreviewForms.VCX Class Library if using the MERE 3.X version of the ActiveX control.
2. Remove the MERE ActiveX Control named oReportEngine from the MindsEyeReportPreviewForm.
3. Save the MindsEyeReportPreviewForm Form Class BEFORE placing the ActiveX Control back on to the Form Class because Visual FoxPro caches the license information and your new license will not embed properly if you added the control before saving.
4. Open the MindsEyeReportPreviewForm Form Class again in order to add the MERE ActiveX Control onto the Form Class.
5. Select the ActiveX Controls on the Form Controls Toolbar and locate the Mind's Eye Report Engine Professional ActiveX Control and then add the control onto the MindsEyeReportPreviewForm Form Class by clicking on the Form Class and drawing a bounding box for the ActiveX Control.
6. The new control will be named OLECONTROL1 and this must be renamed in order for the MindsEyeReportEngine Class to properly locate and use the ActiveX control. The Mind's Eye Report Engine's Methods refer to the MERE ActiveX control on the MindsEyeReportPreviewForm by name and therefore it will not find the control if it has not been renamed.
7. IMPORTANT STEP: Rename the MERE ActiveX Control on the Form Class by selecting the Name Property in the Property Sheet and change it to oReportEngine.
8. Now Save and Close the Form Class.

IMPORTANT NOTE:

Your LIC License file should now be embedded properly in the MindsEyeReportPreviewForm Form Class and the copy protection watermark should now be gone. When building your application, executable or DLL, the license file will be located by Visual FoxPro in the Form Class. Your LIC License file DOES NOT and SHOULD NOT be distributed with your application.

Steps to Using Your License in Visual Basic

Visual Basic does not require that you embed your LIC License file into VB Forms. Visual Basic locates your LIC License file when you compile your application and automatically embeds it into the compiled application. The LIC License file must be in the same folder as the MindsEyeReportEnginePro4.OCX file in order to be found at compile time.

See Also:

Trouble Shooting


Distributing the Report Engine Control with Your Applications

In order to use the Mind's Eye Report Engine control in your applications, you must distribute the MindsEyeReportEnginePro1.OCX file with your application. At this time, the only other file required to be distributed with your application is GDIPLUS.DLL from Microsoft. This is the GDI+ graphics library dll. The Software License Agreement DOES NOT allow you to distribute your MindsEyeReportEnginePro1.LIC file with your applications. The license file is only to be used in a development environment.

Files you MUST distribute with your application:

· The Mind's Eye Report Engine ActiveX Control (MindsEyeReportEnginePro4.OCX or MindsEyeReportEnginePro1.OCX depending on version) - This file should be placed in either the SYSTEM32 folder or in the same folder as your application.
· GDIPLUS.DLL - The Microsoft GDI+ support DLL file. This file is required by the MERE ActiveX control to process graphics and some text. It is required in order to REGISTER the control on the system.

Files you MUST NOT distribute with your application:

· MindsEyeReportEnginePro1.LIC - The Mind's Eye Report Engine ActiveX Control developer's license file. This file is to be used only on the development system and is the file that is used to remove the Demo Watermark from the control. This file is embedded into the VCX or SCX file when using VFP and is not needed when distributing your application. The file is embedded at compile time when using Visual Basic, .NET, Delphi or other development tools.

Visual FoxPro Application Distribution (VERY IMPORTANT)

In order to use the Mind's Eye Report Engine Control in Visual FoxPro without using the MindsEyeReportPreviewForm Form Class, you must first place the control onto a VFP Form or subclass the control by creating a new OLECONTROL class using the control. This will give you the ability to add new methods and place code in the controls Events to respond to them. With VFP 8 or VFP 9, you can use BINDEVENT to make it easier to bind Report Engine Events with your own application code. The reason you cannot use ADDOBJECT() to add the ActiveX control to a Form or Container class at runtime is due to the fact that the ActiveX control requires a license to be embedded into the application. Visual FoxPro embeds your LIC License file into the SCX or VCX during design time that can then be used later at runtime to verify the control and therefore eliminates the need for the LIC file to be shipped with an application.

To distribute the control with your Visual FoxPro application, your developer's license must be properly embedded into an SCX or VCX in order to avoid your end users seeing the Demo Watermark or the About Box. This requires that your License file is properly installed onto your development PC in the same folder that the ActiveX control has been installed before adding the control to a form or creating a class containing the control.

Therefore, in order to use the ReportFormObject Method in your production application, you MUST remove the MindsEyeReportEngine ActiveX control from the MindsEyeReportPreviewForm Form Class contained in the MindsEyeReportPreviewForms Visual Class Library supplied with the control and save the Form Class. Next you must reopen the MindsEyeReportPreviewForm Form Class and then add the MindsEyeReportEngine ActiveX Control back onto the MindsEyeReportPreviewForm Form Class and rename the newly added control from OLECONTROL1 to oReportEngine (it is not case sensitive). Below are the steps to properly embed the control with your developer's license.

Visual Basic Application Distribution

Visual Basic will automatically embed your License file information into your Visual Basic application whenever you Build the application as long as the License file is located in the same folder as the Mind's Eye Report Engine ActiveX Control.


Trouble Shooting

Trouble Shooting Problems using the Mind's Eye Report Engine

Many support issues deal with making sure that the MERE ActiveX control is registered properly on the system. Another issue is making sure that a purchased license file is properly "branded" into the MindsEyeReportPreviewForm Form Class. One other issue that occurs is related to renaming the control to "oReportEngine" on the MindsEyeReportPreviewForm Form Class. The OLECONTROL must be named oReportEngine in order for the VFP Class libraries to properly access and call the Methods of the ActiveX control on the MindsEyeReportPreviewForm when it is instantiated.

First Things to Check

· Make sure that the MindsEyeReportEnginePro4.OCX (Version 4.x) or MindsEyeReportEnginePro1.OCX (Version 3.x) file is registered on the current system.
· Run REGSVR32 to register the MindsEyeReportEnginePro4.OCX (Version 4.x) or MindsEyeReportEnginePro1.OCX.
· Verify that the GDIPLUS.DLL file is installed in the same folder as the MERE ActiveX (OCX) file before attempting to register the control.
· Make sure that you don't have duplicate copies of the ActiveX control on your system that may be of different versions. If you have an older copy of the OCX on your system, it may have an error if running using the latest VFP Class Libraries. So, check to make sure that you are using the most recent MERE ActiveX control. You can always check te Date/Time Stamp or the OCX Version # by right clicking over the OCX file and selecting Properties from Windows Explorer.
· Verify that the MERE ActiveX control has been renamed to "oReportEngine" on the MindsEyeReportPreviewForm Form Class in the MindsEyeReportPreviewForms Class Library.
· There are now 2 separate Form Class for the MindsEyeReportPreviewForm Form class. The new MERE 4.0 ActiveX component should be used with the new MEREPRO4PREVIEWFORMS.VCX Class Library. The older MINDSEYEREPORTPREVIEWFORMS.VCX Class Library should be used with the older MERE 3.X ActiveX component.

Class Not Registered Error

This error occurs when the control cannot be found in the system's registry. The MindsEyeReportEnginePro1.OCX file must be registered on the system that it will be running on prior to being used. You can use REGSVR32.EXE to manually register the control or add the MERE ActiveX control to your list of files to be installed and registered when using 3rd party installation tools such as InnoSetup, InstallShield or Wise Installer.

Other Things to Check

Make sure that your computer has the most up to date Video Drivers installed

· Video drivers can cause your system to crash a graphically intensive program or even hang the system completely. Although, hanging completely is not as much a problem when using Windows 2000/XP and above.
· Reduce the amount of Video Acceleration by changing the settings in the Display Properties Dialog box by using the following steps.
1. Right Click over the Desktop and select Properties from the Popup Menu
2. Then select the Display Settings Tab
3. Then click on the Advanced button in the lower right corner of the dialog box
4. Select the Troubleshoot Tab at the top of the new dialog box
5. Now slide the Hardware Acceleration Settings to the left a notch at a time to see if that resolves the problem.

Make sure that your computer has the most up to date Printer Drivers.

· Printer drivers are known to cause issues with systems that is why it is important to use the latest driver available from your printer manufacturer.


MERE Visual FoxPro Support

The Mind's Eye Report Engine ActiveX Control combined with the supplied Visual FoxPro Class Libraries allows the running of Visual FoxPro FRX reports without changing your FRX Reports. With the release of Visual FoxPro 9, there are now three different Visual FoxPro Class Libraries for running Visual FoxPro FRX Reports. The MERE_ReportListener Class Library is written specifically to work with Visual FoxPro 9's object-assisted reporting based on the Visual FoxPro 9 ReportListener Class. The MindsEyeReportEngine Class Library was written to run Visual FoxPro reports with Visual FoxPro 5 through 8. There are now two different VFP Class Libraries that contain a MindsEyeReportPreviewForm Form class. There is a Class Library for the Version 4.X and another class library for the Version 3.X control. Both versions of the control can exist on the same machine simultaneously and the new updated Mind's Eye Report Engine Test Tool allows for switching between the 2 versions quickly using the Combo Drop Down Box. It is possible to launch a 4.x version and 3.x version of the Report Preview at the same time in the IDE. MindsEyeReportPreviewForms Class Library contains a MindsEyeReportPreviewForm Form Class and a subclass named MindsEyeReportPreviewTopLevelForm used for running reports as a Top Level Form.

Visual FoxPro 9 Report Writer Improvements

Visual FoxPro 9 has a new ReportListener Class which makes rendering VFP reports much SIMPLER and FASTER for MERE. The new ReportListener Class has a Render Event which fires right before rendering an object and which provides location and size information for the object about to be rendered. With this information calculated and provided by Visual FoxPro, MERE no longer has to do all of the calculations to determine what and where objects will be placed onto a page. With the introduction of the ReportListener Class, the MindsEyeReportEngine Class is no longer used and is completely replaced by the new MERE_ReportListener Class which was written to take advantage of this new support using the AddText(), AddShape(), AddPicture(), AddLine(), AddBarcode() and AddReportField() Methods of the MERE ActiveX control.

VFP 9 Performance Improvements

Below is an example of a performance test using MERE in VFP 9 using the current MindsEyeReportEngine Class and the new VFP 9 MERE ReportListener Class as well as the native VFP 9 Report Writer output of a 1000 page report.

Report Engine | Time
MERE MindsEyeReportEngine Class | ~63 seconds
MERE ReportListener Class | ~10 seconds
Native VFP 9 Report Writer | ~8 seconds

Visual FoxPro 9

The MERE_ReportListener Class is the recommended method to run Visual FoxPro Reports in VFP 9. The MERE_ReportListener Class allows MERE to run at near native Visual FoxPro Report Writer Preview speeds (see performance table).

Visual FoxPro 6 through 8

The MindsEyeReportEngine Class Library was designed and tested with VFP 6 SP3 through 8. Therefore, MERE works well with these versions and only a COMPILE CLASSLIB needs to be done on the MindsEyeReportEngine and MindsEyeReportPreviewForms Class Libraries before using MERE in VFP.

Visual FoxPro 5

Support has been added for using MERE with Visual FoxPro 5 using the MindsEyeReportEngine Class. VFP 5 has the limitation of not being able to execute code contained within a Report's DataEnvironment. However, all other functionality with VFP 5 remains the same as Visual FoxPro 6 though 8. In later versions of VFP, the COMPILE and EXECSCRIPT commands are used to execute VFP source code at runtime by the MindsEyeReportEngine Class.


Sample FoxPro Reports

The MindsEyeReportEngineSetup.EXE installation program installs several sample Visual FoxPro FRX reports into the REPORTS subfolder for testing with the MERE_ReportListener Class or the MindsEyeReportEngine.VCX Class Library to demonstrate the performance and features of using the Mind's Eye Report Engine ActiveX control with Visual FoxPro. All of the reports are self running in that they each have code in the INIT of the DataEnvironment to create cursors and populate them with sample data automatically when the report is ran. You will also find that creating reports with code in the INIT to run queries and or create cursors is a great way to distribute updated reports with your applications as the reports are completely standalone. This feature has been available ever since Visual FoxPro 3.0.

Using the MindsEyeReportEngineTestForm.SCX Form to test Reports

It's very easy to test the sample reports and compare the difference in performance when using the MERE ActiveX control and the native Visual FoxPro Report Engine using the MindsEyeReportEngineTestForm.SCX Visual FoxPro Form located in the FORMS subfolder. Simply, launch the MindsEyeReportEngineTestForm using the DO FORM command in the VFP Command Window. Then click on the Test Mind's Eye Engine, Append Report or Insert Report command button on the form to test run a Visual FoxPro report. After clicking on one of the previously mentioned buttons, choose a report from the REPORTS subfolder to run the report using the MERE ActiveX control and the MERE_ReportListener Class or MindsEyeReportEngine Class depending on the version of Visual FoxPro being used. After the report has completed, the time to run the selected report is displayed. To compare the performance to using the native Visual FoxPro Report Engine, simply click on the Run VFP Engine command button and choose the same report again to see the amount of time using VFP. If you are using Visual FoxPro 9, you can choose between SET REPORTBEHAVIOR 80 or 90 on the first tab of the form.

Sample Reports Included

The following Visual FoxPro sample reports are included in the REPORTS subfolder after installing the Mind's Eye Report Engine.

Dynamic Font and Shape Property Expression Example.FRX

Demonstrates using the Dynamic Property Expressions to modify the Font Style and Alpha Level of a Label or Field dynamically using FoxPro expressions at runtime. It also demonstrates changing the Fill Color of a Shape and the Width of a Shape object at runtime as well.

Dynamic Shape Width Property Expression Example.FRX

Demonstrates using the Dynamic Property Expressions to change the Width of a shape at runtime as an example for creating simple bar charts using a standard Visual FoxPro Shape object and a Dynamic Property Expression.

Page Numbering Sample 1000 Records.FRX

Page Numbering Sample 5000 Records.FRX

Page Numbering Sample 10000 Records.FRX

Page Numbering Sample 20000 Records.FRX

The Page Numbering Sample XXXXX Records.FRX Reports are used to demonstrate both the performance of using the MERE ActiveX control with Visual FoxPro as well as the real time rendering of _PAGENO and _PAGETOTAL system variables. There are 4 reports each with a different record count created in the INIT of the report for testing a large number of pages using MERE compared to Visual FoxPro performance wise.

GeneralFieldTest Single.FRX

GeneralFieldTest Multiple.FRX

This sample is used to demonstrate General Field support in in Visual FoxPro 9 using the MERE_ReportListener. General Fields are not supported in Visual FoxPro 8 and below. General Fields are not recommended for use in reports and if it all possible avoid them from a performance point of view. General Fields must be rendered to an image file prior to being displayed in the report and as you can see from the samples that this can be a very slow process even for simple bitmap images stored in a general field. The major problem is that currently the resolution of the printer affects the output resolution of the rendered image extracted from the General Field. A simple 2x2 bitmap which is 70 bytes on disk can easily become 45KB or more when extracted from a general field to an image file on disk.

Simple With Everything.FRX

This tests the various alignments and font styles as well as placing lines and images onto a report page. Each detail band has an image contained in it which begins to degrade performance with SET REPORTBEHAVIOR 90 in Visual FoxPro due to the rendering of every page to an EMF image in memory for report previews and printing. Additionally, this will render large PDF documents as well when using a PDF Printer Driver as it is difficult to optimize all of the images on a page or several pages when rendering from an EMF file. The MERE ActiveX control can optimize the PDF document generated since it tracks each image file by name while rendering a PDF document and it will reuse the same image object multiple times within a single PDF document if it is the same file name thus reducing the size of the PDF file generated. Additionally, MERE will use much less memory when previewing the document since it uses a file pointer to the image and repaints it in real time as opposed to rendering each and every page to an EMF file before previewing.

Stretch With Overflow Test.FRX

SWO REPORT.FRX

These two reports demonstrate the Stretch With Overflow support using MERE with Visual FoxPro reports. With Visual FoxPro 9 and the MERE_ReportListener Class, the matching of wrapping long Stretch With Overflow and floating objects is easily maintained and matched compared to using the older MindsEyeReportEngine Class Library code.

Test BARCODE.FRX

This report is used to demonstrate the built in Barcode engine in the MERE ActiveX control.


Real Time Rendered Page X of Y Feature

This is probably one of the Mind's Eye Report Engine's slickest little features. MERE has the ability to Dynamically process Page X of Y Page Number Expressions on report pages as they are rendered in "real time". Visual FoxPro 8 improved the Report Writer by adding the ability to chain multiple reports together without resetting the _PAGENO and _PAGETOTAL system variables by using the NORESET clause option of the REPORT FORM command. However, previewing the chained reports was not what you might have expected. With Visual FoxPro 9, multiple reports can be chained together and previewed as a single report. However, there are still limitations when displaying page numbers on your reports. MERE solves this issue without having to make any changes to your FRX reports and it displays the page numbers as you would have expected. The problem with native Visual FoxPro is that it does not know how many Total Pages there will be for all of your chained reports as each of them are ran even though Visual FoxPro makes two passes on your report whenever the _PAGENO or _PAGETOTAL system variables are found within a Report Field Expression in a report.

So, when you chain two reports together, Visual FoxPro calculates the value for _PAGETOTAL after the first pass and when it renders the report on the second pass, it will output the _PAGETOTAL value calculated for the first report. For example, if you have a report that has 3 pages, _PAGETOTAL will be 3. Now, when you append a second report to the first report using the NORESET clause, Visual FoxPro will continue to increment the _PAGETOTAL variable for the 2nd report. However, the first report has already been rendered with static values being used for the _PAGETOTAL values and when the first pass is completed on the second report, the value of _PAGETOTAL will be 6 if it also contains 3 pages. Therefore, when the second report is rendered it will continue incrementing the _PAGENO value from where it left off on the first report, but it will also be rendering 6 where the _PAGETOTAL is displayed. Thus creating the output as shown in the table below.

The Mind's Eye Report Engine gets around this problem by using Report Field objects which are evaluated in "real time" as report pages are rendered onto the preview window, printed to the printer or rendered to a PDF document. Using the AddReportField Method of the MERE ActiveX control allows you to place expressions onto report pages at anytime outside of a Visual FoxPro Report. However, the MERE_ReportListener will automatically call the AddReportField Method during the Render() Event as it is processing the an FRX report rather than simply placing the static values rendered by the Visual FoxPro engine. T

The MERE_ReportListener Class also uses the MERE ActiveX control's SetPageNumberToOne Method to add Page Break entries into its internal page break array for tracking when page numbers are to be reset to 1 which it uses as a lookup table for automatically determining what values to display for the _PAGENO and _PAGETOTAL variables at render time by mathematically looking locating the current physical report page within its internal page break array.

Below is a table that displays the output rendered using a Report Field Expression when chaining two reports together using native Visual FoxPro 8 and 9 compared to the output rendered in "real time" using the Mind's Eye Report Engine Control that supports the "Real Time" Page X of Y rendering.

Report Field Expression Example:

"Page " + TRANSFORM(_PAGENO) + " of " + TRANSFORM(_PAGETOTAL)

Visual FoxPro 8 and 9 | Mind's Eye Report Engine
Page 1 of 3 Page 2 of 3 Page 3 of 3 Page 4 of 6 Page 5 of 6 Page 6 of 6 | Page 1 of 6 Page 2 of 6 Page 3 of 6 Page 4 of 6 Page 5 of 6 Page 6 of 6

How does the Mind's Eye Report Engine Process VFP expressions at Render Time?

The Mind's Eye Report Engine ActiveX control has a parsing engine written in Delphi that can parse a string expression and tokenize it recognizing a small subset of Visual FoxPro commands that are commonly placed in Report Field Expressions along with _PAGENO and _PAGETOTAL. This parsing engine processes the string in "real time" and evaluates it and returns the output as a string to the MERE rendering engine. It currently recognizes the following VFP functions and system variables: STR(), TRANSFORM(), ALLTRIM(), _PAGENO and _PAGETOTAL. It also recognizes single quotes, double quotes and parentheses and searches for matching quotes, double quotes and parentheses to render it's output.

For example the following expressions should process and render properly in "real time":

· _PAGENO
· _PAGETOTAL
· STR(_PAGENO)
· TRANSFORM(_PAGENO)
· "Page " + TRANSFORM(_PAGENO) + " of " + TRANSFORM(_PAGETOTAL)
· "Page " + ALLTRIM(STR(_PAGENO)) + " of " + ALLTRIM(STR(_PAGETOTAL))
· "Page " + STR(_PAGENO) + " of " + STR(_PAGETOTAL)


MERE Visual FoxPro 9 Support

There are some distinct advantages to using the Mind's Eye Report Engine with Visual FoxPro 9 over the native Visual FoxPro Report Writer especially when Preview Reports with SET REPORTBEHAVIOR 90 since VFP 9 renders all report pages to EMF images in memory. In reports that contain photos or images, this can be a significant drain on system resources as report pages can be from 4 to 90MB in memory depending on the resolution of the photo or image. So, with a one hundred page report with images on every page, you can imagine the memory usage. MERE simply keeps a pointer to the images on disk while a report is being previewed, printed or saved to pdf, etc. and paints the images in real time. Additionally, MERE circumvents the Page Numbering problem when chaining multiple reports together by processing _PAGENO and _PAGETOTAL expressions at render time. Refer to the Real Time Rendered Page X of Y Feature topic for more information.

The Mind's Eye Report Engine takes advantage of the new Visual FoxPro 9 object-assisted reporting using the new Visual FoxPro ReportListener base class. With the new ReportListener Class in Visual FoxPro 9, you no longer need or use the MindsEyeReportEngine.VCX Class Library. In Visual FoxPro 9, you use the new MERE_ReportListener Class to render reports using the new REPORT FORM Filename OBJECT oReportListener command clause option where oReportListener will be an instance of the MERE_ReportListener Class.

Very Easy to Use

With object-assisted reporting you can now use the same REPORT FORM command as you normally do with Visual FoxPro and all of the Report processing is handled by Visual FoxPro. The MERE_ReportListener simply responds to the VFP Report Engine object-assisted events and redirects the output into the Mind's Eye Report Engine ActiveX control using it's Methods and Properties. This makes it ultra easy to switch to using the Mind's Eye Report Engine in your Visual FoxPro applications.

To learn more about the Visual FoxPro ReportListener Class and object-assisted reporting refer to the Visual FoxPro 9 Help File.

Visual FoxPro 9 Usage Examples

See Also

Real Time Rendered Page X of Y Feature


MERE Visual FoxPro 9 Improvements

· Report Rendering is now handled by Visual FoxPro. The MERE_ReportListener Class simply calls the MERE ActiveX control methods to transfer the VFP output into the MERE ActiveX control.
· Much Faster Report Rendering
· Reports with graphics can run faster than the native VFP Report Preview when rendering to the MERE ActiveX control.
· Report Previews using MERE use less memory than the native VFP Report Preview. The MERE Report Engine places all report objects into a collection in memory and only renders the page in real time from the page collection when needed as opposed to rendering all pages of the Report Preview to EMFs in memory as native Visual FoxPro does with SET REPORTBEHAVIOR 90. Reports that use a lot of images can render very large EMFs in memory. Four 6 mega pixel images rendered on a single page can create an almost 100MB EMF image.
· Much less VFP code to maintain (little to none)
· MERE now uses GDI+ to Measure and Render Text allowing for smoother text scaling during Report Preview.
· Much easier to implement in your VFP applications
· GENERAL FIELDS are now supported
· ALPHA LEVEL Support on Text

Also, you can download the latest build of the MERE ReportListener Class to support VFP 9. There are a few updates in the Parameters in the OCX for improving support for VFP 9. The newest build of the MERE ActiveX control is now using GDI+ code to now measure the text and draw it during the Preview so scaling is much smoother now and only slightly slower than GDI. However, you will notice a significant speed improvement to the overall engine. In fact, there are many times that MERE will produce a Report Preview display FASTER than Native VFP. This mostly occurs whenever there are graphics in the report due to the way MERE places objects into a collection verses VFP 9 rendering each page to EMFs in memory. Additionally, MERE uses much less RAM while running verses VFP's Report Preview.

Important Note

In VFP 9, you no longer need to use the MindsEyeReportEngine.VCX Class Library. You still need the MindsEyeReportPreviewForms Class Library and will need to re brand any overwritten Preview Form Class with your license again.


MERE Visual FoxPro 9 Usage

Visual FoxPro 9 has a new ReportListener Class which is used for processing Visual FoxPro reports using the REPORT FORM OBJECT command. A ReportListener class was created specifically for use with the Mind's Eye Report Engine ActiveX control. Using the MERE ReportListener class provides MERE the ability of processing VFP reports nearly as fast and sometimes faster than the native Visual FoxPro Report Preview.

IMPORTANT NOTE:

DO NOT USE the MINDSEYEREPORTENGINE.VCX Class Library with VFP 9.

You only need to use the MERE_REPORTLISTENER.VCX and the MEREPro4ReportPreviewForms.VCX or the MindsEyeINDSEYEREPORTPREVIEWFORMS.VCX Class Libraries.

To use the new MERE_ReportListener Class in Visual FoxPro 9, you must use the SET CLASSLIB command to make the MERE_ReportListener Class Library available to Visual FoxPro or use the NEWOBJECT() Method and then instantiate an instance of the ReportListener for use with the REPORT FORM command. Sample code is listed below:

MERE ReportListener Sample Code

SET REPORTBEHAVIOR 90

SET CLASSLIB TO

SET CLASSLIB TO MERE_ReportListener ADDITIVE

SET CLASSLIB TO MEREPro4PreviewForms ADDITIVE && or (MindsEyeReportPreviewForms ADDITIVE)

PUBLIC oMERE AS 'MERE_ReportListener' OF 'MERE_ReportListener.VCX'

PUBLIC oRPT AS 'MindsEyeReportPreviewForm' OF 'MindsEyeReportPreviewForms.VCX'

LOCAL lcFileName

m.lcFileName = GETFILE('frx')

IF EMPTY(m.lcFileName) THEN

RETURN

ENDIF

LOCAL llShowAsTopLevelForm, llDoNotShowMEREPreview, llDynamicLineHeight

m.llShowAsTopLevelForm = .F.

m.llDynamicLineHeight = .T.

* Setting the llDoNotShowMEREPreview to TRUE will keep the MERE_ReportListener

* from calling the SHOW() Method of the MindsEyeReportPreviewForm.

* This is useful for generating reports without any User Interface for example

* when running MERE on a Web Server.

* m.llDoNotShowMEREPreview = .T.         && DO NOT AUTOMATICALLY DISPLAY THE MERE PREVIEW

m.llDoNotShowMEREPreview = .F. && AUTOMATICALLY DISPLAY THE MERE PREVIEW

IF m.llShowAsTopLevelForm THEN

m.oRPT = CREATEOBJECT('MindsEyeReportPreviewTopLevelForm')

ELSE

m.oRPT = CREATEOBJECT('MindsEyeReportPreviewForm')

ENDIF

* To combine multiple reports into a single report, pass

* an existing instance of a MindsEyeReportPreviewForm object

* to the INIT of the MERE_ReportListener. If a MindsEyeReportPreviewForm

* object is not passed to the INIT of the MERE_ReportListener, then the

* MERE_ReportListener will instantiate its own instance

* of a MindsEyeReportPreviewForm.

IF VARTYPE(oRPT) = 'O' THEN

m.oMERE = CREATEOBJECT('MERE_ReportListener',oRPT,m.llDoNotShowMEREPreview)

ELSE

m.oMERE = CREATEOBJECT('MERE_ReportListener',,m.llDoNotShowMEREPreview)

ENDIF

* Before processing your VFP Report using the MERE_ReportListener you can set Properties

* of the MERE_ReportListener prior to processing your report.

WITH oMERE

.DynamicLineHeight = m.llDynamicLineHeight

ENDWITH

* Use the Visual FoxPro REPORT FORM OBJECT command passing it the

* Mind's Eye ReportListener Object to process your

* Visual FoxPro report.

REPORT FORM [&lcFileName] OBJECT oMERE NODIALOG

IF m.llDoNotShowMEREPreview THEN

* Since the MindsEyeReportPreviewForm was told NOT to Show by this variable

* above you can generate a PDF document or Print without any UI at this point

* and then release the oRPT Object Reference Variable after you have done this.

* Or, you could call the oRPT.SHOW() Method to display the report in the

* MindsEyeReportPreviewForm Form.

* oRPT.oReportEngine.SaveToPDF('SomeReport.PDF')

* m.lcPDFStream = oRPT.oReportEngine.PDFStream()

* oRPT.SHOW()

ELSE

oRPT.SHOW()

ENDIF


Visual FoxPro 9 Examples

The following Help Topics contain examples demonstrating how to use the new MERE_ReportListener Class in Visual FoxPro 9 and above that supports object-assisted reporting. The examples also demonstrate how to use features that extend the capabilities of the native Visual FoxPro object-assisted report engine.

Running Reports Using the MERE ReportListener

Chaining Multiple FRX Reports Together

Inserting a Report Example

Show 2 Reports Simultaneously

Emailing Reports and Adding Attachments


Running Reports Using the MERE ReportListener

To use the new MERE_ReportListener Class in Visual FoxPro 9, you must instantiate an instance of the MERE_ReportListener Class prior to calling the REPORT FORM command using either NEWOBJECT() or CREATEOBJECT(). The instance of the MERE_ReportListener Class is used as the OBJECT oReportListener clause.

MERE ReportListener Sample Code

SET CLASSLIB TO MERE_ReportListener ADDITIVE

SET CLASSLIB TO MindsEyeReportPreviewForms ADDITIVE

PUBLIC oMERE AS 'MERE_ReportListener' OF 'MERE_ReportListener.VCX'

PUBLIC oRPT  AS 'MindsEyeReportPreviewForm' OF 'MindsEyeReportPreviewForms.VCX'

LOCAL lcFileName

m.lcFileName = GETFILE('frx','Open Report','Open',0,'Select a Report File From the REPORTS Folder')

IF EMPTY(m.lcFileName) THEN

  RETURN

ENDIF

LOCAL llShowAsTopLevelForm, llDoNotShowMEREPreview, llDynamicLineHeight

m.llShowAsTopLevelForm = .F.

m.llDynamicLineHeight  = .T.

* Setting the llDoNotShowMEREPreview to TRUE will keep the MERE_ReportListener

* from calling the SHOW() Method of the MindsEyeReportPreviewForm.

* This is useful for generating reports without any User Interface for example

* when running MERE on a Web Server.

* m.llDoNotShowMEREPreview = .T.         && DO NOT AUTOMATICALLY DISPLAY THE MERE PREVIEW

m.llDoNotShowMEREPreview = .F.         && AUTOMATICALLY DISPLAY THE MERE PREVIEW

IF m.llShowAsTopLevelForm THEN

  m.oRPT = CREATEOBJECT('MindsEyeReportPreviewTopLevelForm')

ELSE

  m.oRPT = CREATEOBJECT('MindsEyeReportPreviewForm')

ENDIF

* To combine multiple reports into a single report, pass

* an existing instance of a MindsEyeReportPreviewForm object

* to the INIT of the MERE_ReportListener. If a MindsEyeReportPreviewForm

* object is not passed to the INIT of the MERE_ReportListener, then the

* MERE_ReportListener will instantiate its own instance

* of a MindsEyeReportPreviewForm.

IF VARTYPE(oRPT) = 'O' THEN

  m.oMERE = CREATEOBJECT('MERE_ReportListener',oRPT,m.llDoNotShowMEREPreview)

ELSE

  m.oMERE = CREATEOBJECT('MERE_ReportListener',,m.llDoNotShowMEREPreview)

ENDIF

* Before processing your VFP Report using the MERE_ReportListener you can set Properties

* of the MERE_ReportListener prior to processing your report.

WITH oMERE

  .DynamicLineHeight = m.llDynamicLineHeight

ENDWITH

* Use the Visual FoxPro REPORT FORM OBJECT command passing it the

* Mind's Eye ReportListener Object to process your

* Visual FoxPro report.

REPORT FORM (lcFileName) OBJECT oMERE NODIALOG

IF m.llDoNotShowMEREPreview THEN

* Since the MindsEyeReportPreviewForm was told NOT to Show by this variable

* above you can generate a PDF document or Print without any UI at this point

* and then release the oRPT Object Reference Variable after you have done this.

* Or, you could call the oRPT.SHOW() Method to display the report in the

* MindsEyeReportPreviewForm Form.

* oRPT.oReportEngine.SaveToPDF('SomeReport.PDF')

* m.lcPDFStream = oRPT.oReportEngine.PDFStream()

* oRPT.SHOW()

ELSE

oRPT.SHOW()

ENDIF


Rendering PDF's to a Memory Stream for Web Output

To use the new MERE_ReportListener Class in Visual FoxPro 9, you must instantiate an instance of the MERE_ReportListener Class prior to calling the REPORT FORM command using either NEWOBJECT() or CREATEOBJECT(). The instance of the MERE_ReportListener Class is used as the OBJECT oReportListener clause.

MERE ReportListener Sample Code to Render a PDF Document to a Memory Stream

SET CLASSLIB TO MERE_ReportListener ADDITIVE

SET CLASSLIB TO MindsEyeReportPreviewForms ADDITIVE

PUBLIC oMERE AS 'MERE_ReportListener' OF 'MERE_ReportListener.VCX'

PUBLIC oRPT  AS 'MindsEyeReportPreviewForm' OF 'MindsEyeReportPreviewForms.VCX'

LOCAL lcFileName

LOCAL llDoNotShowMEREPreview

m.lcFileName = GETFILE('frx','Open Report','Open',0,'Select a Report File From the REPORTS Folder')

IF EMPTY(m.lcFileName) THEN

  RETURN

ENDIF

* Setting the llDoNotShowMEREPreview to TRUE will keep the MERE_ReportListener

* from calling the SHOW() Method of the MindsEyeReportPreviewForm.

* This is useful for generating reports without any User Interface for example

* when running MERE on a Web Server.

m.llDoNotShowMEREPreview = .T.         && DO NOT AUTOMATICALLY DISPLAY THE MERE PREVIEW

m.oRPT = CREATEOBJECT('MindsEyeReportPreviewForm')

* Create an instance of the MERE_ReportListener for running the report

m.oMERE = CREATEOBJECT('MERE_ReportListener',oRPT,m.llDoNotShowMEREPreview)

* Before processing your VFP Report using the MERE_ReportListener you can set Properties

* of the MERE_ReportListener prior to processing your report.

WITH oMERE

  .DynamicLineHeight = .T.

ENDWITH

* Use the Visual FoxPro REPORT FORM OBJECT command passing it the

* Mind's Eye ReportListener Object to process your

* Visual FoxPro report.

REPORT FORM (lcFileName) OBJECT oMERE NODIALOG

* Now that the report has been rendered using the VFP/MERE ReportListener into

* the Mind's Eye Report Engine, you can now send the PDF document to a memory

* stream using the MERE PDFStream() Method. The PDFStream() method will generate

* a PDF document from the MERE Report Engine's memory and return it as a string.

* This string can then be passed directly to a web server's Response.Write() method

* or saved as a file using the VFP STRTOFILE() function.

m.lcPDFStream = m.oRPT.oReportEngine.PDFStream()

* To save the PDF Memory Stream to a file on disk you can use the VFP STRTOFILE()

* function as follows:

STRTOFILE(m.lcPDFStream,"PDFSTREAM.PDF")

See Also:

PDFStream Method


Chaining Multiple FRX Reports Together

Appending multiple FRX Reports into a single report can easily be done using the nReportPlacement Property of the MERE_ReportListener Class. The nReportPlacement Property controls where in the MERE OCX that the report will be placed. By default running a report into the MERE OCX will clear any reports currently rendered in MERE and replace it with the new report. Additionally, a report can be Appended or Inserted into MERE. Most of the time you will be appending reports. However, if you need to insert a Table of Contents in front of other reports, this can be accomplished by setting the nReportPlacement Property to -1.

*==========================================================================

* APPEND_REPORT_EXAMPLE.PRG

*

* This example demonstrates how to append or chain multiple Visual FoxPro

* FRX Reports into a single report.

*

* NOTE:

* Use the NORESET clause when using _PAGENO and _PAGETOTAL to draw

* Page Numbers on reports where you want the Page Numbers to continue

* incrementing and not be reset by the VFP ReportListener.

*==========================================================================

PUBLIC oRPT AS 'MindsEyeReportPreviewForm' OF 'MindsEyeReportPreviewForms.VCX'

LOCAL oMERE AS 'MERE_ReportListener' OF 'MERE_REPORTLISTENER.VCX'

*==========================================================================

* Create an instance of the MindsEyeReportPreviewForm Form so that it can

* be passed to the MERE_ReportListener Class for rendering the report into.

*==========================================================================

m.oRPT = NEWOBJECT('MindsEyeReportPreviewForm','MindsEyeReportPreviewForms.VCX')

*==========================================================================

* Create an instance of the MERE_ReportListener to be used by the

* REPORT FORM command.

*==========================================================================

m.oMERE = NEWOBJECT('MERE_ReportListener','MERE_ReportListener.VCX','',m.oRPT)

*==========================================================================

* Run the First report using the native VFP REPORT FORM command using

* the new OBJECT clause and passing it the MERE ReportListener instance.

*==========================================================================

REPORT FORM REPORTS\MultiPageReport.FRX OBJECT oMERE NODIALOG

*==========================================================================

* Now set the nReportPlacement Property to 1 before running the

* second report so that it will be Appended to the first report.

*==========================================================================

m.oMERE.nReportPlacement = 1 && (0 = NEW REPORT, 1 = APPEND REPORT, -1 = INSERT REPORT)

*==========================================================================

* Use the NORESET Clause to keep VFP from resetting the

* _PAGENO and _PAGETOTAL system variables to 1 if you want

* your page numbers to keep incrementing with each appended

* report.

*==========================================================================

REPORT FORM REPORTS\MultiPageReport.FRX OBJECT oMERE NORESET NODIALOG

m.oRPT.Show()


Inserting a Report Example

*===================================================================================

* INSERT_REPORT_EXAMPLE.PRG

*

* This example shows how to INSERT a Report prior to any other reports already

* rendered into the Mind's Eye Report Engine Control (MERE) by setting the

* nReportPlacement Property of an instance of the MERE_ReportListener Class prior

* to the VFP REPORT FORM cFilename OBJECT oReportListener command.

*

* POSSIBLE USES:

* Generating a Table of Contents to be placed at the beginning of a document after

* processing a number of reports that were appended/chained together.

*

*===================================================================================

PUBLIC oRPT

LOCAL oMERE AS 'MERE_ReportListener' OF 'MERE_REPORTLISTENER.VCX'

m.oRPT  = NEWOBJECT('MindsEyeReportPreviewForm','MindsEyeReportPreviewForms.VCX')

m.oMERE = NEWOBJECT('MERE_ReportListener','MERE_ReportListener.VCX','',m.oRPT)

*=================================================================

* Run the first report using the MERE_ReportListener rendering

* the report into the MERE ActiveX control contained on the

* oRPT Form Object.

*=================================================================

REPORT FORM REPORTS\Portrait_Report.FRX OBJECT oMERE NODIALOG

*=================================================================

* Now set the nReportPlacement Property of the

* oMERE ReportListener object to -1 to insert the next report

* prior to any reports currently rendered in the MERE ActiveX

* control.

*=================================================================

oMERE.nReportPlacement = -1 && (0 = NEW REPORT, 1 = APPEND REPORT, -1 = INSERT REPORT)

REPORT FORM REPORTS\Landscape_Report.FRX OBJECT oMERE NORESET NODIALOG

*=================================================================

* Now that both reports have been rendered into the MERE ActiveX

* control you can display the Preview using the SHOW() Method or

* call Methods of the MERE ActiveX Control to save the reports

* as a single PDF document using the SaveToPDF() Method or

* email them using the SendMail() method.

*=================================================================

oRPT.Show()


Show 2 Reports Simultaneously

*==============================================================================================

* SHOW2REPORTS_EXAMPLE.PRG

*

* THIS EXAMPLE CREATES TWO SEPARATE INSTANCES OF THE MINDSEYEREPORTPREVIEWFORM CLASS

* SO THAT 2 REPORTS CAN BE DISPLAYED AT THE SAME TIME.

*

* EACH INSTANCE OF A MINDSEYEREPORTPREVIEWFORM CLASS CONTAINS IT'S OWN MERE ACTIVEX CONTROL

* AND USES A SEPARATE MEMORY AREA AND CAN PREVIEW A DIFFERENT REPORT

*

* IMPORTANT NOTE:

* ---------------

* IMAGE FILES ARE READ OFF OF THE DISK IN REAL TIME WHEN A PAGE IS PAINTED, THEREFORE

* IF MULTIPLE REPORTS ARE USING THE SAME FILENAMES FOR TEMPORARY FILES AND ONE WRITES

* OVER ANOTHER TEMPORARY FILE ONLY THE MOST RECENT IMAGE WILL BE DISPLAYED.

*==============================================================================================

LOCAL llDoNotShowMEREPreview

m.llDoNotShowMEREPreview = .T.

SET CLASSLIB TO MindsEyeReportPreviewForms ADDITIVE

SET CLASSLIB TO MERE_ReportListener ADDITIVE

m.lcFileName = GETFILE('frx','Open Report','Open',0,'Select a Report File From the REPORTS Folder')

IF EMPTY(m.lcFileName) THEN

RETURN

ENDIF

LOCAL oMERE AS 'MERE_ReportListener' OF 'MERE_ReportListener.VCX'

PUBLIC oRPT1 AS 'MindsEyeReportPreviewForm' OF 'MindsEyeReportPreviewForms.VCX'

PUBLIC oRPT2 AS 'MindsEyeReportPreviewForm' OF 'MindsEyeReportPreviewForms.VCX'

*==============================================================================

* CREATE 2 SEPARATE INSTANCES OF THE MINDSEYEREPORTPREVIEWFORM FORM CLASSES FOR

* RENDERING THE REPORTS INTO

*==============================================================================

m.oRPT1 = NEWOBJECT('MindsEyeReportPreviewForm','MindsEyeReportPreviewForms.VCX')

m.oRPT2 = NEWOBJECT('MindsEyeReportPreviewForm','MindsEyeReportPreviewForms.VCX')

*==============================================================================

* GENERATE THE FIRST REPORT INTO A MINDSEYEREPORTPREVIEWFORM INSTANCE

*==============================================================================

IF VARTYPE(oRPT1) = 'O' THEN

m.oMERE = NEWOBJECT('MERE_ReportListener','MERE_ReportListener.VCX','',;

oRPT1,m.llDoNotShowMEREPreview)

IF VARTYPE(oMERE) = 'O' THEN

REPORT FORM (lcFilename) OBJECT oMERE NODIALOG

m.oMERE = NULL

ENDIF

ENDIF

*==============================================================================

* GENERATE THE SECOND REPORT INTO A SEPARATE MINDSEYEREPORTPREVIEWFORM INSTANCE

*==============================================================================

IF VARTYPE(oRPT2) = 'O' THEN

m.oMERE = NEWOBJECT('MERE_ReportListener','MERE_ReportListener.VCX','',;

oRPT2,m.llDoNotShowMEREPreview)

IF VARTYPE(oMERE) = 'O' THEN

REPORT FORM (lcFilename) OBJECT oMERE NODIALOG

m.oMERE = NULL

ENDIF

ENDIF

*=================================================

* NOW DISPLAY THE 2 SEPARATE REPORT FORM INSTANCES

*=================================================

IF VARTYPE(oRPT1) = 'O' THEN

WITH m.oRPT1

.Left = 0

.Width = (_SCREEN.Width / 2) - 10

.Height = _SCREEN.Height - 60

.SHOW()

ENDWITH

ENDIF

IF VARTYPE(oRPT2) = 'O' THEN

WITH m.oRPT2

.Left = _SCREEN.Width / 2

.Width = (_SCREEN.Width / 2) - 10

.Height = _SCREEN.Height - 60

.SHOW()

ENDWITH

ENDIF


Emailing Reports and Adding Attachments

This example demonstrates how easy it is to Email reports using the Mind's Eye Report Engine. MERE has a built in SMTP Email Engine as well as built in support for sending emails via MAPI. MERE also supports the ability to add additional attachments to a single email using the EMAILAddAttachment Method as shown below.

The fastest and easiest way to send emails is using SMTP since there isn't a need to worry being hung up by the MAPI protection of sending unauthorized emails. So, you can leave the EMAILMessagingType Property set to 0 for SMTP. In order to send the same email via MAPI set the EMAILMessagingType Property to 1.

*==========================================================================

* This example demonstrates how to email reports using the

* MERE_ReportListener and the MERE ActiveX control.

*

* This example shows how to email the reports without a User Interface

* since the oRPT.SHOW() method is never called. However, after emailing

* the reports a call to the oRPT.SHOW() command will display the report.

*==========================================================================

PUBLIC oRPT AS 'MindsEyeReportPreviewForm' OF 'MEREPro4PreviewForms.VCX' && MindsEyeReportPreviewForms.VCX' - for MERE V 3.X

LOCAL oMERE AS 'MERE_ReportListener' OF 'MERE_REPORTLISTENER.VCX'

*==========================================================================

* Create an instance of the MindsEyeReportPreviewForm Form so that it can

* be passed to the MERE_ReportListener Class for rendering the report into.

*==========================================================================

m.oRPT = NEWOBJECT('MindsEyeReportPreviewForm','MEREPro4PreviewForms.VCX')

WITH oRPT.oReportEngine

.EMAILMessagingType = 0 && Set to SMTP (Default = 0)

.EMAILSMTPHost = 'SomeHost.net'

.EMAILRecipients = 'someone@somecompany.com'

.EMAILFromAddress = 'me@mycompany.com'

.EMAILSubject = 'Test Message using Minds Eye Report Engine'

.EMAILBody = 'This is the body of the message.'

.EMAILAttachmentFilename = 'test.pdf'

  * Now add some additional Email Attachments to be sent with this email

.EMAILAddAttachment('C:\SomeFolder\SomeFile.prg')

.EMAILAddAttachment('C:\SomeFolder\SomeOtherFile.txt')

.EMAILAddAttachment('C:\SomeFolder\SomeWordDoc.doc')

ENDWITH

*==========================================================================

* Create an instance of the MERE_ReportListener to be used by the

* REPORT FORM command.

*==========================================================================

m.oMERE = NEWOBJECT('MERE_ReportListener','MERE_ReportListener.VCX','',m.oRPT)

*==========================================================================

* Run the Report using the native VFP REPORT FORM command using

* the new OBJECT clause and passing it the MERE ReportListener instance.

* The MERE_ReportListener will render the Report into the MERE ActiveX

* control.

*==========================================================================

REPORT FORM REPORTS\MultiPageReport.FRX OBJECT oMERE NODIALOG

*==========================================================================

* At this point the report has been rendered into the MERE ActiveX control

* and it can now be emailed by calling the SendMail() Method of the ActiveX

* control. The same report can be emailed several times to different

* recipients by simply changing the EMAILRecipients Property and calling

* SendMail() again after each recipient change.

*==========================================================================

WITH m.oRPT.oReportEngine

.EMAILRecipients = 'someoneelse@someothercompany.com'

.SendMail()

.EMAILRecipients = 'anotherperson@someothercompany.com'

.SendMail()

.EMAILRecipients = 'andanotherperson@someothercompany.com'

.SendMail()

ENDWITH

See Also:


Visual FoxPro 9 Class Libraries

Using the Mind's Eye Report Engine ActiveX control with Visual FoxPro 9 requires the MERE_ReportListener.VCX Class Library and the MindsEyeReportPreviewForms.VCX Class Library. The MERE_ReportListener Class is a subclass of the Visual FoxPro ReportListener baseclass. An instance of the MERE_ReportListener class must be instantiated and used as the OBJECT clause parameter of the REPORT FORM command in order to render Visual FoxPro Reports into the MERE ActiveX control.

See Also

Visual FoxPro 9 Examples


MERE_ReportListener Class

The MERE_ReportListener Class is in the MERE_ReportListener Class Library. The MERE_ReportListener Class is a subclass of the Visual FoxPro 9 ReportListener Class. This class is used with the new REPORT FORM Command OBJECT option. Using REPORT FORM with the OBJECT clause will take precedence over the SET REPORTBEHAVIOR command in Visual FoxPro 9 and above.


MERE Visual FoxPro 8 and Below Support

For Visual FoxPro 8 and below, the Mind's Eye Report Engine processes reports using the MindsEyeReportEngine Class contained in the MindsEyeReportEngine.VCX Class Library. Using the MindsEyeReportEngine Class is not near as fast or as accurate at matching the native Visual FoxPro Report Writer. The new object-assisted reporting in Visual FoxPro 9 allows MERE to run at near native VFP Report Preview rendering speed and in some cases faster than the native VFP Report Writer when graphic images are used on reports.

The MindsEyeReportEngine Class works in conjunction with many Methods and Properties of the MERE ActiveX control in order to render VFP FRX Reports without using the native VFP REPORT FORM command. Therefore, all of the code to render a VFP FRX is written completely independent of the Visual FoxPro REPORT FORM command and relies upon a lot of VFP and Delphi code in order to emulate the native VFP Report Writer. Thus it is not 100% accurate but is very close for most VFP FRX reports. But, if you need really fast PDF output and all of the other features of the Mind's Eye Report Engine in older versions of Visual FoxPro, then using the MindsEyeReportEngine Class is still a great way to go, but for the fastest rendering and the closest matching of VFP FRX Report Output with the added advantages of MERE, then I highly recommend using Visual FoxPro 9.


Previewing a Visual FoxPro FRX Report

Previewing a VFP FRX Report using Visual FoxPro 8 and below

It is very easy to run a Visual FoxPro FRX Report with the included MindsEyeReportEngine Class Library.

SET CLASSLIB TO MindsEyeReportEngine

PUBLIC oRPT

oReportEngine = CREATEOBJECT('MindsEyeReportEngine')

* The following line of code runs the VFP Report and returns an

* Object Reference to a VFP Form hosting the Report Engine ActiveX Control

oRPT = oReportEngine.ReportFormObject('SomeReport.FRX')

oRPT.Show()

After running the code above, the report will be displayed inside the ActiveX control which is hosted by a Visual FoxPro Form.


Running a Visual FoxPro Report without a User Interface

This example demonstrates how to run a Visual FoxPro FRX Report without a User Interface. If for example, you wish to generate PDF documents on a Web Server without a User Interface, you simply run the report as before but do not call the SHOW() Method of the VFP Form hosting the Report Engine.

SET CLASSLIB TO MindsEyeReportEngine

* Instantiate an instance of the MindsEyeReportEngine

* Class needed to process the FRX Report.

oRPTEngine = CREATEOBJECT('MindsEyeReportEngine')

* Now declare a variable to use as an object reference to the VFP Form created by the

* MindsEyeReportEngine.ReportFormObject Method.

PUBLIC oRPT

* If running on a Web Server then Disable the display of any errors since

* we don't want any UI to popup accidentally.

oRPTEngine.lDisplayErrors

oRPT = oRPTEngine.ReportFormObject('SomeReport.FRX')

oRPT.oReportEngine.SaveToPDF('SomeReport.PDF') && Saves the report to a PDF document

oRPT.oReportEngine.PrintReport() && Prints to the Currently Selected Printer

oRPT.oReportEngine.PrintReport('HP LaserJet 4') && Uses Printer Name to specify the printer to print to

* NOW EMAIL THE REPORT WITHOUT ANY USER INTERFACE

WITH oRPT.oReportEngine

.EMAILMessagingType = 0 && SMTP = 0, MAPI = 1

.EMAILSMTPHost = 'yourSMTPhost.com'

.EMAILRecipients = 'someone@hotmail.com'

.EMAILFromAddress = 'me@hotmail.com'

.EMAILBody = 'This is the body text for the email message'

.EMAILSubject = 'EMAIL Subject goes here!'

.EMAILAttachmentFileName = 'My Report.PDF'

.SendMail() && NOW SEND THE EMAIL USING THE SENDMAIL METHOD

ENDWITH

oRPT = NULL


Emailing Reports and Adding Attachments

This example demonstrates how easy it is to Email reports using the Mind's Eye Report Engine. MERE has a built in SMTP Email Engine as well as built in support for sending emails via MAPI. MERE also supports the ability to add additional attachments to a single email using the EMAILAddAttachment Method as shown below.

The fastest and easiest way to send emails is using SMTP since there isn't a need to worry being hung up by the MAPI protection of sending unauthorized emails. So, you can leave the EMAILMessagingType Property set to 0 for SMTP. In order to send the same email via MAPI set the EMAILMessagingType Property to 1.

SET CLASSLIB TO MindsEyeReportEngine

oRPTEngine = CREATEOBJECT('MindsEyeReportEngine')

PUBLIC oRPT

oRPT = oReportEngine.ReportFormObject('SomeReport.FRX')

WITH oRPT.oReportEngine

.EMAILMessagingType = 0 && Set to SMTP (Default = 0)

.EMAILSMTPHost = 'SomeHost.net'

.EMAILRecipients = 'someone@somecompany.com'

.EMAILFromAddress = 'me@mycompany.com'

.EMAILSubject = 'Test Message using Minds Eye Report Engine'

.EMAILBody = 'This is the body of the message.'

.EMAILAttachmentFilename = 'test.pdf'

* Now add some additional Email Attachments to be sent with this email

.EMAILAddAttachment('C:\SomeFolder\SomeFile.prg')

.EMAILAddAttachment('C:\SomeFolder\SomeOtherFile.txt')

.EMAILAddAttachment('C:\SomeFolder\SomeWordDoc.doc')

.SendMail()

* Now send the same email to some additional recipients using the same attachments.

.EMAILRecipients = 'someoneelse@someothercompany.com'

.SendMail()

.EMAILRecipients = 'anotherperson@someothercompany.com'

.SendMail()

.EMAILRecipients = 'andanotherperson@someothercompany.com'

.SendMail()

ENDWITH

See Also:


Running VFP Reports with the Mind's Eye Report Engine

Most Visual FoxPro Reports can run unmodified using the MindsEyeReportEngine Class Library. All of the VFP Report Engine emulation could have been written in native VFP code using the Methods of the Mind's Eye Report Engine (MERE) ActiveX/OLECONTROL Control. However, for performance reasons most of the report engine algorithms that perform text string measurements, text height calculations, measuring of character widths and other calculation and looping intensive code was written in Delphi inside the OCX control. The ActiveX Control was written independently of Visual FoxPro as a control that can dynamically generate reports at runtime.

Two methods were recently added to the MindsEyeReportEngine Class that expose the PEM's of the Report Engine ActiveX control after running a report. These two methods make it easy to merge VFP Reports, add Pages, Charts, Text and more after a VFP Report has been processed by the MindsEyeReportEngine Class. There is sample code on doing this in the Method links below:

ReportFormObject(cReportFileName, nShowWindow, nLeft, nTop, nWidth, nHeight)

AppendReportToObject(oReportEngine, cReportFileName)

InsertReportIntoObject(oReportEngine, cReportFileName)


Merging Multiple VFP Reports into a Single Report

To merge multiple VFP FRX Reports into a single report using the MindsEyeReportEngine Class in Visual FoxPro 8 and below call the AppendReportToObject Method of the MindsEyeReportEngine Class. The AppendReportToObject Method requires an Object Reference Variable to a MindsEyeReportEngine OLECONTROL and the name of the FRX Report File to execute. This method will then append the output of the Report File passed to the end of any reports already loaded into the MindsEyeReportEngine Control. Each report can have a different Page Size and Orientation and is only limited to the number of pages by the amount of memory on your PC.


VFP Scope, FOR and WHILE Expression Support

When using the MindsEyeReportEngine Class with Visual FoxPro, you must use the Properties of the MindsEyeReportEngine Class to control the Scope and FOR and WHILE support when running Visual FoxPro reports. This does not apply to the MERE_ReportListener class in Visual FoxPro 9 and above as the MERE_ReportListener uses the native REPORT FORM command.

Support for Scope, FOR and WHILE Expressions are handled by Properties of the MindsEyeReportEngine Class.

cScope - String Value

The cScope property is used to control the records that are processed. The valid options are:

ALL - This tells the Report Engine to process all records in the Detail table.

NEXT - This tells the Report Engine to process the next nRecords in the detail table.

RECORD - Specifies that the Report Engine is to process the specified record set by the nRecords property.

REST - Specifies that the Report Engine is to process the rest of the records in the detail table starting with the current record.

nRecords - Numeric Value

The nRecords Property can be set to a Record Number or a Range of Records

cFORExpression - String Value

The cFORExpression property is used to specify the FOR clause expression to be processed by the Report Engine. Only those records that the cFORExpression evaluates to TRUE will be processed onto the report.

cWHILEExpression - String Value

The cWHILEExpression property is used to specify the WHILE clause expression to be processed by the Report Engine. Records will only be printed as long as the cWHILEExpression is TRUE.

EXAMPLE CODE:

To use the SCOPE clause set the cScope property and then if using the NEXT or RECORD Scope values then set the nRecords property as well.

Example that prints only the NEXT 20 Records:

SET CLASSLIB TO MindsEyeReportEngine

o = CREATEOBJECT('MindsEyeReportEngine')

o.cScope = 'NEXT'

o.nRecords = 20

oRPT = o.ReportFormObject('SomeReport.FRX')

Example that prints only the 10th RECORD:

SET CLASSLIB TO MindsEyeReportEngine

o = CREATEOBJECT('MindsEyeReportEngine')

o.cScope = 'RECORD'

o.nRecords = 10

oRPT = o.ReportFormObject('SomeReport.FRX')

Example FOR Expression to print records FOR CUST_CODE Field starts with 'C':

SET CLASSLIB TO MindsEyeReportEngine

o = CREATEOBJECT('MindsEyeReportEngine')

o.cFORExpression = [CUST_CODE = 'C']

oRPT = o.ReportFormObject('SomeReport.FRX')

Example WHILE Expression to print records WHILE RECNO() <= 100:

SET CLASSLIB TO MindsEyeReportEngine

o = CREATEOBJECT('MindsEyeReportEngine')

o.cWHILEExpression = [RECNO()<= 100]

oRPT = o.ReportFormObject('SomeReport.FRX')


VFP Frequently Asked Questions

Q: Does the Report Engine Preview Control have a Royalty Free License?

A: Yes with the following limitations:

The control can only be bundled in an End User application. In no way is the control to be resold to a developer. Also, the Development License LIC file is not to be shipped with the control. Each developer is required to purchase his or her own license for development purposes.

File and Web Server Restrictions

The control can be used to produce documents on a File Server and/or Web Server using the PDF File Output only. The control was not designed to be used in a File or Web Server capacity therefore you should test the component under load to determine usage viability. However, there have been several developers in the community that do use the MERE ActiveX control on web servers to generate PDF documents with their applications.

Q: Can I generate a PDF document without any User Interface?

A: Yes. There are several ways to do this. The most flexible way is to use the ReportFormObject Method

Q: Why does the preview (with ShowWindow=0) behave like a modeless form, ie. the program continues?

A: This behavior can be easily modified to be a Modal or Non-Modal Form and can be done by making a simply passing a 1 to the SHOW() Method of the MindsEyeReportPreviewForm Form instance.

Q: There seems to be a limit of 32,767 pages, so the line on the web page that says "is only limited by the amount of memory/disk space available" is not quite true.

A: This is not a limitation of the control. It is a limitation of the Visual FoxPro _PAGENO and _PAGETOTAL internal VFP Variables. Currently, their values cannot exceed 32,767. I will be coding around this limitation but you will not be able to rely upon the _PAGENO and _PAGETOTAL variables if you pass that limitation.

Q: The engine does not seem to always pick up landscape mode from the FRX?

A: Do not clear out the EXPR field in your Report FRX table. The MindsEyeReportEngine Class reads the EXPR field to get the Page Size and Page Orientation of the Report. At the moment, the MindsEyeReportEngine Class ignores the TAG and TAG2 fields.

Q: My bitmap image is stored in a General Field and it is not displaying on the Report. Why not?

A: Currently support for images is limited to BMP, JPG, PNG, EMF, WMF, GIF and TIFF files. All image files are loaded onto the report when they are set to Picture From File.


Previewing VFP Reports

The Mind's Eye Report Engine ActiveX control has several special methods that were added specifically for use with Visual FoxPro. These methods are used to help the control process and run Visual FoxPro FRX Reports. In order to run a VFP Report, you will need to use the included VFP Class Library MindsEyeReportEngine.VCX. This library contains the MindsEyeReportEngine class that has Methods and Properties to process and run most standard VFP FRX Reports. Included in the MindsEyeReportPreviewForms Class Library is a Form Class called MindsEyeReportPreviewForm. This Form Class is used to host the MindsEyeReportEngine ActiveX control when previewing and running reports.

SAMPLE VFP CODE TO PREVIEW A VFP REPORT

To run a VFP Report in Visual FoxPro 6 and above, place the following code into your program:

SET CLASSLIB TO MindsEyeReportEngine

PUBLIC oRPT

oReportEngine = CREATEOBJECT('MindsEyeReportEngine')

* The following line of code runs the VFP Report and returns an

* Object Reference to a VFP Form hosting the Report Engine ActiveX Control

oRPT = oReportEngine.ReportFormObject('SomeReport.FRX')

oRPT.Show()


Printing VFP Reports

To print a Visual FoxPro Report without first previewing the report but with a prompt for the printer to print to, you must instantiate the MindsEyeReportEngine Class as an object and then call the ReportFormObject Method passing it the FRX Report Filename. The ReportFormObject() Method returns an Object Reference to a VFP Form containing the Report Engine and the rendered report. Once you have the Object Reference to the VFP Form you can then call the methods of the Report Engine ActiveX control by accessing them directly on the control which is named OREPORTENGINE.

SAMPLE VFP CODE TO PRINT A VFP REPORT

To print a VFP Report in Visual FoxPro 6 and above, place the following code into your program:

SET CLASSLIB TO MindsEyeReportEngine

oVFPReportEngine = CREATEOBJECT('MindsEyeReportEngine')

oRPT = oVFPReportEngine.ReportFormObject(cReportFileName)

* Now call the PrintReport Method of the ActiveX control

oRPT.oReportEngine.PrintReport(GETPRINTER())

Where:

cReportFileName = The Filename of the FRX Report to run including the .FRX file extension.

See Also:

PrintReport


Saving VFP Reports to PDF Documents

There are several ways to Save a VFP Report to a PDF Document. Users can click on the Save To PDF Button on the Report Engine Control's Toolbar or you can programmatically call Methods of the Control or of the VCX Class.

The most flexible way is to use the ReportFormObject Method of the MindsEyeReportEngine Class which returns an Object Reference to a MindsEyeReportPreviewForm Form Object. Since the ReportFormObject Method returns an Object Reference to a Form hosting the MindsEyeReportEngine ActiveX Control, you can then reference the MindsEyeReportEngine ActiveX Control's Methods directly and called the SaveToPDF

Sample VFP code to save a VFP Report to a PDF document using the ReportFormObject() Method

SET CLASSLIB TO MindsEyeReportEngine

oVFPReportEngine = CREATEOBJECT('MindsEyeReportEngine')

oRPT = oVFPReportEngine.ReportFormObject(cReportFileName)

* Now call the SaveToPDF Method of the ActiveX control to save

* the report to a PDF Document

oRPT.oReportEngine.SaveToPDF(cPDFFileName, lOpenPDFDocument)

Where:

cReportFileName = The Filename of the FRX Report to run including the .FRX file extension.

cPDFFileName = The Filename to save the PDF document to.

lOpenPDFDocument = Indicates whether the PDF Document will be automatically opened using ShellExecute() after it has been created.

See Also:

SaveToPDF


Visual FoxPro 8 and Below Tips

In order for the MindsEyeReportEngine Class to process and run VFP FRX Reports there are some general tips to follow to ensure that your reports will run properly.

DO NOT CLEAR THE EXPR FIELD OF THE FIRST RECORD IN THE FRX TABLE.

The MindsEyeReportEngine reads the EXPR field of the FRX table to obtain the PAPER SIZE and ORIENTATION of the Report. If this field is cleared, the MindsEyeReportEngine will default to LETTER SIZE and PORTRAIT ORIENTATIONS.

DO NOT PLACE DODEFAULT OR NODEFAULT IN ANY DATAENVIRONMENT METHODS

The MindsEyeReportEngine can read and execute code that is placed into the DataEnvironment Record of a Report FRX Table. However, the DODEFAULT and NODEFAULT commands cannot be executed in a PROGRAM FILE, which is how the MindsEyeReportEngine executes the code. Also, you must be using VFP 6 SP3 and above in order to process and run the code in the DataEnvironment.

SOURCE CODE IS UNAVAILABLE IN THE DATAENVIRONMENT WITH DEBUG INFO OFF

Compiling reports into an application without DEBUG INFO checked and with method code in the DataEnvironment will cause the code not to run. Apparently, whenever VFP BUILDS an application or standalone executable, the source code in the DE is removed at build time and therefore unavailable for use by the MindsEyeReportEngine when needed later at runtime. Therefore it is important that you either compile with DEBUG INFO checked or that you place any code needed to run your report outside of the DataEnvironment INIT Method.


VFP 8 and below Known Issues and Limitations

VFP 8 and below FRX Report Engine Known Issues and Limitations

 Top Previous Next

There are some limitations and known issues as far as rendering Visual FoxPro FRX Reports using the MindsEyeReportEngine Class which is required with Visual FoxPro 8 and below. To avoid these limitations, you are highly encouraged to use Visual FoxPro 9 and the MERE_ReportListener Class which has much faster performance and nearly exact matching output of the native VFP Report Writer.

The MindsEyeReportEngine Class Library works in combination with code in the Delphi engine in the ActiveX control to interpret a Visual FoxPro FRX report, process it and render as close to the same as the native Visual FoxPro REPORT FORM command. However, due to measuring calculations and interpretations of the location of objects placed onto an FRX report, a report rendered via MERE may not be rendered exactly the same as it is rendered using the Visual FoxPro REPORT FORM method. Several thousand hours of work was involved in reverse engineering the FRX data structure and modeling and developing code to render reports similar to the VFP REPORT FORM command. There are many "features" built into the VFP Report Writer that have been found to just not make since and they have been modeled as close to the same as possible. However, reports are received all the time where a developer has used some new "feature" that has not been seen before and improvements are made to the MindsEyeReportEngine class library and ActiveX control to match the new "feature".

Known Issue in the April 2005 release of the MERE ActiveX Control and MindsEyeReportEngine

· Some long Stretch With Overflow Reports are causing an Integer overflow issue in the ActiveX Control and this is currently being investigated.
· Some calculated fields are not summing properly and is being investigated.

Below is a list of items that are not currently supported as of the April 2005 release when using the MindsEyeReportEngine Class

· Summary Reports
· GENERAL FIELD EMBEDDED OBJECTS
· Variance Calculation on Report Fields and Variables
· Source code in the DataEnvironment of a Report is unavailable for compiling at runtime when an application is built without the DEBUG INFO checked. There may be a workaround built using a Project Hook to copy the source code to another field within the Report FRX table.
· OLE Objects

Source Code Unavailable in Reports built with DEBUG INFO OFF

Compiling reports into an application without DEBUG INFO checked and with method code in the DataEnvironment will cause the code not to run. Apparently, whenever VFP BUILDS an application or standalone executable, the source code in the DE is removed at build time and therefore unavailable for use by the MindsEyeReportEngine when needed later at runtime. Therefore it is important that you either compile with DEBUG INFO checked or that you place any code needed to run your report outside of the DataEnvironment INIT Method.


MindsEyeReportEngine VFP Class Libraries

MindsEyeReportEngine Class Libraries for Visual FoxPro 8 and below

 Top Previous Next

The MindsEyeReportEngine and MindsEyeReportPreviewForms Visual Class Libraries were created to run VFP FRX Reports and load them into an instance of the Mind's Eye Report Engine ActiveX control for previewing, printing and saving reports to PDF documents. The Class Libraries used with Visual FoxPro 8 and below currently contain the following class definitions.

MindsEyeReportEngine Class

MindsEyeReportEngine

MindsEyeReportPreviewToobar

MindsEyeReportPreviewForms Class

MindsEyeReportPreviewForm

MindsEyeReportPreviewTopLevelForm

The MindsEyeReportEngine Class is the main engine for running VFP FRX Reports. The MindsEyeReportEngine Class automatically instantiates the MindsEyeReportPreviewForm when running VFP Reports. However, you can also instantiate the MindsEyeReportPreviewForm Class yourself to create runtime reports by programmatically using the PEMs of the MindsEyeReportEngine ActiveX control.

Without the MindsEyeReportEngine Class Library you cannot run a VFP FRX Report unless you write your own VFP Report Engine. In order to write your own report engine to use the Mind's Eye Report Engine ActiveX control's PEMs, you can study the DEMOIT() Method in the MindsEyeReportEngine class. This class library can be subclassed and modified and enhanced for your own purposes.

The main function of this class is to open a VFP FRX Report File and load the layout information into the Mind's Eye Report Engine ActiveX control so it can process the layout and placement of report element objects onto the ActiveX control's pages. Also, the MindsEyeReportEngine Class opens up the tables needed for the report if they are stored in the DataEnvironment record of the FRX and it will also compile and execute any code that it finds in the INIT Method of the DataEnvironment record to run queries, open tables, etc. prior to running a VFP Report.

There are a number of Properties that you can set prior to calling the ReportFormPreview Method or some of the other methods that can be called to run a VFP Report. Many of these Properties such as the PDF and EMAIL Properties that have been added to actually set the Properties automatically in the Minds Eye Report Engine ActiveX control when the MindsEyeReportPreviewForm Form Class is instantiated.


MindsEyeReportEngine Class

The MindsEyeReportEngine Class is the main engine for running VFP FRX Reports using Visual FoxPro 8 and below. For Visual FoxPro 9 and above use the MERE_ReportListener Class. Several Methods of the MindsEyeReportEngine Class automatically instantiate a MindsEyeReportPreviewForm object when running VFP Reports.

Without the MindsEyeReportEngine Class Library you cannot run a VFP FRX Report unless you write your own VFP Report Engine. In order to write your own report engine to use the Mind's Eye Report Engine ActiveX control's PEMs, you can study the DEMOIT() Method in the MindsEyeReportEngine class. This class library can be subclassed and modified and enhanced for your own purposes.

The main function of this class is to open a VFP FRX Report File and load the layout information into the Mind's Eye Report Engine ActiveX control so it can process the layout and placement of report element objects onto the ActiveX control's pages. Also, the MindsEyeReportEngine Class opens up the tables needed for the report if they are stored in the DataEnvironment record of the FRX and it will also compile and execute any code that it finds in the INIT Method of the DataEnvironment record to run queries, open tables, etc. prior to running a VFP Report.

There are a number of Properties that you can set prior to calling the ReportFormPreview Method or some of the other methods that can be called to run a VFP Report. Many of these Properties such as the PDF and EMAIL Properties that have been added to actually set the Properties automatically in the Minds Eye Report Engine ActiveX control when the MindsEyeReportPreviewForm Form Class is instantiated.


ReportFormObject Method

ReportFormObject(cReportFileName, nShowWindow, nLeft, nTop, nWidth, nHeight)

This method will instantiate an instance of the MindsEyeReportPreviewForm Form Class and then execute the FRX Report Filename passed and load the output from that report into the MindsEyeReportEngine control that is contained on the MindsEyeReportPreviewForm Form. It then returns an Object Reference to the MindsEyeReportPreviewForm Form that is automatically instantiated by this method. This makes it very easy to access the PEMs of the MERE Control. With the Object Reference returned by this method, it is now possible to easily add more pages to a report, add Charts to a report, set Watermarks and more before Previewing, Printing, Emailing or Saving to PDF the report contained on the MERE Control.

SAMPLE VFP CODE TO RUN A VFP REPORT AND RETURN AN OBJECT REFERENCE

SET CLASSLIB TO MindsEyeReportEngine

oReportEngine = CREATEOBJECT('MindsEyeReportEngine')

oReportForm = oReportEngine.ReportFormObject('MyFRXReport.FRX')

IF VARTYPE(oReportForm) # 'O'

* OOPS Something happened and the MindsEyeReportPreviewForm was not created.

RETURN

ENDIF

WITH oReportForm.oReportEngine

FOR i = 1 to .nTotalPages

.GoToPage(i)

.WatermarkText = 'DRAFT'

ENDFOR

.NewPage()

.AddChart('',2,1,1,5,5)

.ChartAddXYData(100,0,'Software',RGB(255,0,0))

.ChartAddXYData(200,0,'Hardware',RGB(0,255,0))

.ChartAddXYData(300,0,'Service',RGB(0,0,255))

.SaveToPDF('MyReport.PDF',.T.)

ENDWITH


AppendReportToObject Method

AppendReportToObject(oReportEngine, cReportFileName)

This method takes as parameters an Object Reference to a MindsEyeReportEngine ActiveX Object or to a returned MindsEyeReportPreviewForm Form Object and an FRX Filename to process. This allows you to easily append multiple FRX Reports into a single Report before Previewing, Printing, Emailing or Saving them to a PDF document.

The following sample code demonstrates how to combine two different VFP Reports into a Single Report and then Save the Report to a PDF document which is automatically opened by the SaveToPDF Method.

SAMPLE VFP CODE TO MERGE 2 VFP REPORTS INTO A SINGLE PDF DOCUMENT

SET CLASSLIB TO MindsEyeReportEngine

oReportEngine = CREATEOBJECT('MindsEyeReportEngine')

oReportForm = oReportEngine.ReportFormObject('FRXReportOne.FRX')

oReportEngine.AppendReportToObject(oReportForm,'FRXReportTwo.FRX')

oReportForm.oReportEngine.SaveToPDF('TwoReportsInOne.PDF',.T.)


InsertReportIntoObject Method

InsertReportIntoObject(oReportEngine, cReportFileName)

This Method of the MindsEyeReportEngine Class will insert a Visual FoxPro FRX Report starting at the first page. This method is very useful in generating a Table Of Contents for a report. This method takes as parameters an Object Reference to a MindsEyeReportEngine ActiveX Object followed by the name of an FRX Report to insert.

The following sample code demonstrates how to combine two different VFP Reports into a Single Report and then insert another Report prior to the two previously processed reports.

Sample Code to Merge two VFP Reports and then Insert a third VFP Report prior to the First Two

SET CLASSLIB TO MindsEyeReportEngine

oReportEngine = CREATEOBJECT('MindsEyeReportEngine')

oReportForm = oReportEngine.ReportFormObject('FRXReportOne.FRX')

oReportEngine.AppendReportToObject(oReportForm,'FRXReportTwo.FRX')

* Now call the InsertReportIntoObject Method of the VCX passing it the

* Report Engine ActiveX Object followed by the name of the report.

oReportEngine.InsertReportIntoObject(oReportForm,'FRXReportThree.FRX')

oReportForm.oReportEngine.SaveToPDF('TwoReportsInOn.PDF',.T.)


MindsEyeReportPreviewToolbar Toolbar Class

The MindsEyeReportPreviewToolbar Toolbar Class is a VFP Toolbar class that was created to emulate the native Visual FoxPro Report Preview Toolbar. This toolbar class is instantiated automatically by the MindsEyeReportPreviewForm class if the MindsEyeReportEngine.lShowReportPreviewToolbar Property is set to TRUE.


Visual FoxPro Usage in General

Both the new Visual FoxPro 9 MERE_ReportListener Class and the older Visual FoxPro 8 and below MindsEyeReportEngine Class process and render reports into the Mind's Eye Report Engine ActiveX control for Previewing, Printing and Saving to PDF documents regardless of whether or not your application requires a visible User Interface. Once a report or multiple reports have been rendered into the MERE ActiveX control using either the MERE_ReportListener Class or the MindsEyeReport Engine Class, calling the Methods and setting the Properties of the MERE ActiveX control are the same between both versions.

The ActiveX control itself has the Properties and Methods that you will use for printing and saving reports to PDF or Image files. So, you will typically want to have a reference to the ActiveX contol itself as you will see in most of the sample code. The standard name for the MERE ActiveX control on the MindsEyeReportPreviewForm Form Class is oReportEngine. Therefore, your code will be calling methods of the oReportEngine Object such as oReportEngine.SaveToPDF(), oReportEngine.PDFStream(), etc.

Although the MERE ActiveX control is hosted in a Visual FoxPro Form, it does not have to be visible to be used. There are several examples of running reports and calling the Methods of the MERE ActiveX control without calling the SHOW() Method of the Form. The MERE ActiveX control only needs to be hosted in a VFP Form or Container in order to support the ActiveX licensing technology supported by Visual FoxPro.


VFP Dynamic Report Object Properties Expression Support

Dynamic Report Object Properties Expression Support for VFP Reports

 Top Previous Next

Dynamic Property Expressions (DPE) can be used to override Static VFP FRX Report Object Properties set at Design Time as a Report is rendered using the Mind's Eye Report Engine by simply entering Dynamic Property Expressions for Report Objects using Visual FoxPro Expressions. This makes it very easy to change Font Colors, Font Styles, Shape Colors, Widths and more on an FRX Report at runtime according to the values returned by the DPEs.

Since the DPE Commands are entered into the COMMENT FIELD of FRX Report Objects, they will not affect the way a report runs when using the native Visual FoxPro REPORT FORM command. However, when processing the same FRX Report using the Mind's Eye Report Engine you can now time designing reports by only having to place Report Objects onto your report once rather than multiple times and using PRINT WHEN expressions to hide or show objects just to change the color or style of an object.

THE OLD WAY OF CHANGING COLORS OF A REPORT EXPRESSION

The old way to display a Report Expression in two different colors depending on the Value of the Report Expression using the native VFP RW, required that you to place Two Report Expressions on your Report with the exact same expression. One RE would have it's color set to RED and the other RE's color would be set to BLACK. You would then stack the two RE's on top of each other so they printed in the same spot in the report band. Then you would place code in the PRINT WHEN Expression for each Report Expression on the report to control which one of the two RE's should be printed according to the Value of the RE. Essentially, this PRINT WHEN trick is used to hide the RE that is RED when the Value is POSITIVE and hide the RE that is BLACK when the Value is Negative, thus doubling the amount of work and objects for each object on a report requiring this type of output.

THE NEW WAY OF CHANGING COLORS OF A REPORT EXPRESSION

Using the same example from above, you now only have to place one Report Expression on your FRX Report and then simply enter a Dynamic Property Expression into the COMMENT FIELD for each of the Report Object Properties you want to change while the Report is rendered and then run the FRX Report using the Mind's Eye Report Engine.

DPE SYNTAX AND USAGE

Each DPE should be entered as a separate line into the COMMENT FIELD and CANNOT contain any carriage returns in the Dynamic Property Expression string. The DPE command should start with an ASTERISK followed by a COLON, followed by the DPE COMMAND, followed by a COLON which is then followed by a valid VFP Expression that the DPE is to Evaluate at report runtime using the EVALUATE() command. The DPE should return a value with the type specified below in order for the Report Object Property to be properly changed at render time. If the DPE returns a value of a type other than specified below for the DPE Command, it is ignored.

Dynamic Property Expression Commands

Command

Name

DPE Data Type

Description

DFN

Dynamic Font Name

String

Sets the Font Name for the Report Expression or Label to the String Value returned by the DPE.

The DPE should return a string use any valid TrueType Font Name.

DFS

Dynamic Font Style

String

Sets the Font Style for the Report Expression or Label to the String Value returned by the DPE.

The DPE should return a string using any combination of the following characters:

"B" - Bold

"I" - Italic

"U" - Underline

"-" - Strikeout

DFA

Dynamic Fill Alpha Level

Numeric

Sets the Alpha Level of the Fill Color to the Value returned by the DPE. This controls the transparency level of the Text.

DFC

Dynamic Fill Color

Numeric

Sets the Fill Color to the Value returned by the DPE.

DFP

Dynamic Fill Pattern

Numeric

Sets the Fill Pattern to the Value returned by the DPE. Values Range from 0 - 8

DPC

Dynamic Pen Color

Numeric

Sets the Pen Color to the Value returned by the DPE.

DPP

Dynamic Pen Pattern

Numeric

Sets the Pen Pattern to the value returned by the DPE. Values Range from 0 - 8

DPS

Dynamic Pen Size

Numeric

Sets the Pen Size or width of a Line or border of a shape to the value returned by the DPE.

Values can Range from 0 - 20.

DPL

Dynamic Position Left

Numeric

Sets the Left Position of the Report Object in inches using the value returned by the DPE. Modifying the Left Position will automatically be limited by the rendering engine between the 0 and the width of the Band.

DSH

Dynamic Size Height

Numeric

Sets the Height of the Report Object in inches using the value returned by the DPE.

DSW

Dynamic Size Width

Numeric

Sets the Width of the Report Object in inches using the value returned by the DPE.

HYPERLINK

PDF Hyperlink

String

Embeds the HYPERLINK Expression evaluated by the Rendering Engine to be stored into the Report Object. This HYPERLINK Expression should be in the form of:

http://www.somewebaddress.com

or

mailto:somename@somedomain.com

When the Report Engine renders the Report to a PDF document and it encounters an object that has an embedded PDF Hyperlink command assigned to it, it will render the Hyperlink into the PDF document.

PAPERBIN

PaperBin Property of current page being rendered

Numeric

While rendering the report, the value returned by the expression will be used to set the PaperBin Property for the Report Page currently being rendered using the VFP FRX Report. This makes it quite easy to set the PaperBin Property during a report according to a Field or Variable Expression.

Valid Values: See PaperBin Property

DYNAMIC PROPERTY EXPRESSION EXAMPLES

Making a Report Expression Black when Positive and Red when Negative:

While running a report, you would like to have a Report Expression rendered so that POSITIVE Values of the number are rendered in BLACK and NEGATIVE Values rendered in RED. Instead of having to place 2 separate Report Expression objects on the report stacked right on top of each other, you can now place one Report Expression on the report and enter a Dynamic Property Expression into the COMMENT FIELD in the native VFP Report Writer of the Report Expression to change the Color of the Font according to the Value of the Field in your table. When the Mind's Eye Report Engine, processes the Report, the DPE will be evaluated right before the Report Expression is rendered onto the Report Page.

COMMENT FIELD DPE COMMAND

*:DFC:IIF(Amt<0,RGB(255,0,0),RGB(255,255,255))

VFP Dynamic Fill Color Expression Example

Changing the Width of a Shape Object according to a Field Value:

Let's say you have a report where you would like to draw a bar where its width represents a student's Test Score as a percentage for a field. This can easily be done by creating a DPE using the DynamicSizeWidthExpr command "DSW" where you divide the student's Test Score Value by the Total Possible Score Field and multiply it by the maximum width in inches to draw the bar. This would be done by entering the DPE Command below into the COMMENT FIELD for a SHAPE OBJECT on the Report.

COMMENT FIELD DPE COMMAND

*:DSW:(TestScore/PossibleScore) * 4

VFP Dynamic Size Width Expression Example

Screen Shot of Example Report using Dynamic Size Width Property Expression

Dynamic Shape Width Property Expression Screen Shot


MindsEyeReportPreviewForm Form Class

With the release of Version 4.0 of the Mind's Eye Report Engine ActiveX control, there are now two separate Class Libraries built for hosting the MERE ActiveX control. It was done this way in order to allow for running both the old and the new version for testing and deployment as many of the Methods have been removed from the MERE 4.0 version of the ActiveX control that are no longer needed when using the new VFP 9 MERE_ReportListener Class.

The MindsEyeReportPreviewForm Form Class is a VFP Form class contained in the MEREPRO4PreviewForms.VCX or MindsEyeReportPreviewForms.VCX Class Library. This Form Class contains a MindsEyeReportEngine ActiveX Control Object. The Form is simply a container for the ActiveX control that does all of the work.

SET CLASSLIB TO MEREPro4PreviewForms.VCX Class Library if you are using the new MERE 4.0 Version of the ActiveX Control.

ActiveX Licensing

If the Mind's Eye Report Engine ActiveX Control displays a Demo Watermark across it, then you are working with the control in the demo mode without a valid license. This allows you to test the control for your application's use without having to purchase a license. However, the Demo Watermark will appear when Previewing, Printing or Saving to PDF documents. If you have purchased a developer's license, then you need to "brand" your copy of the MindsEyeReportPreviewForm Form Class with your purchased license. Refer to the Installing Your License Key Help File Topic for more information.

Visual FoxPro 9 and Above

To support appending multiple reports or have more control over the MERE control, it is recommended that you instantiate an instance of the MindsEyeReportPreviewForm Class as an object to be passed to the MERE_ReportListener Class. Please refer to the Visual FoxPro 9 Examples.

Visual FoxPro 8 and Below

This VFP Form class is automatically instantiated by several Methods contained within the MindsEyeReportEngine Class such as ReportFormObject used in Visual FoxPro 8 and below.


Mind's Eye Report Engine ActiveX Events

The following Events are available for use on the Report Engine Control.

OnToolbarButtonClick - Occurs when a Custom Toolbar Button is clicked on the MERE Toolbar.


OnToolbarButtonClick Event

Occurs when you click on a Custom Toolbar Button contained on the Mind's Eye Report Engine ActiveX Control's Toolbar that was added using the AddToolbarButton Method. This Event can be used to call your own custom programs or methods when the event is triggered.

PROCEDURE OnToolbarButtonClick

LPARAMETERS cButtonName

Parameters

cButtonName - String

Contains the name of the button that was clicked.

Example

PROCEDURE OnToolbarButtonClick

LPARAMETERS cButtonName

Messagebox('OnToolbarButton Click: '+cButtonName)

See Also

AddToolbarButton


Properties

Mind's Eye Report Engine ActiveX Properties

Properties

The Properties for the Report Engine Control have been broken down into different sections to make it easier to locate the desired properties. Click on one of the sections below to review the properties for that section.

Report Properties

Report Display Properties

Default Text Properties

Default Line Properties

Default Shape Properties

Printer Information Properties

PDF Document Properties

Chart Properites

Watermark Display Properties

Calendar Display Properties


Report Properties

Mind's Eye Report Engine Report Properties

REPORT PROPERTIES

Property Name | Data Type | Description
nBackgroundColor | Numeric | Specifies the background color behind the page area in the Report Engine Preview.
nCurrentPageHeight | Numeric | The page height of the current page.
nCurrentPageOrientation | Numeric | The Orientation of the current page.
nCurrentPageWidth | Numeric | The page width of the current page.
nGridColor | Numeric | Specifies the color to display the grid bars.
nLastError | Numeric | The last error that occurred while processing a request.
nPageNumber | Numeric | The current page number being displayed in the Report Engine Preview.
nPageOrientation | Numeric | Specifies the current orientation of the current page as either Portrait or Landscape.
nPaperColor | Numeric | Specifies the color of the paper on the Report Engine Preview.
nPrintScale | Numeric | Specifies the amount of scaling when printing report pages. This property is not currently used.
nReportObjects | Numeric | The number of Report Objects on the current page.
nTotalPages | Numeric | The number of pages currently loaded into the Report Engine. Read/Only
nXOffset | Numeric | The amount of Horizontal Offset for Preview Mode in Inches to offset all objects on the page.
nXPrintOffset | Numeric | The amount of Horizontal Offset for Printing in Inches to shift objects on the page.
nYOffset | Numeric | The amount of Vertical Offset for Preview Mode in Inches to offset all objects on the page.
nYPrintOffset | Numeric | The amount of Vertical Offset for Printing in Inches to shift objects on the page.
Scale | Numeric | Specifies the scale ratio for the current preview. Read/Write at runtime. Valid values range from 10% to 1,000,000%.
ScaleStep | Numeric | Specifies the amount of step in percent between zoom factors.


Report Display Properties

Mind's Eye Report Engine Report Display Properties

REPORT DISPLAY PROPERTIES

Property Name | Data Type | Description
DisplayActualSizeButton | Boolean | Specifies whether or not the Actual Size Button will be displayed in the toolbar.
DisplayDeletePageButton | Boolean | Specifies whether or not the Delete Page Button will be displayed in the toolbar.
DisplayFindButton | Boolean | Specifies whether or not the Find Button will be displayed in the toolbar.
DisplayFindToolbar | Numeric | Hides or displays the Find Toolbar in the Preview Window. Focus is moved to the text box in the Find Toolbar. Valid Values: 0 = Hidden 1 = Display Toolbar at Bottom of Preview 2 = Display Toolbar at Top of Preview
DisplayFitInWindowButton | Boolean | Specifies whether or not the Fit In Window Button will be displayed in the toolbar.
DisplayFitToWidthButton | Boolean | Specifies whether or not the Fit To Width Button will be displayed in the toolbar.
DisplayGrid | Boolean | Specifies whether or not the Grid is displayed on the Report Object page.
DisplayGridButton | Boolean | Specifies whether or not the Grid Button will be displayed in the toolbar.
DisplayHelpButton | Boolean | Specifies whether or not the Help Button will be displayed in the toolbar.
DisplayLicenseInfo | Boolean | Specifies whether or not the Licensee Information is displayed in the About Box during Runtime.
DisplayNewPageButton | Boolean | Specifies whether or not the New Page Button will be displayed in the toolbar.
DisplayPDFButton | Boolean | Specifies whether or not the Save To PDF Button will be displayed in the toolbar.
DisplayPageBorder | Boolean | Specifies whether or not a border is drawn around the page displayed in the Report Engine Preview.
DisplayPageNavigation | Boolean | Specifies whether or not the Page Navigation control will be displayed in the toolbar.
DisplayPageScale | Boolean | Specifies whether or not the Page Scale controls will be displayed in the toolbar.
DisplayPageScroller | Boolean | Specifies whether or not the Page Scroller control will be displayed in the toolbar.
DisplayPageSize | Boolean | Specifies whether or not the Page Size will be displayed in the toolbar.
DisplayPopupMenu | Numeric | Specifies how the Popup Menu is displayed over the Report Preview window at runtime. It is suggested to use -1 to disable the menu and 0 to enable the menu. Other positive values may be supported later for other features. Valid Values: -1 = Disables the right click popup menu 0 = Enables support for the right click popup menu. (Default value)
DisplayPrintButton | Boolean | Specifies whether or not the Print Button will be displayed in the toolbar.
DisplayPrinterList | Boolean | Specifies whether or not the Printer Dropdown List is displayed in the toolbar.
DisplayStatusBar | Boolean | Specifies whether or not the Status Bar is displayed at the bottom of the Report Engine Control. (For future use)
DisplayToolbar | Boolean | Specifies whether or not the Toolbar will be displayed in the Report Object Control.
DisplayToolbarStyle | Numeric | Selects the Toolbar Style changing the Icons on the Toolbar to select between the Standard or Newer Style icons. Valid Values: 0 - Standard Icons 1 - Newer XP Style Icons
DisplayUnitOfMeasure | Numeric | Selects the Unit Of Measure used to display the Page Size in the Report Preview Window. Valid Values: 0 - Inches 1 - Centimeters 2 - Millimeters
DisplayZoomButtons | Boolean | Specifies whether or not the Zoom Buttons will be displayed in the toolbar.
GDIPlusTextRenderingHint | Numeric | Specifies the GDI+ Text Rendering Hint specification to use while rendering text. Valid Values: 0 = System Default (Default) 1 = Glyph Bitmap With Hinting 2 = Glyph Bitmap Without Hinting 3 = Glyph Anti-Alias Bitmap With Hinting 4 = Glyph Anti-Alias Bitmap Without Hinting 5 = Glyph ClearType Bitmap With Hinting
nBackgroundColor | Numeric | Specifies the color of the Background area around the Page Object in the Report Preview.
nPaperColor | Numeric | Specifies the color of the paper for Previewing a Report.
PictureJPEGSpeed | Numeric | Specifies the image quality for Preview speed and can be set between 0 and 4 with 0 being the fastest and 4 being the slowest.


Default Text Properties

Mind's Eye Report Engine Default Text Properties

DEFAULT TEXT PROPERTIES

Property Name | Data Type | Description
TextFontBackColor | Numeric | Specifies the default Back Color to be used for Text placed onto the Report Engine control using the AddText Method.
TextFontForeColor | Numeric | Specifies the default Fore Color to be used for Text placed onto the Report Engine control using the AddText Method.
TextFontName | String | Specifies the default Font Name to be used for Text placed onto the Report Engine control using the AddText Method.
TextFontSize | Numeric | Specifies the default Font Size to be used for Text placed onto the Report Engine control using the AddText Method.
TextFontStyle | String | Specifies the default Font Style to be used for Text placed onto the Report Engine control using the AddText Method. Any of the values listed below can be combined together. Valid Values are: "" - Normal "B" - Bold "I" - Italic "U" - Underline "S" - Strikeout


EMAIL Properties

Mind's Eye Report Engine EMAIL Properties

EMAIL PROPERTIES

Several of the Properties listed below must be set in order to send an email using the SMTP email support in the Report Engine. In order to support emailing from the toolbar button, you must preset the EmailSMTPHost, EmailFromAddress ahead of time. Additionally, if your SMTP Server requires Authentication then you must also set the EmailSMTPAuthenticationType to 1 and you must also set the EmailSMTPUserID and EmailSMTPPassword values as well in order to connect to the SMTP Server.

Property Name | Data Type | Description
EmailAttachmentFileName | String | Specifies the file name to be used as the attachment that the report will be emailed as. Setting this Property to an empty string value will prevent MERE from automatically generating a PDF File attachment and sending it with the EMAIL. This allows you to send emails without PDF attachments using it as an EMAIL only control.
EmailAttachmentCount | Numeric | Tracks the number of attachment filenames that have been added using the EMAILAddAttachment Method to attach additional files to any emails sent using the SendMail Method. Set this Property to ZERO to clear all of the Files from the Attachment Files list.
EmailBCCAddresses | String | Specifies a comma separated list of formatted Blind Carbon Copy addresses to email to
EmailBody | String | Specifies the Plain Text for the Body of the email. If the Email contains HTML text, email programs that cannot display or are not configured to display HTML will display the Plain Text portion of the email. You can set both the EmailBody and EmailBodyHTML properties at the same time.
EmailBodyHTML | String | Specifies the HTML Text for the Body of the email that will be displayed as an HTML email.
EmailCCAddresses | String | Specifies a comma separated list of formatted Carbon Copy addresses to email to.
EmailFromAddress | String | Specifies the From Address for the email and is required.
EmailFromDisplayStyle | Numeric | Specifies the Display Style for the FROM Field on the EMAIL Dialog Form when the EmailMessagingType Property is set to 0 (SMTP Mode). Valid Values: 0 = Edit (User can change the Value at Runtime) 1 = Read Only (Field is shown but is Read Only) 2 = Hidden (Field is not shown on the dialog form)
EmailMessagingType | Numeric | Specifies the Email Messaging Type: Valid Values: 0 = SMTP 1 = MAPI
EmailRecipients | String | Specifies a comma separated list of formatted Recipient addresses to email to.
EmailReturnReceipt | Boolean | Specifies that a Return Receipt will be requested.
EmailSMTPAuthorizationType | Numeric | Specifies the SMTP Authorization Type Valid Values: 0 = none, 1 = Login Required
EmailSMTPHost | String | Specifies the name of the SMTP Host and must be specified in order to send an email.
EmailSMTPHostDisplayStyle | Numeric | Specifies the Display Style for the SMTP Host Field on the EMAIL Dialog Form when the EmailMessagingType Property is set to 0 (SMTP Mode). Valid Values: 0 = Edit (User can change the Value at Runtime) 1 = Read Only (Field is shown but is Read Only) 2 = Hidden (Field is not shown on the dialog form)
EmailSMTPPassword | String | Specifies the Password for logging into an SMTP Server when the Authentication Type is set to 1.
EmailSMTPPort | Numeric | Specifies the Port for the SMTP Server if required. Default is 0 and not used. Use this property to set the SMTP Port to a different value required by some email servers for enhanced security.
EmailSMPTUserID | String | Specifies the UserID for logging into an SMTP Server when the Authentication Type is set to 1.
EmailSubject | String | Specifies the Subject for the Email address.


Default Line Properties

Mind's Eye Report Engine Default Line Properties

DEFAULT LINE PROPERTIES

Property Name | Data Type | Description
LinePenColor | Numeric | Specifies the default PenColor to be used for Line objects placed onto the Report Engine control using the AddLine Method.
LinePenStyle | Numeric | Specifies the default PenStyle to be used for Line objects placed onto the Report Engine control using the AddLine Method.
LinePenWidth | Numeric | Specifies the default PenWidth to be used for Line objects placed onto the Report Engine control using the AddLine Method.


Default Shape Properties

Mind's Eye Report Engine Default Shape Properties

DEFAULT SHAPE PROPERTIES

Property Name | Data Type | Description
ShapeBackStyle | Numeric | Specifies the default BackStyle to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeBorderStyle | Numeric | Specifies the default BorderStyle to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeBorderWidth | Numeric | Specifies the default BorderWidth to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeCurvature | Numeric | Specifies the default Curvature to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeFillColor | Numeric | Specifies the default FillColor to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeFillStyle | Numeric | Specifies the default FillStyle to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapePenColor | Numeric | Specifies the default PenColor to be used for Shape objects placed onto the Report Engine control using the AddShape Method.


Page Related Properties

PAGE RELATED PROPERTIES

Property Name

Data Type

Description

MediaType

Numeric

Specifies the MediaType to set in the DEVMODEstructure prior to printing the page on the printer. Each page within a report can be set to a specific MediaType. This value ONLY affects printing reports and has no effect when a PDF document is rendered. Below are example values that are from the Windows API Constants and MERE supports a default value of 0 which acts the same as 1 (DMMEDIA_STANDARD).

Example MediaType Values:

1 = DMMEDIA_STANDARD

2 = DMMEDIA_GLOSSY

3 = DMMEDIA_TRANSPARENCY

MediaType Examples from a Canon i850

281 = Photo Paper Pro

285 = Photo Paper Plus Glossy

284 = Matte Photo Paper

277 = Glossy Photo Paper

271 = High Resolution Paper

276 = High Gloss Photo Film

273 = T-Shirt Transfer

263 = Envelope

PaperBin

Numeric

Specifies the PaperBin to set in the DEVMODE structure prior to printing the page on the printer. Each page within a report can be set to a specific PaperBin. This value ONLY affects printing reports and has no effect when a PDF document is rendered. Below are example values that are from the Windows API Constants and MERE supports a default value of 0 which acts the same as 7 (DMBIN_AUTO).

Example PaperBin Values:

0 = DMBIN_AUTO

1 = DMBIN_UPPER

1 = DMBIN_FIRST

1 = DMBIN_ONLYONE

2 = DMBIN_LOWER

3 = DMBIN_MIDDLE

4 = DMBIN_MANUAL

5 = DMBIN_ENVELOPE

6 = DMBIN_ENVMANUAL

7 = DMBIN_AUTO

8 = DMBIN_TRACTOR

9 = DMBIN_SMALLFMT

10 = DMBIN_LARGEFMT

11 = DMBIN_LARGECAPACITY

14 = DMBIN_CASSETTE

14 = DMBIN_LAST

256 And Above = DMBIN_USER

For printers that support many Paper Bins that are device specific, check with the printer manufacturer. These values begin at 256 and above.


Printing and Printer Information Properties

Mind's Eye Report Engine Printer Information Properties

PRINTER INFORMATION PROPERTIES

Property Name | Data Type | Description
PrintCollatePages | Boolean | Specifies if the pages will be collated when printing multiple copies.
PrintColor | Boolean | Specifies if the printer should print in color if capable.
PrintCopies | Numeric | Specifies the number of copies to print.
PrintDuplex | Boolean | Specifies whether to print using Duplex mode. This flag is also used to default the Duplex checkbox on the Print Dialog Form as well. The End User can disable the Duplex checkbox at runtime.
PrintEndPage | Numeric | Specifies the last page to print.
PrintJobTitle | String | Specifies the name of the Print Job that will be displayed in the Print Manager window.
PrintPagesPerPage | Numeric | Specifies the number of pages to print per page when printing. Valid values are 1, 2, 4 and 8.
PrintPromptForPrint | Boolean | Specifies if the Print Dialog box should be displayed when the user clicks on the Print toolbar button.
PrintReversePages | Boolean | Specifies if the pages should be printed in reverse order.
PrintShrinkToFit | Boolean | Specifies that the Report Engine automatically Shrink To Fit any pages that have printable data outside of the Printable Area of the page being printed to. This provides the Report Engine with the ability to scale an 11inch x 17inch drawing to be printed on to an 8.5inch x 11inch paper size. (Default Value = FALSE)
PrintStartPage | Numeric | Specifies the first page to print.
PrinterName | String | The Name of the Printer
PrinterPort | String | The port name (ie. "LPT1")
PrinterPaperWidth | Numeric | The paper width in millimeters.
PrinterPaperHeight | Numeric | The paper height in millimeters.
PrinterUsePhysicalOffset | Boolean | Flag to use the Printer's Physical Offset values when displaying pages for the currently selected printer. This will affect how the page is viewed while in the print preview by offsetting all object locations by the PrinterPhysicalOffsetX and PrinterPhysicalOffsetY values according to the selected printer resolution.
PrinterPhysicalOffsetX | Numeric | The physical offset from the left edge of the paper that the printer begins printing at.
PrinterPhysicalOffsetY | Numeric | The physical offset from the top edge of the paper that the printer can physically start printing at.
PrinterCount | Numeric | The number of printers installed on the current system running the control.
PrinterID | Numeric (Read/Write) String (Write) | The currently selected printer ID number. Changing this number between 1 and the PrinterCount value will select a different printer. The PrinterID Property can also be set using the text string name of the printer. The value read will always be numeric.
PrinterYResolution | Numeric | The Y resolution currently set for the currently selected printer.
PrinterPrintQuality | Numeric | The print quality currently set for the currently selected printer. Sometimes this value is a number representing the resolution in dpi or it can also be of 4 preset values: – 1 (Draft) – 2 (Low Resolution) – 3 (Medium Resolution) – 4 (High Resolution)
PrinterScale | Numeric | The current scaling resolution for the currently selected printer.
PrinterBinCount | Numeric | The number of bins for the currently selected printer.
PrinterPaperBinName | String | The name of the currently selected bin for the currently selected printer.
PrinterCopies | Numeric | The number of copies set to print for the currently selected printer. Not all printers have the ability to print multiple copies. However, the Report Preview Control can print multiple copies regardless of the printer's capabilities.
PrinterMaxCopies | Numeric | The maximum number of copies that the currently selected printer can print using it's printer driver.
PrinterColor | Numeric | The current setting for printing color or monochrome on the currently selected printer.


PDF Document Properties

Mind's Eye Report Engine PDF Document Properties

PDF DOCUMENT PROPERTIES

The following properties can be used to specify what is stored into a PDF document when it is created using the SaveToPDF Method or clicking on the Save To PDF command button by the user.

Property Name | Data Type | Description
PDFAuthor | String | The Author of the PDF Document. Default value: ""
PDFBitmapQuality | Numeric | The Quality Level to use for compressing BITMAP images between 1 and 100 using JPEG compression. Default Value: 100
PDFCompress | Boolean | Flag to indicate if the PDF document will be compressed when saved. Default Value: TRUE
PDFCompressBitmaps | Boolean | Flag to indicate whether or not BITMAP images will be compressed when saved into the PDF document. Default value: TRUE
PDFCreator | String | The Creator of the PDF document. Default value: "Mind's Eye Report Engine Control"
PDFDisplayConfirmationAfterCreate | Boolean | Displays a confirmation dialog after creating the PDF document.
PDFDisplaySecurityOptions | Boolean | Used to Hide or Display the Security Options Tab on the PDF Save Dialog Document Options Dialog. With this Property set to TRUE, the PDF Security Options Properties will be displayed for End Users to change while saving a PDF Document from the Toolbar. Default Value: FALSE
PDFEmbedFonts | Boolean | Flag to indicate whether Fonts marked for embedding will be embedded into the PDF document when generated. Embedding True Type fonts into a document will ensure that the document will appear properly when loaded into a PDF Viewer tool when viewed on a computer that does not have those fonts installed. However, embedding fonts can increase the file size between 60KB to 500KB per font on average within a document. Set this value to TRUE to embed True Type Fonts. NOTE: Individual Fonts must be flagged to be embedded using the PDFFontMetric Method. Default Value: FALSE
PDFEncrypt | Boolean | Flag to indicate whether or not the PDF Document is encrypted when it is saved. Default Value: 0 - No Encryption 1 - 40 Bit 2 - 128 Bit (Currently Not Supported)
PDFFileName | String | Specifies the default PDF Filename to use when saving to a PDF document. If the PDFPromptForSaveToPDF is set to FALSE then this will be the name of the document that will be saved.
PDFFontCount | Numeric | The number of unique PDF Fonts in the report currently. This value is increased automatically as new text is added to a report using the AddText() Method. If running reports using the Visual FoxPro Class Library, this property will be automatically increased as well. This property can be used along with the PDFFontMetricMethod to determine all of the unique PDF Fonts in the current report (Read Only)
PDFJPEGQuality | Numeric | The Quality Level to use for compressing JPEG images between 1 and 100 using JPEG compression. Images that are already compressed at a lower quality than the specified quality will not be modified. Default value: 90.
PDFKeywords | String | A comma delimted list of Keywords for the PDF Document. Default value: ""
PDFMargin | Numeric | The PDF Margin in inches used when saving the PDF document for both the top and left margin of the page. Changing the PDFMargin Property sets the PDFXOffset and PDFYOffset to the PDFMargin value. To override the individual margins use the PDFXOffset and PDFYOffset Properties. Default Value: 0.25
PDFOpenAfterCreate | Boolean | Specifies that ShellExecute will be used to attempt to open the PDF document created with the default PDF viewer registered on the system.
PDFOwnerPassword | String | The Owner Password to be used when creating a PDF Document and the document is to be encrypted by MERE. Default Value: ""
PDFPromptForSaveToPDF | Booelan | Specifies whether or not the user will be prompted for a PDF File Name when the Save To PDF button is clicked on in the Report Engine Toolbar. Set this value to FALSE to suppress the display of the prompt window when the user clicks on the Save To PDF toobar button. Default Value: TRUE
PDFSubject | String | The Subject of the PDF document when saved. Default Value: ""
PDFTitle | String | The Title of the PDF document when saved. Default Value: ""
PDFUserPassword | String | The User Password to be used when encrypting a PDF document to disk. Default Value: ""
PDFXOffset | Numeric | The X Offset of the Left Margin in inches used when saving the PDF document for all pages within the report. This will shift ALL pages within the document left or right by the amount specified when the PDF Document is generated. This Property does not affect the Preview or Printing of reports.
PDFYOffset | Numeric | The Y Offset of the Top Margin in inches used when saving the PDF document for all pages within the report. This will shift ALL pages within the document Up or Down by the amount specified when the PDF Document is generated. This Property does not affect the Preview or Printing of reports.


Chart Properties

Mind's Eye Report Engine Chart Properties

CHART PROPERTIES

All Properties are Read/Write at runtime and apply only to the currently selected chart or the last chart added using the AddChart() Method.

Property Name | Data Type | Description
Chart3DPercent | Numeric | Controls the ratio of the 3-D effect depending on the Chart dimensions. Valid range of values is 1 to 100. (Default value = 15)
Chart3DView | Boolean | Specifies whether currently selected Chart will be displayed in a simulated 3-D View. (Default Value = TRUE)
Chart3DWalls | Boolean | Specifies whether currently selected Chart will be display Walls in a simulated 3-D View. (Default Value = TRUE)
ChartAxisVisible | Boolean | Specifies whether the Axes for the Chart will be visible or not.
ChartBackWallColor | Numeric | Specifies the Color of the Chart Back Wall.
ChartBackWallSize | Numeric | Specifies the Size of the Chart Back Wall.
ChartBackWallTransparent | Boolean | Specifies whether or not the Chart Back Wall is Transparent.
ChartBottomWallColor | Numeric | Specifies the Color of the Chart Bottom Wall.
ChartBottomWallSize | Numeric | Specifies the Size of the Chart Bottom Wall.
ChartBottomWallTransparent | Boolean | Specifies whether or not the Chart Bottom Wall is Transparent.
ChartDataPointLegendFontSize | Numeric | Specifies the font size for the Data Points Legend.
ChartGradientDirection | Numeric | The direction the Gradient background is to be displayed. Valid Values: 0 - Top to Bottom 1 - Bottom to Top 2 - Left to Right 3 - Right to Left 4 - From Center 5 - From Top Left 6 - From Bottom Left
ChartGradientEndColor | Numeric | The color to end the gradient with.
ChartGradientStartColor | Numeric | The color to start the gradient with.
ChartGradientVisible | Boolean | Specifies if the background color is to be displayed as a gradient.
ChartLeftWallColor | Numeric | Specifies the Color of the Chart Left Wall.
ChartLeftWallSize | Numeric | Specifies the Size of the Chart Left Wall.
ChartWallTransparent | Boolean | Specifies whether or not the Chart Left Wall is Transparent.
ChartLegendBorderColor | Numeric | Specifies the color of the Legend border.
ChartLegendBorderStyle | Numeric | Specifies the line style for the border of the Chart Legend. Valid Values: 0 - Solid 1 - Dash 2 - Dot 3 - Dash Dot 4 - Dash Dot Dot 5 - Clear 6 - InsideFrame
ChartLegendBorderWidth | Numeric | Specifies the width in pixels for the Legend border. Valid values are between 0 and 25.
ChartLegendFontColor | Numeric | Specifies the Legend font color.
ChartLegendFontName | String | Font name to use for the Legend.
ChartLegendFontSize | Numeric | Font size to use for the Legend.
ChartLegendMarginSize | Numeric | The amount of margin in pixels to use between the legend and the chart.
ChartLegendPosition | Numeric | The position on the chart that the legend should be displayed. Valid Values: 1 - Left Top 2 - Middle Top 3 - Right Top 4 - Bottom
ChartLegendResizeChart | Boolean | Specifies if the chart should be resized to accomodate the Legend.
ChartLegendShadowColor | Numeric | Specifies the color of the shadow on the Legend.
ChartLegendShadowSize | Numeric | Specifies the size of the shadow under the Legend in pixels.


Watermark Display Properties

Mind's Eye Report Engine Watermark Display Properties

WATERMARK PROPERTIES

Watermarks can be displayed on pages by simply setting the WatermarkText property for the current page. Each page has it's own independent WatermarkText property. Therefore, each and every page can have a separate Watermark with its own Watermark settings. To set the Watermark Properties for a given page go to the page that you want to set the Properties for and set them.

Property Name | Data Type | Description
WaterMarkBackColor | Numeric | Specifies the Back Color of the WaterMark text for the current page.
WaterMarkForeColor | Numeric | Specifies the Fore Color of the WaterMark text for the current page.
WatermarkFontName | String | Specifies the Font Name of the WaterMark text for the current page.
WatermarkFontSize | Numeric | Specifies the Font Size of the WaterMark text for the current page.
WatermarkFontStyle | String | Specifies the Font Style of the Month and Year. Any of the values listed below can be combined together. Valid Values are: "" - Normal "B" - Bold "I" - Italic "U" - Underline "S" - Strikeout
WatermarkRotationAngle | Numeric | Specifies the Rotation Angle for the WaterMark text for the current page.
WatermarkText | String | Specifies the Watermark Text to be displayed on the current page.


Calendar Display Properties

Mind's Eye Report Engine Calendar Display Properties

CALENDAR DISPLAY PROPERTIES

Property Name | Data Type | Description
CalendarDateFontColor | Numeric | Specifies the font color of the numeric dates.
CalendarDateFontName | String | Specifies the Font Name of the numeric dates.
CalendarDateFontSize | Numeric | Specifies the Font Size of the numeric dates.
CalendarDateFontStyle | String | Specifies the Font Style of the numeric dates. Any of the values listed below can be combined together. Valid Values are: "" - Normal "B" - Bold "I" - Italic "U" - Underline "S" - Strikeout
CalendarGridLineColor | Numeric | Specifies the color of the Grid Lines to be drawn for the calendar.
CalendarGridLineWidth | Numeric | Specifies the point size of the Grid Lines to be drawn for the calendar.
CalendarHeight | Numeric | Specifies the Height of the Calendar in inches to be drawn on the Page.
CalendarLeft | Numeric | Specifies the location of the Left edge of the Calendar in inches on the page.
CalendarMonth | Numeric | Specifies the starting month of the Calendar to be displayed in the Report Engine Control.
CalendarMonthFontColor | Numeric | Specifies the Font Color of the Month and Year name in the Calendar to be displayed.
CalendarMonthFontName | String | Specifies the Font Name of the Month and Year in the calendar to be displayed.
CalendarMonthFontSize | Numeric | Specifies the Font Size of the Month and Year displayed in the calendar.
CalendarMonthFontStyle | String | Specifies the Font Style of the Month and Year. Any of the values listed below can be combined together. Valid Values are: "" - Normal "B" - Bold "I" - Italic "U" - Underline "S" - Strikeout
CalendarShow | Boolean | Specifies whether or not the Calendar Overlay is displayed on the Report Object Control.
CalendarShowGridLines | Boolean | Specifies whether or not the Grid Lines are displayed on the calendar.
CalendarTop | Numeric | Specifies the location of the Top of the calendar on the page in inches.
CalendarWidth | Numeric | Specifies the Width of the Calendar in inches to be drawn on the page.
CalendarYear | Numeric | Specifies the starting Year of the Calendar to be displayed in the Report Engine Control.


Methods

Mind's Eye Report Engine ActiveX Control Methods

Methods

The following Methods are available for use on the Report Engine Control.

Method Name | Return Value | Description
AboutBox | Boolean | Displays the About Box for the control.
AddBarCode | Boolean | Adds a Barcode object to the report surface.
AddChart | Boolean | Adds a Chart object to the Report Surface.
AddFRXReport Engine Controlord | void | This method is used by the MindsEyeReportEngine VFP VCX Report Engine. It should not be used outside of this context.
AddFRXReport Engine Controlord1 | void | This method is used by the MindsEyeReportEngine VFP VCX Report Engine. It should not be used outside of this context.
AddFRXReport Engine Controlord2 | void | This method is used by the MindsEyeReportEngine VFP VCX Report Engine. It should not be used outside of this context.
AddLine |  | Adds a line to the report surface.
AddPicture |  | Adds an Image to the Report.
AddReportField |  | Adds a Report Object Field for evaluation to the Report Surface.
AddShape |  | Adds a Report Engine Control rectangle or circular shape to the report surface.
AddText |  | Adds text to the report surface.
AddToolbarButton |  | Adds a custom Toolbar Button to the Report Engine Control's Toolbar at runtime.
Clear |  | Clears all pages and objects from the Report Engine Control.
ClearAll |  | Clears all pages and objects from the Report Engine Control.
ClearLastItem |  | Clears the last object items on the current page of the Report Engine Control.
CopyPageToClipboard |  | Copies the current report page or the page specified to the clipboard.
DisplayReportExpression |  | Displays or hides the Report Expression Dialog Box (0 - Hides, 1 - Shows)
FRXClear |  | Clears all of the FRX Definitions from memory.
FRXLoadReport |  | Loads an FRX Report File into the Control from the File Name passed. Returns a value of TRUE if successful and FALSE if unsuccessful. Check the LastError property for Error Codes.
FRXLocateBands |  | Locates the Bands of the currently loaded FRX Report definition.
FRXPaintDetailBand |  | Paints the Detail Band of the FRX Report Definition on the Report Surface.
FRXPaintPage |  | No Longer used.
FRXPaintPageBottom |  | Paints the Page Footer and Page Summary onto the Report.
FRXPaintPageTop |  | Paints the Title Band, Page Header Band and Group Header Bands onto the Report
FRXSaveReport |  | Saves an FRX Report defined in the Control to the File Name passed. Returns a value of TRUE if successful and FALSE if unsuccessful. Check the LastError property for Error Codes.
FRXSetDate |  | Updates the DateTime Value in the FRX Report Engine Control from the Character DateTime value passed.
FRXSetDateTime |  | Updates the DateTime Value in the FRX Report Engine Control from the Character DateTime value passed.
FRXSetLogical |  | Updates the Logical Data value of the passed nIndex FRX Report Engine Control.
FRXSetNumeric |  | Updates the Numeric Data value of the passed nIndex FRX Report Engine Control.
PrinterAddForm |  | Adds a Custom Form sizes to a Windows NT/2K/XP system for printing to custom paper sizes.
PrinterDeleteForm |  | Deletes a Custom Form sizes to a Windows NT/2K/XP system for printing to custom paper sizes.
SetPrinterTo |  | The SetPrinterTo Method can be used to change the Currently Selected Printer for the Report Engine Control. This updates the Printer DropDown List printer and the Printer Dialog Box as well.


General Report Engine Methods


AddToolbarButton Method

Description:

The AddToolbarButton Method can be used to add your own Custom Toolbar Buttons at runtime programmatically. There is an OnToolbarButtonClick Event that fires when a custom Toolbar Button is clicked. This event can then be used to call your own custom code in your applications.

Syntax:

oReportEngine.AddToolbarButton(cName, [cBitmapFileName], [cHint], [nPosition])

Return Type:

Parameters:

cName | String | The name to be used for the custom button. This name is returned in the OnToolbarButtonClick Event so that you can decode which button was clicked on in your application.
cBitmapFileName | String | (Optional) Specifies the name of the Bitmap file to display on the Custom Toolbar Button. The Bitmap file must be a 16x16 bitmap image otherwise the bitmap will not be loaded into the toolbar button. Not specifying a Bitmap will display a blank button.
cHint | String | (Optional) Specifies the Hint or Tooltip to be displayed when the mouse hovers over the button.
nPosition | Numeric | (Optional) Specifies which where to place the button on the Toolbar. By default the new button will be placed at the far left position in front of all other toolbar buttons or objects.

Example:

* The following example will add a new custom toolbar button to the toolbar

* on the Report Engine at runtime. The name of the button is MyButton and the

* the name of the bitmap file is MyBitmap.BMP and the Hint for the button is

* My Custom Toolbar Button.

oReportEngine.AddToolbarButton('MyButton','MyBitmap.BMP','My Custom Toolbar Button')

See Also:


DeletePage Method

Description:

The DeletePage Method removes a page from the Report Engine or a range of pages. The paramaters are nStartPage and nLastPage and are optional. By default, the currently selected page will be deleted if no parameters are passed. Specifying only the nStartPage page number will delete only that page. Specifying the nStartPage and nLastPage will delete all pages between the specified page range.

Syntax:

oReportEngine.DeletePage([nStartPage], [nLastPage])

Return Type:

Parameters:

nStartPage | Numeric | (Optional) Specifies the first page to delete. The default value is 0 and corresponds to the currently active page.
nLastPage | Numeric | (Optional) Specifies the last page to be deleted. If the nStartPage is a positive value and nLastPage is omitted or has a value of 0, then only the page specified as the nStartPage will be deleted. If nStartPage is omitted and nLastPage is a positive value, then the currently active page and all pages up to the nLastPage specified will be deleted. The default value is 0 and corresponds to the currently active page.

Example:

* The following example Deletes the current page from the Report.

oReportEngine.DeletePage()

* The following example Deletes page 10 from the Report.

oReportEngine.DeletePage(10)

* The following example Deletes pages 1 through 10 from the Report.

oReportEngine.DeletePage(1,10)

See Also:


NewPage Method

Description:

The NewPage Method is used to add new pages to the Report Engine at runtime. Page sizes can be set to any size. A PDF document can accept any page size when generated, however, printing is a different issue and may require a custom page size.

When the NewPage Method is called the new page will be added to the end of the report unless the nPageNumber parameter is set. If the nPageNumber parameter is set, the page can be inserted anywhere within the current report. For example, passing nPageNumber=1 will insert the new page prior to page 1 in the current report.

Syntax:

oReportEngine.NewPage([nPageWidth], [nPageHeight], [nOrientation], [nBinNumber], [nPageNumber=0])

Return Type:

Parameters:

nPageWidth | Numeric | (Optional) Specifies the Page Width in inches for the new page.
nPageHeight | Numeric | (Optional) Specifies the Page Height in inches for the new page.
nOrientation | Numeric | (Optional) Specifies the orientation of the newly added page. Valid Values: 0 = Portrait (Default) 1 = Landscape
nBinNumber | Numeric | (Optional) Specifies the PaperBin for the page to be printed from. Valid Values: 0 = DMBIN_AUTO (Default Value) 1 = DMBIN_UPPER 2 = DMBIN_LOWER 3 = DMBIN_MIDDLE 4 = DMBIN_MANUAL 5 = DMBIN_ENVELOPE 6 = DMBIN_ENVMANUAL 7 = DMBIN_AUTO 8 = DMBIN_TRACTOR 9 = DMBIN_SMALLFMT 10 = DMBIN_LARGEFMT 11 = DMBIN_LARGECAPACITY 14 = DMBIN_CASSETTE 15 = DMBIN_FORMSOURCE 256 and above = DMBIN_USER (Values 256 and above will be specific to the printer being used.)
nPageNumber | Numeric | (Optional) Specifies the Page Number where to place the new page into the report. If nPageNumber=1 then the new page will be inserted as Page 1 in the report. By default the new page will be appended to the end of the report.

Example:

* The following example adds a new page to the report engine with a size

* of 8.5 inches by 11 inches. By default the Orientation is Portrait

oReportEngine.NewPage(8.5,11)

* Add a Landscape page to the report engine

oReportEngine.NewPage(8.5,11,1)

* Both of the following examples add a new

* 11x17 inch Landscape page to the report engine

oReportEngine.NewPage(17,11)

oReportEngine.NewPage(11,17,1)

See Also:


NewPageByPaperSize Method

Description:

The NewPageByPaperSize Method is used to add new pages to the Report Engine at runtime by specifying a PaperSize by number rather than a Width and Height. Using the NewPageByPaperSize sets the newly added page to the dimensions matching the PaperSize Number.

When the NewPageByPaperSize Method is called the new page will be added to the end of the report unless the nPageNumber parameter is set. If the nPageNumber parameter is set, the page can be inserted anywhere within the current report. For example, passing nPageNumber=1 will insert the new page prior to page 1 in the current report.

Syntax:

oReportEngine.NewPageByPaperSize(nPaperSize, [nOrientation], [nBinNumber], [nPageNumber=0])

Return Type:

Parameters:

nPaperSize

Numeric

Specifies the PaperSize from the following list of Paper Size Values:

1 = DMPAPER_LETTER (Letter 8.5 x 11 in)

2 = DMPAPER_LETTERSMALL (Letter 8.5 x 11 in)

3 = DMPAPER_TABLOID (Tabloid 11 x 17 in)

4 = DMPAPER_LEDGER (Ledger 17 x 11 in)

5 = DMPAPER_LEGAL (Legal 8.5 x 14 in)

6 = DMPAPER_STATEMENT (Statement 5.5 x 8.5 in)

7 = DMPAPER_EXECUTIVE (Executive 7.25 x 10.5 in)

8 = DMPAPER_A3 (A3 297 x 420 mm)

9 = DMPAPER_A4 (A4 210 x 297 mm)

10 = DMPAPER_A4SMALL (A4 Small 210 x 297 mm)

11 = DMPAPER_A5 (A5 148 x 210 mm)

12 = DMPAPER_B4 (B4 (JIS) 250 x 354 mm)

13 = DMPAPER_B5 (B5 (JIS) 182 x 257 mm)

14 = DMPAPER_FOLIO (Folio 8.5 x 13 in)

15 = DMPAPER_QUARTO (Quarto 215 x 275 mm)

16 = DMPAPER_10X14 (10 x 14 in)

17 = DMPAPER_11X17 (11 x 17 in)

18 = DMPAPER_NOTE (Note 8.5 x 11 in)

19 = DMPAPER_ENV_9 (Envelope #9 3.875 x 8.875 in)

20 = DMPAPER_ENV_10 (Envelope #10 4.125 x 9.5 in)

21 = DMPAPER_ENV_11 (Envelope #11 4.5 x 10.375 in)

22 = DMPAPER_ENV_12 (Envelope #12 4 x 11 in)

23 = DMPAPER_ENV_14 (Envelope #14 5 x 11.5 in)

24 = DMPAPER_CSHEET (C Size Sheet 12 x 22 in)

25 = DMPAPER_DSHEET (D Size Sheet 22 x 34 in)

26 = DMPAPER_ESHEET (E Size Sheet 34 x 44 in)

27 = DMPAPER_ENV_DL (Envelope DL 110 x 220 mm)

28 = DMPAPER_ENV_C5 (Envelope C5 162 x 229 mm)

29 = DMPAPER_ENV_C3 (Envelope C3 324 x 458 mm)

30 = DMPAPER_ENV_C4 (Envelope C4 229 x 324 mm)

31 = DMPAPER_ENV_C6 (Envelope C6 114 x 162 mm)

32 = DMPAPER_ENV_C65 (Envelope C65 114 x 229 mm)

33 = DMPAPER_ENV_B4 (Envelope B4 250 x 353 mm)

34 = DMPAPER_ENV_B5 (Envelope B5 176 x 250 mm)

35 = DMPAPER_ENV_B6 (Envelope B6 176 x 125 mm)

36 = DMPAPER_ENV_ITALY (Envelope 110 x 230 mm)

37 = DMPAPER_ENV_MONARCH (Envelope Monarch 3.875 x 7.5 in)

38 = DMPAPER_ENV_PERSONAL (Envelope 3.625 x 6.5 in)

39 = DMPAPER_FANFOLD_US (US Std Fanfold 14.875 x 11 in)

40 = DMPAPER_FANFOLD_STD_GERMAN (German Std Fanfold 8.5 x 12 in)

41 = DMPAPER_FANFOLD_LGL_GERMAN (German Legal Fanfold 8.5 x 13 in)

nOrientation

Numeric

(Optional) Specifies the orientation of the newly added page.

Valid Values:

0 = Portrait (Default)

1 = Landscape

nBinNumber

Numeric

(Optional) Specifies the PaperBin for the page to be printed from.

Valid Values:

0 = DMBIN_AUTO (Default Value)

1 = DMBIN_UPPER

2 = DMBIN_LOWER

3 = DMBIN_MIDDLE

4 = DMBIN_MANUAL

5 = DMBIN_ENVELOPE

6 = DMBIN_ENVMANUAL

7 = DMBIN_AUTO

8 = DMBIN_TRACTOR

9 = DMBIN_SMALLFMT

10 = DMBIN_LARGEFMT

11 = DMBIN_LARGECAPACITY

14 = DMBIN_CASSETTE

15 = DMBIN_FORMSOURCE

256 and above = DMBIN_USER (Values 256 and above will be specific to the printer being used.)

nPageNumber

Numeric

(Optional) Specifies the Page Number where to place the new page into the report. If nPageNumber=1 then the new page will be inserted as Page 1 in the report.

By default the new page will be appended to the end of the report.

Example:

* The following example adds a new page to the report engine with a size

* of 8.5 x 11 inches. By default the Orientation is Portrait

oReportEngine.NewPageByPaperSize(1)

* Add an 8.5 x 11 inch Landscape page to the report engine

oReportEngine.NewPageByPaperSize(1,1)

* All of the following examples add a new

* 11x17 inch Landscape page to the report engine

oReportEngine.NewPageByPaperSize(3,1)

oReportEngine.NewPageByPaperSize(4)

See Also:


SetPageByPaperSize Method

Description:

The SetPageByPaperSize Method is used to change the current page in the Report Engine to a specific size by from a list of predefined Paper Sizes by number rather than specifying a Width and Height for the page.

When specifying the Paper Size, you can optionally assign the Orientation for the page and the PaperBin assignment for the page. Assigning the PaperBin will result in the page being pulled from a specific Paper Bin or Tray from a printer only when printing.

Syntax:

oReportEngine.SetPageByPaperSize(nPaperSize, [nOrientation], [nBinNumber])

Return Type:

Parameters:

nPaperSize

Numeric

Specifies the PaperSize from the following list of Paper Size Values:

1 = DMPAPER_LETTER (Letter 8.5 x 11 in)

2 = DMPAPER_LETTERSMALL (Letter 8.5 x 11 in)

3 = DMPAPER_TABLOID (Tabloid 11 x 17 in)

4 = DMPAPER_LEDGER (Ledger 17 x 11 in)

5 = DMPAPER_LEGAL (Legal 8.5 x 14 in)

6 = DMPAPER_STATEMENT (Statement 5.5 x 8.5 in)

7 = DMPAPER_EXECUTIVE (Executive 7.25 x 10.5 in)

8 = DMPAPER_A3 (A3 297 x 420 mm)

9 = DMPAPER_A4 (A4 210 x 297 mm)

10 = DMPAPER_A4SMALL (A4 Small 210 x 297 mm)

11 = DMPAPER_A5 (A5 148 x 210 mm)

12 = DMPAPER_B4 (B4 (JIS) 250 x 354 mm)

13 = DMPAPER_B5 (B5 (JIS) 182 x 257 mm)

14 = DMPAPER_FOLIO (Folio 8.5 x 13 in)

15 = DMPAPER_QUARTO (Quarto 215 x 275 mm)

16 = DMPAPER_10X14 (10 x 14 in)

17 = DMPAPER_11X17 (11 x 17 in)

18 = DMPAPER_NOTE (Note 8.5 x 11 in)

19 = DMPAPER_ENV_9 (Envelope #9 3.875 x 8.875 in)

20 = DMPAPER_ENV_10 (Envelope #10 4.125 x 9.5 in)

21 = DMPAPER_ENV_11 (Envelope #11 4.5 x 10.375 in)

22 = DMPAPER_ENV_12 (Envelope #12 4 x 11 in)

23 = DMPAPER_ENV_14 (Envelope #14 5 x 11.5 in)

24 = DMPAPER_CSHEET (C Size Sheet 12 x 22 in)

25 = DMPAPER_DSHEET (D Size Sheet 22 x 34 in)

26 = DMPAPER_ESHEET (E Size Sheet 34 x 44 in)

27 = DMPAPER_ENV_DL (Envelope DL 110 x 220 mm)

28 = DMPAPER_ENV_C5 (Envelope C5 162 x 229 mm)

29 = DMPAPER_ENV_C3 (Envelope C3 324 x 458 mm)

30 = DMPAPER_ENV_C4 (Envelope C4 229 x 324 mm)

31 = DMPAPER_ENV_C6 (Envelope C6 114 x 162 mm)

32 = DMPAPER_ENV_C65 (Envelope C65 114 x 229 mm)

33 = DMPAPER_ENV_B4 (Envelope B4 250 x 353 mm)

34 = DMPAPER_ENV_B5 (Envelope B5 176 x 250 mm)

35 = DMPAPER_ENV_B6 (Envelope B6 176 x 125 mm)

36 = DMPAPER_ENV_ITALY (Envelope 110 x 230 mm)

37 = DMPAPER_ENV_MONARCH (Envelope Monarch 3.875 x 7.5 in)

38 = DMPAPER_ENV_PERSONAL (Envelope 3.625 x 6.5 in)

39 = DMPAPER_FANFOLD_US (US Std Fanfold 14.875 x 11 in)

40 = DMPAPER_FANFOLD_STD_GERMAN (German Std Fanfold 8.5 x 12 in)

41 = DMPAPER_FANFOLD_LGL_GERMAN (German Legal Fanfold 8.5 x 13 in)

nOrientation

Numeric

(Optional) Specifies the orientation of the newly added page.

Valid Values:

0 = Portrait (Default)

1 = Landscape

nBinNumber

Numeric

(Optional) Specifies the PaperBin for the page to be printed from.

Valid Values:

0 = DMBIN_AUTO (Default Value)

1 = DMBIN_UPPER

2 = DMBIN_LOWER

3 = DMBIN_MIDDLE

4 = DMBIN_MANUAL

5 = DMBIN_ENVELOPE

6 = DMBIN_ENVMANUAL

7 = DMBIN_AUTO

8 = DMBIN_TRACTOR

9 = DMBIN_SMALLFMT

10 = DMBIN_LARGEFMT

11 = DMBIN_LARGECAPACITY

14 = DMBIN_CASSETTE

15 = DMBIN_FORMSOURCE

256 and above = DMBIN_USER (Values 256 and above will be specific to the printer being used.)

Example:

* The following example changes the current page size in the Report Engine

* to 8.5 x 11 inches. By default the Orientation is Portrait

oReportEngine.SetPageByPaperSize(1)

* This example changes the current page to an 8.5 x 11 inch Landscape page

oReportEngine.SetPageByPaperSize(1,1)

* The following exmples all set the current page to an 11x17 inch Landscape

* size

oReportEngine.SetPageByPaperSize(3,1)

oReportEngine.SetPageByPaperSize(4)

See Also:


SetAll Method

Description:

The SetAll Method can be used to set the value of a Property of the Report Engine that applies to more than one page with a single line of code. For example, this method can be used to set properties such as the WatermarkText Property for all pages or a range of pages in the Report Engine.

Current Properties Supported:

PaperBin

WatermarkFontName

WatermarkFontSize

WatermarkFontStyle

WatermarkForeColor

WatermarkRotationAngle

WatermarkText

Syntax:

oReportEngine.SetAll(cProperty, Value, [cClass], [nStartRange=0], [nEndRange=0])

Return Type:

Parameters:

cProperty | String | The name of the Property to set such as 'WatermarkText' or 'WatermarkRotationAngle'
Value | String Numeric Boolean | Specifies the new setting for the property. The data type of Value depends on the property being set.
cClass | String | (Optional) Specifies the class name to apply the value to.
nStartRange | Numeric | (Optional) Specifies the starting range to begin setting the new value.
nEndRange | Numeric | (Optional) Specifies the ending range to set the new value.

Example:

* The following example will set the WatermarkText Property to 'Draft Copy'

* for all pages within the Report Engine

oReportEngine.SetAll('WatermarkText','Draft Copy')

* The following example will set the WatermarkRotationAngle Property

* to 45 degrees between pages 5 and 10 within the Report Engine

oReportEngine.SetAll('WatermarkRotationAngle',45,,5,10)

See Also:


SetPageNumberToOne Method

Description:

The SetPageNumberToOne Method is used to flag a physical page in the Report Engine that it should reset the virtual page number to one again. The Report Engine has it's own real time page numbering capability using ReportField objects. This feature supports reports where the page number should be reset to Page 1 each time a particular Group in a Report Changes or when a different section of a report occurs or even when multiple reports are appended together into a single report.

Being able to mark physical pages to reset their virtual page numbering to one, allows the 'real time' Page X of Y functionality to mathematically compute via a lookup what the page X of Y is from quickly scanning the internal page break array.

Inserting new pages or deleting pages from the Report Engine will still maintain the Page X of Y until a page marked as Reset To Page One is removed causing the Page X of Y to increase the Y value since all pages following the Page with the Reset To Page One will now be counted as part of the current page numbering section.

Syntax:

oReportEngine.SetPageNumberToOne(nPageNumber)

Return Type:

Parameters:

nPageNumber

Numeric

Specifies the Physical Page Number in the Report Engine to begin numbering the Virtual Page Numbers at page one.

Example:

* The following example creates an entry in the Report Engine's Page Break

* array to Page 10. Resulting in Physical Page 10 being displayed as Page 1 in the

* Virtual Page when displaying _PAGENO in a ReportField Object.

*

* If the Report Engine currently contained 20 pages in the report and Physical Page

* one in the Report Engine had a ReportField expression of:

* 'Page: '+ALLTRIM(STR(_PAGENO)) + ' of '+ALLTRIM(STR(_PAGETOTAL))

*

* Then the output on the page 1 would be:

* Page: 1 of 9

*

* If the same ReportField Object was placed on Physical Page 10 of the Report Engine

* then the output would appear as:

* Page: 1 of 9

*

oReportEngine.SetPageNumberToOne(10)

See Also:


ZoomIn Method

Description:

The ZoomIn Method is used to zoom in on the Report Engine by the ZoomScale amount. Each call to the ZoomIn Method will increase the Scale Property by the ZoomScale amount and refresh the Report Engine.

Syntax:

oReportEngine.ZoomIn

Return Type:

Parameters: none

Example:

oReportEngine.ZoomIn

See Also:

ZoomOut


ZoomOut Method

Description:

The ZoomOut Method is used to zoom out on the Report Engine by the ZoomScale amount. Each call to the ZoomOut Method will decrease the Scale Property by the ZoomScale amount and refresh the Report Engine.

Syntax:

oReportEngine.ZoomOut

Return Type:

Parameters: none

Example:

oReportEngine.ZoomOut

See Also:

ZoomIn


Report Navigation Methods

The Methods in this section are used to programmatically navigate a Report that has been created or loaded into the Report Engine at Runtime. There are methods to move the page pointer.


FirstPage Method

Description:

The FirstPage Method is used to move to the first physical page in the Report Engine.

Syntax:

oReportEngine.FirstPage

Return Type:

Parameters:None

Example:

oReportEngine.FirstPage()

See Also:


PriorPage Method

Description:

The PriorPage Method is used to move the currently selected page in the Report Engine to the Prior Page.

For example if the Report Engine is currently on Page 10, calling the PriorPage Method will move the page to Page 9.

Syntax:

oReportEngine.PriorPage

Return Type:

Parameters:None

Example:

oReportEngine.PriorPage()

See Also:


NextPage Method

Description:

The NextPage Method is used to move the currently selected page in the Report Engine to the next physical page.

For example if the Report Engine is currently on Page 1, then calling the NextPage Method will move the Report Engine to Page 2.

Syntax:

oReportEngine.NextPage

Return Type:

Parameters:None

Example:

oReportEngine.NextPage()

See Also:


LastPage Method

Description:

The LastPage Method is used to move to the last physical page in the Report Engine.

Syntax:

oReportEngine.LastPage

Return Type:

Parameters:None

Example:

oReportEngine.LastPage()

See Also:


GoToPage

Description:

The GoToPage Method is used to move the currently selected page in the Report Engine to a specific physical Page.

Syntax:

oReportEngine.GoToPage(nPageNumber)

Return Type:

Parameters:

nPageNumber

Numeric

Specifies the Physical Page Number in the Report Engine to move to and select as the active page.

Example:

oReportEngine.GoToPage(10)

See Also:


Charting Methods and Sample Code

Mind's Eye Report Engine Charting Methods and Sample Code

The Report Engine has a built in Chart Engine which allows you to create Charts programmatically within your application without the need of any 3rd party chart tools. The Chart Engine is completely contained within the ActiveX control. The methods for adding charts to your reports are both intuitive and easy to use. There is also a lot of flexibility in what can be controlled all from the Chart Properties in the Report Engine.

Multiple charts can be added to each page of your report. Each Chart Object placed onto a report page maintains it's own data internally and is displayed/painted in real time when previewing, printing and saving your reports to PDF documents.


AddChart Method

Description:

The AddChart Method will add a Chart Object to a Report Page as a specific Chart Type at the specified nHPOS, nVPOS with the nWidth and nHeight specified.

Syntax:

oReportEngine.AddChart(cName, nChartType, nHPos, nVPos, nWidth, nHeight)

Return Type:

Numeric - Index Reference number of object on page.

Parameters:

cName | String | A name identifying the object that allows for searching for the object by name at runtime. Optional.
nChartType | Numeric | Specifies the Chart Type. Valid Chart Types 0 - Line Series 1 - Vertical Bar Series 2 - Horizontal Bar Series 3 - Area Series 4 - Point Series 5 - Pie Chart Series
nHPos | Numeric | Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.
nVPos | Numeric | Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.
nWidth | Numeric | Specifies the Width of the Chart object on the report surface in inches up to 10,000th of an inch.
nHeight | Numeric | Specifies the Height of the Chart object on the report surface in inches up to 10,000th of an inch.

Example:

oReportEngine.AddChart("", 1, 1.0, 1.0, 5, 5)

oReportEngine.ChartAddXYData(100,0,'Software',RGB(255,0,0))

oReportEngine.ChartAddXYData(220,0,'Hardware',RGB(255,0,0))

oReportEngine.ChartAddXYData(850,0,'Consulting',RGB(255,0,0))

This adds a Vertical Bar Series Chart to the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch with a width and height of 5 inches. The ChartAddXYData() Method adds data points to the Vertical Bar Chart that will be displayed when the report page is refreshed or scaled.

Adding Multiple Charts

Multiple Charts can be added to a single page. Simply call the AddChart() Method again to add another chart to the current page. Once you have added a new chart to the current page, calling the ChartAddXYData() Method will add data points to the most recent chart. In order to add more data points to a chart that already exists on the current page call the ChartSelect(n) Method with a number ranging from 1 to the number of charts on the current page. You can first determine the number of charts on the current page by calling the ChartGetCount() Method. The ChartGetCount() Method will return the total number of charts on the current page.

Example Showing Multiple Charts:

oReportEngine.AddChart("", 1, 1.0, 1.0, 5, 5)

oReportEngine.ChartAddXYData(100,0,'Software',RGB(255,0,0))

oReportEngine.ChartAddXYData(220,0,'Hardware',RGB(255,0,0))

oReportEngine.ChartAddXYData(850,0,'Consulting',RGB(255,0,0))

* Now add a second chart to the current page.

oReportEngine.AddChart("", 1, 1.0, 6, 4, 4)

oReportEngine.ChartAddXYData(1250,0,'Contracting',RGB(255,0,0))

oReportEngine.ChartAddXYData(350,0,'Internet Services',RGB(255,0,0))

* Now select the first chart and add more data points to that chart

oReportEngine.ChartSelect(1)

oReportEngine.ChartAddXYData(675,0,'Other',RGB(255,0,0))

See Also:

ChartAddXYData | ChartAddSeries | ChartSelect

Example Code to Create Charts


ChartAddSeries Method

Description:

The ChartAddSeries Method adds another data series to the currently selected chart.

Syntax:

oReportEngine.ChartAddSeries(nSeriesType, cSeriesTitle, nSeriesColor)

Return Type:

Parameters:

nSeriesType | Numeric | The type of Series to add to the current chart. Valid Series Types: 0 - Line Series 1 - Vertical Bar Series 2 - Horizontal Bar Series 3 - Area Series 4 - Point Series 5 - Pie Chart Series
cSeriesTitle | Numeric | Specifies the Title Name for the series being added.
nSeriesColor | Numeric | Specifies the default color for the items in the series.

Example:

oReportEngine.ChartAddSeries(1,'Portfolio 3',14089977)

See Also:


ChartAddXYData Method

Description:

The ChartAddXTData Method adds new data points to the currently selected data series in the currently selected chart. This method allows for specifying both X and Y data points as well as the

Syntax:

oReportEngine.ChartAddXYData(nX, nY, cLegend, nColor)

Return Type:

Parameters:

nX | String | Specifies the X Value of the data point.
nY | Numeric | Specifies the Y Value of the data point.
cLegend | Numeric | Specifies the Legend to be used for the data point being added.
nColor | Numeric | Specifies the color to be used for the data point.

Example:

The following example adds a Vertical Bar Series Chart to the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch with a width and height of 5 inches. The ChartAddXYData() Method adds data points to the Vertical Bar Chart that will be displayed when the report page is refreshed or scaled.

oReportEngine.AddChart("", 1, 1.0, 1.0, 5, 5)

oReportEngine.ChartAddXYData(100,0,'Software',RGB(255,0,0))

oReportEngine.ChartAddXYData(220,0,'Hardware',RGB(255,0,0))

oReportEngine.ChartAddXYData(850,0,'Consulting',RGB(255,0,0))

See Also:

AddChart | ChartAddSeries | ChartSelect | ChartSelectSeries | ChartGetCount

Example Code to Create Charts


ChartSaveToMetafile

Description:

The ChartSaveToMetafile Method provides support to save the currently selected chart to an Enhanced Metafile.

Syntax:

oReportEngine.ChartSaveToMetafile(cFileName, nWidth, nHeight)

Return Type:

Numeric

Parameters:

cFileName | String | Specifies the name of the file to save the Chart to.
nWidth | Numeric | Specifies the Width of the Metafile in Pixels.
nHeight | Numeric | Specifies the Height of the Metafile in Pixels.

Example:

The following example adds a Vertical Bar Series Chart to the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch with a width and height of 5 inches. The ChartAddXYData() Method adds data points to the Vertical Bar Chart that will be displayed when the report page is refreshed or scaled. The last line then saves the chart as an Enhanced Metafile called SampleChart.DBF with measurements of 800 pixels by 600 pixels.

oReportEngine.AddChart("", 1, 1.0, 1.0, 5, 5)

oReportEngine.ChartAddXYData(100,0,'Software',RGB(255,0,0))

oReportEngine.ChartAddXYData(220,0,'Hardware',RGB(255,0,0))

oReportEngine.ChartAddXYData(850,0,'Consulting',RGB(255,0,0))

oReportEngine.ChartAddXYData('SampleChart.EMF',800,600)

See Also:

AddChart | ChartAddSeries | ChartAddXYData | ChartSelect | ChartSelectSeries | ChartGetCount

Example Code to Create Charts


ChartSelect Method

Description:

The ChartSelect Method is used to specify the currently selected chart on the current page.

Syntax:

oReportEngine.ChartSelect(nChartIndex)

Return Type:

Parameters:

nChartIndex

Numeric

Specifies the Chart to set as the currently selected chart on the page.

Examples:

* Select the first chart on the Current Page

oReportEngine.ChartSelect(1)

* Select the Second chart on the Current Page

oReportEngine.ChartSelect(2)

oReportEngine.AddChart("", 1, 1.0, 1.0, 5, 5)

oReportEngine.ChartAddXYData(100,0,'Software',RGB(255,0,0))

oReportEngine.ChartAddXYData(220,0,'Hardware',RGB(255,0,0))

oReportEngine.ChartAddXYData(850,0,'Consulting',RGB(255,0,0))

* Now add a second chart to the current page.

oReportEngine.AddChart("", 1, 1.0, 6, 4, 4)

oReportEngine.ChartAddXYData(1250,0,'Contracting',RGB(255,0,0))

oReportEngine.ChartAddXYData(350,0,'Internet Services',RGB(255,0,0))

* Now the first chart on the Current Page and add more data

oReportEngine.ChartSelect(1)

oReportEngine.ChartAddXYData(250,0,'Internet Sales',RGB(255,255,0))

See Also:


ChartSelectSeries Method

Description:

The ChartSelectSeries Method is used to specify the currently selected Data Series within a chart that has more than one Data Series. Once a different series is selected all calls to the ChartAddXYData Method adds data points to the currently selected series.

Syntax:

oReportEngine.ChartSelectSeries(nSeries)

Return Type:

Parameters:

nSeries

Numeric

Specifies the Chart Series to select as the currently selected series on the currently selected Chart.

Examples:

* Selects the 2nd Series in the currently selected Chart

oReportEngine.ChartSelectSeries(2)

See Also:


ChartGetCount Method

Description:

The ChartGetCount Method is used to determine the number of Charts on the current Page or the Page Number specified of the Report Engine. If the Page Number specified is out of the range of the current page count in the Report Engine, the return value is -1.

Syntax:

oReportEngine.ChartGetCount([nPageNumber=0])

Return Type:

Numeric - The number of Charts on the current Page of the Report Engine or -1 if the Page Number specified is out of range.

Parameters: None

nPageNumber

Numeric

(Optional) Specifies the Page Number to look at for returning the number of charts on the page. The default value is 0 which represents the current page.

Examples:

* Returns the number of Charts on the currently selected page in the Report Engine

nChartCount = oReportEngine.ChartGetCount()

* Returns the number of Charts on page 3 of the Report Engine

nChartCount = oReportEngine.ChartGetCount(3)

See Also:


Example Code to Create Charts

Adding Charts into the Report Engine

The Mind's Eye Report Engine has a built in Charting Engine, so that charts can be added to your Reports. It is very easy to add Charts and manipulate them at runtime by using the Charting Methods and Properties of the Report Engine.

The following example demonstrates how to programmatically generate a Chart within the Report Engine. With Visual FoxPro you can highlight the code below and past it into the Command Window or into a program file and run the example.

SET CLASSLIB TO MindsEyeReportPreviewForms

PUBLIC oRPT

oRPT = CREATEOBJECT('mindseyereportpreviewform')

oRPT.Top = 10

oRPT.Left = 20

oRPT.Width = 600

oRPT.Height = 800

WITH oRPT.oReportEngine

.AddChart('',1,1,1,6,5)

.ChartSeriesTitle = 'Portfolio 1'

.ChartSeriesColor = 16744576

.ChartAddXYData(4.8,0,'Sep 02',16744576)

.ChartAddXYData(4.1,0,'Dec 02',16744576)

.ChartAddXYData(3.8,0,'Mar 03',16744576)

.ChartAddXYData(3.4,0,'Jun 03',16744576)

* Add another Series to the Current Chart and set the Legend to 'Portfolio 2'

.ChartAddSeries(1,'Portfolio 2',4194432)

.ChartAddXYData(4.2,0,'Sep 02',4194432)

.ChartAddXYData(3.8,0,'Dec 02',4194432)

.ChartAddXYData(3.5,0,'Mar 03',4194432)

.ChartAddXYData(3.1,0,'Jun 03',4194432)

* Add another Series to the Current Chart and set the Legend to 'Portfolio 3'

.ChartAddSeries(1,'Portfolio 3',14089977)

.ChartAddXYData(3.6,0,'Sep 02',14089977)

.ChartAddXYData(3.2,0,'Dec 02',14089977)

.ChartAddXYData(2.7,0,'Mar 03',14089977)

.ChartAddXYData(2.5,0,'Jun 03',14089977)

.ChartTitle = 'Portfolio VS Benchmark'

.ChartXAxisTitle = 'Period'

.ChartXAxisFontSize = 16

.ChartYAxisTitle = 'Return'

.ChartYAxisFontSize = 16

.ChartSeriesMarksVisible = .f.

ENDWITH

oRPT.Show()

See Also:


AddFromClipboard Method

Description:

The AddFromClipboard Method can be used to programmatically add an Enhanced Metafile Object from the Clipboard onto a Report Page at runtime.

Uses:

This Method can be used to programmatically place images from other applications that have been copied onto the clipboard into a report. This can be used for annotating reports by adding charts from a spreadsheet, text from a word processor, an image from a webpage or from another graphic application.

Syntax:

oReportEngine.AddFromClipboard(cName, nHPos, nVPos, nWidth, [nImageScaling=1])

Return Type:

Numeric: 0 = Successful

1 = Failed to create

Parameters:

cName

String

A name for the object for locating at a later time.

nHPos

Numeric

The Horizontal position on the page to locate the clipboard object in inches.

nVPos

Numeric

The Vertical position on the page to locate the clipboard object in inches.

nWidth

Numeric

The Width of the object to be placed on the page in inches.

nHeight

Numeric

The Height of the object to be placed on the page in inches.

nImageScaling

Numeric

The scaling of the clipboard object being placed on the page.

Valid Values:

0 - Clip. The Clipboard image is clipped to fit the width and height specified.

1 - Isometric. The Clipboard image resizes to fit the width and height specified while maintaining its original proportions.

2 - Stretch. The Clipboard image resizes to fit the width and height specified, but does not maintain its original proportions.

(Default Value: 1)

Example:

* The following command places an object on the Clipboard

* onto the current page at the position and size specified.

oReportEngine.AddFromClipboard('',1,1,5,5)

See Also:

CopyPageToClipboard


CopyPageToClipboard Method

Description:

The CopyPageToClipboard Method can be used to copy a page in the Report Engine to the clipboard as an enhanced metafile object. The clipboard contents can then be used to paste an exact duplicate of a report page into other applications that support pasting in enhanced metafile objects. This method can be used to automate Microsoft Word to paste in images of report pages into a Word Document.

Syntax:

oReportEngine.CopyPageToClipboard([nPageNumber=0])

Return Type:

Numeric: 0 = Successful

1 = Failed to create

Parameters:

nPageNumber

Numeric

(Optional) Specifies a specific page within the report engine to save.

Example:

* Copies an enhanced metafile image representation of the current page to the Clipboard.

oReportEngine.CopyPageToClipboard()

See Also:

AddFromClipboard


Text Methods

The AddText and the AddReportField Methods are used to add Text objects to the Report Engine pages at runtime programmatically. These methods allow you to place text at any position on the page and at any rotation angle. The FontName, FontSize, FontStyle and FontColor can all be specified in the AddText Method.

See Also:


AddText Method

Description:

The AddText method will add a text object to the current drawing page of the Report Object at the given nHPOS, nVPOS coordinate with optional nWidth and nHeight. You can Optionally specify the FontName, FontSize, ForeColor, BackColor, FontStyle, RotationAngle, BackStyle, Alignment and Subtype.

Syntax:

oReportEngine.AddText(cName, cText, nHPOS, nVPOS, [nWidth], [nHeight],

[cFontName], [nFontSize], [nForeColor], [nBackColor],

[cFontStyle], [nRotationAngle], [nBackStyle], [nAlignment],

[cSubType], [nAlphaLevel=255], [nTrimmingStyle=2])

Return Type: void

Parameters:

cName

String

A name identifying the object that allows for searching for the object by name at runtime.

cText

String

The text string to be added to the page.

nHPos

Number

Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.

IMPORTANT NOTE:

Specifying Center Aligned text requires that the nHPos is set to the Center Point where the text should be centered upon on the page.

Specifying Right Aligned text requires that the nHPos is set to the Rightmost position where the text should be placed onto the page. All text will be rendered to the left of the rightmost position.

nVPos

Number

Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.

nWidth

Number

(Optional) Specifies the bounding box width for the text to be positioned within. The nWidth value is used to compute the when text will wrap to the next line when a multi-line text string is rendered. Setting this value to zero will allow the text to be placed without being bound by width and will ensure a single line of text.

nHeight

Number

(Optional) Specifies the bounding box Height for the text to be positioned within. Setting this value to zero will allow the text to be placed withouth being bound by height.

cFontName

String

(Optional) Specifies the Font Name to be used for the text object.

nFontSize

Number

(Optional) Specifies the Font Size in points to be used for the text object.

nForeColor

Number

(Optional) Specifies the Font ForeColor for the text object.

nBackColor

Number

(Optional) Specifies the Font BackColor for the text object.

cFontStyle

String

(Optional) Specifies the Font Style for the text object. Any combination of values can be assigned.

Valid Values are:

' ' - Normal

'B' - Bold

'I' - Italic

'U' - Underline

'S' - Strikeout

nRotationAngle

Number

(Optional) Specifies the Rotation Angle for the text to be drawn onto the page in degrees.

nBackStyle

Number

(Optional) Specifies the Back Style for the text object as either Transparent or Solid. When text is rendered with a solid background a solid rectangle shape will be drawn behind the text. Use the nBackColor parameter to set the color of the solid background color.

0 - Transparent (Default)

1 - Solid

nAlignment

Number

(Optional) Specifies the alignment of the text as:

0 - Left Justify (Default)

1 - Right Justify

2 - Center Justify

IMPORTANT NOTE: Center Aligned text is Centered around the nHPos value. This makes it easier to compute the location of the text on the page. The nWidth value can be set to 0 or not specified for single line text. If the text is going to be a multi-line text then the nWidth value will be used to calculate the wrapping point for each line.

cSubType

String

(Optional) Specifies if the object is drawn as a Field or a Label.

Values are 'F' for Field and 'L' for label. This is only used by the MERE_ReportListener class at this time to determine how text is to be trimmed as Visual FoxPro labels are not trimmed by default unless the FRX width and height is tampered with and then rendered with SET REPORTBEHAVIOR 90 in native Visual FoxPro which produces unusual results.

nAlphaLevel

Number

(Optional) Specifies the Alpha value of the Color. This controls the level of Transparency when the text is painted.

0 - 255 (Default Value = 255)

nTrimmingStyle

Number

(Optional) Specifies the Trimming Style to use when measuring and drawing text using GDI+.

0 = Default trimming

1 = Trim to nearest character

2 = Trim to nearest word

3 = Trim to nearest character, append ellipsis

5 = Show inner path as ellipsis

6 = Trim to nearest word, append ellipsis

Example:

* The following example places the string 'Text Object' at the X and Y position

* of 1 inch, 1 inch on the current page with a defined width of 2.5inch and a

* height of 0.25 inches.

oReport.AddText('MyText','Text Object',1.0,1.0,2.5,.25)

* The following example passes a long string of text to the AddText() Method

* specifying the Font as Arial 20 points in size with a BOLD setting. It is

* also specified to be Center aligned within a 3 inch wide by 3 inch tall

* region.

lcString = 'This is a really long string that will be wrapped and centered.'

oReport.AddText('',lcString,1,1,3,3,'Arial',20,,,'B',0,,2)

See Also:

AddReportField


AddReportField Method

Description:

The AddReportFIeld method will add a Report Field Object to the current drawing Page Object of the Report Object at the given nHPOS, nVPOS coordinate with optional nWidth and nHeight. You can Optionally specify the Picture formatting, Data Type, FontName, FontSize, ForeColor, BackColor, FontStyle, RotationAngle, BackStyle, Alignment and Subtype.

The cExpression value currently only supports the _PAGENO and _PAGETOTAL variables. The cExpression will be parsed and evaluated in "real time" whenever a report page is previewed or printed. So for example if you have a 30 page report and you place a ReportField Object onto the first page using the following command:

oReportEngine.AddReportField('',["Page No: "+STR(_PAGENO)+" of "+STR(_PAGETOTAL)],6.5,10,0,0,'','','Arial',10)

The first page will have the following string printed at 6.5 inches across and 10 inches down on the page:

Page No: 1 of 30

Notice that the Report Field object is actually parsing the command in the cExpression field as a VFP command string using it's own internal mini-VFP interpreter written in Delphi. Currently the following VFP functions are supported for the cExpression value:

TRANSFORM()

STR()

ALLTRIM()

Therefore another valid expression would be:

"Page No: "+TRANSFORM(_PAGENO)+" of "+TRANSFORM(_PAGETOTAL)

As you add more pages to the Report Control using the NewPage() Method and go back to the first page and check the string above it will automatically increment the 1 of x pages to reflect the total number of pages in the Report Control. There is also a method for adding in page breaks that will start the _PAGENO value over at 1 again. To reset a Page Number to 1 again call the SetPageNumberToOne(nPageNumber) Method. This method will then add a page break to the internal page break array for the current report. By resetting a page number to 1 will automatically reflect when using a Report Field object on a report since it's evaluation looks into the page break array for any page breaks. Thefore, if you were to call the SetPageNumberToOne(10) Method with 10 as the parameter the first page would now reflect, Page No: 1 of 9. The Page Number and Page Total values are evaluated in real time and are mathematically calculated based upon the physical page of the Report Object and using the Page Break Array.

Syntax:

oReportEngine.AddReportField(cName, cExpression, nHPOS, nVPOS, [nWidth], [nHeight], [cPicture], [cDataType], [cFontName], [nFontSize], [nForeColor], [nBackColor], [cFontStyle], [nRotationAngle], [nBackStyle], [nAlignment], [cSubType])

Return Type: void

Parameters:

cName | String | A name identifying the object that allows for searching for the object by name at runtime.
cExpression | String | The Report Field Expression to be evaluated at Run Time.
nHPos | Number | Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.
nVPos | Number | Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.
nWidth | Number | (Optional) Specifies the bounding box width for the text to be positioned within. Setting this value to zero will allow the text be placed without being bound by width.
nHeight | Number | (Optional) Specifies the bounding box Height for the text to be positioned within. Setting this value to zero will allow the text to be placed withouth being bound by height.
cPicture | String | (Optional) Specifies the Picture clause to use for display formatting.
cDataType | String | (Optional) Specifies the Data Type of the Expression for formatting.
cFontName | String | (Optional) Specifies the Font Name to be used for the text object.
nFontSize | Number | (Optional) Specifies the Font Size in points to be used for the text object.
nForeColor | Number | (Optional) Specifies the Font ForeColor for the text object.
nBackColor | Number | (Optional) Specifies the Font BackColor for the text object.
cFontStyle | String | (Optional) Specifies the Font Style for the text object. Any combination of values can be assigned. Valid Values are: ' ' - Normal 'B' - Bold 'I' - Italic 'U' - Underline 'S' - Strikeout
nRotationAngle | Number | (Optional) Specifies the Rotation Angle for the text to be drawn onto the page in degrees.
nBackStyle | Number | (Optional) Specifies the Back Style for the text object.
nAlignment | Number | (Optional) Specifies the alignment of the text as: 0 - Left Justify (Default) 1 - Right Justify 2 - Center Justify
cSubType | String | (Optional) Specifies if the object is drawn as a Field or a Label. Values are 'F' for Field and 'L' for label.

Example

oReport.AddReportField('PageNumber','_PAGENO',7.5,10.0,0,0,'99999','N')

oReportEngine.AddReportField('',["Page No: "+STR(_PAGENO)+" of "+STR(_PAGETOTAL)],6.5,10,0,0,'','','Arial',10)

See Also:

AddText


SendMail Method

Description:

The SendMail method supports sending a Report as an Email message automatically by creating a PDF document of the current Report Engine contents and attaching it to the Email. The SendMail method supports both SMTP and MAPI. Use the EmailMessagingType Property to specify if the email message will be sent using 0 = SMTP or 1 = MAPI. All parameters of the SendMail message are optional.

It is possible to add additional attachments to emails using the EMAILAddAttachment Method to specify addtional file names to be added to the email when it is sent. The EMAILAddAttachment method accepts a fully qualified file name as it's parameter and adds each filename to an internal list of files that will be automatically attached to the email when sent using the SendMail Method.

NOTE: It is possible to send an email without automatically generating a PDF document as an attachment by setting the EmailAttachmentFileName Property to an Empty String or by passing in the cAttachmentFileName Parameter as an Empty String.

NOTE: You must set the EmailCCAddresses and EmailBCCAddresses Properties in order to use Carbon Copy and Blind Carbon Copy addresses prior to calling the SendMail Method.

SMTP Email Notes

In order for email messages to be sent properly via SMTP, you must set the following Email Properties or set them via the SendMail Parameters.

EmailMessagingType = 0

EmailSMTPHost

EmailFromAddress

EmailRecipients

EmailAttachmentFileName

If Authorization is required you must also set the following Email Properties:

EmailSMTPAuthorizationType = 1

EmailSMTPUserID

EmailSMTPPassword

MAPI Email Notes

In order for email messages to be sent properly via MAPI, you must set the following Email Properties or set them via the SendMail Parameters.

EmailMessagingType = 1

EmailRecipients

EmailAttachmentFileName

When sending email via MAPI, the SendMail Method will add the outgoing message to the Outbox of the current MAPI profile.

Syntax:

oReportEngine.SendMail([cSMTPHost], [cFromAddress], [cRecipients], [cSubject], [cBodyText], [cAttachmentFileName] )

Return Type:

Long

0 = Success

n = Other Error Occcurred and depends on EmailMessagingType

Parameters:

cSMTPHost | String | (Optional) Name or IP Address of the SMTP Host Email Server.
cFromAddress | String | (Optional) Specifies the From Address for SMTP Email Messages. Not required for MAPI.
cRecipients | String | (Optional) Specifies the Recipients of the Email message. This can be a comma delimited list of Email Addresses (SMTP) or semicolon delimited list of addresses MAPI. All email addresses should be in the form of name@domain.com.
cSubject | String | (Optional) Specifies the Subject of the Email message.
cBodyText | String | (Optional) Specifies the Body Text of the Email message.
cAttachmentFileName | String | (Optional) Specifies the RGB color of the pen to draw the line.

Example:

The following code will send an Email message via SMTP by passing in the parameters to the SendMail Method.

oReportEngine.EmailMessagingType = 0

oReportEngine.SendMail('myhost.net', 'myaddress@myhost.net', 'info@domain.com', 'Test Message', 'Body of Test Message', 'MyReport.PDF')

The following code will send an Email message via SMTP without passing any parameters after setting the required EMAIL Properties. This code will also send additional file attachments using the EMAILAddAttachment Method.

* First set all of the required properties for sending an email via SMTP

oReportEngine.EmailMessagingType = 0

oReportEngine.EmailSMTPHost = 'MyHost.Net'

oReportEngine.EmailFromAddress = 'myemail@mydomain.com'

oReportEngine.EmailRecipients = 'someone@hotmail.com'

oReportEngine.EmailAttachmentFileName = 'myreport.pdf'

* Now specify some additional files to be attached to the email

oReportEngine.EMAILAddAttachment('C:\My Documents\Attachment1.DOC')

oReportEngine.EMAILAddAttachment('C:\My Documents\Attachment2.PDF')

oReportEngine.EMAILAddAttachment('C:\My Documents\Attachment3.XLS')

* Now send the email using the SendMail() Method without passing any parameters

* since all of the required Email Properties have already been set.

oReportEngine.SendMail()

See Also:

EMAILAddAttachment


EMAILAddAttachment

Description:

The EMAILAddAttachment Method can be used to add additional files as email attachments to an email sent using the SendMail() Method. The EMAILAddAttachment method accepts a single parameter as a string which should be the name of the file includng the full path and filename. You can add multiple attachment file names to a single email. Each additional attachment filename increases the EMAILAttachmentCount Property by 1. To remove all EMAIL Attachment Filenames from the file list set the EMAILAttachmentCount to zero.

This method allows attachments to be sent with both the SMTP or MAPI protocols.

Syntax:

oReportEngine.EMAILAddAttachment(cFileName)

Return Type:

Parameters:

cFileName

String

The name of the file to be attached to the EMAIL. This should be the full path plus the filename.

Example:

oReportEngine.EMAILMessagingType = 0 && Set to SMTP (Default = 0)

oReportEngine.EMAILSMTPHost = 'SomeHost.net'

oReportEngine.EMAILRecipients = 'someone@somedomain.com'

oReportEngine.FROMAddress = 'someone@testcompany.com'

oReportEngine.EMAILSubject = 'Test Message From Rich'

oReportEngine.EMAILBody = 'This is the body of the message'

oReportEngine.EMAILAttachmentFilename = 'test.pdf'

oReportEngine.EMAILAddAttachment('C:\SomeFolder\SomeFile.prg')

oReportEngine.EMAILAddAttachment('C:\SomeFolder\SomeOtherFile.txt')

oReportEngine.EMAILAddAttachment('C:\SomeFolder\SomeWordDoc.doc')

oReportEngine.SendMail()

This will send an Email message via SMTP along with the 3 attachments from the file names specified as well as automatically creating the PDF File named TEST.PDF and attaching that as well.

See Also:

SendMail


Drawing Methods

The Report Engine has several methods that can be used to draw Barcodes, Shapes, Lines or Pictures onto pages contained within the Report Engine programmatically at runtime. When creating a report you may want to draw lines or boxes onto pages to represent sections of a page like an invoice for example. You may also want to add photos or drawings to a report or document as well. The drawing methods of the report engine allow you to specify the bounding box of a Shape, Picture or Barcode or the starting and ending points of a line when drawing them onto the page.


AddArc Method

Description:

The AddArc Method will add an Arc Shape Object to a Report Page at the specified nHPOS, nVPOS with the nWidth and nHeight specified. The optional parameters will override the default PenColor, FillColor, FillStyle, BackStyle, BorderStyle and BorderWidth Properties of the Report Engine control. Otherwise, the Arc Shape Object will be added with the current Shape Properties of the Report Engine control.

Syntax:

oReportEngine.AddArc(cName, nHPOS, nVPOS, nWidth, nHeight, nXStart, nYStart, nXEnd, nYEnd, [nPenColor], [nFillColor], [nFillStyle], [nBackStyle], [nBorderStyle], [nBorderWidth], [nAlphaLevel])

Return Type:

Parameters:

cName | String | A name identifying the object that allows for searching for the object by name at runtime.
nHPos | Numeric | Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.
nVPos | Numeric | Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.
nWidth | Numeric | Specifies the Width of the object on the report surface in inches up to 10,000th of an inch.
nHeight | Numeric | Specifies the Height of the object on the report surface in inches up to 10,000th of an inch.
nXStart | Numeric | Specifies the X Coordinate of the first radial ending point of the object on the report surface in inches up to 10,000th of an inch.
nYStart | Numeric | Specifies the Y Coordinate of the first radial ending point of the object on the report surface in inches up to 10,000th of an inch.
nXEnd | Numeric | Specifies the X Coordinate of the second radial ending point of the object on the report surface in inches up to 10,000th of an inch.
nYEnd | Numeric | Specifies the Y Coordinate of the second radial ending point of the object on the report surface in inches up to 10,000th of an inch.
nPenColor | Numeric | (Optional) Specifies the RGB color of the pen to draw the border line. (Default Value: 0 (BLACK))
nFillColor | Numeric | (Optional) Specifies the Fill Color for the shape object added to the report page.
nFillStyle | Numeric | (Optional) Specifies the FillStyle of the shape object added to the report page. 0 - Solid Fill (Default Value) 1 - Transparent Fill 2 - Horizontal Line Fill 3 - Vertical Line Fill 4 - Diagonal Fill Upper Left to Lower Right 5 - Diagonal Fill Lower Left to Upper Right 6 - Cross Fill 7 - Diagonal Cross Fill 8 - Solid Fill
nBackStyle | Numeric | (Optional) Specifies the BackStyle of the object. Valid values are: 0 - Solid Backstyle (Default Value) 1 - Transparent Backstyle
nBorderStyle | Numeric | (Optional) Specifies the BorderStyle of the line. 0 - No Line 1 - Dotted Line 2 - Dashed Line 3 - Dash Dot Line 4 - Dash Dot Dot Line 8 - Solid Line (Default Value)
nBorderWidth | Numeric | (Optional) Specifes the width of the Border in pixel. (Default Value = 0)
nAlphaLevel | Numeric | (Optional) Specifies the transparency level of the object Valid values range from 0 - 255 where 255 is opaque. (Default Value = 255)

Example:

oReportEngine.AddChord('Chord',1.0,1.0,2.25,2,1.5,2,,255,RGB(0,0,255))

This places a Chord Shape object on the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch and a width of 2.25 inches and a vertical height of 2 inches with a Red Border color and a Blue fill.

See Also:


AddBarcode Method

Description:

The AddBarcode Method will add a Barcode Object to a Report Page at the specified nHPOS, nVPOS with the nWidth and nHeight specified. Optionally you can specify to Clip the color of the Barcode and the Rotation Angle.

Syntax:

oReportEngine.AddBarcode(cName, cData, nBarcodeType, nHPOS, nVPOS, nWidth, nHeight, [nBarcodeColor], [nRotationAngle])

Return Type:

void

Parameters:

cName | String | A name identifying the object that allows for searching for the object by name at runtime. Optional.
cData | String | The text string of data for the Barcode. You do not need to add any check digits.
cBarcodeType | Numeric | The text string of data for the Barcode. You do not need to add any check digits. Valid Barcode Types 0 - Code 3 of 9 1 - Code 3 of 9 Extended 2 - PostNet 3 - Codebar 4 - 2 of 5 Interleaved 5 - 2 of 5 Industrial 6 - 2 of 5 Matrix 7 - Code 93 8 - Code 93 Extended 9 - Code 128 A 10 - Code 128 B 11 - Code 128 C 12 - EAN 8 13 - EAN 13 14 - EAN 128A 15 - EAN 128B 16 - EAN 128C 17 - MSI 18 - UPC A 19 - UPC E0 20 - UPC E1 21 - UPC 2 Digit Supplemental 22 - UPC 5 Digit Supplemental
nHPos | Numeric | Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.
nVPos | Numeric | Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.
nWidth | Numeric | Specifies the Width of the object on the report surface in inches up to 10,000th of an inch. This should be set to zero for most barcodes since the width of the barcode is determined by the ratio of the bar sizes.
nHeight | Numeric | Specifies the Height of the object on the report surface in inches up to 10,000th of an inch.
nBarcodeColor | Numeric | (Optional) Specifies the color of the barcodes to be drawn. Typically this should be black but you can change the color if necessary. (Default Value = 0 (Black))
nRotationAngle | Numeric | (Optional) Specifies the angle of rotation for the barcode on the page measured in degrees.

Example:

oReportEngine.AddBarcode('', '63010', 2, 1.0, 1.0, 0, 0.25)

This adds a Postal Barcode to the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch and a Height of 0.25 inches. The barcode will be printed in black with a rotation angle of zero.

See Also:


AddChord Method

Description:

The AddChord Method will add a Chord Shape Object to a Report Page at the specified nHPOS, nVPOS with the nWidth and nHeight specified. The optional parameters will override the default PenColor, FillColor, FillStyle, BackStyle, BorderStyle and BorderWidth Properties of the Report Engine control. Otherwise, the Chord Shape Object will be added with the current Shape Properties of the Report Engine control.

Syntax:

oReportEngine.AddChord(cName, nHPOS, nVPOS, nWidth, nHeight, nXStart, nYStart, nXEnd, nYEnd, [nPenColor], [nFillColor], [nFillStyle], [nBackStyle], [nBorderStyle], [nBorderWidth], [nAlphaLevel])

Return Type:

Parameters:

cName | String | A name identifying the object that allows for searching for the object by name at runtime.
nHPos | Numeric | Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.
nVPos | Numeric | Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.
nWidth | Numeric | Specifies the Width of the object on the report surface in inches up to 10,000th of an inch.
nHeight | Numeric | Specifies the Height of the object on the report surface in inches up to 10,000th of an inch.
nStartAngle | Numeric | Specifies the Start Angle in degrees as to where the pie should start with positive angles going clockwise with zero degrees being horizontal to the right.
nSweepAngle | Numeric | Specifies the Sweep Angle in degrees as to how many degrees the pie wedge should sweep starting clockwise from the start angle. For example a 90 degree sweep would create a quarter of a pie wedge.
nPenColor | Numeric | (Optional) Specifies the RGB color of the pen to draw the border line. (Default Value: 0 (BLACK))
nFillColor | Numeric | (Optional) Specifies the Fill Color for the shape object added to the report page.
nFillStyle | Numeric | (Optional) Specifies the FillStyle of the shape object added to the report page. 0 - Solid Fill (Default Value) 1 - Transparent Fill 2 - Horizontal Line Fill 3 - Vertical Line Fill 4 - Diagonal Fill Upper Left to Lower Right 5 - Diagonal Fill Lower Left to Upper Right 6 - Cross Fill 7 - Diagonal Cross Fill 8 - Solid Fill
nBackStyle | Numeric | (Optional) Specifies the BackStyle of the object. Valid values are: 0 - Solid Backstyle (Default Value) 1 - Transparent Backstyle
nBorderStyle | Numeric | (Optional) Specifies the BorderStyle of the line. 0 - No Line 1 - Dotted Line 2 - Dashed Line 3 - Dash Dot Line 4 - Dash Dot Dot Line 8 - Solid Line (Default Value)
nBorderWidth | Numeric | (Optional) Specifes the width of the Border in pixel. (Default Value = 0)
nAlphaLevel | Numeric | (Optional) Specifies the transparency level of the object Valid values range from 0 - 255 where 255 is opaque. (Default Value = 255)

Example:

oReportEngine.AddArc('Chord',1.0,1.0,2.25,2,1.5,2,,255,RGB(0,0,255))

This places a Chord Shape object on the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch and a width of 2.25 inches and a vertical height of 2 inches with a Red Border color and a Blue fill.

See Also:


AddLine Method

Description:

The AddLine method will add a line to the Report Surface at the specified nHPOS, nVPOS with the nWidth and nHeight specified. The optional parameters will override the default Line Properties of the Report Engine control. Otherwise, the line will be added with the current Line Properties of the Report Engine control.

Syntax:

oReportEngine.AddLine(cName, nHPOS, nVPOS, nWidth, nHeight, [nPenColor], [nPenWidth], [nPenStyle])

Return Type:

void

Parameters:

cName | String | A name identifying the object that allows for searching for the object by name at runtime.
nHPos | Numeric | Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.
nVPos | Numeric | Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.
nWidth | Numeric | Specifies the Width of the line on the report surface in inches up to 10,000th of an inch.
nHeight | Numeric | Specifies the Height of the line on the report surface in inches up to 10,000th of an inch.
nPenColor | Numeric | (Optional) Specifies the RGB color of the pen to draw the line. (Default Value: 0 - Black)
nPenWidth | Numeric | (Optional) Specifies the PenWidth in points of the line. (Default Value: 1)
nPenStyle | Numeric | (Optional) Specifies the PenStyle of the line. Valid values are: 0 - No Line 1 - Dotted Line 2 - Dashed Line 3 - Dash Dot Line 4 - Dash Dot Dot Line 8 - Solid Line (Default Value)

Examples:

oReportEngine.AddLine('Horizontal Line',1.0,1.0,2.25,0,255,4)

This places adds a Red Line object with a thickness of 4 points to be drawn on the current Report Page at an Horizontal position of 1 inch and a Vertical position of 1 inch and a width of 2.25 inches and a vertical height of 0 inches with . Specifying an nHeight of 0 creates a Horizontal line.

oReportEngine.AddLine('Vertical Line',1.0,1.0,0,2,RGB(0,0,255),4)

This places adds a Blue Line object with a thickness of 2 points to be drawn on the current Report Page at an Horizontal position of 1 inch and a Vertical position of 1 inch and a width of 0 inches and a vertical height of 2 inches with . Specifying an nWidth of 0 creates a Vertical line.

See Also:


AddPicture Method

Description:

The AddPicture Method will add a Picture Object to a Report Page at the specified nHPOS, nVPOS with the nWidth and nHeight specified. Optionally you can specify to Clip the Picture, Stretch the Picture and Keep Proportional or Stretch the Picture and Fill the Frame.

Syntax:

oReportEngine.AddPicture(cName, cFileName, nHPOS, nVPOS, nWidth, nHeight, [nImageScaling=1], [nFlags])

Return Type:

void

Parameters:

cName

String

A name identifying the object that allows for searching for the object by name at runtime.

cFileName

String

The Filename of the Picture or image to be added to the Page Object.

nHPos

Numeric

Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.

nVPos

Numeric

Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.

nWidth

Numeric

Specifies the Width of the object on the report surface in inches up to 10,000th of an inch.

nHeight

Numeric

Specifies the Height of the object on the report surface in inches up to 10,000th of an inch.

nImageScaling

Numeric

(Optional)The scaling of the clipboard object being placed on the page.

Valid Values:

0 - Clip. The Clipboard image is clipped to fit the width and height specified.

1 - Isometric. The Clipboard image resizes to fit the width and height specified while maintaining its original proportions.

2 - Stretch. The Clipboard image resizes to fit the width and height specified, but does not maintain its original proportions.

(Default Value: 1)

nFlags

Numeric

(Optional) For Future Use

Example:

oReportEngine.AddPicture('Picture1','MyPicture.JPG',1.0,1.0,5.0,7.0,1)

This adds the picture 'MyPicture.JPG' onto the current Report Page at an Horizontal position of 1 inch and a Vertical position of 1 inch and a width of 5.0 inches and a Vertical Height of 7.0 inches and set to fill the shape to the but Keep Proportional.

See Also:


AddPie Method

Description:

The AddPie Method will add a Pie Object to a Report Page at the specified nHPOS, nVPOS with the nWidth and nHeight specified. The optional parameters will override the default Shape Properties of the Report Engine control. Otherwise, the Shape Object will be added with the current Shape Properties of the Report Engine control.

Syntax:

oReportEngine.AddPie(cName, nHPOS, nVPOS, nWidth, nHeight, nStartAngle, nSweepAngle, [nPenColor], [nFillColor], [nFillStyle], [nBackStyle], [nBorderStyle], [nBorderWidth], [nAlphaLevel])

Return Type:

Parameters:

cName | String | A name identifying the object that allows for searching for the object by name at runtime.
nHPos | Numeric | Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.
nVPos | Numeric | Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.
nWidth | Numeric | Specifies the Width of the object on the report surface in inches up to 10,000th of an inch.
nHeight | Numeric | Specifies the Height of the object on the report surface in inches up to 10,000th of an inch.
nStartAngle | Numeric | Specifies the Start Angle in degrees as to where the pie should start with positive angles going clockwise with zero degrees being horizontal to the right.
nSweepAngle | Numeric | Specifies the Sweep Angle in degrees as to how many degrees the pie wedge should sweep starting clockwise from the start angle. For example a 90 degree sweep would create a quarter of a pie wedge.
nPenColor | Numeric | (Optional) Specifies the RGB color of the pen to draw the border line. (Default Value: 0 (BLACK))
nFillColor | Numeric | (Optional) Specifies the Fill Color for the shape object added to the report page.
nFillStyle | Numeric | (Optional) Specifies the FillStyle of the shape object added to the report page. 0 - Solid Fill (Default Value) 1 - Transparent Fill 2 - Horizontal Line Fill 3 - Vertical Line Fill 4 - Diagonal Fill Upper Left to Lower Right 5 - Diagonal Fill Lower Left to Upper Right 6 - Cross Fill 7 - Diagonal Cross Fill 8 - Solid Fill
nBackStyle | Numeric | (Optional) Specifies the BackStyle of the object. Valid values are: 0 - Solid Backstyle (Default Value) 1 - Transparent Backstyle
nBorderStyle | Numeric | (Optional) Specifies the BorderStyle of the line. 0 - No Line 1 - Dotted Line 2 - Dashed Line 3 - Dash Dot Line 4 - Dash Dot Dot Line 8 - Solid Line (Default Value)
nBorderWidth | Numeric | (Optional) Specifes the width of the Border in pixel. (Default Value = 0)
nAlphaLevel | Numeric | (Optional) Specifies the transparency level of the object Valid values range from 0 - 255 where 255 is opaque. (Default Value = 255)

Example:

oReportEngine.AddPie('Shape',1.0,1.0,2.25,2,1.5,2,,255,RGB(0,0,255))

This places a Shape object on the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch and a width of 2.25 inches and a vertical height of 2 inches with a Red Border color and a Blue fill.

See Also:


AddShape Method

Description:

The AddShape Method will add a Shape Object to a Report Page at the specified nHPOS, nVPOS with the nWidth and nHeight specified. The optional parameters will override the default Shape Properties of the Report Engine control. Otherwise, the Shape Object will be added with the current Shape Properties of the Report Engine control.

Syntax:

oReportEngine.AddShape(cName, nHPOS, nVPOS, nWidth, nHeight, [nPenColor], [nFillColor], [nFillStyle], [nBackStyle], [nBorderStyle], [nBorderWidth], [nCurvature])

Return Type:

Parameters:

cName | String | A name identifying the object that allows for searching for the object by name at runtime.
nHPos | Numeric | Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.
nVPos | Numeric | Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.
nWidth | Numeric | Specifies the Width of the object on the report surface in inches up to 10,000th of an inch.
nHeight | Numeric | Specifies the Height of the object on the report surface in inches up to 10,000th of an inch.
nPenColor | Numeric | (Optional) Specifies the RGB color of the pen to draw the border line. (Default Value: 0 (BLACK))
nFillColor | Numeric | (Optional) Specifies the Fill Color for the shape object added to the report page.
nFillStyle | Numeric | (Optional) Specifies the FillStyle of the shape object added to the report page. 0 - Solid Fill (Default Value) 1 - Transparent Fill 2 - Horizontal Line Fill 3 - Vertical Line Fill 4 - Diagonal Fill Upper Left to Lower Right 5 - Diagonal Fill Lower Left to Upper Right 6 - Cross Fill 7 - Diagonal Cross Fill
nBackStyle | Numeric | (Optional) Specifies the BackStyle of the object. Valid values are: 0 - Solid Backstyle (Default Value) 1 - Transparent Backstyle
nBorderStyle | Numeric | (Optional) Specifies the BorderStyle of the line. 0 - No Line 1 - Dotted Line 2 - Dashed Line 3 - Dash Dot Line 4 - Dash Dot Dot Line 8 - Solid Line (Default Value)
nBorderWidth | Numeric | (Optional) Specifes the width of the Border in pixel. (Default Value = 0)
nCurvature | Numeric | (Optional) Specifes the curvature of the corners of the shape. Valid values range from 0 - 99. 0 is no rounding and 99 represents a circle. (Default Value = 0)

Example:

oReportEngine.AddShape('Shape',1.0,1.0,2.25,2,255,RGB(0,0,255))

This places a Shape object on the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch and a width of 2.25 inches and a vertical height of 2 inches with a Red Border color and a Blue fill.

See Also:


SaveToBitmap Method

Description:

The SaveToBitmap Method saves an image of a page in the Report Engine to a Bitmap File. By default the current page in the Report Image is imaged. Optionally, a specific page number and the maximum image size can be specified as well as the number of Bits Per Pixel and can force the image to Grayscale.

Syntax:

oReportEngine.SaveToBitmap(cFileName,[nPageNumber=0],[lOpenFile=.F.],[nThumbnailSize=0],[nBitsPerPixel=24],[lGrayScale=.F.])

Return Type:

Numeric: 0 = Successful

1 = Failed to create

-1 = File Saved but cannot be opened

Parameters:

cFileName | String | The Filename to use when saving the report page to the Bitmap file. The file extension will be changed to BMP.
nPageNumber | Numeric | (Optional) Specifies a specific page within the report engine to save.
lOpenFile | Numeric | (Optional) Specifies if the report engine uses ShellExecute to Open the file after it is created.
nThumbnailSize | Numeric | (Optional) Specifies the maximum size of the image file in pixels. This can be used to create thumbnail size images of report pages. The minimum size is 5 pixels.
nBitsPerPixel | Numeric | (Optional) Specifies the number of Bits Per Pixel to use for color depth in the image. The default value is 24. (Valid Values: 24, 16, 15, 8, 4, 1)
lGrayScale | Boolean | (Optional) Specifies whether to force the image to save as a Grayscale image. (Default Value: FALSE)

Example:

* Saves the current report page to the bitmap file named MyReportPage.BMP

oReportEngine.SaveToBitmap('MyReportPage.BMP')

* Saves page 2 of the Report Engine and will attempt to open the file using ShellExecute

oReportEngine.SaveToBitmap('MyReportPage.BMP',2,.T.)

* Saves page 2 of the Report Engine with a maximum dimension of 120 pixels

* and will attempt to open the file using ShellExecute

oReportEngine.SaveToBitmap('MyReportPage.BMP',2,.T.,120)

See Also:

SaveToJPEG | SaveToMetafile | SaveToPNG | SaveToTIFF | SaveToWord


SaveToJPEG Method

Description:

The SaveToJPEG Method saves an image of a page in the Report Engine to a JPEG File. By default the current page in the Report Image is imaged. Optionally, a specific page number and the maximum image size can be specified as well as the compression quality and can force the image to Grayscale

Syntax:

oReportEngine.SaveToJPEG(cFileName,[nPageNumber=0],[lOpenFile=.F.],[nThumbnailSize=0],

[lGrayScale=.F.],[nCompressionQuality=90],[lProgressiveEncoding=.F.])

Return Type:

Numeric: 0 = Successful

1 = Failed to create

-1 = File Saved but cannot be opened

Parameters:

cFileName | String | The Filename to use when saving the report page to the JPEG image file. The file extension will be changed to JPG.
nPageNumber | Numeric | (Optional) Specifies a specific page within the report engine to save.
lOpenFile | Numeric | (Optional) Specifies if the report engine uses ShellExecute to Open the file after it is created.
nThumbnailSize | Numeric | (Optional) Specifies the maximum size of the image file in pixels. This can be used to create thumbnail size images of report pages. The minimum size is 5 pixels.
lGrayScale | Boolean | (Optional) Specifies whether to force the image to save as a Grayscale image. (Default Value: FALSE)
nCompressionQuality | Numeric | (Optional) Specifies the Compression Quality to use when creating the JPEG file. A larger number creates a larger file size but has a better image quality than a smaller number. (Valid Values: between 1 and 100) (Default Value: 90)
lProgressiveEncoding | Boolean | (Optional) Specifies whether or not to use Progressive Encoding when generating the JPEG Image File. (Default Value: FALSE)

Example:

* Saves the current report page to the bitmap file named MyReportPage.JPG

oReportEngine.SaveToJPEG('MyReportPage.JPG')

* Saves page 2 of the Report Engine and will attempt to open the file using ShellExecute

oReportEngine.SaveToJPEG('MyReportPage.JPG',2,.T.)

* Saves page 2 of the Report Engine with a maximum dimension of 120 pixels

* and will attempt to open the file using ShellExecute

oReportEngine.SaveToJPEG('MyReportPage',2,.T.,120)

See Also:

SaveToBitmap | SaveToMetafile | SaveToPNG | SaveToTIFF | SaveToWord


SaveToMetafile Method

Description:

The SaveToMetafile Method saves an image of a page in the Report Engine to an Enhanced Metafile file. By default the current page in the Report Image is imaged. Optionally, a specific page number can be imaged and specified to be automatically opened in the default viewer.

Syntax:

oReportEngine.SaveToMetafile(cFileName,[nPageNumber=0],[lOpenFile=.F.])

Return Type:

Numeric: 0 = Successful

1 = Failed to create

-1 = File Saved but cannot be opened

Parameters:

cFileName | String | The Filename to use when saving the report page to the Enhanced Metafile image file. The file extension will be changed to WMF.
nPageNumber | Numeric | (Optional) Specifies a specific page within the report engine to save.
lOpenFile | Numeric | (Optional) Specifies if the report engine uses ShellExecute to Open the file after it is created.

Example:

* Saves the current report page to the bitmap file named MyReportPage.WMF

oReportEngine.SaveToMetafile('MyReportPage.WMF')

* Saves page 2 of the Report Engine and will attempt to open the file using ShellExecute

oReportEngine.SaveToJPEG('MyReportPage.WMF',2,.T.)

See Also:

SaveToBitmap | SaveToJPEG | SaveToPNG | SaveToTIFF | SaveToWord


SaveToPNG Method

Description:

The SaveToPNG Method saves an image of a page in the Report Engine to a PNG File. By default the current page in the Report Image is imaged. Optionally, a specific page number and the maximum image size can be specified as well as the number of bits per pixel and can force the image to Grayscale. The PNG file format is typically much smaller in size than an equivilant JPEG image.

Syntax:

oReportEngine.SaveToPNG(cFileName,[nPageNumber=0],[lOpenFile=.F.],[nThumbnailSize=0],

[nBitsPerPixel=24],[lGrayScale=.F.])

Return Type:

Numeric: 0 = Successful

1 = Failed to create

-1 = File Saved but cannot be opened

Parameters:

cFileName | String | The Filename to use when saving the report page to the PNG image file. The file extension will be changed to PNG.
nPageNumber | Numeric | (Optional) Specifies a specific page within the report engine to save.
lOpenFile | Numeric | (Optional) Specifies if the report engine uses ShellExecute to Open the file after it is created.
nThumbnailSize | Numeric | (Optional) Specifies the maximum size of the image file in pixels. This can be used to create thumbnail size images of report pages. The minimum size is 5 pixels.
nBitsPerPixel | Numeric | (Optional) Specifies the Compression Quality to use when creating the JPEG file. A larger number creates a larger file size but has a better image quality than a smaller number. (Valid Values are: 24, 16, 15, 8, 4) (Default Value: 24)
lGrayScale | Boolean | (Optional) Specifies whether to force the image to save as a Grayscale image. (Default Value: FALSE)

Example:

* Saves the current report page to the bitmap file named MyReportPage.PNG

oReportEngine.SaveToPNG('MyReportPage.PNG')

* Saves page 2 of the Report Engine and will attempt to open the file using ShellExecute

oReportEngine.SaveToPNG('MyReportPage.PNG',2,.T.)

* Saves page 2 of the Report Engine with a maximum dimension of 120 pixels

* and will attempt to open the file using ShellExecute

oReportEngine.SaveToPNG('MyReportPage',2,.T.,120)

See Also:

SaveToBitmap | SaveToJPEG | SaveToMetafile | SaveToTIFF | SaveToWord


SaveToWord Method

Description:

The SaveToWord Method creates a Word document using OLE Automation but does it very quickly by placing Enhanced Metafile renderings of each Report Page onto each page of the Word document.

Syntax:

oReportEngine.SaveToWord(cFileName,[lOpenFile=.F.])

Return Type:

Numeric: 0 = Successful

1 = Failed to create

-1 = File Saved but cannot be opened

Parameters:

cFileName | String | The Filename to use when exporting the report to a Word Document. The file extension will be automatically changed to DOC.
lOpenFile | Numeric | (Optional) Specifies if the report engine uses ShellExecute to Open the file after it is created.

Example:

* Exports the pages within the Report Engine

* to a Word document using OLE Automation

oReportEngine.SaveToWord('Somereport.doc')

See Also:

SaveToBitmap | SaveToJPEG | SaveToMetafile | SaveToPNG | SaveToTIFF


PDF Methods

These methods are used to generate or to configure how PDF Documents will be created using the Mind's Eye Report Engine at runtime. There are currently 2 different methods that can be used to generate PDF Documents at runtime. The first being the SaveToPDF Method which will generate a PDF document directly to a File on disk. The second method which is more geared to use on a webserver is the PDFStream Method which will generate a PDF Document as a memory stream which can be loaded directly into a memory variable or used as an output stream sent directly to a web server.


PDFFontMetric

Description:

The PDFFontMetric Method can be used to read the names of the unique PDF Fonts in the current report or to Set or Read the Embedded Font Settings for each font that will be generated when creating a PDF document. At this time only True Type Fonts can be embedded into a PDF document. Future capabilities may be added as well.

NOTE: The PDFEmbedFonts Flag must be set to TRUE in order for the True Type Fonts to be embedded into a PDF document.

Syntax:

oReportEngine.PDFFontMetric(nFontIndex, nFontMetric, [nEmbedFont])

Return Type:

Depends on the nAttribute value specified.

Parameters:

nFontIndex | Numeric | Specifies the index value for the PDF Font PDFFontMetrics returns information for. Valid values range from 1 to the PDFFontCount Property Value. A simple loop can be used to test the name of each unique PDF Font within the report.
nAttribute | Numeric | Used to select which Font Metric information. Valid Values: 0 - Returns the Unique PDF Font Name as a string. 1 - Set the Embed Flag for the specified nFontIndex and returns the value as set if changed. If a font is not allowed to be embedded a value of -1 will be returned. 2 - Reads the Embed Flag for the specified nFontIndex and returns the EmbedFont flag as: 0 - Do Not Embed 1 - Embed Font -1 - Embedding Not Allowed
nEmbedFont | Numeric | Flag to EMBED or NOT EMBED Font. Valid Values: 0 - Do Not Embed Font 1 - Embed Font

Examples:

* Retrieves the unique PDF Font Name for the first unique PDF Font in the report.

oReportEngine.PDFFontMetric(1,0)

* Sets the first PDF Font to be flagged AS EMBEDDED within the PDF document.

oReportEngine.PDFFontMetric(1,1,1)

* Sets the first PDF Font to be flagged AS NOT EMBEDDED within the PDF document.

oReportEngine.PDFFontMetric(1,1,0)

* Set ALL fonts to BE EMBEDDED when generating a PDF document.

FOR i = 1 to oReportEngine.PDFFontCount

oReportEngine.PDFFontMetric(1,i,1)

ENDFOR

oReportEngine.PDFEmbedFont = .T.

* Set ALL fonts to NOT EMBED when generating a PDF document.

oReportEngine.PDFEmbedFont = .F.

FOR i = 1 to oReportEngine.PDFFontCount

oReportEngine.PDFFontMetric(1,i,0)

ENDFOR

See Also:


PDFSetPermissions

Description:

The PDFSetPermissions Method is used to quickly and easily set the Permission Properties used while generating a PDF Document using encryption to protect the document.

Syntax:

oReportEngine.PDFSetPermissions(nAllowPrintingLevel, lAllowCopying, lAllowChanges, lAllowCommenting, lAllowFillingFormFields, lAllowCopyingAccessibility, lAllowDocumentAssembly)

Return Type:

None

Parameters:

nAllowPrintingLevel | Numeric | The Printing Level to allow when the PDF Document is opened in Adobe Reader. Valid Values: 0 - Deny Printing 1 - Allow Low Resolution Printing (Used for 40 Bit Encryption) 2 - Allow High Resolution Printing
lAllowCopying | Boolean | Denies or Allows a user to Copy contents in the PDF Document.
lAllowChanges | Boolean | Denies or Allows a user to make Changes to contents in the PDF Document.
lAllowCommenting | Boolean | Denies or Allows a user to Add Comments to the PDF Document.
lAllowFillingFormFields | Boolean | Denies or Allows a user to fill in Form Fields in the PDF Document.
lAllowCopyingAccessibility | Boolean | Denies or Allows a user to Copy Contents for Accessibility in the PDF Document.
lAllowDocumentAssembly | Boolean | Denies or Allows a user to Assemble PDF documents while working with the PDF Document.

Examples:

* Set the Permissions for the PDF Document before creating the PDF Document

oReportEngine.PDFSetPermissions(1,.T.,.T.,.F.,.T.,.T.,.T.)

See Also:


PDFStream Method

Description:

The PDFStream Method generates a PDF Document and returns it as a string variable. The PDFStream Method returns the same stream of data as the SaveToPDF Method when it generates a file to disk. However, the stream of data IS NOT written to disk as a file but is returned as a string. This string can then be used to write directly to disk or be passed to a web server as a response to a browser request.

Set any PDF Properites of the Report Engine before calling the PDFStream Method to embed the information for those properties into the document or for setting compression properties etc. Optionally, the starting page and ending page within the control can be specified to output a range of pages.

Syntax:

oReportEngine.PDFStream([nStartPage=0], [nEndPage=0])

Return Type:

String - The PDF Document as a string.

Parameters:

nStartPage | Numeric | (Optional) The page to start saving at to the PDF document. (Default Value = 0 (First Page))
nEndPage | Numeric | (Optional) The page to end saving at to the PDF document. (Default Value = 0 (Last Page))

Examples:

* Quickly and Easily send a PDF Document back to a web server

lcPDFDocument = oReportEngine.PDFStream()

Response.Write(lcPDFDocument)

VFP Example:

* Quickly and Easily Store PDF Documents inside of Memo Fields

lcPDFDocument = oReportEngine.PDFStream()

REPLACE MyPDFMemo WITH lcPDFDocument

See Also:


SaveToPDF Method

Description:

Saves the contents of the current Report to an Adobe PDF document. Set the PDF Properites before calling the SaveToPDF method to embed the information for those properties into the document or for setting compression properties etc. Optionally, the starting page and ending page within the control can be specified to output a range of pages.

Syntax:

oReportEngine.SaveToPDF(cFileName, lOpenFile, [nStartPage=0], [nEndPage=0])

Return Type:

Boolean -

TRUE if successful

FALSE if unsuccessful

Parameters:

cFileName | String | The name of the file to save the report to.
lOpenFile | Boolean | (Optional) Specifies whether or not to automatically open the PDF file after saving.
nStartPage | Numeric | (Optional) The page to start saving at to the PDF document. (Default Value = 0 (First Page))
nEndPage | Numeric | (Optional) The page to end saving at to the PDF document. (Default Value = 0 (Last Page))

Examples:

oReportEngine.SaveToPDF('Report.PDF',.T.)

oReportEngine.SaveToPDF('Report.PDF',.T.,5)

oReportEngine.SaveToPDF('Report.PDF',.T.,5,20)

See Also:


PrinterAddForm Method

Description:

The PrinterAddForm Method supports adding Custom Form sizes to a Windows NT/2K/XP system for printing to custom paper sizes.

Syntax:

oReportEngine.PrinterAddForm(cFormName,nFormWidth,nFormHeight,[nLeftMargin=0],[nTopMargin=0],

[nRightMargin=0],[nBottomMargin=0],[cPrinterName])

Return Type:

Numeric: 0 = Successful

1 = Failed to create

-1 = File Saved but cannot be opened

Parameters:

cFormName | String | Specifies the Form Name to be added.
nFormWidth | Numeric | Specifies the Width of the Form in inches
nFormHeight | Numeric | Specifies the Height of the Form in inches.
nLeftMargin | Numeric | (Optional) Specifies the Left Margin in inches for the custom form.
nTopMargin | Numeric | (Optional) Specifies the Top Margin in inches for the custom form.
nRightMargin | Numeric | (Optional) Specifies the Right Margin in inches for the custom form.
nBottomMargin | Numeric | (Optional) Specifies the Bottom Margin in inches for the custom form.
cPrinterName | String | (Optional) Specifies the Printer Name to assign the custom form to. If the printer is not specified then it is assigned to the Default Printer.

Example:

* Adds a new Custom Form to the Default Printer with

* a page size of 5 inches X 7 Inches

oReportEngine.PrinterAddForm('MyCustomForm',5,7)

* Adds a new Custom Form to the HP4 Printer with

* a page size of 5 inches X 7 Inches

oReportEngine.PrinterAddForm('MyCustomForm',5,7,0,0,0,0,'HP4')


PrinterDeleteForm Method

Description:

The PrinterDeleteForm Method supports deleting a Custom Form from a Windows NT/2K/XP system.

Syntax:

oReportEngine.PrinterDeleteForm(cFormName,[cPrinterName])

Parameters:

cFormName | String | Specifies the Form Name to be added.
cPrinterName | String | (Optional) Specifies the Printer Name to remove the custom form from. If the printer is not specified then an attempt is made to remove it from the Default Printer.

Example:

* Deletes a Custom Form named MyCustomForm from

* the Default Printer

oReportEngine.PrinterDeleteForm('MyCustomForm')

* Deletes a Custom Form named MyCustomForm from

* the HP4 Printer

oReportEngine.PrinterDeleteForm('MyCustomForm','HP4')


SetPrinterTo Method

Description:

The SetPrinterTo Method can be used to change the Currently Selected Printer for the Report Engine Control. This updates the Printer DropDown List printer and the Printer Dialog Box as well.

Syntax:

oReportEngine.SetPrinterTo(nPrinterID | cPrinterName)

Parameters:

nPrinterID | Numeric | Specifies the Printer by PrinterID number. Valid Values: -1 : Selects the DEFAULT PRINTER 1 - N : Selects any of the other printers on the system specified by number
cPrinterName | String | Specifies the Printer by using the Printer Name as a text string. If the Printer Name can be found in the list of printers on the computer, it is then selected as the currently selected printer.

Example:

* Sets the Currently Selected Printer to the DEFAULT PRINTER

oReportEngine.SetPrinterTo(-1)

* Sets the Currently Selected Printer to the the HP4 Printer

oReportEngine.SetPrinterTo('HP4')

* Sets the Currently Selected Printer to the the Generic Postscript Printer Printer

oReportEngine.SetPrinterTo('Genric Postscript Printer')

See Also:


PrintReport Method

Description:

The PrintReport Method will print the Report to the Current Printer or to the Printer passed as a parameter or will prompt the user for the Printer depending on the PrintPromptForPrint Property. This method optionally accepts a Starting Page, Ending Page, Page Type and/or a File Name to further specify printing options. Use the SetPrinterTo Method or the PrinterID Property, to specify the Current Printer printer to calling the PrintReport Method.

Syntax:

oReportEngine.PrintReport([PrinterID], [nStartPage], [nEndPage], [nPageType], [cFileName], [lDuplex = FALSE])

Parameters:

Printer | Number or String | (Optional) The Number or Name of the Printer. Printer names can also be network printer names as shown below. Passing -1 will force the printing to be done to the DEFAULT PRINTER. Example Values: 1 -1 HP LaserJet 4 \\Server\PrinterName
nStartPage | Number | (Optional) Specifies the First report page to print. Not specifying a value causes printing to start with Page 1.
nEndPage | Number | (Optional) Specifies the Last report page to print. Not specifying a value causes printing to end with the last page in the Report Engine.
nPageType | Number | (Optional) Specifies the pages to print whether they be All pages or Even or Odd pages. Valid Values: 0 = BOTH ODD AND EVEN 1 = ODD 2 = EVEN
cFileName | String | (Optional) Specifies the name of a File to print the report to. This filename should include the full path to the location of the file. NOTE: The folder must exist or the file will not be created. For example: 'C:\MyDirectory\PrintedFile.PRN'
lDuplex | Boolean | (Optional) Can be used to turn Duplex Printing ON or OFF for the current print job programmatically.

Examples:

Printing All Pages in the Report Engine

The following two examples show how to print all pages to a specific printer by passing the Printer Number or the Printer Name to the PrintReport Method and not specifying any other parmeters.

oReport.PrintReport(1)

oReport.PrintReport('HP LaserJet 4') && Prints to the HP LaserJet 4 Printer

oReport.PrintReport(-1) && Prints to the Default Printer

Printing a Range of Pages

The following example would print to the HP LaserJet 4 printer starting with Page 10 and ending with Page 20.

oReport.PrintReport('HP LaserJet 4', 10, 20)

Printing To A File

The following example would print all pages contained within the Report Engine to an output file named PrintedFile.PRN located in C:\SomeFolder.

oReport.PrintReport('HP LaserJet 4',,,,'C:\SomeFolder\PrintedFile.PRN')

See Also:


Mind's Eye Report Engine ActiveX PDF Output

The Report Engine Control can save the contents of the current report to an Adobe PDF Document. The PDF Engine is built into the Mind's Eye Report Engine and DOES NOT does not require any 3rd party external PDF printer drivers.

There are two ways to create PDF documents. Programatically you can call the SaveToPDF() Method passing it a File Name and optionally indicating whether or not to use ShellExecute to automatically open the PDF document after it is created. You can also optionally specify a range of pages within the Report Engine to save to a PDF document. This allows you to save just a portion of a report to a PDF document.

The second way to create a PDF document is for the user to click on the Save To PDF button on the toolbar of the control when it is visible. Clicking on the Save To PDF button on the Toolbar brings up a PDF Document Options form where the user can specify the name of the PDF document as well as several other parameters of the PDF document.

PDF Document Properties

There are several PDF Document Properties that can be used to manage how your documents are different options that are used when saving report documents to PDF files.

There are Properties to control the amount of compression of both JPEG and BITMAP images that are saved to a PDF document. All images are that are saved to a PDF file are saved as JPEG images. BITMAP, TIFF, GIF, PNG and EMF files are all compressed into a JPEG image before embedding them into a PDF document.

Controlling Photo and Image Quality and Compression

The size of a PDF document can increase dramatically if it contains a large number of photos or image files. Most PDF engines only support a single compression level for all images embedded into a PDF document. The Mind's Eye Report Engine has two seperate image compression Properties that can be used to control the compression level for BITMAP images separately from JPEG and other image file formats. These two properties are called PDFBitmapQuality and PDFJPEGQuality. The PDFBitmapQuality Property is set to 100 by default. With this setting, the Report Engine uses 100% Quality, the highest quality possible when compressing BITMAP images into JPEG images before embedding them into the PDF document. The PDFJPEGQuality Property is set to 90 by default, which compresses JPEG images with a quality of 90%, meaning that images will be compressed but with fairly high quality.

To decrease the size of your PDF documents that contain a large number of images, you can set the PDFJPEGQuality and PDFBitmapQuality Properties to lower values. Most photos can be compressed with a quality level of 50 to 75 percent and still look very presentable. However, if you are embedding Bitmap screen shots into your reports and you do not want to see any JPEG compresion artifacts then set the PDFBitmapQuality to 100.

See Also:


PDF Document Options Dialog Box

Below is the PDF Document Options dialog box that is displayed when a user clicks on the Save To PDF button on the Mind's Eye Report Engine toolbar.

The second screen shot displays the PDF Security Options that are displayed when the PDFDisplaySecurityOptions Property is set to TRUE.

There are PDF Properties that can be set to pre-populate the fields on the PDF Document Options dialog box.

PDFFileName

PDFTitle

PDFSubject

PDFAuthor

PDFKeywords

PDFOpenAfterCreate

PDFCompress

MindsEyeReportEngine PDF Document Options without Security Options

PDF Document Options with the PDFDisplaySecurityOptions Property set to FALSE.

MindsEyeReportEngine PDF Document Options with Security

PDF Document Options with the PDFDisplaySecurityOptions Property set to TRUE.

See Also:


Report Properties

Mind's Eye Report Engine Report Properties

REPORT PROPERTIES

Property Name | Data Type | Description
nBackgroundColor | Numeric | Specifies the background color behind the page area in the Report Engine Preview.
nCurrentPageHeight | Numeric | The page height of the current page.
nCurrentPageOrientation | Numeric | The Orientation of the current page.
nCurrentPageWidth | Numeric | The page width of the current page.
nGridColor | Numeric | Specifies the color to display the grid bars.
nLastError | Numeric | The last error that occurred while processing a request.
nPageNumber | Numeric | The current page number being displayed in the Report Engine Preview.
nPageOrientation | Numeric | Specifies the current orientation of the current page as either Portrait or Landscape.
nPaperColor | Numeric | Specifies the color of the paper on the Report Engine Preview.
nPrintScale | Numeric | Specifies the amount of scaling when printing report pages. This property is not currently used.
nReportObjects | Numeric | The number of Report Objects on the current page.
nTotalPages | Numeric | The number of pages currently loaded into the Report Engine. Read/Only


PDF Document Properties

Mind's Eye Report Engine PDF Document Properties

PDF DOCUMENT PROPERTIES

The following properties can be used to specify what is stored into a PDF document when it is created using the SaveToPDF Method or clicking on the Save To PDF command button by the user.

Property Name | Data Type | Description
PDFAuthor | String | The Author of the PDF Document. Default value: ""
PDFBitmapQuality | Numeric | The Quality Level to use for compressing BITMAP images between 1 and 100 using JPEG compression. Default Value: 100
PDFCompress | Boolean | Flag to indicate if the PDF document will be compressed when saved. Default Value: TRUE
PDFCompressBitmaps | Boolean | Flag to indicate whether or not BITMAP images will be compressed when saved into the PDF document. Default value: TRUE
PDFEmbedFonts | Boolean | Flag to indicate whether Fonts marked for embedding will be embedded into the PDF document when generated. Embedding True Type fonts into a document will ensure that the document will appear properly when loaded into a PDF Viewer tool when viewed on a computer that does not have those fonts installed. However, embedding fonts can increase the file size between 60KB to 500KB per font on average within a document. Set this value to TRUE to embed True Type Fonts. NOTE: Individual Fonts must be flagged to be embedded using the PDFFontMetric Method. Default Value: FALSE
PDFEncrypt | Boolean | Flag to indicate whether or not the PDF Document is encrypted when it is saved. Default Value: 0 - No Encryption 1 - 40 Bit 2 - 128 Bit (Not Currently Supported)
PDFFontCount | Numeric | The number of unique PDF Fonts in the report currently. This value is increased automatically as new text is added to a report using the AddText() Method. If running reports using the Visual FoxPro Class Library, this property will be automatically increased as well. This property can be used along with the PDFFontMetricMethod to determine all of the unique PDF Fonts in the current report (Read Only)
PDFJPEGQuality | Numeric | The Quality Level to use for compressing JPEG images between 1 and 100 using JPEG compression. Images that are already compressed at a lower quality than the specified quality will not be modified. Default value: 90.
PDFKeywords | String | A comma delimted list of Keywords for the PDF Document. Default value: ""
PDFMargin | Numeric | The PDF Margin in inches used when saving the PDF document for both the top and left margin of the page. Changing the PDFMargin Property sets the PDFXOffset and PDFYOffset to the PDFMargin value. To override the individual margins use the PDFXOffset and PDFYOffset Properties. Default Value: 0.25
PDFOwnerPassword | String | The Owner Password to be used when creating a PDF Document and the document is to be encrypted by MERE. Default Value: ""
PDFSubject | String | The Subject of the PDF document when saved. Default Value: ""
PDFTitle | String | The Title of the PDF document when saved. Default Value: ""
PDFUserPassword | String | The User Password to be used when encrypting a PDF document to disk. Default Value: ""
PDFXOffset | Numeric | The X Offset of the Left Margin in inches used when saving the PDF document for all pages within the report. This will shift ALL pages within the document left or right by the amount specified when the PDF Document is generated. This Property does not affect the Preview or Printing of reports.
PDFYOffset | Numeric | The Y Offset of the Top Margin in inches used when saving the PDF document for all pages within the report. This will shift ALL pages within the document Up or Down by the amount specified when the PDF Document is generated. This Property does not affect the Preview or Printing of reports.


Methods

Mind's Eye Report Engine ActiveX Control Methods

Methods

The following Methods are available for use on the Report Engine Control.

Method Name | Return Value | Description
AboutBox |  | Displays the About Box for the control.
AddLine |  | Adds a line to the report surface.
AddPicture |  | Adds an Image to the Report.
AddShape |  | Adds a Report Engine Control rectangle or circular shape to the report surface.
AddText |  | Adds text to the report surface.
Clear |  | Clears all pages and objects from the Report Engine Control.
ClearAll |  | Clears all pages and objects from the Report Engine Control.


Document Report Engine Methods


SaveToPDF Method

Description:

Saves the contents of the current Report to an Adobe PDF document. Set the PDF Properites before calling the SaveToPDF method to embed the information for those properties into the document or for setting compression properties etc. Optionally, the starting page and ending page within the control can be specified to output a range of pages.

Syntax:

oReportEngine.SaveToPDF(cFileName, lOpenFile, [nStartPage=0], [nEndPage=0])

Return Type:

Numeric:

0 = Successful

-1 = File Could Not Be Created

-2 = Empty File Name Passed in and No File was Created

Parameters:

cFileName | String | The name of the file to save the report to.
lOpenFile | Boolean | (Optional) Specifies whether or not to automatically open the PDF file after saving.
nStartPage | Numeric | (Optional) The page to start saving at to the PDF document. (Default Value = 0 (First Page))
nEndPage | Numeric | (Optional) The page to end saving at to the PDF document. (Default Value = 0 (Last Page))

Examples:

oReportEngine.SaveToPDF('Report.PDF',.T.)

oReportEngine.SaveToPDF('Report.PDF',.T.,5)

oReportEngine.SaveToPDF('Report.PDF',.T.,5,20)

See Also:


Trial Demo Limitations

The Report Engine control is limited only by the Watermark Branding and the About Box popup message when you DO NOT have a valid Design Time License. Additionally, any emails that are sent using the control without a valid Design Time License key will embed a Demo Watermark in both the SUBJECT and BODY TEXT of the email message, All other functions of the control work as normal. In order to remove the Watermark Branding and suppress the About Box popup, you must purchase a Developer's license for the control. By purchasing a Developer's License, you will receive unlimited email support and software updates for 1 year from the date of purchase. It will also suppress the About Box popups and the Watermark Branding when you add the control to a Form or Form Class. When you add the control to a Form or Form Class, License Key information is stored in the Form or Class when you application is compiled into an EXE or APP file.

The Software License Agreement DOES NOT allow for you to redistribute your Developer's License file with your application nor do you have to. The Developer's License is a file named: MindsEyeReportEnginePro4.LIC or MindsEyeReportEnginePro1.LIC, which will be sent to you via email once you have purchased a Developer's License. This file should be copied into the same folder that the Report Engine control is registered in.

As mentioned above, License Key information is automatically embedded by your application development tool such as Visual FoxPro, Visual Basic or Delphi into the Form or Class when you drop the ActiveX control onto your Form or create a Class wrapper around the control. When your executable application runs on a non-development platform, the License Key information is read at runtime and verified by the control automatically. If the License Key information is verified properly, you will not see the About Box popup nor will you see the Watermark Branding on the report pages in the Preview, Printing or PDF Output. Also, the Demo Information will be removed from the Email messages when sending Email.

Installing Your License Key


Multilingual Support

Multilingual support has been added to the Report Engine ActiveX Control to allow the developer to change the Tooltip Text on all Toolbar Objects. There are two ways to change the Tooltip Text.

The first and easiest method is by setting the LanguageIndexID Property of the ActiveX Control to a numeric value that corresponds to any of the following languages. When the LanguageIndexID Property value is changed the control will automatically change all of the text strings to the appropriate language to localize the control to the selected language. If you have a language with all of the translations that you would like to see added to the list please email me the list of translations I will add them.

Visual FoxPro NOTE:

A LanguageIndexID Propery has also been added to the MindsEyeReportEngine Class definition to support automatic changes of the language setting for the ActiveX control. Therefore, you can set the LanguageIndexID value of the MindsEyeReportEngine Object after instantiation and before you Preview a Report to have it automatically set at the time the Report Preview Window appears.

LanguageIndexID Property

0 - English (Default)

1 - Spanish

2 - French

3 - German

4 - Portugese

5 - Dutch

6 - Italian

7 - Turkish

Alternatively, you can also use the SetReportEngineText(nIndexID, cNewString) Method to specify whatever text you wish for each of the Toolbar Objects specifically. The following Index ID's list the Objects and what the text is defined for. More text string objects will be added to this list so you can customize the control to your own language.

SetReportEngine(nIndexID, cNewString) Method

Index ID | Description
1 | Save TO PDF button
2 | Print Report button
3 | Email as PDF Attachment button
4 | Actual Size button
5 | Fit In Window button
6 | Fit To Width button
7 | Zoom In button
8 | Zoom Out button
9 | Actual Size button
10 | Page Size text box
11 | First Page button
12 | Prior Page button
13 | Next Page button
14 | Last Page button
15 | Page Position text box
16 | Scale text box
17 | Zoom dropdown menu button
18 | Page Position scrollbar
19 | Find button
20 | Display Grid button
21 | Help button


Printer DEVMODE Structure

The DEVMODE data structure contains information about the initialization and environment of a printer or a display device. MERE sets several of the values in the DEVMODE structure prior to rendering the page to the printer based upon the Properties set for each page within a report in MERE. This is how changing Page Orientations, Paper Bins, Media Types and Duplexing is accomplished during a single print job on a page by page basis.

The structure of the DEVMODE is defined in the Windows API documentation as:

typedef struct _devicemode {

BCHAR dmDeviceName[CCHDEVICENAME];

WORD dmSpecVersion;

WORD dmDriverVersion;

WORD dmSize;

WORD dmDriverExtra;

DWORD dmFields;

union {

struct {

short dmOrientation;

short dmPaperSize;

short dmPaperLength;

short dmPaperWidth;

short dmScale;

short dmCopies;

short dmDefaultSource;

short dmPrintQuality;

};

POINTL dmPosition;

DWORD dmDisplayOrientation;

DWORD dmDisplayFixedOutput;

};

short dmColor;

short dmDuplex;

short dmYResolution;

short dmTTOption;

short dmCollate;

BYTE dmFormName[CCHFORMNAME];

WORD dmLogPixels;

DWORD dmBitsPerPel;

DWORD dmPelsWidth;

DWORD dmPelsHeight;

union {

DWORD dmDisplayFlags;

DWORD dmNup;

}

DWORD dmDisplayFrequency;

#if(WINVER >= 0x0400)

DWORD dmICMMethod;

DWORD dmICMIntent;

DWORD dmMediaType;

DWORD dmDitherType;

DWORD dmReserved1;

DWORD dmReserved2;

#if (WINVER >= 0x0500) || (_WIN32_WINNT >= 0x0400)

DWORD dmPanningWidth;

DWORD dmPanningHeight;

#endif

#endif /* WINVER >= 0x0400 */

} DEVMODE;


Software License Agreement

Mind's Eye Report Engine Software License Agreement

 Top Previous

Mind's Eye Report Engine Professional

IMPORTANT - READ CAREFULLY: This Mind's Eye End-User License Agreement ("EULA") is a legal agreement between you (either an individual or an entity) and Mind's Eye, Inc. for the Mind's Eye product identified above, which includes computer software and may include associated media, printed materials, and "online" or electronic documentation ("SOFTWARE PRODUCT"). By installing, copying, or otherwise using the SOFTWARE PRODUCT, you agree to be bound by the terms of this EULA. If you do not agree to the terms of this EULA, you are not authorized to install, copy, or otherwise use the SOFTWARE PRODUCT; you may, however, return the SOFTWARE PRODUCT, along with all printed materials and other items that form a part of the Mind's Eye product that includes the SOFTWARE PRODUCT, to the place you obtained them for a full refund.

MIND'S EYE, INC. IS WILLING TO LICENSE THIS SOFTWARE TO YOU ONLY IF YOU ACCEPT ALL OF THE TERMS IN THIS LICENSE AGREEMENT. PLEASE READ THE TERMS CAREFULLY BEFORE YOU INSTALL THIS SOFTWARE, BECAUSE YOU ARE INSTALLING THIS SOFTWARE YOU ARE AGREEING TO BE BOUND BY THE TERMS OF THIS AGREEMENT. IF YOU DO NOT AGREE TO THESE TERMS, MIND'S EYE, INC. WILL NOT LICENSE THIS SOFTWARE TO YOU, AND IN THAT CASE YOU SHOULD RETURN OR REMOVE THIS PRODUCT PROMPTLY, INCLUDING THE INSTALLATION SOFTWARE AND ALL WRITTEN MATERIALS.

OWNERSHIP OF THE SOFTWARE:

The SOFTWARE PRODUCT is protected by United States copyright laws and international treaties, as well as other intellectual property laws and treaties. The SOFTWARE PRODUCT is licensed, not sold.

The product in this package (libraries and object code) is proprietary to Mind's Eye, Inc. and is protected by Federal Copyright Laws, by laws of other nations, and by international treaties. Mind's Eye, Inc. retains the title to and ownership of the Product. You are licensed to use this Product on the following terms and conditions:

LICENSE:

The licensee is defined as the individual software developer utilizing the Product. This license is not for an entire company but for a single developer. Mind's Eye, Inc. hereby grants the licensee a nonexclusive license authorizing the licensee to use the enclosed Product on one computer at a time for development purposes. Distribution of the application(s) using Report Engine is royalty-free, requiring no additional license fees. You may incorporate the sample code into your applications. Use of this product by more than one individual or by anyone other than the licensee terminates, without notification, this license and the right to use this product.

YOU MAY NOT:

Distribute, rent, sub-license or otherwise make available to others the software or documentation or copies thereof, except as expressly permitted in this License without prior written consent from Mind's Eye, Inc. In the case of an authorized transfer, the transferee must agree to be bound by the terms and conditions of this License Agreement.

RESTRICTIONS:

You may use this Product in your business application for sale or distribution as long as:

The product that you produce and/or distribute is NOT a software development product, a product that is sold primarily to software developers or a development environment of any kind.

The product that you produce includes recognition of Mind's Eye Inc.'s proprietary rights in the "Help About" dialog box.

The software serial number and user must be registered with Mind's Eye, Inc. in order to receive support or distribution rights.

You may not remove any proprietary notices, labels, trademarks on the software or documentation.

You may not reverse engineer, decompile, disassemble or translate the Software.

FILES THAT MAY BE DISTRIBUTED WITH YOUR APPLICATION: MindsEyeReportEnginePro1.OCX, MERE_ReportListener.VCX, MindsEyeReportEngine.VCX.

TERM:

You may terminate your License and this Agreement at anytime by destroying all copies of the Product and Product Documentation. They will also terminate automatically if you fail to comply with any term or condition in this Agreement.

LIMITED WARRANTY:

This software and documentation are sold "as is" without any warranty as to their performance, merchantability or fitness for any particular purpose. The licensee assumes the entire risk as to the quality and performance of the software. Mind's Eye, Inc. warrants that the media on which the Program is furnished will be free from any defects in materials. Exclusive remedy in the event of a defect is expressly limited to the replacement of media. In no event shall Mind's Eye, Inc. or anyone else who has been involved in the creation, development, production, or delivery of this software be liable for any direct, incidental or consequential damages, such as, but not limited to, loss of anticipated profits, benefits, use, or data resulting from the use of this software, or arising out of any breach of warranty.

LICENSOR DISCLAIMS ALL OTHER WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT, WITH RESPECT TO THE SOFTWARE AND THE ACCOMPANYING WRITTEN MATERIALS. This limited warranty gives you specific legal rights. You may have others, which vary from state to state.

This Limited Warranty is void if failure of the Software has resulted from modification, accident, abuse or misapplication.

This Agreement is governed by the laws of the State of Missouri.

US GOVERNMENT RESTRICTED RIGHTS: The Software and documentation are provided with Restricted Rights. Use, duplication or disclosure by the United States Government is subject to restrictions as set forth in subparagraph (c)(1) of The Rights in Technical Data and Computer Software clause at DFARS 252.227-7013 or subparagraphs (c)(1)(ii) and (2) of Commercial Computer Software - Restricted Rights at 48 CFR 52.227-19, as applicable. Supplier is Mind's Eye, Inc. / 4115 Hidden Meadows Dr. / Arnold, MO 63010.


Counting Groups

Counting Groups in a Visual FoxPro Report

 Top

To count Data Groups in a Visual FoxPro Report, create a Report Variable and update that Report Variable in the ONEXIT() Event of the Group Footer Band of the Data Group you wish to count. This is done by using the SetVar() Function of the _VFP Object. Every time the Data Group's Group Footer Band OnExit Event fires, the _VFP.SetVar() Function will be called and update the Report Variable.

Steps to count groups in a Visual FoxPro Report:

1. Begin by creating a Report Variable and name it Group1Count.
2. Set the Inital Value to 0.
3. Set the Value to Store as 0.
4. Set the Calculate Option to SUM.
5. Double Click on the Group Footer Band of the Data Group to count and enter the following expression into the ONEXIT Expression:

_VFP.SetVar("Group1Count", Group1Count + 1)


.topic 24000
MERE UPDATE TO DO LIST
IMPORTANT: CHECK ALL BUGS POSTED TO DATE
Update the HELP FILE
TEST Reports
Update Sample Code
Post Information on Using MERE 4.0
VERIFY ALL FILES IN THE SETUP

MERE_ReportListener Fixes
Fix issues related to GetPageHeight and GetPaperSize
Fix issue related to PRINT AREA: WHOLE PAGE or PRINTABLE AREA
PROMOTE the MERE Report Engine Testing Tool
Try stopping the PRINT SPOOLER and running the ReportListener
Take the output from Roman's VFP GDI+ Charting Tool and render it into MERE Objects.

MERE REPORT TO DO ITEMS
Write code to parse an EMF+ file and generate the output to MERE Objects
Add support for a PLUGIN technology to the report engine
PLUGIN TECHNOLOGY - Find out how other applications handle

0 0 0 0 3 0 0 0 165 5 0 0 94 0 0 0 1 0 0 0 85 85 135 64 0 128 135 64 0 0 0 0 77 0 0 0 37 0 0 0 76 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 148 17 0 0 150 22 0 0 152 0 0 0 87 0 104 0 97 0 116 0 32 0 105 0 115 0 32 0 116 0 104 0 101 0 32 0 77 0 105 0 110 0 100 0 39 0 115 0 32 0 69 0 121 0 101 0 32 0 82 0 101 0 112 0 111 0 114 0 116 0 32 0 69 0 110 0 103 0 105 0 110 0 101 0 63 0 0 0 81 0 0 0 45 0 0 0 46 0 0 0 23 0 0 0 23 0 0 0 18 0 0 0 42 0 0 0 23 0 0 0 23 0 0 0 46 0 0 0 46 0 0 0 23 0 0 0 70 0 0 0 18 0 0 0 47 0 0 0 46 0 0 0 16 0 0 0 42 0 0 0 23 0 0 0 57 0 0 0 40 0 0 0 46 0 0 0 23 0 0 0 61 0 0 0 46 0 0 0 47 0 0 0 46 0 0 0 28 0 0 0 23 0 0 0 23 0 0 0 55 0 0 0 47 0 0 0 46 0 0 0 19 0 0 0 46 0 0 0 46 0 0 0 46 0 0

.topic 26500
Clete Ahearn - October 21, 2008

DAX ERROR on a LEXMARK T640 PRINTER DRIVER on Windows 2003.

.topic 24800
MERE 3.0 UPDATE BY 12PM - 06/02/2008
BUG: RIGHT ALIGNED TEXT FROM A MERE_RL is slightly OFF to the LEFT in MERE than in VFP.
BUG: BACKSTYLE=1 (SOLID BACK COLOR) DOES NOT ROTATE WITH TEXT (Preview, Print or PDF)
BUG: Fix CHARACTER SET on characters in PDF and on PREVIEW
IMPORTANT BUG:  REFACTOR the PaintThisPage Method and REMOVE ALL DUPLICATE CODE!
BUG: PDF OUTPUT FONT is WRONG with BACKSTYLE = 1
BUG: WATERMARK TRANSPENCY LEVEL NOT WORKING USING NEGATIVE NUMBERS

TO DO: Update Help file for the new MEREPRO4PreviewForms.VCX Class
TO DO: Add more items to the Help File with examples to program the control
TO DO: Post benchmarks

FIXED: BUG: _PAGENO and _PAGETOTAL not working with VFP 9 in the RL
FIXED: BUG: RepaintThisPage() Method needs to be recoded so that the FONTNAME IS COPIED and NOT IN A LOOP FOR THE GDI CALL
FIXED: BUG: Multiple Lines not working now in the RL on the PREVIEW
FIXED: BUG: FIX ROTATION AND TRANSLATION BUGS WITH TEXT on Preview, Print, PDF

NEW FEATURE TO DO LIST TO COMPLETE 4.0
NEW IDEA: Add FTP Engine and FTP Methods to transfer PDF documents on the fly.
NEW IDEA: Performance tracking. Need a Method to RESET the Performance Statistics. Then need a method to return the Performance Statistics. This could ALL be in one method with a Parameter passed.
EngineStats(0) - Clear Statistics
EngineStats(1) - Returns Engine Statistics, # of Pages Added, Time to Add and Number of Objects per page
NEW IDEA: Just a thought for testing. But, how would it be if we modified the code so that we don't have to repaint the entire page all of the time when we are displaying a single page. This would be similar to how the reports are persisted in VFP. So, that we render the page to an EMF in memory and then the EMF is simply resized on the fly by Delphi and repainted. STUDY HOW DELPHI PERSISTS IT'S IMAGES.
TEST: Check to see that the MERE_ReportListener is properly centering Text still after we make the change to the new MERE 4.0.
NEW: Add a Method to MERE to get the Version Number or a Property so we can check to see what version we are running in the MERE RL and properly handle any changes made to the control. Or have a property to reverse the angle of the rotated text.
BUG: FIX LINE DRAWING IN 4.0 - We are not drawing all of the lines with the correct dashes
BUG: FIX GRID in 4.0 - IT'S DRAWING SOLID LINES
BUG: FIX THE ZOOM SO THAT IT ZOOMS TO THE CURRENT POSITION
BUG: Need GDI+ ROUNDED RECTANGLES
HELP: Add Screen Shots of the BarCodes, Add Examples for generating the BARCODES
FIXED: BUG: NEED TO KNOW HOW TO TRANSLATE AROUND A POINT

MERE 4.0 MARKETING
NEW IDEAS: COMPETITIVE UPGRADE AGAINST XFRX AND FRX2ANY
NEW IDEAS: DISCOUNT FOR UNIVERSAL THREAD MEMBERS
IMPORTANT: Memory Usage Examples and Speed Tests against the standard VFP ReportListener
Post Screen Shots up at MEI and DOWNLOAD.COM website
Advantages
Rendering done without Printer Driver produces text instead of graphics images from GDI+ commands.
Until June 30, 2008 - Competitive Upgrade available for all licensed users of XFRX and FRX2ANY. If you own a legal license of XFRX or FRX2ANY and wish to purchase a copy of the Mind's Eye Report Engine PRO 4.0 control, you will be entitled to a 40% discount off of the standard $695 price. This allows you to purchase MERE PRO for the low price of $417 (a $278 discount).

Performance Benchmarks Using
VFP 9 Report Listener Class in Seconds

Memory Usage in KB
using Process Monitor

Table Rows
MERE
Report Behavior 90
Report Behavior 90
Pages Rendered
MERE
Report Behavior 90
MERE
Rendering PDF
1,000
0.63
3.16
0.29
29
25,504

5,000
2.42
14.59
0.51
143
43,424
43,648

10,000
4.61
28.80
0.66
286
46,688
50,396

20,000
9.07
58.03
1.42
572
50,108
63,968
56,576
200,000
89
524

(NOTE: VFP could not finish the report due to 10K GDI Handle Limit resulting in ERROR 2203)
10.13
5715
185,364
269,612

(NOTE: Amount used before reporting ERROR 2203)
259,136

GDI+ FIXES
GDI+ Fixes
Add Code to draw ROUNDED RECTANGLES
Add Code to Draw

PDF FIXES
Write Code to Draw BEZIER CURVE ARCS

Figure out how to Control ALPHA LEVEL in PDF
Figure out how to draw Bezier Curves for the Ellipses in the PDF
FOUND DRAWELLIPSE in the PDFDOC methods
Now need to figure out how to draw the ARCS, and CHORDS
Also need to add a ROTATED SQUARE and ROTATED ELLIPSE
NEW: ADD PAGE ROTATION PROPERTY for a particular page
NEW: Add PDF OPEN FILE FEATURES, ZOOM SIZE, MENU INFORMATION, ETC.
NEW: COLOR BLENDING SUPPORT (GRADIENTS)
NEW: PDF OUTLINE ENTRIES

MERE WEBSITE UPDATE
Create a SCREEN SHOTS under the Report Engine Folder
Create a SAMPLE CODE section under the Report Engine Folder (Include VBSCRIPT code)
Virtual Print Engine Comparison

FOR BO'S STUFF
I would like to be able to tell it 2 options:
1) don't crop text. if the rectangle is in the middle of text, make the rectangle smaller (passed by reference)
[3:14:30 PM] Bo Durban says: 2) Don't crop images. Same as above, but for images...I pass an EMF and a rectangle...the routine will create a new EMF that has all the objects that were in the rectagle, except any images that are cut by the rectangle
then the new bounding rectanle is returned as an in/out parameter of the original rectangle, passed by reference

WHAT'S NEW in the new MERE 4.0 Version
Drawing commands for the Preview and Printing have been converted to use GDI+.
Add Alpha Level (transparency) support to shapes.
Added new Shape Objects to the Drawing Methods: AddArc, AddChord, AddPie
Added a new PageFlip Property to support flipping pages 180 degrees while printing.
Reduced the memory footprint of the OCX by removing no longer used or supported FoxPro FRX Methods and Properties. This new MERE 4.0 and above versions are only supported in Visual FoxPro by using the MERE_ReportListener class for rendering reports.
Report objects on pages use less memory.

BUG FIXES (Both MERE 3.x and 4.0)
Resolved issue with Printer Fonts not being supported in the GDI+ code which was causing OLE Errors.
Fixed display of rotated text in the Preview display

WHAT WILL BE NEW
Transparency is now supported in PDF documents
New EMF Methods to convert EMF images or Clipboard EMF objects into native MERE Objects. Note: Not all embedded EMF objects may be supported as there are a few obscure drawing functions not yet covered in the EMF Parsing Engine.
Gradient fills are now supported on Shape Objects.
Added option to keep all objects in memory which was the original design or to support using a memory file for large documents.
New PageRotation Property - This property will allow for an angle of 0, 90, 180 and 270 to be specified. IMPORTANT: Ability to specify an ENTIRE PAGE ROTATION angle in Print, Preview and PDF output.

NEW FEATURES
New PageRotation Property - This property will allow for an angle of 0, 90, 180 and 270 to be specified. IMPORTANT: Ability to specify an ENTIRE PAGE ROTATION angle in Print, Preview and PDF output.
AddEMF() Method - Adds an EMF image/document to the report engine converting it to native MERE Objects.
GDI+ Drawing commands are now used for rendering output with support for Alpha Levels (transparency).
New Shape Functions Added
Smaller Footprint
Faster Rendering

PDF TRANSPARENCY

NOTES:
To use the ExtGState for individual Objects, those objects must be placed into a <</Group>> Object on the page which is part of the ExtGState Subdictionary in the Page Resources Section of the page.
Each MERE Page will need to know if it has an ALPHALEVEL object on the page ahead of generating the PDF Page, so the PDFENGINE will know if it needs to create an Extended Graphics State for the Objects needing the AlphaLevel Property controlled.

PDF ExtGState - Extended Graphics State entries are PDF Dictionary Subsets in the RESOURCES Section

8 0 obj<</Parent 7 0 R/Contents 6 0 R/Type/Page/Resources<</ExtGState<</GS1 1 0 R>>/XObject<</Xf2 3 0 R/Xf1 2 0 R>>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]/Font<</F1 5 0 R>>>>/MediaBox[0 0 595 842]>>
endobj
5 0 obj<</BaseFont/Helvetica/Type/Font/Encoding/WinAnsiEncoding/Subtype/Type1>>
endobj
3 0 obj <</Group<</S/Transparency>>/Type/XObject/Resources<</ExtGState<</GS2 4 0 R>>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]>>/Subtype/Form/BBox[0 0 200 200]/Matrix [1 0 0 1 0 0]/Length 164/FormType 1/Filter/FlateDecode>>stream
xœEPÉ
Ã0
ûk
OJN]Ût€Œ` yõÓîTw`À"$Rï£–ëTß÷ªX:–‚Ù·ùï
žuÛ§âdYyG«Úoi%’C¡:yò
3v]APóég5.èÖƒñMtñ¨£¹R…ÞMR7Rz‚˜AºÌ;FšÝ
‰U'Ìh¯·¼Ãš®¥)7m¤)•¹M
endstream
endobj
2 0 obj <</Group<</S/Transparency>>/Type/XObject/Resources<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]>>/Subtype/Form/BBox[0 0 200 200]/Matrix [1 0 0 1 0 0]/Length 154/FormType 1/Filter/FlateDecode>>stream
xœEP91ìy…_°oã÷XÚTiòÿ"Ü–%3‚Ž¡†ò~ ŽmbûXózSüQÐ°áÕ¯{.–—7Hôªÿž6Qñ¨8”ªdBl0„qÛ
ŠFL÷À’A´¸azÁ‡â
ÐN
¥	£›¦Jú€šA¶
§œ‡ÖFNwC²G·	+ÛÛm\×bZ¢B×2åÐ¸Lù`!K¡
endstream
endobj
4 0 obj<</ca 0.5/BM/SoftLight>>
endobj
1 0 obj<</ca 0.5>>
endobj

8 0 obj
<</Parent 7 0 R/Contents 6 0 R/Type/Page/Resources
<</ExtGState<</GS1 1 0 R>>
/XObject<</Xf2 3 0 R/Xf1 2 0 R>>
/ProcSet
[/PDF /Text /ImageB /ImageC /ImageI]
/Font<</F1 5 0 R>>>>
/MediaBox[0 0 595 842]>>
endobj

1 0 obj<</ca 0.5>>
endobj

8 0 obj<</Parent 7 0 R/Contents 6 0 R/Type/Page/Resources<</ExtGState<</GS1 1 0 R>>/XObject<</Xf2 3 0 R/Xf1 2 0 R>>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]/Font<</F1 5 0 R>>>>/MediaBox[0 0 595 842]>>
endobj
5 0 obj<</BaseFont/Helvetica/Type/Font/Encoding/WinAnsiEncoding/Subtype/Type1>>
endobj
3 0 obj <</Group<</S/Transparency>>/Type/XObject/Resources<</ExtGState<</GS2 4 0 R>>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]>>/Subtype/Form/BBox[0 0 200 200]/Matrix [1 0 0 1 0 0]/Length 164/FormType 1/Filter/FlateDecode>>stream
endstream
endobj
2 0 obj <</Group<</S/Transparency>>/Type/XObject/Resources<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]>>/Subtype/Form/BBox[0 0 200 200]/Matrix [1 0 0 1 0 0]/Length 154/FormType 1/Filter/FlateDecode>>stream
xœEP91ìy…_°oã÷XÚTiòÿ"Ü–%3‚Ž¡†ò~ ŽmbûXózSüQÐ°áÕ¯{.–—7Hôªÿž6Qñ¨8”ªdBl0„qÛ
ŠFL÷À’A´¸azÁ‡â
ÐN
¥	£›¦Jú€šA¶
§œ‡ÖFNwC²G·	+ÛÛm\×bZ¢B×2åÐ¸Lù`!K¡
endstream
endobj
4 0 obj<</ca 0.5/BM/SoftLight>>
endobj

NEW DRAWING FUNCTIONS
AddShapeRotated(nRotation)
AddPolygon
AddPolyLine
StrokeAndFillPath
DONE: AddChord
DONE: AddPie
DONE: AddArc

PATH FUNCTIONS
NewPath
AddCurveTo
ClosePath

The new AddEMF() method will have the ability to in one pass interpret the entire EMF document and convert it into a page instead of writing a separate interpreter that then calls individual MERE Methods.

AddEMF() Method Notes
It may be quicker to simply keep a reference to the EMF File name and simply convert the EMF to PDF objects on the fly when call to SaveToPDF() is done.
Native objects could be converted ahead of time.
How should large EMF Images be stored when converted to native objects.
Temporary files for EMF Images could be costly in disk space.
Using the EMF file with images in it could be costly on the REPAINT
If MERE Supports breaking up EMF images across pages, then we would have to convert to MERE Native Objects.
We could store an Array of what EMF Records of a Single EMF are Painted on What Page.

.topic 26400
Add Support for Twain Scanning
JEDI Code

METHODS
ScanPage(nX,nY,nWidth,nHeight,)
ScannerSetSource('Source Name')
ScannerGetSource(nSourceID)

PROPERTIES
ScannerDeviceCount = n

.topic 26300
RTF TO DO LIST
Add the FONT LOOKUP Support and FONT Selection Support for searching for the Font when Outputting
Add TEXT Replacement code to convert:
"\" to "\\"
"{" to "\{"
"}" to "\}"
CHR(9) (tab) to "\tab"
CRLF to "\line"
CR to "\line"
AddPage support

 The format of the value depends on the property name it is paired with. Many values are simple single numbers. Distances are expressed in EMU units. There are 12700 EMU units in a point hence 914400 in an inch and 360000cm-1. Fractional or fixed values are expressed using units that are 1/65536th of a whole. Angles are expressed as fractions of a degree. Colors are 24 bit color values. Booleans have two possible values: 1 for True and 0 for False.

Arrays are formatted as a sequence of number separated by semicolons. The first number tells the size of each element in the array in bytes. The number of bytes per element may be 2, 4, or 8. When the size of the element is 8, each element is represented as a group of two numbers. The second number tells the number of elements in the array. For example, the points of a square polygon are written as:

.topic 25200
The Conception - What Is VPE?
VPE (Virtual Print Engine) for Windows is a tool for software developers. VPE allows the dynamic creation of documents for screen- and printer output by calling functions during the runtime of your application.
The free positioning of graphical objects (i.e. text, images, lines, etc.) by code offers unlimited layout options. Using VPE you can create both: reports and lists as well as complex documents and forms.
VPE is capable of computing the width and height of images as well as of  text objects depending on their textual content and font settings, including word- and page-breaks. This allows to adapt the layout dynamically to the content of your data.

VPE is just more: generate perfect PDF files!
Using an add-on module, VPE becomes a simple-to-program and powerful tool to create easily PDF files.
The Enterprise Edition of the PDF Module supports all important features of PDF, including Encryption, Linearized PDF ("Fast Web View") and True-Type Fontsubsetting.
Example files, which were created using VPE

How Does It Work?
A VPE document consists of any number of pages. All graphical objects are placed on the current page by calling methods. At any time you may select the current page freely, or you can add blank pages to the document. The positioning of the graphical objects is performed in a device independent coordinate system with 0.1mm resolution.
I want to know more details

For What Tasks Should One Use VPE?

In all cases of printing and data presentation, such as:

Dynamic generation of complex documents, forms and reports

Drawing plans, graphs, diagrams, etc.

Printing forms and labels exactly and printer independent

High performance printing with thousands of pages

Importing images of all common types

Printing barcodes (supports 38 types)

Import and presentation of RTF (Rich Text Format)

Creation of Charts

Interactive reports (clickable objects)

Export of pages to all common image file formats

e-Mail and Internet / Intranet publishing of VPE document files

Can I Try It?
Yes, you can! The VPE trial-versions are available for download.

The VPE Trial-Versions Offer:

The complete and fully programmable VPE-SDK
(Software Development Kit)

No restrictions (only demo banners)

The complete manuals as helpfiles, additionally in PDF format

Detailed demo source codes for all common programming tools / languages

.NET Winforms, ASP.NET Components, ActiveX, VCL and DLL
in one package

.topic 24600
NEW METHODS TO ADD
AddPolyLine
AddPolygon(cName, cPoints, cVertices, nFillColor, nBorderWidth)
AddPath()
NewPath()
AddPie()
SetRotationAngle - Changes the coordinate system so that all future items are rotated at the specified angle
AddMetafile() - Converts a Metafile Image into native MERE Objects and adds it to a page. This could also scale the EMF to fit within a certain scaling.

HANDLING METAFILES
Add a metafile as a whole page.
Have the ability to Split Metafiles that are taller than a page into multiple pages. This would be helpful for

.topic 24500
MERE IMPROVEMENTS TO MAKE
FIX PREVIEW OF ROTATED TEXT
MAKE WEEKLY UPDATES OF THE PRODUCT
CREATE NEW ADD ONS FOR THE PRODUCT
Improve MEMORY USAGE OF OBJECTS
Test SPEED of Adding Objects
CREATE VBScript Examples
Create a new Examples Folder which includes
.NET EXAMPLES
VB SCRIPT EXAMPLES
DELPHI EXAMPLES

.topic 24400
Add FAQ Sections for each of the languages on the MERE Page
Move ALL of the Downloads to the CENTRAL DOWNLOAD PAGE
Make a VB6 DEMO Only Download WITH SOURCE
Make a MERE PRO 4 ONLY LINK - Package inside Installer

.topic 24200

MERE GOALS
Create and Install a MERE Printer Driver
Ability to Edit PDF Documents
Ability to load PDF Documents into the MERE Preview Engine
EMF FILES ARE HEAVY
SUPPORT PLUGINS / ADD ONS
Make a FireFox PLUGIN that allows dumping pages directly to a PDF document
COMPILE A DELPHI ASSEMBLY
MAKE A .NET COMPONENT OUT OF THE MERELITE COMPONENT
READ A SPOOL FILE

POSSIBLE PRODUCTS

MARKETING GOALS
Create a Virtual Box for the product as below

[PICTURE deskPDF.gif]

MERE ADVANTAGES
What are the advantages to MERE?

.topic 24100
LIST OF FUNCTIONS TO ADD
Read EMF from CLIPBOARD
Add POLYGON Support to MERE
AddPolyLine() Method
AddPolygon() Method

Width x Height: 301 x 101
nXRes / nYRes: 81.27999 / 81.27999
Width / Height (inches): 3.703249 / 1.242618

1: EmfMin : 100  Flags:0
0 0 0 0 0 0 0 0 44 1 0 0 100 0 0 0 0 0 0 0 0 0 0 0 159 36 0 0 53 12 0 0 32 69 77 70 0 0 1 0 168 3 0 0 30 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 3 0 0 64 1 0 0 240 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 226 4 0 128 169 3

2: Header : 16  Flags:1
1 16 192 219 1 0 0 0 96 0 0 0 96 0 0

HEIGHT: -608169983
WIDTH: 1
YRES: 81.27999
XRES: 81.27999

3: FillRects : 16  Flags:49152
0 0 0 255 1 0 0 0 0 0 0 0 100 0 100 0

X0: -16777216
x4: 1
x8: 0
x12: 6553700

4: FillEllipse : 12  Flags:49152
5: EndOfFile : 0  Flags:0
6: EmfEof : 12  Flags:0

85: EmfBeginPath : 0  Flags:0
86: EmfMoveToEx : 8  Flags:0
87: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 245 11 242 14 246 11 247 14 246 11 253 14

88: EmfPolylineTo16 : 28  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 2 0 0 0 246 11 253 14 246 11 161 20

89: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 243 11 195 20 216 11 221 20 182 11 224 20

90: EmfPolylineTo16 : 28  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 2 0 0 0 182 11 224 20 21 9 224 20

91: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 243 8 221 20 216 8 195 20 213 8 161 20

92: EmfPolylineTo16 : 28  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 2 0 0 0 213 8 161 20 213 8 253 14

93: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 213 8 247 14 214 8 242 14 215 8 237 14

94: EmfPolylineTo16 : 28  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 2 0 0 0 215 8 237 14 213 8 237 14

95: EmfPolyBezierTo16 : 80  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 15 0 0 0 213 8 236 14 213 8 235 14 213 8 235 14 213 8 85 14 136 9 219 13 101 10 219 13 66 11 219 13 246 11 85 14 246 11 235 14 246 11 235 14 246 11 235 14 246 11 235 14 246 11 235 14 246 11 236 14 246 11 237 14

96: EmfLineTo : 8  Flags:0
From: 31.83915,39.68568 To: 0,0

97: EmfCloseFigure : 0  Flags:0
98: EmfMoveToEx : 8  Flags:0
99: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 245 11 242 14 246 11 247 14 246 11 253 14

100: EmfPolylineTo16 : 28  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 2 0 0 0 246 11 253 14 246 11 161 20

101: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 242 11 194 20 215 11 221 20 182 11 224 20

102: EmfPolylineTo16 : 28  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 2 0 0 0 182 11 224 20 21 9 224 20

103: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 243 8 221 20 216 8 194 20 213 8 161 20

104: EmfPolylineTo16 : 28  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 2 0 0 0 213 8 161 20 213 8 253 14

105: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 213 8 247 14 214 8 242 14 215 8 237 14

106: EmfPolylineTo16 : 28  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 2 0 0 0 215 8 237 14 213 8 237 14

105: EmfPolyBezierTo16 : 32  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 3 0 0 0 213 8 247 14 214 8 242 14 215 8 237 14

107: EmfPolyBezierTo16 : 80  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 15 0 0 0 213 8 236 14 213 8 235 14 213 8 235 14 213 8 85 14 136 9 219 13 101 10 219 13 66 11 219 13 246 11 85 14 246 11 235 14 246 11 235 14 246 11 235 14 246 11 235 14 246 11 235 14 246 11 236 14 246 11 237 14

108: EmfLineTo : 8  Flags:0
From: 31.83915,39.68568 To: 0,0

109: EmfCloseFigure : 0  Flags:0
110: EmfMoveToEx : 8  Flags:0
111: EmfPolylineTo16 : 36  Flags:0
0 0 0 0 0 0 0 0 255 255 255 255 255 255 255 255 4 0 0 0 70 12 179 13 70 12 56 21 133 8 56 21 133 8 179 13

112: EmfCloseFigure : 0  Flags:0
113: EmfEndPath : 0  Flags:0
114: EmfStrokePath : 16  Flags:0
115: EmfSelectObject : 4  Flags:0
7 0 0 128

.topic 24300
Option Explicit
Public oRPT As Object

Private Sub Command1_Click()
    ' myoRPT = Me
    oRPT.AddText "", "This is a test.", 1, 1
    oRPT.AddText "", "Here is some more text.", 1, 2, , , "Arial", 20
End Sub

Private Sub Command2_Click()
    Unload Me
End Sub

Private Sub Exit_Click()
  If MsgBox("Are you sure you want to quit?", vbYesNo Or vbQuestion) = vbNo Then
    Exit Sub
  End If
  Dim tmpForm As Form
  For Each tmpForm In Forms
    If tmpForm.Name <> "frmMain" Then
        Unload tmpForm
        Set tmpForm = Nothing
    End If
  Next
  Unload Me
End Sub

Private Sub Form_Load()
  Set oRPT = Controls.Add("MEREPro4.MEREPro", "oRPT")
  oRPT.Width = Me.Width * 0.75
  oRPT.Height = Me.Height
  oRPT.Visible = True
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
    If UnloadMode = 0 Then
        If MsgBox("Are you sure you want to quit?", vbYesNo Or vbQuestion) = vbNo Then Cancel = True
    End If
End Sub

.topic 24700
PRODUCTS TO STUDY
XFRX
IIPDFLibX

.topic 25300
 Virtual Print Engine v4.00 SDK Windows x86 32-Bit Ansi

Standard Edition
(Win 2000, Win XP, Win 2003, Vista)
€
198,00

Standard Edition Site License
(Win 2000, Win XP, Win 2003, Vista)
€
1.398,00

Enhanced Edition
(Win 2000, Win XP, Win 2003, Vista)
€
498,00

Enhanced Edition Site License
(Win 2000, Win XP, Win 2003, Vista)
€
2.998,00

Professional Edition
(Win 2000, Win XP, Win 2003, Vista)
€
998,00

Professional Edition Site License
(Win 2000, Win XP, Win 2003, Vista)
€
4.998,00

The Conception - What Is VPE?
VPE (Virtual Print Engine) for Windows is a tool for software developers. VPE allows the dynamic creation of documents for screen- and printer output by calling functions during the runtime of your application.
The free positioning of graphical objects (i.e. text, images, lines, etc.) by code offers unlimited layout options. Using VPE you can create both: reports and lists as well as complex documents and forms.
VPE is capable of computing the width and height of images as well as of  text objects depending on their textual content and font settings, including word- and page-breaks. This allows to adapt the layout dynamically to the content of your data.

VPE is just more: generate perfect PDF files!
Using an add-on module, VPE becomes a simple-to-program and powerful tool to create easily PDF files.
The Enterprise Edition of the PDF Module supports all important features of PDF, including Encryption, Linearized PDF ("Fast Web View") and True-Type Fontsubsetting.
Example files, which were created using VPE

How Does It Work?
A VPE document consists of any number of pages. All graphical objects are placed on the current page by calling methods. At any time you may select the current page freely, or you can add blank pages to the document. The positioning of the graphical objects is performed in a device independent coordinate system with 0.1mm resolution.
I want to know more details

For What Tasks Should One Use VPE?

In all cases of printing and data presentation, such as:

Dynamic generation of complex documents, forms and reports

Drawing plans, graphs, diagrams, etc.

Printing forms and labels exactly and printer independent

High performance printing with thousands of pages

Importing images of all common types

Printing barcodes (supports 38 types)

Import and presentation of RTF (Rich Text Format)

Creation of Charts

Interactive reports (clickable objects)

Export of pages to all common image file formats

e-Mail and Internet / Intranet publishing of VPE document files

Can I Try It?
Yes, you can! The VPE trial-versions are available for download.

The VPE Trial-Versions Offer:

The complete and fully programmable VPE-SDK
(Software Development Kit)

No restrictions (only demo banners)

The complete manuals as helpfiles, additionally in PDF format

Detailed demo source codes for all common programming tools / languages

.NET Winforms, ASP.NET Components, ActiveX, VCL and DLL
in one package

Home
Conception
Examples
Editions
References
Download
Ordering
Update Info
Support
Forum
e-Mail

Overview: The Different Editions

"Thank you for such a great product as it has met every item of our "Wish List" for such a utility.
Keep up the good work."
Dan Climent, President, SoftPoint Systems Inc., Fremont, California, USA

Virtual Print Engine Is Available In Three Editions

Standard

Enhanced

Professional

The editions differ in price and functionality. Each edition is fully downwards compatible, i.e. all features and functions of the Standard Edition are also included in the Enhanced Edition, and so forth.
All editions are available as fully programmable Trial Versions for download on this site.

Introduction

VPE is a fast and reliable engine made for professional applications

Over 14 years running in the development process, has been re-worked multiple times

The flexible concept, which has been evolved during this long-term development process, provides you total control about what's happening at any time

Very easy to use, saves man-years of development work

Introduces Dynamic Layouts: an incredibly simple but powerful method of positioning and sizing objects (like text, bitmaps, etc.) relative to their contents and relative to each other; so the management of complex dependencies between objects is child's play

Unlimited royalty-free distribution to end-users!

The Preview (all Editions - Windows platform only)
The preview is optional, you can print or generate PDF documents without displaying it.
While the document is created by your application, you can open the Preview and let the user zoom and scroll through it.
11 Languages: VPE selects for all tooltips and dialogs automatically the right language (depending on the country setting in the control panel). Supported languages are: English, Spanish, German, French, Italian, Dutch, Danish, Swedish, Finnish, Norwegian, Portuguese. Optional you can select the language by code. Furthermore you can define all text of the GUI elements by code, so you can use any language.
The measuring for the rulers can be switched between cm or inch units.

Screenshot on Windows Vista (Whidbey Theme):
The user interface is themeable, here the Office 2000 theme on Windows 2000:

The Whidbey Theme on Windows 2000:

The Office 2003 Blue Theme on Windows XP:

Each theme can be used on any supported Windows version, except the Office 2003 Blue, Olive und Silver themes, which are especially adapted to the predefined themes of Windows XP.

e-Mail and Internet / Intranet Publishing (all Editions)
With the eMail-Button your users can send documents via Internet or by Fax. You may specify in advance by code optional receiver(s), CC's, BCC's, title, text and any attachments. As with printing, you can send e-mails without showing a Preview.
Additionally the VPE SDK contains "VPE View", the Royalty-Free Document Viewer for VPE-Documents (very useful, if documents are sent by e-mail).
For the previewing and printing in the Internet / Intranet you can bind the VPE ActiveX into the Internet Explorer web-browser.

Facts - Standard Edition

includes .NET component, ActiveX, Delphi / C++ Builder VCL and DLL all together in one single package (on non-Windows platforms currently only available as shared object, Java JNI interface being prepared).

Includes the PDF Export Module Standard Edition

Support of lines, polylines, polygons, frames, boxes, circles, ellipses, pies, text, true-color and hatching

incredible fast device-independent vector graphics

Automatic wordbreak

Can optionally break long text automatically over multiple pages

Imports the image formats:
Windows Bitmaps - BMP (2 / 16 / 256 / HiColor / True Color)
Windows Placeable Metafile Format - WMF
Windows Enhanced Metafile Format - EMF
Independently manages image files within a self-optimizing dynamic cache. Therefore multiple used images are held only once in memory. In contrast less often used images are loaded dynamically from the hard disk.

Rendering: the dimensions of images and text (using the current font settings) can be computed during runtime to create layouts accordingly.

Virtual Processing: while generating a document, you may move at any time to any page to insert new objects

Unlimited number of pages per document and unlimited number of open documents at the same time - limited only by available memory. Optional VPE is able to use with nearly no loss of performance SmartPaging to swap all pages of a document into a file. Thererfore even the creation of documents with 10,000 pages or 100,000 pages and more is no problem.

Considers the unprintable margins of the output devices. So, everything appears on any printer at exactly the same position. This is IDEAL for printing or filling in forms and labels.

The product ships with an extensive help guide in english language (over 850 print-pages), and detailed sample sources for Visual Basic, Delphi, Visual FoxPro, Progress and C / C++

VPE is able to manage the Preview window itself, or you can embedd it into the windows of your applications - this will also work for MDI applications.

Additional Load and Save buttons in the toolbar

All buttons or button-groups and even the whole toolbar, the statusbar and the rulers can be hidden.

Intelligent printer setup - manages an unlimited number of user-defined printer setups for different document-types and printers in a network: setups can be stored to file including all driver data - this allows to activate by code any printer setup option the printer offers (for example output paper bins, which aren't supported by Windows directly)

Provides hatching, gradients, rounded corners for frames, boxes and text

Cache for image files: manages images within an optimizing dynamic cache, so that frequently used images are held only once in memory. Less frequently used files are reloaded from hard disk.

Methods and properties to read and write special settings of available printers (for example number of copies, sorting of copies, duplex printing, enumerate available paper bins, etc.) [Windows only]

The input paper bin, the page dimensions and orientation (landscape or portrait) can be set for each page separately. [Windows only]

Compression for the creation of native VPE document files

Compression for the creation of PDF files

Embedding of True-Type fonts in PDF files

Facts - Enhanced Edition

Enhanced Import of Image Files
Imports in addition to BMP, WMF und EMF all common graphics formats:
OS/2 Bitmaps (2 / 16 / 256 / HiColor / True Color)
TIFF 6.0 (2 / 16 / 256 / HiColor / True Color, LZW, PackBits, Fax G3, Fax G4, Multipage, RGBA, CMYK, RGB and Grayvalue with 16 Bits/Sample, JPEG compression v7, not the old 6.0 specification)
GIF (2 / 16 / 256 Color, Multipage)
PCX (2 / 16 / 256 / True Color)
JPG (256 / True Color, RGB / CMYK, Standard and Progressive JPEG)
PNG (all possible formats)
ICO (Windows Icon)
JNG (JPEG Network Graphics)
KOA (C64 Koala Graphics)
IFF/LBM (Interchangeable File Format - Amiga/Deluxe Paint)
MNG (Multiple-Image Network Graphics)
PBM (Portable Bitmap [ASCII])
PBM (Portable Bitmap [RAW])
PCD (Kodak PhotoCD, reads always the 768 x 512 pixel image)
PGM (Portable Greymap [ASCII])
PGM (Portable Greymap [RAW])
PPM (Portable Pixelmap [ASCII])
PPM (Portable Pixelmap [RAW])
RAS (Sun Raster Image)
TGA/TARGA (Truevision Targa)
WAP/WBMP/WBM (Wireless Bitmap)
PSD (Adobe Photoshop, only 24-bit RGB or 24-bit RGB RLE, no layers / masks)
CUT (Dr. Halo)
XBM (X11 Bitmap Format)
XPM (X11 Pixmap Format)
DDS (DirectX Surface)
HDR (High Dynamic Range Image)
G3 (Raw fax format CCITT G.3)
SGI (SGI Image Format)
Multi-Page TIFF and GIF: query number of pages contained in a file and load a selected page
Starting with VPE v4.0 DXF import is no longer supported. We recommend the Davinci Image Import Library, in order to import DXF files and to export them as EMF. The EMF files can then be processed by VPE.

Rotation of bitmap-images in 90 degree steps

Generates 38 different Barcode-Types
VPE is shipped with a sophisticated barcode library, which allows to create a total of 38 different barcode types. You can specify wether the labels (i.e. the barcode text in clear) are printed or not and on what position (at the top or the bottom of the barcode).
The library supports automatic checkdigit generation for all barcode types that make use of checkdigits.
Moreover you can specify the aspect ratio between thin and thick modules.
The supported Barcodes:

EAN 13
EAN 13 + 2
EAN 13 + 5
EAN 8
EAN 8 + 2
EAN 8 + 5
EAN 2
EAN 5
UPC A
UPC A + 2
UPC A + 5
UPC E
UPC E + 2
UPC E + 5
CODE128 A
CODE128 B
CODE128 C
EAN128 A
EAN128 B
EAN128 C
CODABAR
Industrial 2 of 5
Interleaved 2 of 5
2 of 5 Matrix
CODE 11
Telepen - A
CODE 39
CODE 39 EXT
CODE 93
CODE 93 EXT
POSTNET
RM4SCC
(Royal Mail 4 State Customer Code)
MSI
ISBN
ISBN + 5
Identcode of the Deutsche Post AG
Leitcode of the Deutsche Post AG
PZN (Pharma Zentral Code)

Facts - Professional Edition

Includes the PDF Export Module Enterprise Edition

Rich Text Format (RTF)
Interprets RTF directly and imports RTF files.
VPE supports a subset of RTF.
Please click here for the detailed VPE RTF Specifications

Charts
VPE supports all basic types of charts using SmartChart technology.
Please click here for an overview

2D Barcodes
Generates all common 2D barcodes: PDF417, Data Matrix, Maxicode und Aztec

HTML Export

Enhanced Layout Options
Pages can be cleared (i.e. all objects of a page are deleted), pages can be removed and pages can be inserted between existing pages (lower editions can only add new pages at the end of a document).

UDO - User Defined Objects
Access to VPE's Device Context. This allows to print and preview any kind of drawing or object, including OLE/COM objects!!!

Clickable Objects
Objects can be made clickable by assigning them a unique Object ID. Moving with the mouse over such an object changes the cursor to a pointing hand. If you click onto such an object your application receives an event containing the Object ID. Then you could for example open a separate dialog, showing more detailed information about the clicked text or image.

Scale-To-Gray Technology
For the import of image files, especially black & white forms, with the option of overlaying: a high resolution image (with for example 300 or 600 DPI) scaled down to the screen preview (which is usually a 96 DPI device) is looking bad due to the nature of the scaling algorithm. The reason is, that pixels are left out when drawing such a high resolution image to the screen.

Example: If you draw a 300 DPI image to a 96 DPI screen, the image is scaled down by a factor of 96 / 300 = 0.32. This means, only 32% of all pixels are drawn, the rest is left out. (i.e. after each pixel that is drawn, 2 pixels are left out)

What the Scale-to-Gray Technology does:
The Scale-to-Gray Technology is especially useful for displaying forms on the screen, because a grayscale image is scaled down to the low screen resolution, while the loss of visual information (the pixels, that are left out) is transformed to gray-values of different intensity (brightness). This produces perfect readability for the human eye.
Additionally, together with the Scale-to-Gray Technology you can use two different images for the same page: one for the screen (preview) in low resolution (see VpeSetViewable), and one for printing (see VpeSetPrintable) in the original high resolution. Therefore you gain perfect readability on the screen as well as on the printouts.
Example, normal scaled image:

Image scaled with Scale-To-Gray Technology:

Image Export
Export of single pages or parts of pages as:
BMP
WMF
EMF
JPEG
PNG
TIFF
GIF
For all bitmap formats you can specify the color depth and the resolution (in DPI).
Additionally dithering is possible.

Character Placement
You can specify a constant offset from one character to another for text objects in 0.1 mm resolution.
This is very good for filling in forms that have pre-printed columns for each letter.

Object Visibility
Objects (like text, images, barcodes, etc.) can be set to printable only, i.e. they are not shown in the preview but they are printed. Vice versa objects can be set to viewable only, i.e. they are shown in the preview (for example as hint or comment) but they are not printed.
This is also very useful, if you display a bitmap form: for the preview you display a Scale-to-Gray form for better readability (set to viewable only) and for printing you use a 600 DPI hi-resolution bitmap for perfect printing (set to printable only). Both images together can be put onto the same page in the VPE document.

Print-Scale
The printout can be scaled freely with a factor between 0.01 and 6.0

Facts - PDF Export Module
The handling is trivial, you can create a complete PDF file from a VPE document with only one line of source code: VPE.WriteDoc("My Document.pdf")
The PDF Export Module Standard Edition:
Offers unrestricted 1:1 export of VPE documents to PDF. Gradients, rounded corners, barcodes, etc. are written as true PDF vector graphics.
Optional creation of PDF files compliant to Acrobat Reader version 4 or 5.
Acrobat Reader versions prior to 4 are not supported.
Optional creation of compressed PDF documents
Optional embedding of True-Type fonts
If one and the same image (i.e. a bitmap, metafile, enhanced metafile) is used multiple times within a document, for example on multiple pages, VPE will detect such multi-references and embeds the image only once into the PDF file.

Embedded images (except JPEG files) can be converted automatically to a lower resolution to save space. JPEG files are always copied with their original RAW binary data to PDF.

The PDF Export Module Enterprise Edition offers the following additional functionality:
Offers unrestricted 1:1 export of VPE documents to PDF. Rich Text, charts and 2D-barcodes are written as true PDF vector graphics.

Encryption with a variable key length between 40 and 128-bit.
Selective protection of documents and password protection
(e.g. protect a document against printing, copy & paste, modifications, etc.)
Creation of Linearized PDF ("Fast Web View")
An enhanced PDF file format especially for the Internet. It allows to view any given page on a client site as fast as possible without downloading the whole document from a server.
True-Type Font Subsetting
Font Subsetting means, that VPE assembles on-the-fly a new font from the source font, that contains only the characters which are used in the document. A subsetted font is in regular much smaller than the original font, which results in significantly smaller documents.
Font Substitution
Supports the optional usage of PostScript fonts by Font Substitution, e.g. the font 'Arial' can be used in VPE for the preview and for printing, but the PDF document will be created using the PostScript font 'Helvetica' instead.

If embedded images are converted to lower resolutions, their quality can be increased by applying automatically the Scale2Gray algorithm.
Creation of Bookmarks
Bookmarks are displayed in the left tree-view of Acrobat Reader. They serve as a "visual table of contents" and allow the quick navigation through the document.

Top

.topic 25500
XFRX and PDF Library order
Please be aware that although XFRX works with most of VFP reports, not all VFP report features are currently supported (e.g. ActiveX objects embedded in reports are not supported in XFRX for VFP 8.0 and earlier). You can download a free evaluation copy to find out if XFRX suits your needs. 100% VFP report compatibility is not guaranteed and we cannot refund for that reason.

Purchase options
You can purchase XFRX online, using the secure order process at the Share*IT web store. Please click the "Buy online" button to navigate to the purchase page.
If you prefer paying by check or wire transfer (bank transfer to our bank account), please send us an email to sales@eqeus.com and we will contact you to agree on payment details.

-- Standard options --

XFRX commercial license, PDF option (exports to PDF) + PDF Library, royalty free
   USD 129.-
Buy online
XFRX commercial license, all output options (Word, Excel, PDF, HTML, OpenOffice, TXT, RTF, XML, XFF, BMP, PNG, JPEG, GIF, TIFF), advanced report previewer + PDF Library, royalty free
   USD 339.-
Buy online

-- Source code options --

XFRX commercial license, all output options (Word, Excel, PDF, HTML, OpenOffice, TXT, RTF, XML, XFF, BMP, PNG, JPEG, GIF, TIFF), advanced report previewer + PDF library, royalty free, source code included
   USD 649.-
Buy online

Please note: All licenses are Enterprise Unlimited Developer licenses - you can purchase just one license for your company, no matter how many developers are going to use XFRX and/or PDF Library.
The license purchase entitles you to receive all new versions of XFRX and/or PDF Library for free within one year from the purchase date.

Please see license section for the license details.

.topic 25600
Current FRX2Any version: 12.04.08

SINGLE edition:
Chart Engine module, royalty free
$US 79.95

DOC module, royalty free
$US 79.95

HTML ( MHT) module, royalty free
$US 79.95

RTF module, royalty free
$US 79.95

XLS module, royalty free
$US 79.95

PDF module, royalty free
$US 79.95

XML module, royalty free
$US 79.95

Image module, royalty free
$US 79.95

Advanced Report Viewer, royalty free
$US 79.95

RTF Engine module, royalty free
$US 79.95

STANDARD edition:
All modules, royalty free
$US 349.95

All modules + Chart Engine module, royalty free
$US 399.95

All modules + RTF Engine module, royalty free
$US 399.95

All modules + Chart Engine module + RTF Engine module, royalty free
$US 449.95

SINGLE DEVELOPER edition*:
Chart Engine module, royalty free, source code included
$US199.95

DOC module, royalty free, source code included
$US199.95

HTML ( MHT) module, royalty free, source code included
$US199.95

RTF module, royalty free, source code included
$US199.95

XLS module, royalty free, source code included
$US199.95

PDF module, royalty free, source code included
$US199.95

XML module, royalty free, source code included
$US199.95

Image module, royalty free, source code included
$US199.95

Advanced Report Viewer, royalty free, source code included
$US199.95

RTF Engine module, royalty free, source code included
$US199.95

 (

DEVELOPER edition*:
All modules, royalty free, source code included

$US 799.95

contact us
All modules + Chart Engine module, royalty free, source code included

$US 899.95

contact us
All modules + RTF Engine module, royalty free, source code included

$US 899.95

contact us
All modules + Chart Engine module + RTF Engine module, royalty free, source code included

$US 999.95

contact us

*The iSEDQuickPDF.DLL source code won't be included.

Current ReportDepot version: 02.01.00

Single User License*
$US 49.95

5-User License*
$US 124.95

10-User License*
$US 174.95

20-User License*
$US 249.95

Annual subscription 20% of retail price

contact us

Source code

contact us

*The 12 months update subscription is included in the price. ReportDepot update subscription includes: Unlimited E-Mail Support and Product Updates . Purchase an annual subscription and receive 12 total months of coverage.
.topic 26100
http://www.activepdf.com

activePDF ServerTM
Automate the PDF generation process from enterprise and web applications.
1 server license: $1,399.00

activePDF ToolkitTM
Append, stamp, stitch, merge, paint, form-fill, secure PDF and more.
1 server license: $499 Standard, $899 Professional

activePDF DocConverterTM
Convert over 280 different file types directly to PDF.
1 server license: $489.00

activePDF PrinterTM
Print to PDF from applications without native printing capabilities.
1 server license: $210.00

activePDF WebGrabberTM
Dynamically convert any URL, HTML stream, or HTML file to PDF while retaining styles.
1 server license: $375.00

activePDF PortfolioTM
Everything you need to develop a complete server-side PDF solution.
1 server license: $2,399.00

Quantity Discounts Available - activePDF Store
Buy 2 Licenses save 10%
Buy 3 Licenses save 15%
Buy 4 Licenses save 20%
Buy 5 or more licenses save 25%

.topic 26000
DOWNLOADS AS OF:
UT - 6957 - 06/05/2008
DOWNLOAD.COM - 2585 - 06/05/2008

.topic 25700
Enter topic text here.
.topic 25900
EMF+ Record Type: Object
Overview
The Object metafile record contains information on an object which must be stored for use by a future metafile record. Examples include pens, brushes, fonts, images, StringFormat objects, and so on. Naturally, the data format of each type of object differs, and so the Flags value is used to determine which type of object is being stored.
Object metafile records contain a numeric index (0 to 255). The first Object record to appear in the file will have an index of 0, the next record 1, and so on. Applications which process metafiles should store these objects in an index-based collection so that a later record can access them. For example, a future DrawRects record might reference the Pen with index 2, and the application should ensure that that object is still accessible. Since the index is only one byte, only 256 objects can be stored at any time. Thus, a simple stack will not suffice and applications will have to be prepared for new Object records overwriting old ones with the same index.

Flag Values
The least significant byte of the Flags value holds the index of the object contained in the record (see above), in the range 0 to 255.
The index value is OR'd with additional flags that specify which type of object is contained in the record. The values are as follows:
Value
Object Type

0x100
Brush

0x200
Pen

0x300
Path

0x400
Region

0x500
Image

0x600
Font

0x700
StringFormat

0x800
ImageAttributes

Data Format
The data format of the Object record differs depending on what type of information is being stored. Because the different formats for the Object record are so complex, they are broken down into separate pages:
Brush
Brush
Position

Contents
Bytes 0 to 3

The first four bytes of the data block contain a generic Object header, with the value 01 10 C0 DB. This block appears in every Object record, and never appears to differ. Any significance it has remains unknown.
Bytes 4 to 7

The next four bytes contain a 32-bit value specifying the type of Brush being stored. This value is one of the members of the BrushType enumeration:
0 - Solid Brush
1 - Hatch-filled Brush
2 - Texture-filled Brush
3 - Path Gradient Brush
4 - Linear Gradient Brush

.topic 25800
EMF+ Record Type: DrawString
Overview
The DrawString metafile record represents a call to Graphics.DrawString, which draws a string using a specified font and format.

Flag Values
The least significant byte of the Flags value holds the index of the font to be used. See the Object record for more information on object indices.
The rest of the Flags value specifies additional flags that apply to the DrawString operation:
Value
Meaning

0x8000
The first four bytes of the data block contain the the ARGB components of a solid color. If this flag is absent, the first four bytes contain the index of the Brush object to be used.

Data Format
The data format of the DrawString record is relatively straightforward, and simply encapsulates the parameters to the call to Graphics.DrawString.
Position

Contents
Bytes 0 to 3

The first four bytes of the data block contain the color or brush to be used. If the Flags value contains 0x8000, this will be the ARGB components of a solid color. Otherwise, it will be an index to the Brush to be used. Note that EMF+ records are always stored in little-endian format, so the color components will actually appear in the order BGRA.
Bytes 4 to 7

The second four bytes contain a 32-bit integer specifying the index of the StringFormat object to be used to format the output. If no StringFormat object was specified, this will contain a value of -1 (0xFFFFFFFF).
Bytes 8 to 11

The second four bytes contain a 32-bit integer specifying the number of character in the string to be drawn.
Bytes 12 to 27

Next is a series of four Single values specifying the bounding box in which to draw the string, appearing in the order X, Y, Width, Height. If a point was used instead of a box (indicating unlimited size), the Width and Height parameters will be 0.
Bytes 28 to end

The remainder of the data block contains the string to be displayed. The string is stored in Unicode format, so there are two bytes per character. The string is not null-terminated, since the number of characters was stored previously.

.topic 23700
Anyway, the error of “Permission Denied: on CREATEOBJECT()” is occurring due to the permissions for the registered application.

In order to configure the Contactmanager.CMTOOLS COM server to run under IIS as an EXE, you need to run DCOMCNFG and then go to COMPONENT SERVICES and then expand the DCOM Config Folder and locate the contactmanager.CMTools entry. Select the contactmanager.CMTools entry and then RIGHT CLICK over the entry and select PROPERTIES. Then you will need to select the SECURITY tab and then click on the CUSTOMIZE radio button and then click on EDIT…. You will then need to ADD the INTERNET GUEST ACCOUNT as a user and set the permissions to LOCAL LAUNCH and LOCAL ACTIVATION. The IDENTITY tab should have the LAUNCHING USER as the selection. Although, I also did a selected account and used my own account as well.

Another thing that will be helpful in debugging any issues is to set the IIS Virtual Directory APPLICATION PROTECTION settings to HIGH (ISOLATED) so that when you restart IIS using IISRESET if there is a problem and you need to recompile the EXE. Setting it to HIGH (ISOLATED) allows the process to be released when restarting IIS. Otherwise, you have to reboot the system (PITA).

I attached some screen shots for you as well. I’m going to add this to the Help File too.

[PICTURE IIS Virtual Directory Properties Application Protection Settings.JPG]

[PICTURE IIS Component Services - Launch Permission Add User.JPG]

[PICTURE IIS Component Services - Security Launch and Activation Permission Settings.JPG]

.topic 15900
Pre August 1999:

The 'Apply' button does not automatically highlight in a Property Page - why?

    Normally this will occur automatically, but if you do something like change a property via another form, you will need to call the "Modified" method to enable the Apply button.

How do I get the Object Inspector to automatically update when I click Ok in a Property Page? Or, how do I get Delphi to recognise that the object has been changed via a Property Page, and therefore enable the "Save All" button?

    You need to make the ActiveX dirty. Since the FIsDirty property is private and there is no way of changing it, you must re-implement IPersistStreamInit on your object, and then provide a method to set or clear it . Then whenever your properties change, make sure you set it to True. When you click on Ok in a Property Page, Delphi calls IsDirty - if the result is not S_FALSE, then the Object Inspector is updated and the "Save All" button is enabled. For example, the following code defines a Dirty method which can be called by subclasses and implements the IsDirty method for an ActiveXControl:

        procedure TNActiveXControl.Dirty(Value: Boolean);
        begin
          FIsDirty := Value;
        end;

        function TNActiveXControl.IsDirty: HResult;
        begin
          if FIsDirty then
            Result := S_OK
          else
            Result := S_FALSE;
        end;

    Then in your control whenever a property is set you include code similar to:

        procedure TMyControl.Set_AProperty(
          const Value: WideString);
        begin
          FAProperty := Value;
          Dirty(True);
        end;

The properties on the ActiveX Control are not being written to the form file - why? Or, the Delphi equivalents of the ActiveX properties have 'Stored False'. Or, the property values are 'forgotten' in VB after I run the application - why?

    The Delphi equivalents have 'Stored False' because it is assumed the ActiveX Control will write the properties to the form file, so the Delphi wrapper should not duplicate the effort. You need to override SaveToStream and LoadFromStream in the ActiveX and write the properties yourself. They will then become part of the ControlData binary property, which can be seen in the form file. For example, to write the integer X:

        inherited SaveToStream(Stream);
        Stream.Write(@X, SizeOf(Integer), nil);

    Overriding these methods also fixes the problem in VB.

The properties on my Active Form are not being written to the form file - why? Or, the property values are 'forgotten' in VB after I run the application - why?

    This is related to the same problem with ActiveX Controls, but is harder to fix. Active Forms delegate all COM stuff to a contained TActiveFormControl, which inherits from TActiveXControl. Therefore it does not write your properties to the form file. To fix this, create a new unit containing TNActiveForm which inherits from TActiveForm and implements IPersistStreamInit. Copy the LoadFromStream and SaveToStream methods from TActiveXControl (including their empty implementations). Copy the code to implement the IPersistStreamInit methods from TActiveXControl, but make the following changes:

    After the implementation line insert

    Type
      TCrack = class(TActiveXControl);

    Then implement each of the methods required by IPersistStreamInit. For example:

        Result := TCrack(ActiveFormControl).InitNew;

    As the last line in PersistStreamLoad and PersistStreamSave, include respectively

        LoadFromStream(stm);
        SaveToStream(stm);

    Now in your Active Form, change it to inherit from TNActiveForm and override LoadFromStream and SaveToStream. Include code to read/write your properties to the form file. For example, to write the integer X:

        inherited SaveToStream(Stream);
        Stream.Write(@X, SizeOf(Integer), nil);

    This will also fix problems in VB where the property values get forgotten after you run the application.

If I rename a method from an Interface and my object also implements another interface that inherits from that Interface, I get a compilation error.

    I have reported this as a bug in Delphi. For example, if an object implements IPersist and IPersistFile (which inherits from IPersist), if you rename GetClassId to Persist_GetClassId, when you compile you will get an error saying "GetClassId" has not been defined. This will also happen if IPersist is implemented in a base class, from which you inherit and also add IPersistFile.

    All:  When I use my ActiveX in VB and save the form I get an "Unexpected Error".

    This will happen if your ActiveX has any properties that are interfaces - VB cannot save them.

    NA:  How can one ActiveX be connected to another in Delphi?

    Delphi forms do not behave like an ActiveX IOleContainer, but you have two options to get around the problem. The harder option is to inherit from TOleControl and reimplement IOleControlSite. Then in the GetContainer method you could create a COM object to act as the container that would know about the form so it could EnumObjects. I have not tried this method.

    A simpler method is to first define the following interface:

        type
          INAmbientProperties = interface(IUnknown)
            ['{A5E59BD3-9AE3-11D3-AAEC-0001FA682208}']
          procedure SetDelphiHost(DelphiHost: TWinControl); safecall;
          function Get_DelphiHost: TWinControl; safecall;
          function UserMode: WordBool; safecall;
          function ContainerType: NAFM_ContainerTypes; safecall;
          property DelphiHost: TWinControl read Get_DelphiHost;
        end;

    The you can inherit from the control in the _TLB file of your ActiveXControl and override CreateWnd with the following code:

        var
          Link: INAmbientProperties;
        begin
          inherited;
          if ControlInterface.QueryInterface(INAmbientProperties,
            Link) = S_OK then
            Link.SetDelphiHost(self);
        end;

    Of course your ActiveXControl already inherits from TNActiveXControl (rather than TActiveXControl), which you have implement INAmbientProperties methods as:

        procedure TNActiveXControl.SetDelphiHost(
          DelphiHost: TWinControl);
        begin
          FDelphiHost := DelphiHost;
        end;

        function TAnActiveXControl.Get_DelphiHost: TWinControl;
        begin
          Result := FDelphiHost;
        end;

    Code (called GetSiblings) to build a TStrings of all the controls on the form which implement a given interface is then:

        function AncestorIs(C: TClass; S: String): Boolean;
        begin
          if C.ClassName = S then
            Result := True
          else if C.ClassParent <> nil then
            Result := AncestorIs(C.ClassParent, S)
          else
            Result := False;
        end;

        function ParentForm(C: TControl): TCustomForm;
        begin
          while (C <> nil) and
            not AncestorIs(C.ClassType, 'TCustomForm') do
              C := C.Parent;
          if C = nil then
            Result := nil
          else
            Result := TCustomForm(C);
        end;

        procedure GetSiblingsDelphi(Control: TWinControl; Siblings: TStrings;
          Implementing: TGUID);
        var
          i: Integer;
          X: IUnknown;
        begin
          if Control = nil then exit;
          for i := 0 to Control.ControlCount - 1 do
            begin
              if AncestorIs(Control.Controls[i].ClassType, 'TOleControl') then
                if IsEqualGUID(Implementing, GUID_NULL) or
                  (IUnknown(TOleControl(Control.Controls[i]).OleObject).QueryInterface(
                  Implementing, X) = S_OK) then
                  Siblings.Add(Control.Controls[i].Name);
              if AncestorIs(Control.Controls[i].ClassType, 'TWinControl') then
                GetSiblingsDelphi(TWinControl(Control.Controls[i]), Siblings,
                  Implementing);
            end;
        end;

        procedure GetSiblings(Unk: IUnknown; Siblings: TStrings; Implementing: TGUID);
        var
          Link: INAmbientProperties;
        begin
          Siblings.Clear;
        if (Unk.QueryInterface(INAmbientProperties, Link) = S_OK) and
          (Link.DelphiHost <> nil) then
          GetSiblingsDelphi(ParentForm(Link.DelphiHost), Siblings, Implementing)
        else
          GetSiblingsVB(Unk, Siblings, Implementing);
        end;

    This code will also work with ActiveX containers, by calling GetSiblingsVB, which is defined in the FAQ item below.

    NA:  How can one ActiveX be connected to another in VB?

    The following code shows how to build a TStrings of names of ActiveX controls within the same container that implement a given interface. Note that this is not 100% because those ActiveX controls could be containers themselves.

        function NameOf(Unk: IUnknown): String;
        var
          IOO: IOleObject;
          IOCS: IOleClientSite;
          IAD: IAmbientDispatch;
        begin
          Result := '';
          if Unk = nil then exit;
          if (Unk.QueryInterface(IOleObject, IOO) <>
            S_OK) or (IOO = nil) then exit;
          if (IOO.GetClientSite(IOCS) <> S_OK) or
            (IOCS = nil) then exit;
          if (IOCS.QueryInterface(IAmbientDispatch, IAD) <>
            S_OK) or (IAD = nil) then exit;
          Result := IAD.DisplayName;
        end;

        procedure GetSiblingsVB(Unk: IUnknown; Siblings: TStrings; Implementing: TGUID);
        var
          IOO: IOleObject;
          IOCS: IOleClientSite;
          IOC: IOleContainer;
          IEU: IEnumUnknown;
          elt: IUnknown;
          Check: Boolean;
          X: IUnknown;
          Name: String;
        begin
          Check := IsEqualGUID(Implementing, GUID_NULL);
          if (Unk.QueryInterface(IOleObject, IOO) <> S_OK) or (IOO = nil) then exit;
          if (IOO.GetClientSite(IOCS) <> S_OK) or (IOCS = nil) then exit;
          if (IOCS.GetContainer(IOC) <> S_OK) or (IOC = nil) then exit;
          if (IOC.EnumObjects($FFFF, IEU) <> S_OK) or (IEU = nil) then exit;
          while IEU.Next(1, elt, nil) = S_OK do
            if elt.QueryInterface(IOleObject, IOO) = S_OK then
              if Check or (elt.QueryInterface(Implementing, X) = S_OK) then
                begin
                  Name := NameOf(elt);
                  if Name = '' then Name := '(No name)';
                  Siblings.Add(Name);
                end;
        end;

How do I connect ActiveX controls at design-time?

    There are two things to consider when connecting controls at design-time: how to save the connection so it is re-established when you reopen the project; and why doesn't it work. You should save the connection by writing the name of the connected control to the stream in SaveToStream. Then in LoadFromStream you can read this control name and find it. The reason it doesn't work is because when the connection name is set that control probably doesn't exist yet. You can overcome this by retrying the connection in the WM_PAINT message for your control as in the code below:

        procedure TCOMEdit.WMPaint(var Message: TWMPaint);
        begin
          inherited;
          if (FCOMReference = nil) and
            (Length(FCOMReferenceName) > 0) then
            Set_COMReferenceName(FCOMReferenceName);
        end;

    I am assuming that your Set_COMReferenceName will try to re-establish the connection.

How can I perform code after all controls have been loaded (like TComponent.Loaded) in VB?

    When you run a project, the last thing VB does is tell all controls to IOleControl.FreezeEvents(False) - note that this call may be called under other circumstances, but I haven't found any. Therefore, you can reimplement IOleControl in your ActiveXControl or ActiveForm and do whatever code is required. In the following example I have assumed to have created a TNActiveXControl that all of your ActiveX controls inherit from. You can then define ActiveXLoaded to be virtual, so subclasses can override it.

        function TNActiveXControl.FreezeEvents(
          bFreeze: BOOL): HResult;
        begin
          Result := inherited FreezeEvents(bFreeze);
          if (not bFreeze) then
          ActiveXLoaded;
        end;

        procedure TNActiveXControl.ActiveXLoaded;
        begin
        end;

    NA:  How can one ActiveX be connected to another in IE?

    The code that works for VB will also work for IE, however there are two traps.

    Firstly: By default the ActiveX controls will not get a name. You should ensure that the HTML includes "id=SomeName" (under FrontPage the name can be set by double-clicking the ActiveX).

    Secondly: FrontPage does not behave like a full IOleContainer. Therefore under the Normal tab, ActiveX controls will not be able to see each other. However, under the Preview tab, all works properly.

How can my ActiveX determine when its form is shown and hidden?

    You can do this by hooking into the WndProc of the form that contains the ActiveX control. The form will be sent a WM_ACTIVATE message when it is being shown and hidden. You locate the form by first finding the IOleInPlaceSite's window, and then moving up the chain of windows until you find one that doesn't have a style of WS_CHILD. To be able to do all this, the ActiveX control must have a ClientSite and the ClientSite must have a window. I have chosen to put the code in IOleObject.DoVerb:

        function TNActiveXControl.DoVerb(...
        var
          InPlace: IOleInPlaceSite;
          Wnd: HWnd;
        begin
          Result := inherited;
          if FOwnerWnd <> 0 then exit;
          ClientSite.QueryInterface(IOleInPlaceSite,
            InPlace);
          InPlace.GetWindow(Wnd);
          FOwnerWnd := OwnerWnd(Wnd);
          FObjectInstance := MakeObjectInstance(NewWndProc);
          FDefWindowProc := Pointer(GetWindowLong(FOwnerWnd,
            GWL_WNDPROC));
          SetWindowLong(FOwnerWnd, GWL_WNDPROC,
          Longint(FObjectInstance));
        end;

    Where FObjectInstance and FDefWindowProc are private pointers within TNActiveXControl. The helper function OwnerWnd is implemented as:

        function OwnerWnd(Wnd: HWnd): HWnd;
        begin
          if Wnd = 0 then
            Result := 0
          else if (GetWindowLong(Wnd, GWL_STYLE) and
            WS_CHILD) <> 0 then
            Result := OwnerWnd(GetWindowLong(Wnd,
            GWL_HWNDPARENT))
          else
            Result := Wnd;
        end;

    NewWndProc is defined as:

        procedure TNActiveXControl.NewWndProc(
          var Message: TMessage);
        begin
          with Message do
          begin
            if Msg = WM_ACTIVATE then
              DoActivate(LoWord(wParam) <> 0);
            Result := CallWindowProc(FDefWindowProc,
            FOwnerWnd, Msg, wParam, lParam);
          end;
        end;

    DoActivate is a new protected method within TNActiveXControl which contains no code. ActiveX controls interested in knowing when they are shown or hidden can override DoActivate. The parameter passed is True for showing, or False for hiding.

    NA:  How do I create an ActiveX control that is visible at design-time but invisible at run-time.

    If you are only going to use the control in Delphi and/or Internet Explorer, then in the initialization of the control where it calls TActiveXControlFactory.Create, change the second last parameter from "0" to "OLEMISC_INVISIBLEATRUNTIME". Unfortunately, VB ignores this information and displays the control anyway.

    To create one for use in VB, firstly create a TNonVisual, and register it so it turns up on the Component Palette somewhere:

        TNNonVisual = class(TCustomControl)
        protected
          FRunTime: Boolean;
          FIcon: TBitmap;
        public
          constructor Create(AOwner: TComponent); override;
          destructor Destroy; override;
          procedure Paint; override;
          procedure DesignPaint; virtual;
          function GetIconName: String; virtual;
          property RunTime: Boolean read FRunTime write FRunTime;
        end;

        constructor TNNonVisual.Create(AOwner: TComponent);
        begin
          inherited Create(AOwner);
          if AOwner is TWinControl then
            Parent := (AOwner as TWinControl);
          Width := 24;
          Height := 24;
        end;

        procedure TNNonVisual.Paint;
        begin
          inherited Paint;
          if not FRunTime then DesignPaint;
        end;

        procedure TNNonVisual.DesignPaint;
        begin
          if FIcon = nil then
            begin
              FIcon := TBitmap.Create;
              with FIcon do
                begin
                  Handle := LoadBitmap(HInstance, PChar(GetIconName));
                  Transparent := True;
                end;
            end;
          Canvas.Draw(0, 0, FIcon);
        end;

        destructor TNNonVisual.Destroy;
        begin
          if FIcon <> nil then FIcon.Free;
          inherited Destroy;
        end;

    Now create:

        TNNonVisualActiveX = class(TNActiveXControl)
        protected
          procedure Initialize; override;
          procedure ModeChanged; override;
        end;

        procedure TNNonVisualActiveX.Initialize;
        begin
          inherited Initialize;
          ModeChanged;
        end;

        procedure TNNonVisualActiveX.ModeChanged;
        var
          AD: IAmbientDispatch;
        begin
          inherited ModeChanged;
          if (Control <> nil) and (Control is TNNonVisual) then
            begin
              TNNonVisual(Control).RunTime := UserMode;
              TNNonVisual(Control).Repaint;
            end;
        end;

    To create a non-visual ActiveX, base it on TNNonVisual..  Then change it to inherit from TNNonVisualActiveX rather than TActiveXControl.  Also add "or OLEMISC_INVISIBLEATRUNTIME" at the bottom of the unit.

    This will always display the icon called TNNonVisual.  You can subclass it and override GetIconName to display something other than an icon matching the ClassName.

How should I persist my COM objects?

    Of course this is the question for which everybody has his or her own differing opinion. What is my opinion? Microsoft offers IPersistStream/IPersistStorage (et al) for persistence to files, nothing much for the registry, and ADO/OLE-DB (et al) for databases. I want one mechanism for persistence to different locations (eg. File, Registry, Database). The closest I have found is IPropertySetStorage/IPropertyStorage, which have the added advantage of persisting all of the properties in one round-trip. I have successfully developed versions that work with compound files and the registry, and the challenge is now to get it to work with OLE-DB. An object's container defines the storage interface (ie. Whether it is a file, the registry, or a database) and the contained object saves itself there. Using Monikers, the following strings can all create and load the same object from different sources:

        C:\test\aFile.ss!TheObject
        MK.Registry:HKLM/Software!TheObject
        MK.Database:PROD!TheObject

    Of course IPersistStreamInit is also required for ActiveX controls.

How can multiple programs share a COM object? Or, how do I create a Singleton?

    Instead of creating a new object, each program should call a function (say, GetCustomerObject) which is implemented in the following way:

        function GetCustomerObject: ICustomer;
        var
          Unk: IUnknown;
        begin
          GetActiveObject(Class_Customer, nil, Unk);
          if Unk = nil then
            Result := CoCustomer.Create
          else
            Unk.QueryInterface(ICustomer, Result);
        end;

    The Customer object should then override Initialize and Destroy, including the code below:

        procedure Initialize;
        begin
          inherited;
          RegisterActiveObject(self, Class_Customer, 0,
            dwRegister);
        end;

        destructor Destroy;
        begin
          RevokeActiveObject(dwRegister, nil);
          Inherited;
        end;

How can multiple units in a COM application share a COM object?

    Create a new unit that has a function to get the object. For example:

        var
          FTheObject: Pointer;
        function GetObject: ITheObject;
        begin
          if FTheObject = nil then
           FTheObject := Pointer(CoTheObject.Create
              as IUnknown);
          Result := IUnknown(ITheObject)
            as ITheObject;
        end;

    This assumes that any unit wanting to use TheObject will keep a local reference to it, which is set to zero when it is no longer required. Since the above code keeps a weak reference to TheObject, when no clients reference the object it will be released.

    Note that this will not work properly in some instances - for example, when a component dropped onto a form calls GetObject. This is because you can destroy and recreate all of the components (by pressing Alt-F12 twice). This will release and destroy FTheObject, but the FTheObject pointer will not be reset to nil.

In IE, how do I activate the first control on my ActiveForm when the Tab key is pressed?

    Firstly your ActiveForm should have the ActiveControl property set to the first control on the form. Secondly, at the bottom of the implementation unit you will find:

        OLEMISC_SIMPLEFRAME or OLEMISC_ACTSLIKELABEL,

    Change it to:

        OLEMISC_SIMPLEFRAME,

How should I handle the Tab key in IE when it is pressed on the last field of my ActiveForm?

    First you have to reimplement IOleInPlaceActiveObject so you can override the default implementation of TranslateAccelerator. It should check to see if the ActiveControl is the last control on the screen (or the first control if GetKeyState(VK_SHIFT) is negative). If it is, it should call the Container's TranslateAccelerator as in the code below:

        IOO := ComObject as IOleObject;
        if (IOO.GetClientSite(IOCS) <> S_OK) or
          (IOCS = nil) then exit;
        if (IOCS.QueryInterface(IOleControlSite,
          IOCtlS) <> S_OK) or
          (IOCtlS = nil) then exit;
        Result := IOCtlS.TranslateAccelerator(@msg, 0);

    Second you have to override the Activate method to select the appropriate control - otherwise when you tab back into your form, the last control will be focussed (since, ActiveControl is still the last control). The code for this is:

        ActiveControl := FindNextControl(nil,
          (GetKeyState(VK_SHIFT) >= 0), True, False);
        if ActiveControl <> nil then
        ActiveControl.SetFocus;
        inherited;

    Note:    In November 1999 I worked out a better method of tabbing to the next control for creating my own Property Frame.  I have not yet tried that code in this situation, but I expect it is a better solution.

How can multiple units in the one program share a COM object? Or, my ActiveX hangs IE when run by itself, but not when run from within Delphi - why?

    I assume here you don't want the COM object to be shared by other programs, or else you would be using a Singleton. Basically, all of the units requiring access to the COM object should 'use' a new unit which contains the following code:

        unit UnitCreateCommonObj;

        interface

        uses CommonObj_TLB;

        function CommonObj: ICommonObj;

        implementation

        var
          FCommonObj: ICommonObj;

        function CommonObj: ICommonObj;
        begin
          if FCommonObj = nil then
            CommonObj := CoCommonObj.Create;
          Result := FCommonObj;
        end;

        initialization

        finalization
          FCommonObj := nil;

        end.

    The object gets created the first time it is referenced, and when the application shuts down, the finalization will be called, thereby destroying the object. Each of the units 'use' this unit so they get access to the CommonObj variable.

    With regards to the problem of IE hanging, I originally wrote this code such that the object was created in the initialization. It seems that this is a bad thing to do. Once it was removed, IE stopped hanging.

How do I find which browser is being used?

    In the registry under section HKCR/http/shell/open/command.

How do I stop my ActiveXControl/ActiveForm overlaying the IE scrollbar?

    You need to override Delphi's implementation of IOleInPlaceObject and include the following code:

        function TNActiveXControl.SetObjectRects(
          const rcPosRect: TRect;
          const rcClipRect: TRect): HResult;
        var
          Rect1, Rect2: TRect;
        begin
          try
            IntersectRect(Rect1, rcPosRect, rcClipRect);
            Rect2 := Bounds(rcPosRect.Left,
              rcPosRect.Top,
              Rect1.Right - Rect1.Left +
              rcClipRect.Left - rcPosRect.Left,
              Rect1.Bottom - Rect1.Top +
              rcClipRect.Top - rcPosRect.Top);
            Control.BoundsRect := Rect2;
            Result := S_OK;
          except
            Result := HandleException;
          end;
        end;

    If the control is an ActiveForm, replace Control.BoundsRect in the above code with ActiveFormControl.Control.BoundsRect.

How do I convert a Delphi 3 type library to Delphi 4 or 5?

    Click on the top node of the tree view, and then click on the "Uses" tab. If you see unchecked items in the list, right-click and select "Show Selected". You should see "Borland Standard VCL type library". Try to uncheck it - you should get an error, which also asks if you want to upgrade to the new version, to which you should agree. Now save the type library and you are finished.  Delphi 5 uses the same library as Delphi 4 (c:\winnt\system32\stdvcl40.dll).

MyType Library is stuffed - how do I fix it?

    I have had this happen a few times. It seems that after a while the type library gets screwed all by itself, and weird things start happening.

    The easiest way I have found to fix the problem is to recreate a new type library to replace the existing. Bring up the existing type library, select the top node in the tree view, click on the "text" tab and copy all of the lines after the "uses" line to the clipboard. Now "close all" and create a new type library (File/New… under ActiveX tab). If the existing type library used extra libraries, add them in now. Replace all but the first line in the "text" tab with that on the clipboard. Change the "Name" and "HelpString" of the top tree view node to match that of your existing type library.

    Delphi cannot cope with you typing in a new method that uses a type/interface that you have also just typed in, but appears further down in the text. Therefore you will have to move all of the Enumerations (eg. TxAlignment) to the top of the text. Similarly you must move all of your own interfaces which are defined after they are used. You can try saving over the existing type library now, but you may find you also need to remove all of the "Font" properties. Reopen and then build your project. All should be fixed.

My COM project will not register properly - why?

    Look for the following problems:

        * A bug in an initialization section (since this code is executed during Registration).
        * Creation of a COM object within the initialization section - particularly one which is being registered now. Its probably not a good idea to do any COM calls during initialization.
        * Inclusion of another COM project's implementation unit in a uses clause. If object A from project A uses object B from project B you might be tempted to include a global function in B's unit called GetObjectB, and then call this in A's unit. However, A's unit will now need B's unit in its "uses" clause. Therefore, B's initialization will try to run while registering A. This is bad.

Strange things are happening at application start/finish (eg. 216, 217 errors) - why?

    Typically this will happen if there is something wrong with a COM object. The most common reason is circular or hanging COM references. The frustrating part is that it is very difficult to debug, and may in fact work when running from Delphi.

    You should put Initialize and Destroy procedures on all of your COM objects. The implementation of these should just call the inherited method, and then put a breakpoint on each one. Now run it within Delphi and write down every COM object that is created, and cross it out once it is destroyed. At the end the list must be completely crossed out, or you are leaving COM objects lying about. If one object is left, you probably forgot to release a reference to it from another object. If two objects are left, they probably have a circular reference to each other.

    You can also get an indication that something is amiss by checking ComServer.ObjectCount in the finalization section of at least one of the units in the project. If it is non-zero, then something has an outstanding reference to at least one of the objects in the project.

    Problems can also occur when you try to do COM things during finalization since OleUninitialize will have been called. This can have the following implications:

        * Delphi loses track of the execution of your program (ie. it has finished, but Delphi still thinks it is running).
        * COM calls, such as GetRunningObjectTable, return MK_E_UNAVAILABLE.

    Note that TApplication frees all forms and DataModules during finalization, so their Destroy code should not include any COM calls.

How do I allow VB to do "for each" on my COM objects?

    At a minimum you need to implement a "_NewEnum" method (the name is unimportant, but the DispId must be -4). This should create a new COM object that implements IEnumVariant. You will need to implement the relevant methods for this interface, ie. Next, Skip, Reset, and Clone. See MSDN for further information.

How do I configure DBDemos for ADO use?

    Start the ODBC applet under Control Panel. Under the "System DSN" page, click Add, and add a DBase driver. Enter "DBDemos" as the "Data Source Name" and uncheck "Use Current Directory". Click on "Select Directory" and navigate to "C:\Program Files\Common Files\Borland Shared\Data". Click OK a few times and you're finished.

Some of my COM objects are not getting released. How can I identify when this occurs?

    Create a unit which uses ComServ and has a finalization section. Put code in this section to do something if ComServ.ObjectCount is not zero. If you now put this unit into the 'uses' clause of any of the units in a COM project, it will check that all COM objects have been released properly when the program/DLL shuts down. For example, consider you have an application, APP, which creates a COM object, MyObject, from Server.DLL. When SERVER.DLL shuts down APP may have an outstanding reference to MyObject (for whatever reason) - the code described can tell you that one object in Server.DLL is still referenced, but it cannot tell you that APP has the reference (although its pretty obvious in this example).

ComServer.ObjectCount is not zero in the finalisation section of a COM unit.

    Firstly, make sure that all of your Destroy methods call the inherited Destroy method.

    Secondly, if any of the COM objects have been dropped into Delphi, ensure that you are using methods/properties that return an interface as MyObject.ControlInterface.Property rather than MyObject.Property. Delphi automatically creates code for you to do the latter, but for some reason if you use it, the returned object gets AddRef'd too often, and therefore never gets released. To avoid the possibility of accidentally coding MyObject.Property, I flag all methods/properties that return an interface as Restricted, for which Delphi does not insert the shortcut version. You don't want to use the shortcut version anyway, because it calls the method/property using late-binding rather than early-binding.

    If you displayed a PropertyPage that is part of the project, then you are experiencing a bug in Delphi. In AxCtrls.pas under TActiveXPropertyPage.Destroy, the inherited Destroy is not called. Therefore it does not get the chance to decrement the ObjectCount. This is not a problem unless you are using the ObjectCount to identify COM objects which have not been destroyed.

    To fix this problem without changing Delphi's code, copy all of TActiveXPropertyPage and TActiveXPropertyPageFactory from ComObj into another unit, rename them to TNActiveX*, and put in the inherited Destroy. Now in each of your PropertyPage implementations, change TActiveXPropertyPageFactory to TNActiveXPropertyPageFactory in the initialization section.

SysErrorMessage is giving me a "Range Check Error" - why?

    The parameter passed to SysErrorMessage is incorrectly defined as an Integer. Some error codes (eg. C0000005) will therefore cause a "Range Check Error" exception (assuming you have Range Checking on). You should reimplement SysErrorMessage, copying the code but making the parameter an HResult instead of an Integer. No other changes are required.

Why doesn't the DLL release when I release the COM object?

    The DLL does not release until CoUninitialize is called. Since this is in the finalization section of ComObj.pas, which your main app uses, it will not be called until the app closes. You can overcome this by calling CoUninitialize yourself, but you had better not do any COM work afterwards.

How can I use Property Pages on COM Objects that are not ActiveX Controls?

    Firstly, create a new unit that implements TNAutoObjectWithProperties. Inherit from TAutoObject and implement ISpecifyPropertyPages. Copy the GetPages and DefinePropertyPages from AxCtrls (TPropPages is also required).

    Start a new application and add a Property Page to it. Save this property page, but discard the project. Change your COM object so that it inherits from TNAutoObjectWithProperties and add the Property Page code to the project (remove it from the "auto-create forms" list). Then override DefinePropertyPages with the following code:

    DefinePropertyPage(Class_YourPropPageClass);

My Property Page is doing a ShowMessage within an exception handler, and the program just hangs.

    In this case, use Windows.MessageBox instead of ShowMessage.

How can I register a Server from within code?

        procedure TNForm1.Button1Click(Sender: TObject);
        type
          TDllRegisterProc = function: HResult stdcall;
        var
          Handle: THandle;
          DllRegisterProc: TDllRegisterProc;
        begin
          Handle := LoadLibrary('c:\dev\calc\calc.dll');
          @DllRegisterProc := GetProcAddress(Handle, 'DllRegisterServer');
          if @DllRegisterProc <> nil then
          if DllRegisterProc = S_OK then
            ShowMessage('Registered')
          else
            ShowMessage('Failed');
        end;

How do I get the container's window handle?

    It depends on what you want. If you are after the InPlaceSite's handle, the following code is for you:

        var
          Inplace: IOleInPlaceSite;
          Wnd: HWnd;
        begin
          ActiveFormControl.ClientSite.QueryInterface
            (IOleInPlaceSite, Inplace);
          Inplace.GetWindow(Wnd);
          ShowMessage('Handle='+IntToHex(Wnd, 8));
        end;

    However, if you want the frame's handle (eg. the handle to IE when you have an ActiveForm on an HTML page), then use this code:

        var
        Inplace: IOleInPlaceSite;
          Wnd: HWnd;
          Frame: IOleInPlaceFrame;
          doc: IOleInPlaceUIWindow;
          rcPosRect: TRect;
          frameInfo: TOleInPlaceFrameInfo;
          rcClipRect: TRect;
        begin
          ActiveFormControl.ClientSite.QueryInterface
            (IOleInPlaceSite, Inplace);
          Inplace.GetWindowContext(Frame, doc,
            rcPosRect, rcClipRect, frameInfo);
          Frame.GetWindow(Wnd);
          ShowMessage('Handle='+IntToHex(Wnd, 8));
        end;

    Note that in both cases I have assumed your code is in an ActiveForm - if it is in an ActiveXControl, remove the "ActiveFormControl." part.

How can I create a COM object that has methods that only I can call?

    Consider you have a COM object, A, which has a property, B, which is another COM object. You want A to be able to call some of B's methods that nobody else can call. One way of doing this is to have B inherit from TAutoIntfObject (or TInterfacedObject if IDispatch is not required) and have A create B via the Delphi object:

        procedure TClassA.Initialize;
        var
          Lib: ITypeLib;
        begin
          LoadRegTypeLib(LIBID_Project, 1, 0, 0, Lib));
          B := TClassB.Create(Lib, Class_B);
        end;

        destructor TClassA.Destroy;
        begin
          B._Release;
          inherited Destroy;
        end;

        procedure TClassB.AfterConstruction;
        begin
          _AddRef;
        end;

    Now A can call non-COM methods on B. Any COM methods you define will be visible to all COM clients.

.topic 15600
Creating a VFP DLL
ASP Code to generate and return the PDF

FUNCTION CreatePDFString
LPARAMETERS lcReportName, lcOutputFile, lcSQL
SET PATH TO .\mere\libs,.\contactmanager\reports additive
SET CLASSLIB TO MERE_ReportListener
SET CLASSLIB TO MindsEyeReportPreviewForms ADDITIVE
PUBLIC oRPT, oMERE

* The main thing to remember for an ASP application is that we do not want
* any UI when used in an ASP app.

lcSQL = lcSQL + " into cursor crsTemp"
execscript(lcSQL)
set classlib to MERE_ReportListener
set classlib to MindsEyeReportPreviewForms additive
public oRPT, oMERE
local llShowAsTopLevelForm, llDoNotShowMEREPreview, llDynamicLineHeight
oRPT = createobject('MindsEyeReportPreviewForm')
oMERE = createobject('MERE_ReportListener',oRPT,.t.)
oMERE.dynamiclineheight = .t.
oMERE.lDoNotShow = .t.
oMERE.lInstantPreview = .f.
oMERE.quietmode = .f.
report form (lcReportName) object oMERE nodialog
m.lcPDF = oRPT.oReportEngine.PDFStream()
close tables all
return m.lcPDF
endfunc

VB ASP CODE
x = oServer.CreatePDFString(cReportName,cOuputFile,sql)
Response.Clear
Response.ContentType = "application/pdf"
Response.AddHeader "Accept-Header", Len(x)
Response.AddHeader("Content-Length", x.Length.ToString());
Response.binarywrite(x)
Response.Flush
Response.End

C# ASP CODE
x = oServer.CreatePDFString(cReportName,cOuputFile,sql)
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("Accept-Header", Len(x));
Response.AddHeader("Content-Length", x.Length.ToString());
Response.binarywrite(x); Response.Flush(); Response.End();
Response.Flush
Response.End

.topic 23800
VB6 Example
VFP Example
ASP Example
VB.NET Example
C# Example

Example Features
Rotated Text
Font Style
Font Size
Colors
Multiple Pages

.topic 23500
DON FREEMAN SOLUTION
Write code to Return a PDF Document from both a FILE and a STREAM from the COMOBJECT

PRODUCT CODE
Finish the ACTIVATELICENSE Method on MERE LITE
Update SETUP Installer
Check out the TRANSPARENCY Watermark
Create Example Code for VB Usage
Create Examples for Using MERE as a COM Object with IIS
MERELITE - Remove the PrintReport() Method code from Global Objects
Create Manifest File for LITE
Create LITE Example Project
Create LITE Example Form

NEW METHODS
ActivateLicense() should be a separate string from the development version of the LIC file. So, the key

DECISIONS
Watermark for the MERE Lite Product?

WEBSITE ITEMS
Update REPORTENGINE page with Updated Information and Remove the Dates from the Previous updates
Update EXAMPLES.HTM page with new examples
Update the FAQ.HTM page with more information

.topic 23300
04/24/2008
Resolved issue with the AddText() Method causing an OLE Error whenever a PRINTER FONT (Non True Type or Non Open Type Font) was used as the FontName. This caused the GDI+ MeasureString method to return 0 for most font size information thus throwing an error when computing text wrapping calculations. It was found that GDI+ does not support PRINTER FONTS and so a check was added back in to use the older GDI measuring code for PRINTER FONTS.

.topic 23900
GetPaperSize() Method

.topic 23400
04/25/2008
Roger Shumaker
Rendering with NON-TRUE TYPE or NON-OPEN FONT fonts does not draw any text using the GDI+ calls on the Print Preview and thus when rendering to the Printer.

http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.drawing/2004-11/0006.html

microsoft.public.dotnet.framework.drawing: RE: Print using Printer Fonts in c# app

Date: Mon, 01 Nov 2004 16:21:06 GMT

The GDI+ library used by the .NET framework will only use TrueType and
OpenType fonts. It does not allow you to access printer fonts. What
usually happends is that you specify the name of the printer font but the
GDI+ library will use a default TrueType font.

In order to access the printer font, you will need to bypass the .NET
framework drawing libraries (i.e. GDI+) and use GDI.

When you come to print, you can get use the Graphics.GetHdc method to get
handle you can use with GDI. You then use GDI routines to select the
printer font and draw the character for the symbol you need to print. You
then call Graphics.ReleaseHdc to continue with the rest of the printing in
NET.

Chris Marchal
Microsoft Developer Support

03/2008
Bob Pierce
WaterMark transparency not working any more

.topic 22600
Methods

ActivateLicense
AddLine
AddText
AddPicture
AddShape

AddPath

Clear
ClearAll

DeletePage
NewPage
NewPageByPaperSize
SetPageByPaperSize
SetPageNumberToOne

FirstPage
PriorPage
NextPage
LastPage
GoToPage

SaveToPDF

PDFFontMetric
PDFSetPermissions
PDFStream
SaveToPDF

AboutBox                      M

============================================================

Active                        P

============================================================

AddAnnotation                 M
(cName as Variant, cAnnotationType as Variant, nHPos as Currency, nVPos as Currency, nWidth as Currency, nHeight as Currency, cContent as Variant, [nBorderWidth as Number=0])

Adds an Annotation to the Report Page

============================================================

AddBarCode                    M
(cName as Variant, cData as Variant, nBarCodeType as Number, nHPos as Number, nVPos as Number, [nWidth as Number], [nHeight as Number], [nBarColor as Number], [nRotationAngle as Number])

============================================================

AddChart                      M
(cName as Variant, nChartType as Number, nHPos as Number, nVPos as Number, nWidth as Number, nHeight as Number)

Adds a Shape Object onto the current Report Page being drawn to.

============================================================

AddFRXRecord                  M
(nObjType as Number, nObjCode as Number, cName as Variant, cExpr as Variant, nVPos as Currency, nHPos as Currency, nHeight as Currency, nWidth as Currency, cStyle as Variant, cPicture as Variant, cOrder as Variant, lUnique as Logical, cComment as Variant, lEnviron as Logical, cBoxChar as Variant, cFillChar as Variant, cTag as Variant, cTag2 as Variant, nPenRed as Number, nPenGreen as Number, nPenBlue as Number, nFillRed as Number, nFillGreen as Number, nFillBlue as Number, nPenSize as Number, nPenPat as Number, nFillPat as Number)

============================================================

AddFRXRecord1                 M
(cFontFace as Variant, nFontStyle as Number, nFontSize as Number, nMode as Number, nRuler as Number, nRulerLines as Number, lGrid as Logical, nGridV as Number, nGridH as Number, lFloat as Logical, lStretch as Logical, lStretchTop as Logical, lTop as Logical, lBottom as Logical, nSupType as Number, nSupRest as Number, lNoRepeat as Logical, nResetRpt as Number, lPageBreak as Logical, lColBreak as Logical, lResetPage as Logical, nGeneral as Number, nSpacing as Number, lDouble as Logical, lSwapHeader as Logical, lSwapFooter as Logical)

============================================================

AddFRXRecord2                 M
(lEjectBefor as Logical, lEjectAfter as Logical, lPlain as Logical, lSummary as Logical, lAddAlias as Logical, nOffset as Number, nTopMargin as Number, nBotMargin as Number, nTotalType as Number, nResetTotal as Number, nResoID as Number, lCurPos as Logical, lSupAlways as Logical, lSupOvFlow as Logical, nSuprCol as Number, nSupGroup as Number, lSupValChng as Logical, [cSupExpr as Variant], [cUser as Variant], [nRotationAngle as Number])

============================================================

AddFromClipboard              M
(cName as Variant, nHPos as Currency, nVPos as Currency, nWidth as Currency, nHeight as Currency, [nImageScaling as Number=1])

Adds the object on the Clipboard to the current page in the Report Engine located at the position specified.

============================================================

AddGrid                       M
(cName as Variant, nHPos as Currency, nVPos as Currency, nWidth as Currency, nHeight as Currency, nColumns as Number, nRows as Number, [nPenWidth as Number=1], [nPenColor as Number=0], [nBorderWidth as Number=1], [nFillColor as Number=0], [nBorderStyle as Number=8], [nFillStyle as Number=1])

============================================================

AddLine                       M
(cName as Variant, nHPos as Number, nVPos as Number, nWidth as Number, nHeight as Number, [nPenColor as Number=0], [nPenWidth as Number=1], [nPenStyle as Number=8], [nFillColor as Number=0], [nBackStyle as Number=0], [nBorderStyle as Number=0])

Adds a Line Object onto the current Report Page being drawn to.

============================================================

AddObject                     M
(oObject as Variant)

============================================================

AddPicture                    M
(cName as Variant, cFileName as Variant, nHPos as Number, nVPos as Number, nWidth as Number, nHeight as Number, [nImageScaling as Number=1], [nFlags as Number], [nPageNumber as Number=0])

Adds a Picture Object onto the current Report Page being drawn to.

============================================================

AddReportField                M
(cName as Variant, cExpression as Variant, nHPos as Number, nVPos as Number, [nWidth as Number], [nHeight as Number], [cPicture as Variant], [cDataType as Variant], [cFontName as Variant], [nFontSize as Number], [nForeColor as Number], [nBackColor as Number], [cFontStyle as Variant], [nRotationAngle as Number], [nBackStyle as Number], [nAlignment as Number], [cSubType as Variant], [nAlphaLevel as Number=255])

Adds a Report Object Field for evaluation to the current Report Page being drawn.

============================================================

AddScript                     M
(cFileName as Variant)

Draws a Report using a Script File

============================================================

AddShape                      M
(cName as Variant, nHPos as Number, nVPos as Number, nWidth as Number, nHeight as Number, [nPenColor as Number=0], [nFillColor as Number=0], [nFillStyle as Number=8], [nBackStyle as Number=0], [nBorderStyle as Number=8], [nBorderWidth as Number=0], [nCurvature as Number=0], [nShapeStyle as Number=0])

Adds a Shape Object onto the current Report Page being drawn to.

============================================================

AddText                       M
(cName as Variant, cText as Variant, nHPos as Number, nVPos as Number, [nWidth as Number], [nHeight as Number], [cFontName as Variant], [nFontSize as Number], [nForeColor as Number], [nBackColor as Number], [cFontStyle as Variant], [nRotationAngle as Number], [nBackStyle as Number], [nAlignment as Number], [cSubType as Variant], [nAlphaLevel as Number=255], [nStringTrimmingStyle as Number=2], [nLineSpacing as Number=0])

Adds a Text Object onto the current Report Page being drawn to.

============================================================

AddTiff                       M
(cName as Variant, cFileName as Variant, nHPos as Number, nVPos as Number, nWidth as Number, nHeight as Number, [nImageScaling as Number], [nFlags as Number])

Adds a Picture Object onto the current Report Page being drawn to.

============================================================

AddToolbarButton              M
(cName as Variant, [cBitmapFileName as Variant], [cHint as Variant], [nPosition as Number])

Adds a Toolbar Button to the Report Engine ActiveX Toolbar

============================================================

AddWordDocument               M
(cName as Variant, cFileName as Variant, [nPageNumber as Number=0], [nStartPage as Number=0], [nEndPage as Number=0])

============================================================

AlignDisabled                 P

============================================================

AutoScroll                    P

============================================================

AutoScroll                    P

============================================================

AutoSize                      P

============================================================

AutoSize                      P

============================================================

AxBorderStyle                 P

============================================================

AxBorderStyle                 P

============================================================

CalendarDateFontColor         P

============================================================

CalendarDateFontColor         P

============================================================

CalendarDateFontName          P

============================================================

CalendarDateFontName          P

============================================================

CalendarDateFontSize          P

============================================================

CalendarDateFontSize          P

============================================================

CalendarDateFontStyle         P

============================================================

CalendarDateFontStyle         P

============================================================

CalendarGridLineColor         P

============================================================

CalendarGridLineColor         P

============================================================

CalendarGridLineWidth         P

============================================================

CalendarGridLineWidth         P

============================================================

CalendarHeight                P

============================================================

CalendarHeight                P

============================================================

CalendarLeft                  P

============================================================

CalendarLeft                  P

============================================================

CalendarMonth                 P

============================================================

CalendarMonth                 P

============================================================

CalendarMonthFontColor        P

============================================================

CalendarMonthFontColor        P

============================================================

CalendarMonthFontName         P

============================================================

CalendarMonthFontName         P

============================================================

CalendarMonthFontSize         P

============================================================

CalendarMonthFontSize         P

============================================================

CalendarMonthFontStyle        P

============================================================

CalendarMonthFontStyle        P

============================================================

CalendarShow                  P

============================================================

CalendarShow                  P

============================================================

CalendarShowGridLines         P

============================================================

CalendarShowGridLines         P

============================================================

CalendarTop                   P

============================================================

CalendarTop                   P

============================================================

CalendarWidth                 P

============================================================

CalendarWidth                 P

============================================================

CalendarYear                  P

============================================================

CalendarYear                  P

============================================================

Caption                       P

============================================================

Caption                       P

============================================================

Chart3DPercent                P

============================================================

Chart3DPercent                P

============================================================

Chart3DView                   P

============================================================

Chart3DView                   P

============================================================

Chart3DWalls                  P

============================================================

Chart3DWalls                  P

============================================================

ChartAddData                  M
(nChartIndex as Number, nValue as Number, cLabel as Variant, nColor as Number)

============================================================

ChartAddSeries                M
(nSeriesType as Number, cSeriesTitle as Variant, nSeriesColor as Number)

Adds another series to the currently selected chart.

============================================================

ChartAddXYData                M
(nX as Variant, nY as Number, cLegend as Variant, nColor as Number)

Adds a data point to the currently selected Chart.

============================================================

ChartAxisVisible              P

============================================================

ChartAxisVisible              P

============================================================

ChartBackWallColor            P

============================================================

ChartBackWallColor            P

============================================================

ChartBackWallSize             P

============================================================

ChartBackWallSize             P

============================================================

ChartBackWallTransparent      P

============================================================

ChartBackWallTransparent      P

============================================================

ChartBottomWallColor          P

============================================================

ChartBottomWallColor          P

============================================================

ChartBottomWallSize           P

============================================================

ChartBottomWallSize           P

============================================================

ChartBottomWallTransparent    P

============================================================

ChartBottomWallTransparent    P

============================================================

ChartDataPointLegendFontSize  P

============================================================

ChartDataPointLegendFontSize  P

============================================================

ChartGetCount                 M
([nPageNumber as Number=0])

Returns the number of Charts on the Current Page or the  Page Number specified.

============================================================

ChartGradientDirection        P

============================================================

ChartGradientDirection        P

============================================================

ChartGradientEndColor         P

============================================================

ChartGradientEndColor         P

============================================================

ChartGradientStartColor       P

============================================================

ChartGradientStartColor       P

============================================================

ChartGradientVisible          P

============================================================

ChartGradientVisible          P

============================================================

ChartLeftWallColor            P

============================================================

ChartLeftWallColor            P

============================================================

ChartLeftWallSize             P

============================================================

ChartLeftWallSize             P

============================================================

ChartLeftWallTransparent      P

============================================================

ChartLeftWallTransparent      P

============================================================

ChartLegendBorderColor        P

============================================================

ChartLegendBorderColor        P

============================================================

ChartLegendBorderStyle        P

The Border Style of the Chart Legend.

============================================================

ChartLegendBorderStyle        P

The Border Style of the Chart Legend.

============================================================

ChartLegendBorderWidth        P

============================================================

ChartLegendBorderWidth        P

============================================================

ChartLegendFontColor          P

============================================================

ChartLegendFontColor          P

============================================================

ChartLegendFontName           P

============================================================

ChartLegendFontName           P

============================================================

ChartLegendFontSize           P

============================================================

ChartLegendFontSize           P

============================================================

ChartLegendMarginSize         P

============================================================

ChartLegendMarginSize         P

============================================================

ChartLegendPosition           P

============================================================

ChartLegendPosition           P

============================================================

ChartLegendResizeChart        P

============================================================

ChartLegendResizeChart        P

============================================================

ChartLegendShadowColor        P

============================================================

ChartLegendShadowColor        P

============================================================

ChartLegendShadowSize         P

============================================================

ChartLegendShadowSize         P

============================================================

ChartLegendStyle              P

============================================================

ChartLegendStyle              P

============================================================

ChartLegendVisible            P

Displays or hides the Legend in the current chart.

============================================================

ChartLegendVisible            P

Displays or hides the Legend in the current chart.

============================================================

ChartSaveToMetafile           M
(cFileName as Variant, nWidth as Number, nHeight as Number)

Saves the currently selected Chart to an EMF File

============================================================

ChartSelect                   M
(nChartIndex as Number)

============================================================

ChartSelectSeries             M
(nSeries as Number)

Selects the Series in the currently selected Chart to work with.

============================================================

ChartSeriesBarStyle           P

============================================================

ChartSeriesBarStyle           P

============================================================

ChartSeriesColor              P

============================================================

ChartSeriesColor              P

============================================================

ChartSeriesMarksBackColor     P

Sets the Chart Series Marks back color.

============================================================

ChartSeriesMarksBackColor     P

Sets the Chart Series Marks back color.

============================================================

ChartSeriesMarksStyle         P

Sets the Style for the Series Marks in the current Series.

============================================================

ChartSeriesMarksStyle         P

Sets the Style for the Series Marks in the current Series.

============================================================

ChartSeriesMarksTransparent   P

Sets the Chart Series Marks to transparent or opaque. (Default is False)

============================================================

ChartSeriesMarksTransparent   P

Sets the Chart Series Marks to transparent or opaque. (Default is False)

============================================================

ChartSeriesMarksVisible       P

Displays or Hides the Series Marks for the current Series.

============================================================

ChartSeriesMarksVisible       P

Displays or Hides the Series Marks for the current Series.

============================================================

ChartSeriesMultibarStyle      P

============================================================

ChartSeriesMultibarStyle      P

============================================================

ChartSeriesTitle              P

============================================================

ChartSeriesTitle              P

============================================================

ChartTitle                    P

============================================================

ChartTitle                    P

============================================================

ChartTitleAlignment           P

============================================================

ChartTitleAlignment           P

============================================================

ChartTitleBackColor           P

============================================================

ChartTitleBackColor           P

============================================================

ChartTitleBackStyle           P

============================================================

ChartTitleBackStyle           P

============================================================

ChartTitleBorderColor         P

============================================================

ChartTitleBorderColor         P

============================================================

ChartTitleBorderStyle         P

The Border Style of the Chart Title.

============================================================

ChartTitleBorderStyle         P

The Border Style of the Chart Title.

============================================================

ChartTitleBorderWidth         P

============================================================

ChartTitleBorderWidth         P

============================================================

ChartTitleFontColor           P

============================================================

ChartTitleFontColor           P

============================================================

ChartTitleFontName            P

============================================================

ChartTitleFontName            P

============================================================

ChartTitleFontSize            P

============================================================

ChartTitleFontSize            P

============================================================

ChartType                     P

============================================================

ChartType                     P

============================================================

ChartXAxisAutomatic           P

Determines whether or not the X-Axis Range is automatically calculated

============================================================

ChartXAxisAutomatic           P

Determines whether or not the X-Axis Range is automatically calculated

============================================================

ChartXAxisFontSize            P

============================================================

ChartXAxisFontSize            P

============================================================

ChartXAxisFontStyle           P

============================================================

ChartXAxisFontStyle           P

============================================================

ChartXAxisFontname            P

============================================================

ChartXAxisFontname            P

============================================================

ChartXAxisHideLabels          P

============================================================

ChartXAxisHideLabels          P

============================================================

ChartXAxisLabelAngle          P

============================================================

ChartXAxisLabelAngle          P

============================================================

ChartXAxisMax                 P

Maximum value displayed in the X-Axis

============================================================

ChartXAxisMax                 P

Maximum value displayed in the X-Axis

============================================================

ChartXAxisMin                 P

Minimum value displayed in the X-Axis

============================================================

ChartXAxisMin                 P

Minimum value displayed in the X-Axis

============================================================

ChartXAxisTitle               P

============================================================

ChartXAxisTitle               P

============================================================

ChartXAxisTitleAngle          P

============================================================

ChartXAxisTitleAngle          P

============================================================

ChartYAxisAutomatic           P

============================================================

ChartYAxisAutomatic           P

============================================================

ChartYAxisFontName            P

============================================================

ChartYAxisFontName            P

============================================================

ChartYAxisFontSize            P

============================================================

ChartYAxisFontSize            P

============================================================

ChartYAxisFontStyle           P

============================================================

ChartYAxisFontStyle           P

============================================================

ChartYAxisHideLabels          P

============================================================

ChartYAxisHideLabels          P

============================================================

ChartYAxisLabelAngle          P

============================================================

ChartYAxisLabelAngle          P

============================================================

ChartYAxisLabelFontSize       P

============================================================

ChartYAxisLabelFontSize       P

============================================================

ChartYAxisMax                 P

============================================================

ChartYAxisMax                 P

============================================================

ChartYAxisMin                 P

============================================================

ChartYAxisMin                 P

============================================================

ChartYAxisTitle               P

============================================================

ChartYAxisTitle               P

============================================================

ChartYAxisTitleAngle          P

============================================================

ChartYAxisTitleAngle          P

============================================================

Clear                         M

============================================================

ClearAll                      M

Clears ALL Pages from the RPC memory.

============================================================

ClearLastItem                 M

============================================================

Color                         P

============================================================

Color                         P

============================================================

CopyPageToClipboard           M
([nPageNumber as Number])

Copies the current or specified page in the Report Engine to the Clipboard as a Metafile Image which can then be pasted into other Applications.

============================================================

CurrentPrinter                P

Returns the currently selected printer number. (superceded by PrinterID)

============================================================

Cursor                        P

============================================================

Cursor                        P

============================================================

DeletePage                    M
([nStartPage as Number=0], [nLastPage as Number=0])

============================================================

DisplayActualSizeButton       P

============================================================

DisplayActualSizeButton       P

============================================================

DisplayAddDocumentButton      P

============================================================

DisplayAddDocumentButton      P

============================================================

DisplayCustomExpressionBuilderP

============================================================

DisplayCustomExpressionBuilderP

============================================================

DisplayDeletePageButton       P

============================================================

DisplayDeletePageButton       P

============================================================

DisplayEmailButton            P

Specifies whether the EMAIL button is displayed on the Toolbar

============================================================

DisplayEmailButton            P

Specifies whether the EMAIL button is displayed on the Toolbar

============================================================

DisplayFindButton             P

Shows or Hides the Find Button on the Toolbar

============================================================

DisplayFindButton             P

Shows or Hides the Find Button on the Toolbar

============================================================

DisplayFindToolbar            P

============================================================

DisplayFindToolbar            P

============================================================

DisplayFitInWindowButton      P

============================================================

DisplayFitInWindowButton      P

============================================================

DisplayFitToWidthButton       P

============================================================

DisplayFitToWidthButton       P

============================================================

DisplayGrid                   P

============================================================

DisplayGrid                   P

============================================================

DisplayGridButton             P

============================================================

DisplayGridButton             P

============================================================

DisplayHelpButton             P

============================================================

DisplayHelpButton             P

============================================================

DisplayLicenseInfo            P

Flag to control displaying the Licensee Information in the About box during runtime. (Read/Write)

============================================================

DisplayLicenseInfo            P

Flag to control displaying the Licensee Information in the About box during runtime. (Read/Write)

============================================================

DisplayNewPageButton          P

============================================================

DisplayNewPageButton          P

============================================================

DisplayPDFButton              P

============================================================

DisplayPDFButton              P

============================================================

DisplayPageBorder             P

Shows or Hides the Page Border for pages

============================================================

DisplayPageBorder             P

Shows or Hides the Page Border for pages

============================================================

DisplayPageBorderSize         P

============================================================

DisplayPageBorderSize         P

============================================================

DisplayPageMode               P

============================================================

DisplayPageMode               P

============================================================

DisplayPageNavigation         P

============================================================

DisplayPageNavigation         P

============================================================

DisplayPageScale              P

============================================================

DisplayPageScale              P

============================================================

DisplayPageScroller           P

============================================================

DisplayPageScroller           P

============================================================

DisplayPageSize               P

============================================================

DisplayPageSize               P

============================================================

DisplayPagesPerPage           P

Sets the number of pages that will be painted and displayed on a Single Page Valid Values are 1, 2, 4 and 8

============================================================

DisplayPagesPerPage           P

Sets the number of pages that will be painted and displayed on a Single Page Valid Values are 1, 2, 4 and 8

============================================================

DisplayPaperStyle             P

============================================================

DisplayPaperStyle             P

============================================================

DisplayPopupMenu              P

============================================================

DisplayPopupMenu              P

============================================================

DisplayPrintButton            P

============================================================

DisplayPrintButton            P

============================================================

DisplayPrinterList            P

============================================================

DisplayPrinterList            P

============================================================

DisplayPrinterMargins         P

============================================================

DisplayPrinterMargins         P

============================================================

DisplayReportExpression       M
(nShow as Number)

Displays or hides the Report Expression Dialog Box (0 - Hides, 1 - Shows)

============================================================

DisplaySaveAsImageButton      P

Shows or hides the Save As Image Button which allows Users to Save a Report Page as an Image File from the Report Engine interactively from the toolbar.

============================================================

DisplaySaveAsImageButton      P

Shows or hides the Save As Image Button which allows Users to Save a Report Page as an Image File from the Report Engine interactively from the toolbar.

============================================================

DisplayStatusBar              P

============================================================

DisplayStatusBar              P

============================================================

DisplayToolbar                P

============================================================

DisplayToolbar                P

============================================================

DisplayToolbarStyle           P

Selects the Toolbar Style at runtime (0 = Classic, 1 = XP Style)

============================================================

DisplayToolbarStyle           P

Selects the Toolbar Style at runtime (0 = Classic, 1 = XP Style)

============================================================

DisplayUnitOfMeasure          P

Selects the Unit Of Measure to Display on the Toolbar at runtime (0 = inches, 1 = cm, 2 = mm)

============================================================

DisplayUnitOfMeasure          P

Selects the Unit Of Measure to Display on the Toolbar at runtime (0 = inches, 1 = cm, 2 = mm)

============================================================

DisplayZoomButtons            P

============================================================

DisplayZoomButtons            P

============================================================

DoubleBuffer                  P

============================================================

DoubleBuffer                  P

============================================================

DoubleBuffered                P

============================================================

DoubleBuffered                P

============================================================

DropTarget                    P

============================================================

DropTarget                    P

============================================================

EMAILAddAttachment            M
(cFileName as Variant)

Adds a Filename to the EMAIL Attachments List

============================================================

EMAILAttachmentCount          P

============================================================

EMAILAttachmentCount          P

============================================================

EMAILFromDisplayStyle         P

============================================================

EMAILFromDisplayStyle         P

============================================================

EMAILSMTPHostDisplayStyle     P

============================================================

EMAILSMTPHostDisplayStyle     P

============================================================

EMailContentType              P

============================================================

EMailContentType              P

============================================================

EmailAttachmentFileName       P

Default Filename to be used for the attachment when Emailing.

============================================================

EmailAttachmentFileName       P

Default Filename to be used for the attachment when Emailing.

============================================================

EmailBCCAddresses             P

Specifies a comma separated list of formatted Blind Carbon Copy email addresses

============================================================

EmailBCCAddresses             P

Specifies a comma separated list of formatted Blind Carbon Copy email addresses

============================================================

EmailBody                     P

The Body Text of the Email

============================================================

EmailBody                     P

The Body Text of the Email

============================================================

EmailCCAddresses              P

Specifies a comma separated list of formatted Carbon Copy email addresses

============================================================

EmailCCAddresses              P

Specifies a comma separated list of formatted Carbon Copy email addresses

============================================================

EmailDisplayConfirmationAfterSP

Enables or Disables the displaying of a Confirmation Dialog after an Email is Sent

============================================================

EmailDisplayConfirmationAfterSP

Enables or Disables the displaying of a Confirmation Dialog after an Email is Sent

============================================================

EmailFromAddress              P

SMTP From Address (required)

============================================================

EmailFromAddress              P

SMTP From Address (required)

============================================================

EmailMAPIPassword             P

The MAPI Password to use when logging onto a MAPI Email Server.

============================================================

EmailMAPIPassword             P

The MAPI Password to use when logging onto a MAPI Email Server.

============================================================

EmailMAPIProfileName          P

The MAPI Profile Name to use when logging onto a MAPI Email Server.

============================================================

EmailMAPIProfileName          P

The MAPI Profile Name to use when logging onto a MAPI Email Server.

============================================================

EmailMessagingType            P

============================================================

EmailMessagingType            P

============================================================

EmailPriorityLevel            P

============================================================

EmailPriorityLevel            P

============================================================

EmailRecipients               P

Specifies a comma separated list of formatted Recipient Addresses (ie. reportengine@mindseyeinc.com,info@mindseyeinc.com)

============================================================

EmailRecipients               P

Specifies a comma separated list of formatted Recipient Addresses (ie. reportengine@mindseyeinc.com,info@mindseyeinc.com)

============================================================

EmailReturnReceipt            P

Email Return Receipt Request (default = FALSE)

============================================================

EmailReturnReceipt            P

Email Return Receipt Request (default = FALSE)

============================================================

EmailSMTPAuthorizationType    P

SMTP Authorization Type 0 - None, 1 - Login, 2 - SASL (Default = 0)

============================================================

EmailSMTPAuthorizationType    P

SMTP Authorization Type 0 - None, 1 - Login, 2 - SASL (Default = 0)

============================================================

EmailSMTPHost                 P

The SMTP Host for sending Email (Required)

============================================================

EmailSMTPHost                 P

The SMTP Host for sending Email (Required)

============================================================

EmailSMTPPassword             P

SMTP Password (Required if Authorization Type set to Login)

============================================================

EmailSMTPPassword             P

SMTP Password (Required if Authorization Type set to Login)

============================================================

EmailSMTPPort                 P

The SMTP Port for sending SMTP Email

============================================================

EmailSMTPPort                 P

The SMTP Port for sending SMTP Email

============================================================

EmailSMTPUserID               P

SMTP UserID (Required if Authorization Type set to Login)

============================================================

EmailSMTPUserID               P

SMTP UserID (Required if Authorization Type set to Login)

============================================================

EmailSubject                  P

The Subject text of the email

============================================================

EmailSubject                  P

The Subject text of the email

============================================================

Enabled                       P

============================================================

Enabled                       P

============================================================

FRXBottomMargin               P

============================================================

FRXBottomMargin               P

============================================================

FRXClear                      M

Clears all of the FRX Definitions from memory.

============================================================

FRXCurrentColumn              P

============================================================

FRXCurrentColumn              P

============================================================

FRXDetailBandObjects          P

============================================================

FRXDetailFull                 P

============================================================

FRXDetailFull                 P

============================================================

FRXGetDate                    M
(nIndex as Number)

============================================================

FRXGetDateTime                M
(nIndex as Number)

============================================================

FRXGetLogical                 M
(nIndex as Number)

============================================================

FRXGetNumeric                 M
(nIndex as Number)

============================================================

FRXGetText                    M
(nIndex as Number)

============================================================

FRXLoadReport                 M
(cFileName as Variant)

Loads an FRX Report File into the Control from the File Name passed. Returns a value of TRUE if successful and FALSE if unsuccessful. Check the LastError property for Error Codes.

============================================================

FRXLocateBands                M

============================================================

FRXPageCount                  P

Read Only value of the Total Page Count printed for the current FRX Report running

============================================================

FRXPageFooterBandObjects      P

============================================================

FRXPageHeaderBandObjects      P

============================================================

FRXPaintColumnFooter          M

Paints an FRX Column Footer onto the current Report Page.

============================================================

FRXPaintColumnHeader          M

Paints an FRX Column Header onto the current Report Page.

============================================================

FRXPaintDetailBand            M

Adds a Detail Band of data to the current Report.

============================================================

FRXPaintGroupFooter           M
(nGroupLevel as Number)

Paints all the objects in the Group Footer Level passed

============================================================

FRXPaintGroupFooters          M
([nGroupLevel as Number])

Paints the FRX Group Footers to the Group Level Passed

============================================================

FRXPaintGroupHeader           M
(nGroupLevel as Number)

Paints all the objects in the Group Header Level passed

============================================================

FRXPaintGroupHeaders          M
([nGroupLevel as Number])

Paints the FRX Group Headers from the nGroupLevel specified to the Highest Group Level

============================================================

FRXPaintPage                  M

============================================================

FRXPaintPageBottom            M
([nType as Number])

============================================================

FRXPaintPageFooterBand        M

============================================================

FRXPaintPageHeaderBand        M

============================================================

FRXPaintPageTop               M
([nType as Number])

Paints the Title Band, Page Header Band and Group Header Bands onto the Report

============================================================

FRXPaintSummaryBand           M

Paints the Summary Band Objects for an FRX Report

============================================================

FRXPaintTitleBand             M
(nType as Number)

Paints the Title Band onto the Report

============================================================

FRXRecords                    P

============================================================

FRXRecords                    P

============================================================

FRXResetRowToTop              M

Resets the Vertical Position to the Top Row for a Multi Column Report

============================================================

FRXSaveReport                 M
(cFileName as Variant)

Saves an FRX Report defined in the Control to the File Name passed. Returns a value of TRUE if successful and FALSE if unsuccessful. Check the LastError property for Error Codes.

============================================================

FRXSetDate                    M
(nIndex as Number, cDateTime as Variant)

Updates the DateTime Value in the FRX Record from the Character DateTime value passed.

============================================================

FRXSetDateTime                M
(nIndex as Number, cDateTime as Variant)

Updates the DateTime Value in the FRX Record from the Character DateTime value passed.

============================================================

FRXSetLogical                 M
(nIndex as Number, lValue as Logical)

Updates the Logical Data value of the passed nIndex FRX Record

============================================================

FRXSetNumeric                 M
(nIndex as Number, nValue as Number)

Updates the Numeric Data value of the passed nIndex FRX Record

============================================================

FRXSetObjectProperty          M
(nIndex as Number, cProperty as Variant, Value as Variant)

Sets an Object Property of an FRX Report Object.

============================================================

FRXSetPrintWhen               M
(nIndex as Number, lDoNotPrint as Logical)

Updates an FRX REPORT OBJECT as to whether or not it should print on the current pass.

============================================================

FRXSetText                    M
(nIndex as Number, cText as Variant)

Updates the Text Data value of the passed nIndex FRX Record

============================================================

FRXSummaryBand                P

Evaluates to TRUE if the current FRX Report Layout contains a Summary Band

============================================================

FRXSummaryBandObjects         P

============================================================

FRXTitleBand                  P

Evaluates to TRUE if the current FRX Report Layout contains a Title Band

============================================================

FRXTitleBandObjects           P

============================================================

FRXUpdateGroupLevel           M
([nGroupLevel as Number])

Updates the FRX GROUP LEVEL to the Current Group Level being processed by the VFP Engine.

============================================================

FRXnVertPos                   P

============================================================

Find                          M
(cString as Variant, [lCaseSensitive as Logical], [lFindAll as Logical])

============================================================

FindClear                     M

============================================================

FirstPage                     M

Moves the RPC to the first page in memory and displays the page.

============================================================

Font                          P

============================================================

Font                          P

============================================================

Font                          P

============================================================

GDIPlusEnabled                P

GDI Plus Supported on this machine is indicated by the value of 1 otherwise 0. (Read Only)

============================================================

GDIPlusTextRenderingHint      P

============================================================

GDIPlusTextRenderingHint      P

============================================================

GetImageInfo                  M
(vImageAttribute as Variant, cFileName as Variant)

Returns the value of the Image Attribute specified for the Image Filename passed.

============================================================

GetTextHeight                 M
(nHPos as Number, nVPos as Number, nWidth as Number, cText as Variant, [nAlignment as Number])

============================================================

GotoPage                      M
(nPageNumber as Number) as HRESULT

Moves the RPC to the page specified by nPageNumber

============================================================

HelpContextID                 P

The Help Context ID for Help

============================================================

HelpContextID                 P

The Help Context ID for Help

============================================================

HelpFile                      P

============================================================

HelpFile                      P

============================================================

HelpKeyword                   P

============================================================

HelpKeyword                   P

============================================================

HelpType                      P

============================================================

HelpType                      P

============================================================

InDesignMode                  P

============================================================

KeyPreview                    P

============================================================

KeyPreview                    P

============================================================

LanguageIndexID               P

Read/Write value of the Language Index for setting the Language text automatically by Index Number. (Default 0 - English)

============================================================

LanguageIndexID               P

Read/Write value of the Language Index for setting the Language text automatically by Index Number. (Default 0 - English)

============================================================

LastError                     P

============================================================

LastErrorMessage              P

The Last System Error Message corresponding to the LastError Code.

============================================================

LastPage                      M

Moves the RPC to the last page in memory and displays the page.

============================================================

LastTextHeight                P

============================================================

LastTextHeight                P

============================================================

LinePenColor                  P

============================================================

LinePenColor                  P

============================================================

LinePenStyle                  P

============================================================

LinePenStyle                  P

============================================================

LinePenWidth                  P

============================================================

LinePenWidth                  P

============================================================

LoadPDFFile                   M
(cPDFFilename as Variant)

============================================================

MEILicenseKey                 P

============================================================

MEILicenseKey                 P

============================================================

MediaType                     P

============================================================

MediaType                     P

============================================================

NewOverlayPage                M
([nPageWidth as Number], [nPageHeight as Number], [nOrientation as Number]) as HRESULT

Adds a new page to the RPC in memory after the last page page.

============================================================

NewPage                       M
([nPageWidth as Number], [nPageHeight as Number], [nOrientation as Number], [nBinNumber as Number], [nPageNumber as Number=0]) as HRESULT

Adds a new page to the Report Engine in memory after the last page page.

============================================================

NewPageByPaperSize            M
(nPaperSize as Number, [nOrientation as Number], [nBinNumber as Number], [nPageNumber as Number=0])

Adds a new page by PaperSize Number

============================================================

NextPage                      M

Moves to the next page in the current Report.

============================================================

ObjectClicked                 M

============================================================

PDFAuthor                     P

============================================================

PDFAuthor                     P

============================================================

PDFBitmapQuality              P

============================================================

PDFBitmapQuality              P

============================================================

PDFCodePage                   P

============================================================

PDFCodePage                   P

============================================================

PDFCompress                   P

============================================================

PDFCompress                   P

============================================================

PDFCompressBitmaps            P

============================================================

PDFCompressBitmaps            P

============================================================

PDFCreator                    P

============================================================

PDFCreator                    P

============================================================

PDFDisplayConfirmationAfterCreP

Indicates whether the Confirmation Dialog will be displayed after a PDF File is created by clicking on the Save To PDF button on the Toolbar. (Default = TRUE)

============================================================

PDFDisplayConfirmationAfterCreP

Indicates whether the Confirmation Dialog will be displayed after a PDF File is created by clicking on the Save To PDF button on the Toolbar. (Default = TRUE)

============================================================

PDFDisplaySecurityOptions     P

============================================================

PDFDisplaySecurityOptions     P

============================================================

PDFEmbedFonts                 P

============================================================

PDFEmbedFonts                 P

============================================================

PDFEncrypt                    P

============================================================

PDFEncrypt                    P

============================================================

PDFFileName                   P

The Filename to use when saving a report to a PDF File when clicking on the Save To PDF button from the toolbar.

============================================================

PDFFileName                   P

The Filename to use when saving a report to a PDF File when clicking on the Save To PDF button from the toolbar.

============================================================

PDFFontCount                  P

============================================================

PDFFontMetric                 M
(nFontIndex as Number, nAttribute as Number, [nEmbedFont as Number])

============================================================

PDFJPEGQuality                P

============================================================

PDFJPEGQuality                P

============================================================

PDFKeywords                   P

============================================================

PDFKeywords                   P

============================================================

PDFMargin                     P

============================================================

PDFMargin                     P

============================================================

PDFOpenAfterCreate            P

Indicates that the PDF File should be opened after it is created when clicking on the Save To PDF Button on the Toolbar. (Default = TRUE)

============================================================

PDFOpenAfterCreate            P

Indicates that the PDF File should be opened after it is created when clicking on the Save To PDF Button on the Toolbar. (Default = TRUE)

============================================================

PDFOwnerPassword              P

============================================================

PDFOwnerPassword              P

============================================================

PDFPassword                   P

============================================================

PDFPassword                   P

============================================================

PDFPromptForSaveToPDF         P

Sets whether the Save To PDF Dialog box will be displayed when the User clicks on the Save To PDF button on the toolbar.

============================================================

PDFPromptForSaveToPDF         P

Sets whether the Save To PDF Dialog box will be displayed when the User clicks on the Save To PDF button on the toolbar.

============================================================

PDFSetPermissions             M
(nAllowPrintingLevel as Number, lAllowCopying as Logical, lAllowChanges as Logical, lAllowCommenting as Logical, lAllowFillingFormFields as Logical, lAllowCopyingAccessibility as Logical, lAllowDocumentAssembly as Logical)

Sets the Permissions for creating a Secure PDF Document.

============================================================

PDFStream                     M
([nStartPage as Number=0], [nEndPage as Number=0])

Returns a PDF document as a string. An empty string is returned if an error occurred.

============================================================

PDFSubject                    P

============================================================

PDFSubject                    P

============================================================

PDFTitle                      P

============================================================

PDFTitle                      P

============================================================

PDFUserPassword               P

============================================================

PDFUserPassword               P

============================================================

PDFXOffset                    P

============================================================

PDFXOffset                    P

============================================================

PDFYOffset                    P

============================================================

PDFYOffset                    P

============================================================

PageForm                      P

============================================================

PageForm                      P

============================================================

PageHeight                    P

The Height of the current page. (Read/Write)

============================================================

PageHeight                    P

The Height of the current page. (Read/Write)

============================================================

PageSize                      P

============================================================

PageSize                      P

============================================================

PageWidth                     P

The Width of the current page. (Read/Write)

============================================================

PageWidth                     P

The Width of the current page. (Read/Write)

============================================================

PaperBin                      P

Reads or Sets the Paper Bin for the current page in the Report Engine. (Default = 0 (not set))

============================================================

PaperBin                      P

Reads or Sets the Paper Bin for the current page in the Report Engine. (Default = 0 (not set))

============================================================

ParentWindow                  P

Returns the Handle to the Window hosting the Report Engine.

============================================================

PictureJPEGSpeed              P

============================================================

PictureJPEGSpeed              P

============================================================

PixelsPerInch                 P

============================================================

PixelsPerInch                 P

============================================================

PrintCollatePages             P

Determines whether printing will be Collated

============================================================

PrintCollatePages             P

Determines whether printing will be Collated

============================================================

PrintColor                    P

============================================================

PrintColor                    P

============================================================

PrintCopies                   P

Default number of Copies to Print

============================================================

PrintCopies                   P

Default number of Copies to Print

============================================================

PrintDuplex                   P

============================================================

PrintDuplex                   P

============================================================

PrintEndPage                  P

The Last Page to print when printing

============================================================

PrintEndPage                  P

The Last Page to print when printing

============================================================

PrintJobTitle                 P

The Title of the Print Job to be used when printing to the Printer. (Read/Write)

============================================================

PrintJobTitle                 P

The Title of the Print Job to be used when printing to the Printer. (Read/Write)

============================================================

PrintPagesPerPage             P

Sets the number of pages that will be printed on a Single Page Valid Values are 1, 2, 4 and 8

============================================================

PrintPagesPerPage             P

Sets the number of pages that will be printed on a Single Page Valid Values are 1, 2, 4 and 8

============================================================

PrintPromptForPrint           P

Flag indicating if the Printer Options dialog box will be displayed when printing a report. (Read/Write)

============================================================

PrintPromptForPrint           P

Flag indicating if the Printer Options dialog box will be displayed when printing a report. (Read/Write)

============================================================

PrintReport                   M
([PrinterID as Variant], [nStartPage as Number], [nEndPage as Number], [nPageType as Number], [cFileName as Variant], [lDuplex as Logical=.F.])

Prints the report to the printer. You can specify the Printer by Name or Number, Start Page, End Page and Page Type (0 = ALL, 1 = ODD, 2 = EVEN)

============================================================

PrintReversePages             P

Determines whether printing of pages will be in Reverse Order or not.

============================================================

PrintReversePages             P

Determines whether printing of pages will be in Reverse Order or not.

============================================================

PrintScale                    P

============================================================

PrintScale                    P

============================================================

PrintShrinkToFit              P

Used to automatically Shrink Pages to Fit to the current Paper Size being printed to

============================================================

PrintShrinkToFit              P

Used to automatically Shrink Pages to Fit to the current Paper Size being printed to

============================================================

PrintStartPage                P

The First Page to print when printing

============================================================

PrintStartPage                P

The First Page to print when printing

============================================================

PrintThisPage                 M

============================================================

PrinterAddForm                M
(cFormName as Variant, nFormWidth as Currency, nFormHeight as Currency, [nLeftMargin as Currency=0.0000], [nTopMargin as Currency=0.0000], [nRightMargin as Currency=0.0000], [nBottomMargin as Currency=0.0000], [cPrinterName as Variant])

Adds a new Custom Print Form using the Windows API

============================================================

PrinterBinCount               P

Returns the number of Paper Bins for the currently selected printer.

============================================================

PrinterBinID                  P

============================================================

PrinterBinID                  P

============================================================

PrinterBinName                P

============================================================

PrinterBinName                P

============================================================

PrinterCollate                P

============================================================

PrinterCollate                P

============================================================

PrinterColor                  P

============================================================

PrinterColor                  P

============================================================

PrinterCopies                 P

============================================================

PrinterCopies                 P

============================================================

PrinterCount                  P

Returns the Number of Printers currently installed.

============================================================

PrinterDeleteForm             M
(cFormName as Variant, [cPrinterName as Variant])

Deletes a Custom Print Form that was created using the PrinterAddForm using the Windows API

============================================================

PrinterID                     P

Used to set or determine the currently selected Printer by Number for the Report Engine to be used for printing. PrinterID Numbers range between 1 and the number of printers on the system.

============================================================

PrinterID                     P

Used to set or determine the currently selected Printer by Number for the Report Engine to be used for printing. PrinterID Numbers range between 1 and the number of printers on the system.

============================================================

PrinterName                   P

Returns the Name of the currently selected Printer in the Report Engine.

============================================================

PrinterPaperCount             P

Returns the number of different Paper Sizes for the currently selected printer.

============================================================

PrinterPaperHeight            P

============================================================

PrinterPaperHeight            P

============================================================

PrinterPaperWidth             P

============================================================

PrinterPaperWidth             P

============================================================

PrinterPhysicalOffsetX        P

Returns the PhysicalOffsetX amount for the currently selected printer at it's current resolution.

============================================================

PrinterPhysicalOffsetY        P

Returns the PhysicalOffsetY amount for the currently selected printer at it's current resolution.

============================================================

PrinterPort                   P

============================================================

PrinterPrintQuality           P

============================================================

PrinterPrintQuality           P

============================================================

PrinterScale                  P

============================================================

PrinterScale                  P

============================================================

PrinterYResolution            P

============================================================

PriorPage                     M

Moves the RPC to the prior page and displays the page.

============================================================

ProcessInBackground           P

Tells the Report Engine to process the output in a background mode meaning that the pages are not synchronized until this flag is set to FALSE.

============================================================

ProcessInBackground           P

Tells the Report Engine to process the output in a background mode meaning that the pages are not synchronized until this flag is set to FALSE.

============================================================

ReportInfo                    M
(nParameter as Number)

Returns information about the Report based on the parameter passed.

============================================================

ReturnValue                   M
(nNumber as Number)

============================================================

SaveToBitmap                  M
(cFileName as Variant, [nPageNumber as Number=0], [lOpenFile as Logical], [nThumbnailSize as Number=0], [nBitsPerPixel as Number=24], [lGrayScale as Logical])

Saves a Report Page to the BITMAP file specified.

============================================================

SaveToJPEG                    M
(cFileName as Variant, [nPageNumber as Number=0], [lOpenFile as Logical], [nThumbnailSize as Number=0], [lGrayScale as Logical], [nCompressionQuality as Number=90], [lProgressiveEncoding as Logical])

Saves a Report Page to the JPEG file specified.

============================================================

SaveToMetafile                M
(cFileName as Variant, [nPageNumber as Number=0], [lOpenFile as Logical])

Saves a Report Page to the METAFILE file specified.

============================================================

SaveToPDF                     M
([cFileName as Variant], [lOpenFile as Logical], [nStartPage as Number=0], [nEndPage as Number=0])

Saves the current contents of the Report to a PDF file using the specified Filename

============================================================

SaveToPNG                     M
(cFileName as Variant, [nPageNumber as Number=0], [lOpenFile as Logical], [nThumbnailSize as Number=0], [nBitsPerPixel as Number=24], [lGrayScale as Logical])

Saves a Report Page to the PNG file specified.

============================================================

SaveToTIFF                    M
(cFileName as Variant, [nPageNumberStart as Number=0], [nPageNumberEnd as Number=0], [lOpenFile as Logical], [nThumbnailSize as Number=0], [nCompressionType as Number=0], [nBitsPerPixel as Number=24], [lGrayScale as Logical])

Saves a Report Page or Range of Pages to a TIFF Image File

============================================================

SaveToWord                    M
(cFileName as Variant, [lOpenFile as Logical])

============================================================

Scale                         P

============================================================

Scale                         P

============================================================

Scaled                        P

============================================================

Scaled                        P

============================================================

SendMail                      M
([cSMTPHost as Variant], [cFromAddress as Variant], [cRecipients as Variant], [cSubject as Variant], [cBodyText as Variant], [cAttachmentFileName as Variant])

============================================================

SetAll                        M
(cProperty as Variant, Value as Variant, [cClass as Variant], [nStartRange as Number=0], [nEndRange as Number=0])

Assigns a value to the Property specified for all objects within the container or container class or within the specified range.

============================================================

SetFieldExpression            M
(nIndex as Number, cExpression as Variant)

Sets the Field Expression

============================================================

SetPageByPaperSize            M
(nPaperSize as Number, [nOrientation as Number], [nBinNumber as Number])

Sets the Current Page by PaperSize Number

============================================================

SetPageNumberToOne            M
(nPageNumber as Number)

Sets a Page Break for the Page Numbering to Reset to 1 again by passing the Page Number to Break at.

============================================================

SetPrintWhenExpression        M
(nIndex as Number, cExpression as Variant)

============================================================

SetPrinterTo                  M
(PrinterID as Variant)

Sets the current Printer using either a PrinterID Number or a Printer Name.

============================================================

SetReportEngineText           M
(nIndexID as Number, cNewString as Variant)

Changes the text for the Report Engine text strings to your choosing.

============================================================

ShapeBackStyle                P

============================================================

ShapeBackStyle                P

============================================================

ShapeBorderStyle              P

The Style that the Border is drawn such as a Solid or Dashed Line.

============================================================

ShapeBorderStyle              P

The Style that the Border is drawn such as a Solid or Dashed Line.

============================================================

ShapeBorderWidth              P

The Border Width of the Pen used to draw the shape.

============================================================

ShapeBorderWidth              P

The Border Width of the Pen used to draw the shape.

============================================================

ShapeCurvature                P

============================================================

ShapeCurvature                P

============================================================

ShapeFillColor                P

The Fill Color to be used to fill the shape. If the Shape is transparent the Fill Color will not be seen.

============================================================

ShapeFillColor                P

The Fill Color to be used to fill the shape. If the Shape is transparent the Fill Color will not be seen.

============================================================

ShapeFillStyle                P

============================================================

ShapeFillStyle                P

============================================================

ShapePenColor                 P

The Pen Color used to draw the border of the shape.

============================================================

ShapePenColor                 P

The Pen Color used to draw the border of the shape.

============================================================

ShowTips                      P

============================================================

ShowTips                      P

============================================================

TextFontBackColor             P

Font Back Color

============================================================

TextFontBackColor             P

Font Back Color

============================================================

TextFontForeColor             P

============================================================

TextFontForeColor             P

============================================================

TextFontName                  P

============================================================

TextFontName                  P

============================================================

TextFontSize                  P

============================================================

TextFontSize                  P

============================================================

TextFontStyle                 P

============================================================

TextFontStyle                 P

============================================================

VFPBugEmulation               P

============================================================

VFPBugEmulation               P

============================================================

VFPEmulation                  P

============================================================

VFPEmulation                  P

============================================================

Version                       P

The version number of the control.

============================================================

Visible                       P

============================================================

Visible                       P

============================================================

VisibleDockClientCount        P

============================================================

WaterMarkBackColor            P

The Backcolor of the Watermark Font for the current page.

============================================================

WaterMarkBackColor            P

The Backcolor of the Watermark Font for the current page.

============================================================

WaterMarkForeColor            P

The Color of the Watermark Font for the current page.

============================================================

WaterMarkForeColor            P

The Color of the Watermark Font for the current page.

============================================================

WatermarkFontName             P

The Watermark Font Name for the current page.

============================================================

WatermarkFontName             P

The Watermark Font Name for the current page.

============================================================

WatermarkFontSize             P

The WaterMark Font Size for the current page.

============================================================

WatermarkFontSize             P

The WaterMark Font Size for the current page.

============================================================

WatermarkFontStyle            P

The Font Style of the Watermark for the current page. (B = Bold, I = Italic, U = Underline, S - Strikeout)

============================================================

WatermarkFontStyle            P

The Font Style of the Watermark for the current page. (B = Bold, I = Italic, U = Underline, S - Strikeout)

============================================================

WatermarkRotationAngle        P

The Rotation Angle of the Watermark for the current page.

============================================================

WatermarkRotationAngle        P

The Rotation Angle of the Watermark for the current page.

============================================================

WatermarkText                 P

The WaterMark text for the current page.

============================================================

WatermarkText                 P

The WaterMark text for the current page.

============================================================

ZoomIn                        M

Zooms in on the report stepping by the nZoomScale value.

============================================================

ZoomOut                       M

Zooms out on the report stepping by the nZoomScale value.

============================================================

cFontStyle                    P

============================================================

cFontStyle                    P

============================================================

nBackgroundColor              P

============================================================

nBackgroundColor              P

============================================================

nCurrentPageBinNumber         P

============================================================

nCurrentPageBinNumber         P

============================================================

nCurrentPageHeight            P

============================================================

nCurrentPageHeight            P

============================================================

nCurrentPageOrientation       P

============================================================

nCurrentPageOrientation       P

============================================================

nCurrentPageWidth             P

============================================================

nCurrentPageWidth             P

============================================================

nCurrentScale                 P

============================================================

nCurrentScale                 P

============================================================

nGridColor                    P

============================================================

nGridColor                    P

============================================================

nHDC                          P

============================================================

nHDC                          P

============================================================

nLastError                    P

The last error that occured while processing a request.

============================================================

nLastError                    P

The last error that occured while processing a request.

============================================================

nPageNumber                   P

============================================================

nPageNumber                   P

============================================================

nPageOrientation              P

============================================================

nPageOrientation              P

============================================================

nPaperColor                   P

============================================================

nPaperColor                   P

============================================================

nPrintScale                   P

============================================================

nPrintScale                   P

============================================================

nRedraws                      P

============================================================

nReportMode                   P

============================================================

nReportMode                   P

============================================================

nReportObjects                P

The number of Report Objects on the current page.

============================================================

nReportObjects                P

The number of Report Objects on the current page.

============================================================

nTotalPages                   P

============================================================

nTotalPages                   P

============================================================

nXOffset                      P

The amount of Horizontal Offset for Preview Mode in Inches or Centimeters to shift items on the page.

============================================================

nXOffset                      P

The amount of Horizontal Offset for Preview Mode in Inches or Centimeters to shift items on the page.

============================================================

nXPrintOffset                 P

The amount of Horizontal Offset for Printing in Inches or Centimeters to shift items on the page.

============================================================

nXPrintOffset                 P

The amount of Horizontal Offset for Printing in Inches or Centimeters to shift items on the page.

============================================================

nYOffset                      P

============================================================

nYOffset                      P

============================================================

nYPrintOffset                 P

============================================================

nYPrintOffset                 P

============================================================

nZoomScale                    P

============================================================

nZoomScale                    P

============================================================

.topic 23200
Things to think  about

SaveToPDF() Method will automatically overwrite an existing file. Should we check for this or provide an option

.topic 16100
Feature List
LITE
BASIC
PRO

Save to PDF
ü

GUI

ü
Print Document

ü
ü

Print Preview / Display

ü

Product Comparison Chart

Feature List
LITE
BASIC
PRO
Save to PDF
ü

GUI

ü
Print Document

ü
ü

Print Preview / Display

ü
Add Text
ü
ü
ü
Add Shape
ü
ü
ü
Add Picture
ü
ü
ü
Add Line
ü
ü
ü
Compress PDF
ü
ü
ü

Save as Image (JPG, BMP, TIFF, etc.)

.topic 23600

http://msdn2.microsoft.com/en-us/library/1tced27e(VS.80).aspx

Error Loading Printer Driver

.topic 15700
Rich Simpson says:
Bo, have you received an 1008 OLE IDispatch error before while trying to run a report from a DLL?
Rich Simpson says:
If I change the CONTROL SOURCE TYPE for the image file on the report to EXPRESSION or VARIABLE NAME and then place a variable in the code and reference it in the report, I don't get the error.
Rich Simpson says:
OLE IDispatch exception code 1108 from contactmanager.CMTools contactmanager.CMTools: .createpdf c:\vfp9\reportengine\testreports\donfreeman\cmtools\cmtools.prg Error in line 57 Picture too big, corrupt, or in wrong format. 1108..

TO REPORT A BUG
https://connect.microsoft.com/VisualStudio/feedback/CreateFeedback.aspx?wa=wsignin1.0

.topic 15800
Bill -

With VFP9 is it possible to use the REPORT FORM command to send a report to an ascii file from a VFP com server called from an ASP page? With VFP6 this was not possible due to threading issues with the VFP report engine. Has this been fixed in Version 9?

The answer may be found in the help file, in the "Changes in functionality" topic:

REPORT FORM and LABEL commands are no longer automatically prohibited as user-interface-related commands in COM objects compiled into DLLs, when you run the commands in object-assisted mode. The restriction still applies to these commands when they are run in backward-compatible mode. (The topic Selecting Process Types explains why user-interface-related commands are prohibited in DLLs.) This change is not applicable to multi-threaded DLLs. A number of user-interface-related facilities also are not available in DLLs (whether single- or multi-threaded). For example, the TXTWIDTH( ) Function and TextWidth Method depend on a window handle to function, so they are not available in a DLL. The CREATE REPORT - Quick Report Command relies on the same facilities as TXTWIDTH(), and therefore is not available in a DLL. However, in many instances, creating custom output using a ReportListener does not require any user-interface activity, so a REPORT FORM or LABEL command can now be used productively in a DLL. Using the SYS(2335) - Unattended Server Mode function to trap for potential modal states, as well as the new SET TABLEPROMPT Command, is recommended.

- Colin

.topic 11800
LABELS PROPERTY DIALOG BOX
Does not support TEXT ALIGNMENT
Does Not Support Line Spacing

SHAPE PROPERTY DIALOG BOX
Does not support the HATCH STYLE

BUG: PICTURE OBJECT NOT CENTERING
BUG: FIXED: OPAQUE Label is showing BLACK BACKGROUND using DEFAULT BACKCOLOR on PDF OUTPUT ONLY and the BACKCOLOR Rendered is in the WRONG POSITION
CHANGE: Use the TIdAttachmentMemory Class to send the default PDF document so a temporary file is not created on disk.

.topic 1023
PropertiesVisual FoxPro Usage

In order to use the control in Visual FoxPro, you should first place the control onto a VFP Form or subclass the control by creating a new OLECONTROL class using the control. This will give you the ability to add new methods and place code in the controls Events to respond to them. With VFP 8, you will be able to use BINDEVENT but until now you will have to place the code in the events. Then you can then use this new OLECONTROL class to use the AddObject() Method to add the control to a form at runtime. The main reason for doing this is so that your developer's license file information gets embedded into the SCX or VCX during design time that can then be used later at runtime to verify the control.

IMPORTANT
If you replace the MindsEyeReportEngine ActiveX control on the VFP MindsEyeReportPreviewForm FORM Class contained in the MindsEyeReportEngine Visual Class Library, you MUST RENAME the control to oReportEngine. Failing to rename the control will cause the ReportFormPreview(), ReportToPDF(), ReportFormObject() and other methods of the MindsEyeReportEngine Class definition not to run because they are expecting the ActiveX OLECONTROL Object to be named oReportEngine.

Running VFP Reports

The Mind's Eye Report Engine ActiveX control has several special methods that were added specifically for use with Visual FoxPro. These methods are used to help the control process and run Visual FoxPro FRX Reports. In order to run a VFP Report, you will need to use the included VFP Class Library MindsEyeReportEngine.VCX. This library contains the MindsEyeReportEngine class that has Methods and Properties to process and run most standard VFP FRX Reports.

To run a VFP Report in Visual FoxPro 6 and above, place the following code into your program:

SET CLASSLIB TO MindsEyeReportEngine
oRPT = CREATEOBJECT('MindsEyeReportEngine')
oRPT.ReportFormPreview(cReportFileName, nShowWindow, nLeft, nTop, nWidth, nHeight)

Where:
cReportFileName = The FileName of the FRX Report to run including the .FRX file extension.

nShowWindow (optional) =	0 - Opens Report Preview Form in the main VFP Window
                 2 - Opens the Report Preview Form as a Top Level Form.

nLeft (optional) = The Left coordinate location of the Report Preview Form when it is created.

nTop (optional) = The Top coordinate location of the Report Preview Form when it is created.

nWidth (optional) = The Width of the Report Preview Form when it is created.

nHeight (optional) = The Height of the Report Preview Form when it is created.
.topic 14400
MONDAY MAY 23, 2005
06:55AM -
Worked on the CS MODE code for Scrollable windows.

MONDAY MAY 30, 2005
08:30AM - 12:30PM
Worked on the Save As Image Dialog box and cleaned up the support for the text entries. Also, added an ESCAPE to the Loop for saving to images.
04:30PM - :PM
Worked on the CS Mode code to cleanly scroll the pages.

.topic 16000
PDFOne .NET - All-in-One PDF library for .NET: Create, Manage, Transform...

Version 1.43 - February 8, 2008
Enhancements:
- Support for embedding fonts in an existing PDF. (Previously, font embedding was supported only in creation mode.) [Professional]
- Compatibility with v1.43 of Professional edition [Create, Bookmark, Forms, Stamp & Merge n Split]
Fixes:
- Adding annotations to a rotated page. [Professional & Forms]
- Inability to read PDF dictionary comments containing numbers. [Bookmark, Forms, Stamp & Merge n Split]
- Errors occurring when loading certain types of PDF documents. [Bookmark, Forms, Stamp & Merge n Split]
- Drawing image watermarks. [Professional, Standard & Stamp]

Version 2.0 Preview - December 5, 2007
Enhancements:
[Professional]
- Support for CCITT4 images in viewer.
- Improved rendering in viewer.
- Support for adding annotations to a rotated page.
Fixes:
- Errors occuring when loading certain types of PDF documents.

Version 2.0 Beta - July 4, 2007
- Introduced PDF viewer component
- Introduced PDF printer component
and several fixes.

Version 1.42 - March 26, 2007
- Support for measuring text width in a particular font. [Professional, Standard, Create & Stamp]
- Support for specifying System.Drawing.Bitmap objects for drawing watermarks [Professional, Standard & Stamp]
- Support for creating rotated watermarks [Professional, Standard & Stamp]
- Support for retrieving fully qualified names of form fields [Professional & Forms]

Version 1.41 - January 16, 2007
Enhancements:
[PDFOne .NET Standard]
- Support for splitting PDF files based on numbers of pages and page range.
- Support for reading actions specified for link annotations.

[PDFOne .NET Create Version 1.0]
- Support for reading PDF content from files and memory streams.
- Support for saving PDF content to files and memory streams.
- Support for rendering shapes such as circle, bezier curves, and rectangle.
- Support for rendering images of all image formats supported by the .NET framework.
- Support for Unicode text rendering.
- Support for full and subset embedding of TTC, TrueType and OpenType fonts.
- Support for changing default page layout.
- Support for changing default document view (page mode).
- Support for reading XML metadata of a document.
- Support for 40-bit and 128-bit encryption.
- Support for changing user permissions. (Requires owner password.)
- Support for reading password protected documents. (Requires password.)
- Support for reading and writing viewer preferences properties.
- Support for reading and writing document information properties.
- Support for Unicode document information.
- Support for e-mailing the document after it is saved to a file.
- Support for printing the output PDF file (with Adobe Reader) immediately after it is created.
- Support for opening the output PDF file (with Adobe Reader) immediately after it is created.

[PDFOne .NET Bookmark Version 1.0]
- Support for adding new bookmarks and editing existing bookmarks with unlimited nesting levels.
- Support for adding actions to bookmarks (URI, go-to, remote go-to, launch, and JavaScript].
- Support for deleting existing bookmarks.
- Support for setting and removing thumbnail images.

[PDFOne .NET Forms Version 1.0]
- Support for adding/reading/editing/deleting various types of annotations such as circle, file attachment, link, and free text.
- Support for custom appearance for all annotations except link and popup annotations.
- Support for adding/reading/editing/deleting various types of form fields such as text fields, combo boxes, and radio buttons.
- Support for flattening of form fields.
- Support for importing/exporting form fields to FDF (Forms Data Format).

[PDFOne .NET Stamp Version 1.0]
- Support for inserting watermarks and stamps with text and images.
- Support for adding/reading/editing/deleting stamp annotations.

[PDFOne .NET Merge n Split Version 1.0]
- Support for merging multiple documents.
- Support for inserting pages from one document to another.
- Support for appending pages from one document at the end of another.
- Support for extracting pages from documents to create new ones.
- Support for splitting PDF files based on numbers of pages and page range.

Version 1.4 - December 15, 2006
Enhancements:
[Professional Edition]
- Support for embedding document-level file attachments.
- Support for retrieving embedded document-level file attachments.

[Standard]
- Support for printing the output PDF file (with Adobe Reader) when it is created.
- New overloaded DrawImage method for specifying System.Drawing.Bitmap instance as parameter.

Version 1.3 - November 20, 2006
Enhancements:
[Professional Edition]
- Support for page stitching (side by side, one above another, or with specified offsets).
- Support for changing existing page dimensions.
- Support for creating and editing watermark annotations.

[Standard]
- Support for rendering transparent text, images, and shapes.

Version 1.2 - October 13, 2006
Enhancements:
[Professional Edition]
- ImportFDF (Forms Data Format) introduced in PDFDocument to import FDF document to PDF.
- Support for flattening of form fields introduced in PDFPage and PDFDocument.
- Named action enhanced to support actions like search, print, rotate etc.

[Standard Edition]
- SetColorSpace method introduced in PDFPage to support CMYK colorspace.
- MergeBookmarks event introduced to set root bookmark for bookmarks of each document while merging documents.
Changes:
[Standard Edition]
- Setting OpenAfterCreate property to true now opens the created PDF after saving instead of after closing the PDFDocument object.

Version  1.12 - September 15, 2006
Enhancements:
[Professional Edition]
- Exporting form fields to FDF (Forms Data Format) introduced.
- Support for deletion of form fields introduced.
- Support for new predefined variables/expressions to print Path, File Path, Filename, Author introduced in all text writing methods.
- WriteText and DrawImage methods introduced in PDFAppearanceStream class to allow adding of custom text and images to annotations to change/enhance their appearance.
- Support for creation of form field hierarchy with heterogeneous field types at document and page level introduced.
- Support for editing of hierarchical form fields with heterogeneous fields at document and page level introduced.

[Standard Edition]
- Support for writing text and images to header and footer introduced in PDFDocument class.

Version 1.11 - August 16, 2006
Enhancements:
[Professional Edition]
- Enumeration PDFFormFieldType introduced to select required form field type(s).
- New overloaded version of GetAllAnnotations in class PDFDocument now supports page ranges.
- New overloaded version of GetAllFormFields in class PDFDocument now supports page ranges.
- New overloaded version of GetAllFormFields in class PDFDocument and class PDFPage now takes enumeration PDFFormFieldType to specify required field type(s).
- New overloaded version of GetAllFormFields in class PDFDocument and class PDFPage now takes external list to read form fields into.

[Standard Edition]
- Support for predefined variables/expressions to print date, time, page number and total page number introduced in all text writing methods.

- Support for BDS 2006 for .NET 1.1.

Version 1.1 - August 1, 2006
Enhancements:
[Professional Edition]
- Stamp annotation introduced. Use PDFStampAnnot.
- Support for custom appearance for all annotations except link and popup annotations. Use PDFAppearanceStream and set DownAppearance, NormalAppearance and RollOverAppearance.
- Support for custom popup window for all annotations except link and popup annotations. Use PDFPopupAnnot.
- BorderWidth property introduced for all form fields.
- Reading of annotations optimized.
- Reading of selective annotation types at document and page level introduced.
- New constructors introduced for all annotations with additional parameters to ease creation of objects and initializing properties.

[Standard Edition]
- Font handling completely re-implemented. Component file size reduced (~1MB) and performance drastically improved.

+ Ready to run sample codes snippets included under "<PDFOne .NET install dir>\Samples".
+ Documentation enhanced.
Fixes:
[Professional Edition]
- Page display duration now works even if no presentation is set.
- BorderColor and BackgroundColor of all form fields now works correctly if set to transparent.
Changes:
[Professional Edition]
- SetAllAnnotations is removed in PDFDocument and PDFPage. No need to call SetAllAnnotations after setting properties of annotations.

Version 1.0.3 - June 5, 2006
Enhancements:
[Professional Edition]
- Enhanced Reading of Form Fields for PDFDocument and PDFPage.
- CustomSymbol property introduced to support Custom Symbols for CheckBox.
- AddItem now takes two string parameters to support ExportValue for PDFFormListBox.
- FieldName property introduced for PDFFormRadioButton.
- Visible property introduced for PDFFormRadioButton.
- Printable property introduced for PDFFormRadioButton.
- DefaultSelectedItemIndex property introduced for PDFFormRadioButton.
- CustomSymbol property introduced to support Custom Symbols for RadioItem.
- AutoAdjustColumnHeight has been renamed to AutoAdjustRowHeight for PDFTable.
- AddCell method now takes additional parameters for specifying Font, Backgroundcolor, Text Alignment etc for creating a table.

[Standard Edition]
- DrawBezierCurve method now takes two control points to draw Bezier Curves in PDFDocument and PDFPage.
Fixes:
[Professional Edition]
- AddTable method now works correctly in PDFDocument and PDFPage.
- DrawArc method now works correctly in PDFDocument and PDFPage.
- DrawPie method now works correctly in PDFDocument and PDFPage.
- Background and Border color for FormFields can now be changed correctly.
- DefaultValue property of ListBox now gets correctly set when the form is reset.
- RadioButtons now work correctly when AtLeastOneSelectedItem property is set to false.
Changes:
[Professional Edition]
- DefaultValue property in PDFFormListBox has now been removed, DefaultSelectedIndex should be used instead.
- DoNotSpellCheck property has been removed in PDFFormListBox.

Version 1.0.2 - May 11, 2006
Enhancements:
[Professional Edition]
- ApplyFormAppearances property introduced to allow setting of NeedAppearance flag for FormFields in PDFDocument.
- New constructor introduced for PDFormPushButton, which takes RectangleF parameter.

[Standard Edition]
- HighlightMode property introduced to give different highlighting mode for link annotation in PDFLinkAnnot.
Changes:
[Professional Edition]
- GetFormFields method has been renamed to GetAllFormFields in PDFDocument and PDFPage.
- SetFormField method has been renamed to SetAllFormFields in PDFDocument and PDFPage.
- GetAnnotations method has been renamed to GetAllAnnotations in PDFDocument and PDFPage.
- SetAnnotations method has been renamed to SetAllAnnotations in PDFDocument and PDFPage.

Version 1.0.1 - March 16, 2006
Enhancements:
[Professional Edition]
- Title property introduced for PDFFileAttachmentAnnot.
- Subject property introduced for PDFFileAttachment annotation.

[Standard Edition]
- Load method now also takes stream as parameter to support loading of PDF documents in stream.
- DrawPath method now takes pen, brush and measurementUnit parameters in PDFDocument.

Version 1.0 - March 3, 2006
PDFOne .NET v1.0 Released.
.topic 14200
SWITCHABLE DISPLAY PAGE MODE SUPPORT
NEW PROPERTY: DisplayPageBorderSize = The size of the Page Border in Pixels between the page and the edge of the Report Preview Window. (Default Value: 20).

BUGS: SWITCHABLE DISPLAY PAGE MODE SUPPORT
BUG: FIT TO PAGE SCALING mode needs to RESCALE for each and every page when in SINGLE PAGE mode so that the page Maximizes to the Size of the Report Preview.
BUG: Using the SCROLLING MODE SCROLL Bar with a LARGE NUMBER of pages passes the SCROLLPAGES() Method a LARGE Vertical Scroll DELTA VALUE which then causes the pages to Disappear. This will require a New Function that can calculate from the amount of the Offset passed what PAGE to jump to and then start painting again from that page.
BUG: Change the LARGE CHANGE of the Vertical Scrollbar to be the SCROLLBOX HEIGHT, so that the control moves chunks of pages from one to the next.
BUG SP MODE: RESIZEEVENT is centering the page differently depending on whether or not the entire page can be seen or not. I think there are 2 different versions of the PAINTPAGES code being called.
BUG SP MODE: RESIZEEVENT is causing resetting the page Vertically when the width of the form is being changed. The PAINTPAGES() Method is recentering the pages with each RESIZEEVENT. NOTE: The first pull of a RESIZE is completely moving the page on the SCROLLBOX if the POSITION of the SCROLLBARS are not at 0.
BUG CS MODE: PULLING DOWN to scroll to an earlier page is not scrolling anymore. It stops when the top page hits the border size.

When dragging the SCROLLBOX in CS MODE and we need to repaint the pages down the scrollbox because a page scrolled off the TOP of the display then we need to REMAP all of the NPAGENUMBER values to the SHAPE PAGE OBJECTS and repaint them. Since we are moving the display we also need to tell the top Page Object what VERTICAL POSITION it needs to start painting at so it can continue from where it left off.

STEPS TO MOVING PAGES VERTICALLY
1.	Store the position of the 2nd page object or track it at all times as we paint the pages.
2.	Reset the SHPPAGE object to the same Position and Size of the 2nd page object
3.	Set the nPageNumber to the 2nd page
4.	Repaint the pages WITHOUT SCALING.
5.

KEY DESIGN POINTS

MOUSEWHEEL Support needs to be added both for ZOOMING and for SCROLLING from Page to Page.
Multiple copies of the PAGEOBJECT must be instantiated and all painted at once.
Each page must take a PAGENUMBER as a parameter and be able to paint itself at the position specified
Custom Scrollbars will need to be used to control that scrolling and positioning of the Page Objects on the screen
More than one page will need to be able to be displayed at a time in the Continuous Scrollmode
Each page will need to support MOUSEWHEEL and MOUSEMOVE support so objects can be picked off of the page by number when processed by the event.
The PAGEOBJECT needs to be based upon the SHAPE object and support the normal mouse over events.
TRACKING PROPERTIES
Number of Pages Visible
Pages to display at Once
Possible support of Side By Side Continuous Scrolling Page Support
PageFirst - The First Visible Page when in Continous mode
PageLast - The Last Visible Page when in Continous Mode
DisplayPageMode - (0 = Single Page, 1 = 2 Page, 2 = 4 Page, 3 = 1 - Page Continuous, 4 = Facing Pages Continuous)

CONTINUOUS SCROLLING MODE RULES
When scaled to more than will fit onto the page then ONLY 2 PAGE OBJECTS need to be mapped and populated and/or drawn.
Compute How many Page Objects Will fit into the Viewable area.
Create Method to detect if a Page is in the Viewable area and needs to be displayed before rendering.
Function to determine when to INCREMENT the Current Page Number.
External Method to Scroll the Pages in the Report Engine
Add Support for Bookmarks
SCROLLING RULES:
15 PIXELS per click on the Scroll Buttons
One Entire window View scroll when clicking on the Scrollbar in either Direction. So, move by the number of pixels of the view port.

It would be better to track what pages are viewable in an ARRAY and then populate ONLY those shapes that are needed to be displayed on the fly by mapping the shapes to the array.
Change the PAGENUMBER when the next page breaks past the CENTER of the page vertically.

FIXES TO MAKE:
MAKE SURE PAGES STAY CENTERED ON THE DISPLAY

KISS APPROACH
Always map the PAGE OBJECTS so that Page Object 1 IS ALWAYS AT THE TOP. It is either FULLY Visible or the bottom of the page is Visible on it. No More than 1 page will ever be mapped above the Top Viewable Area of the SCROLLBOX.
ALWAYS MAP from PAGE OBJECT 1 Downward and simply set the NPAGENUMBER value of the PAGE OBJECT until a PAGE OBJECT goes out of View.
When the Next Page comes into View then REMAP.
TRACK THE PIXEL HEIGHT of each page so that you can MAP back to the PAGE SCROLL BAR.
TRACK TOP VIEWABLE PAGE. This will then be used for the mapping of the PAGE OBJECTS.

[PICTURE clip0011.bmp]

.topic 15000
HOWTO: Print Using Custom Page Sizes on Windows NT and Windows 2000
The information in this article applies to:(??)
Microsoft Visual Basic Professional Edition for Windows 6.0
Microsoft Visual Basic Enterprise Edition for Windows 6.0

This article was previously published under Q282474
SUMMARY
Microsoft Windows 95, Windows 98, and Windows Millennium Edition (Me) are flexible on custom, user-defined page sizes. However, on systems that are running Windows NT and Windows 2000, you must define all page sizes as a form before you can use them. This article describes how to print custom page sizes on Windows NT and Windows 2000 and includes a code sample that demonstrates how to add, select, and delete custom forms.

NOTE: Because of the behavior of the Visual Basic 5.0 Printer object, the changes to the DEVMODE that are made by the call to ResetDC has no effect. Thus, the code sample in this article does not work from Visual Basic 5.0.

This article is divided into the following sections:

DEVMODE Members That Define or Select Page Size
How to Programmatically Select a Form
Form Sources and Functions
Steps to Add a Local Print Driver for a Network Printer
Step-by-Step Example
MORE INFORMATIONDEVMODE Members That Define or Select Page Size
Printer drivers store their default settings in a structure called the DEVMODE. W
hen you define or select a page size, four members of this structure may be invol
ved:

dmPaperSize
dmPaperLength
dmPaperWidth
dmFormName
The dmPaperLength and dmPaperWidth members contain values on all operating system
s, but they can only be used to select or define a size on systems that are runni
ng Windows 95, Windows 98, or Windows Me. The dmFormName member is only valid for
systems that are running Windows NT or Windows 2000. The dmPaperSize member can
be used on any 32-bit Windows operating system, as long as the value that is assi
gned to it corresponds to a size or form that is defined on that system.

Thus, on systems that are running Windows 95, Windows 98, or Windows Me, you can
define custom page sizes by height (length) and width or by a predefined paper si
ze. Windows NT-based or Windows 2000-based systems only use defined forms for pag
e sizes, which you can select in one of two ways: set dmFormName or assign a vali
d "constant" value to dmPaperSize.

To use a particular paper size on Windows NT or Windows 2000, you must define a f
orm for it. The Visual Basic Printer object has PageSize, Height, and Width prope
rties that expose the dmPaperSize, dmPaperLength, and dmPaperWidth members of the
DEVMODE. However, the Printer object does not expose a way to select a form by n
ame, nor does it have a method to add a custom form at run time. We must use the
Win32 application programming interface (API) to create a custom form and/or sele
ct a form by name.
How to Programmatically Select a Form
This article uses the EnumForms basic process to list all forms that are supporte
d for the current printer and to check the height and width of each form. If the
specified size is found, it is selected. If it is not found, the code adds the fo
rm and then selects it.

There are three ways to programmatically select a form:
Retrieve the printer's DEVMODE structure, set the dmFormName member, and use the
ResetDC function to set this form as the current form for the Device Context (DC)
of the printer. When this form is selected for the DC, it is only selected for t
he calling process and does not change the driver's default setting. This does no
t require any special permissions. This method is preferred for applications that
change a printer's settings.
Call the SetForm function to change the default form for the printer driver. This
method requires full access permissions to the driver. When the default form is
changed, it affects every application that uses this driver to print. If this is
a network printer, most users do not have the necessary permissions to make this
call.
Assign the system-defined value for the custom form to Printer.PaperSize.
Only the first method is demonstrated in this article's sample code; the sample d
oes not demonstrate the call to SetForm or the value assignment to Printer.PaperS
ize. The sample captures the system-assigned value of the new custom form by retu
rning the value of its ordinal position in the list that EnumForms returns. Note
that this only works for custom forms. Predefined forms have constant values assi
gned to them that do not correspond to their ordinal position in this list.

When you use the AddForm function to add your custom form, the form is given its
own number, if available, which then remains consistent across all printers that
use the form. In this case, the form is defined and given a "constant" value for
the current system. You can then assign this value to Printer.PaperSize to select
it. However, because the number assignment is simply one more than the number of
forms that is listed for the current printer when the form was added, this numbe
r may not be available because a predefined form is already using that number. Th
erefore, it is not recommended that you use this value to select a form, and this
value is not demonstrated here. If you use this number assignment, and the value
for it is unavailable, it will either select the wrong form or raise run-time er
ror 380: "Invalid Property value."
Form Sources and Functions
Most forms are defined by the operating system and are available to all local pri
nters. However, forms for network printers are defined on the printer server. Som
e forms may be defined specifically for a given printer driver and only appear in
the list for that driver. Another source for forms is custom-defined or user-def
ined forms, which can be created manually or through code and are available to al
l local printers on the system. Both printer-specific and user-defined forms are
stored in the registry.

The sample in this article uses a few function calls that are related to forms. B
riefly, the key functions are as follows:

Function Description
EnumForms Returns information about all of the forms that are supported for the c
urrent printer.
AddForm Adds a custom form to the system. The data on this form is stored in the
registry. Thus, custom forms are available for all printers, not just the printer
that was current when the form was added. The numeric value that the system assi
gns to this form is simply one number higher than the number of forms that EnumFo
rms returns for the current printer. You must have full rights to the driver to c
all this function. If you cannot add a form manually, this function call also fai
ls for you. For this reason, you usually cannot use this function on network prin
ters.
DeleteForm Removes a custom form. However, this function does not delete the stan
dard forms that the operating system defines and returns error code 87 if this is
attempted. This function also requires the same rights as AddForm.

Although the sample does not use the following functions, it does include the Declares for these functions:

Function Description
GetForm Retrieves information about a specific form.
SetForm Sets the default form information for the specified printer. This function requires full rights, just as changing any printer driver setting does.

It must be emphasized that some of these functions require Full Control permissio
ns on the printer. Therefore, the SetForm, AddForm, and DeleteForm functions almo
st never work for printers that are installed as "network printers." This is beca
use the drivers for network printers are not installed locally but reside on the
printer server, and your User account is unlikely to have Administrator rights on
the printer server. This differs from systems that are running Windows 95, Windo
ws 98, or Windows Me, in which all printer drivers (even network printers) are al
ways installed locally. However, you can install network printers as local printe
rs in Windows NT or Windows 2000 and set the Port to the printer queue. Then you
can use these functions to make changes without affecting other users who share t
he printer.
Steps to Add a Local Printer Driver for a Network Printer
On the Start menu, point to Settings, and then click Printers. Double-click Add P
rinter to start the Add Printer Wizard.
When prompted, make sure that you click Local printer or My Computer and NOT Netw
ork printer. Although you will connect to a network printer, you want to use a dr
iver on My Computer. Click Next to continue.
On Windows NT, click Add Port. On Windows 2000, click Create a new port.
In the drop-down list box, click Local Port. On Windows NT, click New Port. On Windows 2000,
click Next, and you are prompted for a Port Name.

Type the location of the printer on the network. For example: \\printserver\printername

where you use the exact path name to the printer.
Click OK, and complete the wizard.
If you change the printer properties for the active printer, you still affect all
applications that use that printer, but only for the local system.

IMPORTANT When you use custom page sizes, the behavior differs between Laser or Ink Jet printers and Dot Matrix or impact printers. Obviously, no printer accepts a page size that is wider than it can physically accommodate. But printers that use continuous feed paper can be flexible on page sizes because they print one line at a time. Alternately, Laser and Ink Jet printers print one page at a time. Thus, for example, when you print to a Dot Matrix printer (which uses continuous feed paper), you can easily see the page length during a form feed because the printer advances to the place where it expects the top of the next page to start, regardless of the physical size of the paper that it is using. On Laser and Ink Jet printers, a form feed always ejects a full physical page regardless of the page size it expects. Also, on most Laser printers, the display reads "Load Custom" (or
similar) when you ask the printer to print on a user-defined page size.

Step-by-Step Example
Set a local printer as the default printer. To do this, follow these steps:
On the Start menu, point to Settings, and then click Printers.
Right-click the icon for a local printer, and then click Set as default.
Start a new Standard EXE project in Visual Basic. Form1 is created by default.
Add three CommandButtons and a ListBox control to Form1.
Paste the following code into the module of Form1:
Option Explicit

Private Sub Command1_Click()
Dim FormName As String

FormName = "MyCustomForm" ' Use special, user-defined form.
UseForm FormName
End Sub

Private Sub Command2_Click()
Dim FormName As String

' Get FormName from the ListBox.
On Error GoTo ListBoxERR ' Trap for no selection.
FormName = Mid(List1.Text, 1, InStr(1, List1.Text, " -") - 1)
On Error GoTo 0 ' Turn off Error trap.

UseForm FormName

Exit Sub
ListBoxERR:
MsgBox "Select a printer from the ListBox before using this option.", _
vbExclamation
End Sub

Private Sub Command3_Click()
Dim RetVal As Long
Dim PrinterHandle As Long ' Handle to printer
Dim PrinterName As String
Dim FormName As String
Dim Continue As Long

' Delete form that is selected in ListBox.
PrinterName = Printer.DeviceName ' Current printer
If OpenPrinter(PrinterName, PrinterHandle, 0&) Then

On Error GoTo ListBoxERR ' Trap for no selection.
FormName = Mid(List1.Text, 1, InStr(1, List1.Text, " -") - 1)
On Error GoTo 0 ' Turn off Error trap.

Continue = MsgBox("Are you sure you want to permanently remove " & _
FormName & " from " & PrinterName & "?", vbYesNo)
If Continue = vbYes Then
RetVal = DeleteForm(PrinterHandle, FormName & Chr(0))
If RetVal <> 0 Then ' DeleteForm succeeded.
List1.Clear ' Reflect the deletion in the ListBox.
Form_Load ' Rebuild the list.
MsgBox FormName & " deleted!", vbInformation, "Success!"
Else
MsgBox FormName & " not deleted!" & vbCrLf & vbCrLf & _
"Error code: " & Err.LastDllError, vbInformation, "Failure!"
End If
End If
ClosePrinter (PrinterHandle)
End If

Exit Sub
ListBoxERR:
MsgBox "Select a printer from the ListBox before using this option.", _
vbExclamation
ClosePrinter (PrinterHandle)
End Sub

Private Sub Form_Load()
Dim NumForms As Long, I As Long
Dim FI1 As FORM_INFO_1
Dim aFI1() As FORM_INFO_1 ' Working FI1 array
Dim Temp() As Byte ' Temp FI1 array
Dim BytesNeeded As Long
Dim PrinterName As String ' Current printer
Dim PrinterHandle As Long ' Handle to printer
Dim FormItem As String ' For ListBox
Dim RetVal As Long
Dim FormSize As SIZEL ' Size of desired form

PrinterName = Printer.DeviceName ' Current printer
If OpenPrinter(PrinterName, PrinterHandle, 0&) Then
With FormSize ' Desired page size
.cx = 214000
.cy = 216000
End With
ReDim aFI1(1)
RetVal = EnumForms(PrinterHandle, 1, aFI1(0), 0&, BytesNeeded, _
NumForms)
ReDim Temp(BytesNeeded)
ReDim aFI1(BytesNeeded / Len(FI1))
RetVal = EnumForms(PrinterHandle, 1, Temp(0), BytesNeeded, _
BytesNeeded, NumForms)
Call CopyMemory(aFI1(0), Temp(0), BytesNeeded)
For I = 0 To NumForms - 1
With aFI1(I)
' List name and size including the count (index).
FormItem = PtrCtoVbString(.pName) & " - " & .Size.cx / 1000 & _
" mm X " & .Size.cy / 1000 & " mm (" & I + 1 & ")"
List1.AddItem FormItem
End With
Next I
ClosePrinter (PrinterHandle)
End If
End Sub

Private Sub UseForm(FormName As String)
Dim RetVal As Integer

RetVal = SelectForm(FormName, Me.hwnd)
Select Case RetVal
Case FORM_NOT_SELECTED ' 0
' Selection failed!
MsgBox "Unable to retrieve From name", vbExclamation, _
"Operation halted!"
Case FORM_SELECTED ' 1
' Selection succeeded!
PrintTest ' Comment this line to avoid printing
Case FORM_ADDED ' 2
' Form added and selected.
List1.Clear ' Reflect the addition in the ListBox
Form_Load ' by rebuilding the list.
End Select
End Sub

From the Project menu, add a new Module, Module1.
Paste the following code into Module1:
Option Explicit

Public Declare Function EnumForms Lib "winspool.drv" Alias "EnumFormsA" _
(ByVal hPrinter As Long, ByVal Level As Long, ByRef pForm As Any, _
ByVal cbBuf As Long, ByRef pcbNeeded As Long, _
ByRef pcReturned As Long) As Long

Public Declare Function AddForm Lib "winspool.drv" Alias "AddFormA" _
(ByVal hPrinter As Long, ByVal Level As Long, pForm As Byte) As Long

Public Declare Function DeleteForm Lib "winspool.drv" Alias "DeleteFormA" _
(ByVal hPrinter As Long, ByVal pFormName As String) As Long

Public Declare Function OpenPrinter Lib "winspool.drv" _
Alias "OpenPrinterA" (ByVal pPrinterName As String, _
phPrinter As Long, ByVal pDefault As Long) As Long

Public Declare Function ClosePrinter Lib "winspool.drv" _
(ByVal hPrinter As Long) As Long

Public Declare Function DocumentProperties Lib "winspool.drv" _
Alias "DocumentPropertiesA" (ByVal hwnd As Long, _
ByVal hPrinter As Long, ByVal pDeviceName As String, _
pDevModeOutput As Any, pDevModeInput As Any, ByVal fMode As Long) _
As Long

Public Declare Function ResetDC Lib "gdi32" Alias "ResetDCA" _
(ByVal hdc As Long, lpInitData As Any) As Long

Public Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" _
(hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)

Public Declare Function lstrcpy Lib "KERNEL32" Alias "lstrcpyA" _
(ByVal lpString1 As String, ByRef lpString2 As Long) As Long

' Optional functions not used in this sample, but may be useful.
Public Declare Function GetForm Lib "winspool.drv" Alias "GetFormA" _
(ByVal hPrinter As Long, ByVal pFormName As String, _
ByVal Level As Long, pForm As Byte, ByVal cbBuf As Long, _
pcbNeeded As Long) As Long

Public Declare Function SetForm Lib "winspool.drv" Alias "SetFormA" _
(ByVal hPrinter As Long, ByVal pFormName As String, _
ByVal Level As Long, pForm As Byte) As Long

' Constants for DEVMODE
Public Const CCHFORMNAME = 32
Public Const CCHDEVICENAME = 32
Public Const DM_FORMNAME As Long = &H10000
Public Const DM_ORIENTATION = &H1&

' Constants for PRINTER_DEFAULTS.DesiredAccess
Public Const PRINTER_ACCESS_ADMINISTER = &H4
Public Const PRINTER_ACCESS_USE = &H8
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
Public Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or _
PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)

' Constants for DocumentProperties() call
Public Const DM_MODIFY = 8
Public Const DM_IN_BUFFER = DM_MODIFY
Public Const DM_COPY = 2
Public Const DM_OUT_BUFFER = DM_COPY

' Custom constants for this sample's SelectForm function
Public Const FORM_NOT_SELECTED = 0
Public Const FORM_SELECTED = 1
Public Const FORM_ADDED = 2

Public Type RECTL
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type

Public Type SIZEL
cx As Long
cy As Long
End Type

Public Type SECURITY_DESCRIPTOR
Revision As Byte
Sbz1 As Byte
Control As Long
Owner As Long
Group As Long
Sacl As Long ' ACL
Dacl As Long ' ACL
End Type

' The two definitions for FORM_INFO_1 make the coding easier.
Public Type FORM_INFO_1
Flags As Long
pName As Long ' String
Size As SIZEL
ImageableArea As RECTL
End Type

Public Type sFORM_INFO_1
Flags As Long
pName As String
Size As SIZEL
ImageableArea As RECTL
End Type

Public Type DEVMODE
dmDeviceName As String * CCHDEVICENAME
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * CCHFORMNAME
dmUnusedPadding As Integer
dmBitsPerPel As Long
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type

Public Type PRINTER_DEFAULTS
pDatatype As String
pDevMode As Long ' DEVMODE
DesiredAccess As Long
End Type

Public Type PRINTER_INFO_2
pServerName As String
pPrinterName As String
pShareName As String
pPortName As String
pDriverName As String
pComment As String
pLocation As String
pDevMode As DEVMODE
pSepFile As String
pPrintProcessor As String
pDatatype As String
pParameters As String
pSecurityDescriptor As SECURITY_DESCRIPTOR
Attributes As Long
Priority As Long
DefaultPriority As Long
StartTime As Long
UntilTime As Long
Status As Long
cJobs As Long
AveragePPM As Long
End Type

Public Function GetFormName(ByVal PrinterHandle As Long, _
FormSize As SIZEL, FormName As String) As Integer
Dim NumForms As Long, I As Long
Dim FI1 As FORM_INFO_1
Dim aFI1() As FORM_INFO_1 ' Working FI1 array
Dim Temp() As Byte ' Temp FI1 array
Dim FormIndex As Integer
Dim BytesNeeded As Long
Dim RetVal As Long

FormName = vbNullString
FormIndex = 0
ReDim aFI1(1)
' First call retrieves the BytesNeeded.
RetVal = EnumForms(PrinterHandle, 1, aFI1(0), 0&, BytesNeeded, NumForms)
ReDim Temp(BytesNeeded)
ReDim aFI1(BytesNeeded / Len(FI1))
' Second call actually enumerates the supported forms.
RetVal = EnumForms(PrinterHandle, 1, Temp(0), BytesNeeded, BytesNeeded, _
NumForms)
Call CopyMemory(aFI1(0), Temp(0), BytesNeeded)
For I = 0 To NumForms - 1
With aFI1(I)
If .Size.cx = FormSize.cx And .Size.cy = FormSize.cy Then
' Found the desired form
FormName = PtrCtoVbString(.pName)
FormIndex = I + 1
Exit For
End If
End With
Next I
GetFormName = FormIndex ' Returns non-zero when form is found.
End Function

Public Function AddNewForm(PrinterHandle As Long, FormSize As SIZEL, _
FormName As String) As String
Dim FI1 As sFORM_INFO_1
Dim aFI1() As Byte
Dim RetVal As Long

With FI1
.Flags = 0
.pName = FormName
With .Size
.cx = FormSize.cx
.cy = FormSize.cy
End With
With .ImageableArea
.Left = 0
.Top = 0
.Right = FI1.Size.cx
.Bottom = FI1.Size.cy
End With
End With
ReDim aFI1(Len(FI1))
Call CopyMemory(aFI1(0), FI1, Len(FI1))
RetVal = AddForm(PrinterHandle, 1, aFI1(0))
If RetVal = 0 Then
If Err.LastDllError = 5 Then
MsgBox "You do not have permissions to add a form to " & _
Printer.DeviceName, vbExclamation, "Access Denied!"
Else
MsgBox "Error: " & Err.LastDllError, "Error Adding Form"
End If
AddNewForm = "none"
Else
AddNewForm = FI1.pName
End If
End Function

Public Function PtrCtoVbString(ByVal Add As Long) As String
Dim sTemp As String * 512, x As Long

x = lstrcpy(sTemp, ByVal Add)
If (InStr(1, sTemp, Chr(0)) = 0) Then
PtrCtoVbString = ""
Else
PtrCtoVbString = Left(sTemp, InStr(1, sTemp, Chr(0)) - 1)
End If
End Function

Public Function SelectForm(FormName As String, ByVal MyhWnd As Long) _
As Integer
Dim nSize As Long ' Size of DEVMODE
Dim pDevMode As DEVMODE
Dim PrinterHandle As Long ' Handle to printer
Dim hPrtDC As Long ' Handle to Printer DC
Dim PrinterName As String
Dim aDevMode() As Byte ' Working DEVMODE
Dim FormSize As SIZEL

PrinterName = Printer.DeviceName ' Current printer
hPrtDC = Printer.hdc ' hDC for current Printer
SelectForm = FORM_NOT_SELECTED ' Set for failure unless reset in code.

' Get a handle to the printer.
If OpenPrinter(PrinterName, PrinterHandle, 0&) Then
' Retrieve the size of the DEVMODE.
nSize = DocumentProperties(MyhWnd, PrinterHandle, PrinterName, 0&, _
0&, 0&)
' Reserve memory for the actual size of the DEVMODE.
ReDim aDevMode(1 To nSize)

' Fill the DEVMODE from the printer.
nSize = DocumentProperties(MyhWnd, PrinterHandle, PrinterName, _
aDevMode(1), 0&, DM_OUT_BUFFER)
' Copy the Public (predefined) portion of the DEVMODE.
Call CopyMemory(pDevMode, aDevMode(1), Len(pDevMode))

' If FormName is "MyCustomForm", we must make sure it exists
' before using it. Otherwise, it came from our EnumForms list,
' and we do not need to check first. Note that we could have
' passed in a Flag instead of checking for a literal name.
If FormName = "MyCustomForm" Then
' Use form "MyCustomForm", adding it if necessary.
' Set the desired size of the form needed.
With FormSize ' Given in thousandths of millimeters
.cx = 214000 ' width
.cy = 216000 ' height
End With
If GetFormName(PrinterHandle, FormSize, FormName) = 0 Then
' Form not found - Either of the next 2 lines will work.
'FormName = AddNewForm(PrinterHandle, FormSize, "MyCustomForm")
AddNewForm PrinterHandle, FormSize, "MyCustomForm"
If GetFormName(PrinterHandle, FormSize, FormName) = 0 Then
ClosePrinter (PrinterHandle)
SelectForm = FORM_NOT_SELECTED ' Selection Failed!
Exit Function
Else
SelectForm = FORM_ADDED ' Form Added, Selection succeeded!
End If
End If
End If

' Change the appropriate member in the DevMode.
' In this case, you want to change the form name.
pDevMode.dmFormName = FormName & Chr(0) ' Must be NULL terminated!
' Set the dmFields bit flag to indicate what you are changing.
pDevMode.dmFields = DM_FORMNAME

' Copy your changes back, then update DEVMODE.
Call CopyMemory(aDevMode(1), pDevMode, Len(pDevMode))
nSize = DocumentProperties(MyhWnd, PrinterHandle, PrinterName, _
aDevMode(1), aDevMode(1), DM_IN_BUFFER Or DM_OUT_BUFFER)

nSize = ResetDC(hPrtDC, aDevMode(1)) ' Reset the DEVMODE for the DC.

' Close the handle when you are finished with it.
ClosePrinter (PrinterHandle)
' Selection Succeeded! But was Form Added?
If SelectForm <> FORM_ADDED Then SelectForm = FORM_SELECTED
Else
SelectForm = FORM_NOT_SELECTED ' Selection Failed!
End If
End Function

Public Sub PrintTest()
' Print two test pages to confirm the page size.
Printer.Print "Top of Page 1."
Printer.NewPage
' Spacing between lines should reflect the chosen page height.
Printer.Print "Top of Page 2. - Check the page Height (Length.)"
Printer.EndDoc
MsgBox "Check Printer " & Printer.DeviceName, vbInformation, "Done!"
End Sub

Run the project. The ListBox shows all of the forms that the current printer supports.
Click Command1. This adds "MyCustomForm - 214 mm X 216 mm (xxx)" to the end of the list, where "xxx" is the number that is assigned to the new form.
Click a form in the ListBox, and then click Command2. This prints a test page to the current printer using the selected form.
Click the new custom form in the ListBox, and then click Command3. You are prompted to confirm the deletion of the form. If you click Yes, it removes the custom form. If you try this with a predefined form, it raises error 87 because only custom forms can be deleted.
REFERENCESFor more information on the functions and types that are used in this article, see the MSDN Library CD or the Win32 SDK Programmer's Guide.

For additional information on forms, click the article number below to view the a
rticle in the Microsoft Knowledge Base:
157172 How to Create Custom Forms in Windows NT 4.0 and Windows 2000
HOWTO: Use Visual Basic to List Active Logical Drives
The information in this article applies to:
Microsoft Visual Basic Professional Edition for Windows 5.0
Microsoft Visual Basic Professional Edition for Windows 6.0
Microsoft Visual Basic Enterprise Edition for Windows 5.0
Microsoft Visual Basic Enterprise Edition for Windows 6.0
.topic 26200
SMTP Mail and Indy (again)
Having spent a lot of time recently working on a ping scanner using Indy, I noticed that there's a lot of questions still on using SMTP with Indy. Let me first say that I am not an Indy expert. I get along with it successfully but find I still have to research things frequently.

With the disclaimer out of the way, we can get to the offering. A while back I wrote a handy little unit to simply send a mail message with or without attachments and with or without providing authentication. It even has support for OpenSSL. I use this unit in a number of applications and have seen it successfully send hundreds of e-mails without issue. I recently added support for threaded message sending to take advantage of the multi-core system I'm now running on.

This code has had a few additions (like the logger) that I've gleaned over time from various newsgroup postings, but I didn't record the authors so let me credit the anonymous Internet authors who support Indy. It's really amazing how helpful Google can be when you're stuck. At any rate, here's the code for the mailer in the hopes that it will help someone else who is stuck dealing with SMTP.

unit MailIt;

{requires indy10 - the LATER VERSIONS}

interface

uses Classes, SysUtils, IdSMTP, IdLogFile;

type
  //this class encapsulates the "where to" and "what" portions of the message
  //basically, it sends the BODY, including the files in the FILES list, using the SUBJECT to every person on the SendTo, etc. list
  //SendTo, CCSendTo, and BccSendTo all take comma separated addresses (i.e, SendTo:='first@me.com,second@me.com';)
  TDestinationPart = class
                     SendTo    : string; //list of addresses
                     CCSendTo  : string;
                     BccSendTo : string;
                     ReturnAddy: string; //if this is blank, there will be no return receipt

                     Subject   : string;
                     Body      : string;
                     Files     : TStringList;

                     constructor Create(aSndTo, aCCSndTo, aBCCSndTo, aRtrnRcptAddy, aSubject, aBody:string; aFiles:TStringList);
                     destructor Free;
                     end;

  //this class encapsulates the "how do i get it there" and "who from" portion of the message
  //since this doesn't frequently change, you can use CreateFromFile and SaveToFile to create a template
  //   and save the typing every time you set it up
  TOriginPart = class
                AuthType : TIdSMTPAuthenticationType;
                FromAddy : string;
                UserName : string;
                Password : string;
                Server   : string;
                Port     : integer;
                Debug    : boolean;
                constructor Create(aAuthType:TIdSMTPAuthenticationType; aFromAddy, aUserName, aPassword, aServer: string; aPort:integer);
                constructor CreateFromFile(fn:string);
                procedure SaveToFile(fn:string);
                end;

  //this is the entire message
  //you provide a DestinationPart and OriginPart and send the file using SendNow.
  //   Check SentOk afterwards to make sure it went.
  //   Any error message will be in SendMsg
  TMailMessage = class
                 public
                 Destination : TDestinationPart;
                 Origin      : TOriginPart;
                 SentOk      : boolean;
                 SentMsg     : string;
                 logFile     : TIdLogFile;

                 constructor Create(Dest:TDestinationPart; Orig:TOriginPart);
                 procedure SendNow;
                 destructor Free;
                 end;

  //this REPLACES TMailMessage with a Threaded version.
  //You may want to use the FreeOnTerminate flag to create a "Fire and Forget" threaded solution
  //   NOTE: DO NOT GO CRAZY
  //         Pay attention to the documentation of the OS (try this for what I mean http://blogs.msdn.com/oldnewthing/archive/2005/07/29/444912.aspx)
  //         If you've got a really great quad-cpu quad-core rig, you may want to use a bigger number
  TThreadMailMessage = class(TThread)                           //you get no error results or other
                       protected                                //information from this class, it just tries to send the message in the
                          MailMsg : TMailMessage;               //background.make sure you use the debug function if you're having problems
                          procedure Execute; override;
                       public
                          constructor Create(aDestinationPart:TDestinationPart;
                                             aOriginPart:TOriginPart);
                       end;

//NOTE: The following utility entries use CriticalSections. DO NOT HAMMER THEM.

//You can test this to see if all the TThreadedMailMessages have completed
function MailThreadsDone:boolean;
//A count of the number of TThreadedMailMessages are still out there
function ActiveMailThreadCount:integer;

implementation

uses IdGlobal, IdResourceStringsCore, IdGlobalProtocols, IdResourceStrings, IdExplicitTLSClientServerBase,
    IDPOP3, IdMessage, IdEmailAddress, IdWinSock2, IdIOHandler, IdSSLOpenSSL, IdException,
    IdAttachmentFile, IdText, IdSASL_CRAM_MD5, IdUserPassProvider, IniFiles,
    IdIOHandlerStream, Dialogs, windows;

const
  logFileName='mailit.log'; //the default log file name

var
  ActiveMailThreads : integer=0;
  MailThreadCSR     : TRTLCriticalSection;

// ---------------------------------------------------------------------------

type
 // this is a descendant of TidLogFile, it will create a plain text file with
 // information about the transfer session
 TlogFile = class(TidLogFile)
 protected
   procedure LogReceivedData(const AText, AData: string); override;
   procedure LogSentData(const AText, AData: string); override;
   procedure LogStatus(const AText: string); override;
 public
   procedure LogWriteString(const AText: string); override;
   class function buildLogLine(data, prefix: string) : string;
 end;

// this ensures the output of error and debug logs are in the same format, regardless of source
class function TlogFile.buildLogLine(data, prefix: string) : string;
begin

 data := StringReplace(data, EOL, RSLogEOL, [rfReplaceAll]);
 data := StringReplace(data, CR,  RSLogCR,  [rfReplaceAll]);
 data := StringReplace(data, LF,  RSLogLF,  [rfReplaceAll]);

 result := FormatDateTime('yy/mm/dd hh:nn:ss', now) + ' ';
 if (prefix <> '') then
   result := result + prefix + ' ';
 result := result + data + EOL;
end;

// ---------------------------------------------------------------------------

procedure TlogFile.LogReceivedData(const AText, AData: string);
begin
 // ignore AText as it contains the date/time
 LogWriteString(buildLogLine(Adata, '<<'));
end;

// ---------------------------------------------------------------------------

procedure TlogFile.LogSentData(const AText, AData: string);
begin
 // ignore AText as it contains the date/time
 LogWriteString(buildLogLine(Adata, '>>'));
end;

// ---------------------------------------------------------------------------

procedure TlogFile.LogStatus(const AText: string);
begin
 LogWriteString(buildLogLine(AText, '**'));
end;

// ---------------------------------------------------------------------------

procedure TlogFile.LogWriteString(const AText: string);
begin
 // protected --> public
 inherited;
end;

// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
{TMailMessage}
// ---------------------------------------------------------------------------

constructor TMailMessage.Create(Dest:TDestinationPart; Orig:TOriginPart);
begin
Destination:=Dest;
Origin:=Orig;
//the class expects these, it will create them by default
if Destination=nil then Destination:=TDestinationPart.Create('','','','','','',TStringList.Create);
if Origin=nil      then Origin:=TOriginPart.Create(satDefault,'','','','',0);
end;

// ---------------------------------------------------------------------------
procedure TMailMessage.SendNow;
var MsgSend:TIdMessage;
   SMTP:TIdSMTP;
   ix:integer;
   SASLLogin:TIdSASLCramMD5;
   UserPassProv:TIdUserPassProvider;
   textPart:TIdText;
begin
  logFile := nil;                                                     //init to no logging
  MsgSend:=TIdMessage.Create;                                         //create the message
  with MsgSend do
     begin
        Body.Text:=Destination.Body;
        if POS('<html>',Body.Text)<>0 then
           if (Destination.Files<>nil) AND (Destination.Files.Count>0) then //if you are using attachments with html mail, you have do do it in sections
              begin
              Body.Text:='';                                          //clear the body
              contentType:='multipart/alternative';                   //setup the message parts
              textPart:=TIdText.Create(MsgSend.MessageParts,nil);     // this is for plain text
              textPart.ContentType:='text/plain';                     // set the content type
              textPart.Body.Add('This message is formatted as HTML.');// just tell the user that the message is html - it would be nice to strip the html, but you'd never make it look right. probably should add support for a plain text and html text in the Destination class
              textPart.Body.Add(Destination.Body);                    // add the plain text part which is really html formatted
              textPart:=TIdText.Create(MsgSend.MessageParts,nil);     // this is for html text (which is basically just plain text with special rules)
              textPart.ContentType:='text/html';                      // set the content type - this is the magic that kicks in the special rules
              textPart.Body.Add(Destination.Body);                    // add the html formatted text
              end
           else
              contentType:='text/html';                               //you can just send it as an html message
        From.Text := Origin.FromAddy;                                 //setup the from address
        Recipients.EMailAddresses := Destination.SendTo;              //setup who it's going to
        Subject := Destination.Subject;                               //set the subject
        Priority := mpNormal;                                         //set the priority (note that you could add to Destination to support different priorities)
        CCList.EMailAddresses := Destination.CCSendTo;                //set the CC list
        BccList.EMailAddresses := Destination.BCCSendTo;              //set the BCC list
        ReceiptRecipient.Text := Destination.ReturnAddy;              //set the return receipt address
     end;

  for ix:=0 to Destination.Files.Count-1 do                            //if we got a list of file names, add each file as an attachment
     TIdAttachmentFile.Create(MsgSend.MessageParts, Destination.Files.Strings[ix]);

  try
    SMTP:=TIdSMTP.Create;                                              //create the SMTP object

    try
      TIdSSLContext.Create.Free;                                       //try to create a SSL context (immediately disposes of it) - need OpenSSL to support this, if it fails, it will fall into the exception
      smtp.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(smtp);     //if we succeed, then we can create a SSL socket handler and assign it to the IOHandler
      smtp.UseTLS := utUseExplicitTLS;                                 //and we can mark the we can use tls
    except
      smtp.IOHandler := TIdIOHandler.MakeDefaultIOHandler(smtp);       //the SSL failed to create, so make the default IO handler
      smtp.UseTLS := utNoTLSSupport;                                   //mark that we have no TLS support
    end;
    smtp.ManagedIOHandler := True;                                     //either way, we now have a ManagedIOHandler

    if Origin.Debug then                                               //if we marked that we wanted debugging, we need to do some setup
       begin
       logFile := TLogFile.Create(nil);                                //create the log file
       logFile.FileName:=logFileName;                                  //set the default log file name - NOTE: you could get fancy with this, but I normally don't use it
       logFile.Active:=true;                                           //activate the log file (creates the file and intializes everything)
       smtp.IOHandler.Intercept := logFile;                            //set the logFile to the intercept of the IOHandler to capture the events
       smtp.IOHandler.OnStatus  := smtp.OnStatus;                      // - not sure why we do this, copied code -
       end;

    try
      SMTP.AuthType := Origin.AuthType;                                //setup the auth type : satNONE, satDEFAULT, satSASL
      SMTP.UserName := Origin.UserName;                                //setup the user name
      SMTP.Password := Origin.Password;                                //setup the password

      userPassProv:=TIdUserPassProvider.Create;                        //create the user/pass provider - this handles the login functions for SASL
      userPassProv.UserName:=SMTP.UserName;                            // setup user name
      userPassProv.Password:=SMTP.Password;                            // & password

      if SMTP.AuthType=satSASL then                                    //if we are going to use SASL - basically, SASL just encrypts the login, everything else is still clear text
        begin
        SASLLogin:=TIdSASLCramMd5.Create;                              // create the CramMd5 provider - see http://en.wikipedia.org/wiki/CRAM-MD5 - this is the encryptor
        SASLLogin.UserPassProvider:=userPassProv;                      // assign the user pass provider to it
        SMTP.SASLMechanisms.Add.SASL:=SASLLogin;                       // add the SASL login back to the SMTP object
        end;

      {General setup}
      SMTP.Host := Origin.Server;                                      //setup the server name
      SMTP.Port := Origin.Port;                                        //setup the server port

      {now we send the message}
      SMTP.Connect;                                                    //connect to the server - this will automatically use TLS if configured and supported
      if not SMTP.Authenticate then                                    //authenticate with the server - this will automatically use SASL if configured and supported
         begin
         MessageDlg('An error occurred attempting to send your e-mail. The error was : Unable to authenticate.', mtError, [mbOK], 0);
         exit;
         end;
      try
         try
            SMTP.Send(MsgSend);                                        //send the message
            SentOk:=true;                                              //indicate success
         finally
            SMTP.Disconnect;                                           //disconnect from the server
         end;
      except on E :Exception do                                        //if we had a failure, say so
         begin
         MessageDlg('An error occurred attempting to send your e-mail. The error was : '+E.Message, mtError, [mbOK], 0);
         SentOk:=false;                                                //set failure
         SentMsg:=E.Message;                                           //and grab the error message
         end;
      end;
    finally
    SMTP.Free;                                                         //free the memory
    end;
  finally
     if logFile<>nil then                                              //if we had a log file, free that
        logFile.Free;
     MsgSend.Free;                                                     //free the message
  end;
end;

// ---------------------------------------------------------------------------
destructor TMailMessage.Free;
begin
Destination.Free;                                                      //free the destination
Origin.Free;                                                           //free the origin
end;

// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
{TDestinationPart}
// ---------------------------------------------------------------------------

constructor TDestinationPart.Create(aSndTo, aCCSndTo, aBCCSndTo, aRtrnRcptAddy, aSubject, aBody:string; aFiles:TStringList);
begin
SendTo    := aSndTo;          //send message to, comma separate list for multiple adddesses
CCSendTo  := aCCSndTo;        //CC message to
BccSendTo := aBCCSndTo;       //BCC message to
ReturnAddy:= aRtrnRcptAddy;   //leave blank for not return receipt. set if you want a return receipt (me@mydomain.com)

Subject   := aSubject;        //what's it about
Body      := aBody;           //the text, supports HTML or TEXT
Files     := aFiles;          //a list of files to upload - WATCH THIS - you are giving up control by passing in the list, this list is free'd in the destructor
if Files=nil then
  Files:=TStringList.Create; //we must have a list, create if not provided
end;

// ---------------------------------------------------------------------------
destructor TDestinationPart.Free;
begin
Files.Free;                   //free space claimed in create - watch this, it takes control of the list passed in the create and will dispose of it, can cause A/Vs
end;

// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
{TOriginPart}
// ---------------------------------------------------------------------------

constructor TOriginPart.Create(aAuthType:TIdSMTPAuthenticationType; aFromAddy, aUserName, aPassword, aServer: string; aPort:integer);
begin
AuthType := aAuthType;    //options are : 0=satNONE, 1=satDEFAULT, 2=satSASL
FromAddy := aFromAddy;    //me@mydomain.com
UserName := aUserName;    //me
Password := aPassword;    //mypassword
Server   := aServer;      //smtp.mydomain.com
Port     := aPort;        //SMTP connection port (25 is default)
Debug    := false;        //debugging off/on
end;

// ---------------------------------------------------------------------------
constructor TOriginPart.CreateFromFile(fn:string);
var INF:TIniFile;
   i:integer;
begin
INF:=TIniFile.Create(fn);
i        := INF.ReadInteger('SMTP','AuthType',ord(satDefault));
case i of
0 : AuthType := satNONE;
1 : AuthType := satDEFAULT;
2 : AuthType := satSASL;
end;
FromAddy := INF.ReadString ('SMTP', 'FromAddy', ''); //me@mydomain.com
UserName := INF.ReadString ('SMTP', 'UserName', ''); //me
Password := INF.ReadString ('SMTP', 'Password', ''); //mypassword
Server   := INF.ReadString ('SMTP', 'Server', '');   //smtp.mydomain.com
Port     := INF.ReadInteger('SMTP', 'Port', 25);     //default SMTP is 25
Debug    := INF.ReadBool   ('SMTP', 'Debug', false); //we don't we debugging on
INF.Free;
end;

// ---------------------------------------------------------------------------
procedure TOriginPart.SaveToFile(fn:string);
var INF:TIniFile;
begin
INF:=TIniFile.Create(fn);
INF.WriteInteger('SMTP', 'AuthType', ord(AuthType)); //options are : 0=satNONE, 1=satDEFAULT, 2=satSASL
INF.WriteString ('SMTP', 'FromAddy', FromAddy);      //me@mydomain.com
INF.WriteString ('SMTP', 'UserName', UserName);      //me
INF.WriteString ('SMTP', 'Password', Password);      //mypassword
INF.WriteString ('SMTP', 'Server',   Server);        //smtp.mydomain.com
INF.WriteInteger('SMTP', 'Port',     Port);          //SMTP connection port
INF.WriteBool   ('SMTP', 'Debug',    Debug);         //debugging off/on
INF.Free;
end;

// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
{ TThreadMailMessage & util functions for it}
// ---------------------------------------------------------------------------

procedure IncMailThreadCount;
begin
  EnterCriticalSection(MailThreadCSR);
  inc(ActiveMailThreads);
  LeaveCriticalSection(MailThreadCSR);
end;

procedure DecMailThreadCount;
begin
  EnterCriticalSection(MailThreadCSR);
  dec(ActiveMailThreads);
  LeaveCriticalSection(MailThreadCSR);
end;

function MailThreadsDone:boolean;
begin
  result:=ActiveMailThreadCount=0;
end;

function ActiveMailThreadCount:integer;
begin
  EnterCriticalSection(MailThreadCSR);
  result:=ActiveMailThreads;
  LeaveCriticalSection(MailThreadCSR);
end;

constructor TThreadMailMessage.Create(aDestinationPart: TDestinationPart;
 aOriginPart: TOriginPart);
begin
inherited Create(false);
IncMailThreadCount;
if aDestinationPart=nil then raise Exception.Create('You must supply a destination');
if aOriginPart=nil      then raise Exception.Create('You must supply an origin');
FreeOnTerminate:=true;

MailMsg:=TMailMessage.Create(aDestinationPart, aOriginPart);
end;

procedure TThreadMailMessage.Execute;
begin
  try
     MailMsg.SendNow;
  finally
     DecMailThreadCount;
  end;
end;

initialization
  InitializeCriticalSection(MailThreadCSR);

finalization
  DeleteCriticalSection(MailThreadCSR);

end.

.topic 15200

This message means that the SMTP server requires you to use TLS when authenticating and sending E-Mail.  The server expects you to use explicit TLS SMTP.  For this, you connect to port 25, issue an EHLO command and get a reply, send a STARTTLS command, and after getting a success reply, you then negotiate TLS with the server.

For Indy 8 and 9
Indy 8 and Indy 9 do not support explicit TLS with SMTP.  If the SMTP server supports implicit TLS with SMTP, you may able to use implicit TLS with SMTP by stting the TIdSMTP.IOHandler to TIdSSLIOHandlerSocket and the port to the IdPORT_ssmtp constant in IdAssignedNumbers (465).

For Indy 10
Indy 10 supports SMTP with explicit TLS.  In the Indy 10's TIdSMTP, you simply have to assign a TIdSSLIOHandlerSocketBase descendent to the TIdSMTP.IOHandler property and set the UseTLS property to either utUseRequireTLS if you do not want to use an unencrypted connection or utUseExplicitTLS if you are willing to use an unencrypted connection.
.topic 14900
CUSTOMER BUGS TO BE FIXED ASAP
KEITH - PRINTING ISSUE OF WRAPPING TEXT
ANTIANO - EMAIL ISSUE GOING THROUGH SECURE SERVER

MERE BUGS TO BE FIXED

BUG: Image Centering is drawing the Image to the left side of the defined Rectangle Area when Centering if the Image is Narrower than the Rectangle and should be centered between the defined width.

CUSTOM PAGE SIZE AND FORM NAME SUPPORT
SetPageFormName(cFormName)
PageForm = "SomeFormName"

GetPageInfo(0) - Page Size
GetPageInfo(1) - Form Name
GetPageInfo(2) - Width
GetPageInfo(2) - Height

.topic 14800
Custom Paper Size Support

The following Methods now:

PrinterAddForm(cFormName, nFormWidth, nFormHeight, [nLeftMargin], [nTopMargin], [nRightMargin], [nBottomMargin], [cPrinterName])

PrinterDeleteForm(cFormName, [cPrinterName])
NewPageByPaperSize
SetPageByPaperSize

PageHeight
PageWidth
PaperBin

nCurrentPageBinNumber
nCurrentPageHeight
nCurrentPageOrientation
nCurrentPageWidth

nPageOrientation

PrinterPaperHeight
PrinterPaperWidth

.topic 14700
Print Spooler Folder for Win2K/XP

\WINDOWS\SYSTEM32\SPOOL\PRINTERS

.topic 14300
GOALS TO BE COMPLETED BY JUNE 20, 2005

BUGS TO FIX
BUG FIX ASAP: EMERSON READ: IMAGES that are BUILT INTO A PROJECT are not appearing on the MERE Preview. This has already been coded for in the old Engine.
BUG FIX ASAP: DOUG COOMBS: Printing a Single Line Text String is truncating the last character or couple characters. I fixed this in the Preview for Doug last week but the Printing is still broken.
BUG FIX ASAP: DOUG COOMBS: Change the SAVE AS IMAGE button to show a different Icon than the Save To PDF button. Also, look at changing the SAVE TO PDF button as well.
BUG FIX ASAP: BRIAN COPELAND: SUM TOTALS are not properly totalling on the report in the VFP Report. Samples have been provided to look at.
NEW: Add support for TOOLTIPS when hovering over objects. This will need to be added as a parameter to the AddObject() Method.
BUG: SAVE AS IMAGE: When hitting the ESCAPE KEY while generating a file. The MESSAGEDLG() Method launched the Modal Dialog Form behind the Current Save As Image. This needs to be checked out.
BUG: Locate MERE Dialog Boxes over the same Monitor rather than the MAIN DESKTOP window when displaying them.
BUG: IMAGE OUTPUT: TEXT IS NOT GETTING TRIMMED PROPERLY WHEN IT IS LONG.

FIXED: BUG: Rendering a page to an IMAGE with a SHAPE that is Transparent but over the top of a Label hides the Label.

PRINT DIALOG BUGS:
Need to display STATUS, WHERE, TYPE and COMMENT Fields
FIXED: Need to set the Group Box labels to OPAQUE
BUG: Rendering a STRING witht the Following Expression "TRANSFORM(_PAGENO)" as a String using GDI+ on Screen/Printer is being rendered as: "TRANSFORM_PAGENO)". The Left Parenthesis is being cut off.

NEW CHART ITEMS
Multiple Chart Support
Multiple Series Support
Need to identify a method for tracking the collection of data points
Each AddXYData() Point adds another point to the chart.
Be able to collect data at a Group Level and graph it at the group Footer. For example graphing all of the sales for each day of the month in a Bar Chart and then plotting a Summary of Sales by Month at the end of the chart. This would involve tracking 2 separate sets of data. One way would be to have 31 Report Variables one for each day of the month and then another tracking of data values by the month.
Charts could be placed in the Group Headers or Page Headers since the Chart object could track the page and Chart # that the chart object was placed on and in the AFTERREPORT Method all of the Chart Data collected could be placed into the Chart. When the SAME CHARTID would be set to insert another Chart, the method would populate the first Chart's data.
Place a RESTRICTION on Charts so that they only work in CERTAIN BANDS so that some user does not attempt to print a Chart on Every Single Detail Band.
We could pre-scan all of the Chart Objects to determine how many Charts are found and also to evaluate of the chart properties are expressions or simply text strings for titles etc.

CHART IMPLEMENTATION
For each chart located in the BEFOREREPORT Scan, the code adds a MERE_Chart Object to the Report Listener. Each MERE_Chart Object is linked to the Array record for that Shape Object and is responsible for collecting the data for that chart.
Chart Object
Data Point Collection for Each Series in the Chart to hold data points

CONSIDER collecting the data into the ChartSeries Objects but not assigning the data to the ChartObject itself until the Chart is Rendered. So, instead of updating the Chart Data each and every hit save it until it is needed for the chart to be rendered.

We may want to take one Data Object and use it to populate several chart objects with the same data to present it in different views.
We may also want to place multiple charts per report being displayed at different groupins
Instantiate a CHART Object for each CHART
Instantiate a Series Object for each data Series
How can multiple charts with different layouts share the same Chart Object.
The Layout needs to be separated from the Data

NEW ITEMS
NEW: KEYBOARD NAVIGATION: Implement the PAGE UP, PAGE DN, HOME and END in the CONTINUOUS SCROLL mode so that the user can change pages by using the keyboard. Also support the UP/DN/LEFT/RIGHT arrows as well.
NEW PRINT DIALOG OPTIONS:
NEW: Option to Print in Booklet Form All of the pages on a Side by Side piece of paper and Front and Back autoscaling and autorotating the pages.
NEW: Add PRINT SCALE OPTION selection
NEW: POSTER SIZE OPTION to span multiple pages by scaling the print outs.
NEW: Display the PAPERBIN in the PRINT DIALOG box and possibly allow for changes on the fly before printing. Or allow for changing the PAPERBIN for all pages at Print Time.

NEW: SAVE AS IMAGE DIALOG OPTIONS
NEW: REWRITE the SAVE AS IMAGE code to use MEMORY STREAMS and ALL GDI+ commands rather than the having to go to a BITMAP in Memory and then Transfer the BITMAP to a Temporary File and then Copy the Temporary File back into a GDI+ Object and then write that new GDI+ Object back out to Disk. TOO MANY STEPS.
NEW: Option to set the BATCH NAMING options
NEW: SUPPORT DPI CHANGING
NEW: ADJUSTABLE COMPRESSION SETTINGS
DONE: NEW: Need to add an ESCAPE to the SAVE AS IMAGE code so the system doesn't seem like it is hung up.
DONE: BATCH SAVING OF ALL PAGES WITH AUTONAMING
DONE: SCALING GREATER THAN 100%
DONE: ADD PROGRESS BAR
DONE: PAGE PREVIEW
DONE: SCROLLBAR TO CHANGE PAGES IN PREVIEW
DONE: TIFF IMAGE SAVE WITH MULTIPLE PAGES

DONE: NEW: Implement SAVE AS IMAGE DIALOG BOX
DONE: NEW: Attach Dialog Boxes to the Parent Application

FIXED BUGS

CORRECT OUTPUT: NEW ENGINE:
[PICTURE clip0017.bmp]
FIXED: BUG: PRINTED OUTPUT OLD ENGINE: When the OLD ENGINE renders Multi-Line Right Aligned Field Text the Right Edges of the words are getting cut off as follows:

 [PICTURE clip0013.bmp]
FIXED: BUG: OLD ENGINE PREVIEW DISPLAY BUG:
[PICTURE clip0015.bmp]

FIXED: BUG: PDF OUTPUT: NEW ENGINE AND COPY PAGE TO CLIPBOARD NEW ENGINE: When rendering the output from the PDF Engine and the text is from a MULTI-LINE field the BLANK SPACE BETWEEN WORDS at the end of the line is getting measured in a RIGHT ALIGNMENT and is leaving a BLANK SPACE at the RIGHT SIDE of the line. FIX: The PDF code needs to do a RIGHT TRIME on the String before it measures the string and aligns it for output on the multiple line string.
[PICTURE clip0016.bmp]

Support Multi-Page Display and Continuous Page Display

.topic 8600
2005 ADVISOR CONFERENCE TO DO LIST

PRINTED MATERIAL TO PREPARE
Make Copies of Flyers
Print out a Discount Coupon / Order Form
VENDOR SESSION INFORMATION FOR STAND

KEYPOINTS TO MAKE ON DATA SHEET
Merge Word Documents with VFP Reports
Load Word Documents directly into MERE
Print Word Documents and VFP Reports in one Print Job
Preview Word Documents combined with VFP Reports in a single document.

ITEMS TO PACK
Carry On Luggage
Projector and Spare Bulb
Order Forms / Coupons
Product Literature Flyers
Nikon Camera
Spare shorts, shirt, socks, underwear

NOTEBOOK CASE (BACKPACK?)
T-40 Thinkpad
Memory Cards
Panasonic Camcorder
Need 2nd Notebook with Hard Drive Installed

Checked Baggage
BANNER
SLIDE PROJECTOR
Power Cords
Power Strips
Blank CD-ROMS
Dress Shoes
Dress Socks
Business Casual Shirts
Business Casual Shorts/pants
Mind's Eye Shirts
T-Shirts
Running Shorts
Underwear
Running Socks

.topic 14600
“The horror….the horror….”
Colonel Kurtz, Apocalypse Now

My first 2 – 2 ½ years as a Fox tester with the company went well after I joined in June of 2001. I was consistently leading in most test production statistics and had engineered some substantial procedural changes that had greatly streamlined the daily test process. Mike Stewart was the Test Lead for my first 18 months there and then stepped down for personal reasons.

Shortly thereafter, the Fox Team was merged with the VS Data team and I was asked to assume many of the lead functions; albeit without the actual title of “Lead”. This meant that for about half of the VFP 8 product cycle and all of the VFP 9 product cycle, I was responsible for contractor management, budgeting, resource planning, and served, with Calvin as Lead Developer and Randy as Lead Program Manager, in a sort of triumvirate making the day-to-day decisions about the product. I was the test project manager, but the Test Manager in charge of the full-time personnel remained unchanged.

The structure of the test organization was pretty simple: There was a Test Manager, a Test Lead, and then we test folks. After Mike stepped down, there was no Test Lead.

The work sounds fun, and in many cases was, but it was also very difficult. Since the company was trying to reduce contractor budgets and VFP was not exactly the star of the stage, I kept having to squeeze more and more out of the limited resources I had. There were many times when it was suggested that I work with Randy and Calvin to cut major product features, but I was unwilling to do that unless absolutely necessary. Fortunately, Randy had excess contractor budget on the books which he lent to me and we were able to get along without major feature cuts.

Starting not very long after I joined the company, I began to suffer mood swings and bouts of insomnia. These grew worse as the stress of getting a good product out the door mounted. Sometimes I would be late to work and other days I would leave early, exhausted. Management took note of this and it was often cited as a “minus” when my work performance was discussed.

In 2002 and mid-2003, my performance reviews were above average. My arrival and departure issues were noted but weren’t considered a serious detriment to my overall performance. On top of that, my individual contributor statistics still ranked at or above those my peers in spite of my additional roles as project and contractor manager.

Starting in the summer of 2003, the wheels started to come off. My wife traditionally spends every summer with the kids at her relatives in Miami and the summer of 2003 was no exception. However, her return was postponed over and over and it became apparent that she was prepared to sacrifice our marriage rather than return. She hated the Seattle area, had no friends, and did not like the person I was becoming as the stress mounted.

And that summer, our contractor lab manager was summarily dismissed for gross violations of company policy and we had to scramble to assume control of our own lab operations – which we did with some heroic hard-work by our contract personnel.

Also, in September, I suffered a freak ulnar nerve accident (the funny bone nerve) that left me with only partial use of my right arm for some time. I had to wear; at least I was supposed to, a cast that kept my arm out at an 80 degree angle. Thank goodness, after a few months, my arm seemed to be healing on its own (I was given a slim prognosis that this might occur so I was lucky) and I discarded the cast.

In February 2004 I was served with divorce papers. At that point, I knew I had to go down to Miami and straighten things out. It took every day of vacation I had plus all of my personal days, but I was down there for three weeks and we resolved our issues. She promised to return in the summer with the kids and try to make a go of it here again.

This is about the time when the budget strings were drawn tighter and I was constantly reshuffling responsibilities. It was a very stressful environment – I suppose it would have been easy to jettison VFP 9 features but all of us in the “triumvirate” wanted very much to avoid doing that. We felt that the cool new features were worth possible cutting a few test cycles and getting as creative as possible to spread limited test resources around.

Things were starting to look decent when, in June 1 2004, while in the middle of a “leads meeting”, I received a call that my father had unexpectedly passed away. Obviously, I dropped everything and rushed to fly to my parent’s home in Ft Lauderdale since I’m the eldest child and am expected to be in the lead when tragedy strikes (my great aunt and uncle has passed away within the prior three weeks, unbelievably).

I’ll never forget as I rushed down the hall to leave Microsoft that afternoon, my manager stopped me in the hall to remind me that I only had 4 days of bereavement leave .“5”, I told him, “with travel”, having just read the policies. This was just the typical warm, people-friendly response one could expect.

By the time mid-June rolled around, I felt that I was once again on top of things. The test milestones were being met and I felt that the team was humming along well, albeit with some escalating morale issues.

One problem that we all had on the test team was that we felt we were more or less adrift and that management didn’t seem to care or pay attention to what we were doing. When attention was paid, it was to “stop the presses” and some task was thrown at us that would completely stop VFP 9 testing dead. Don’t get me wrong; sometimes these were valid assignments but they pinched our already limited resources.

I fielded complaint after complaint in our weekly meetings, which management attended perhaps 25-50% of the time. I detected a growing “don’t give a crap” attitude and I didn’t know what to do about it: I was simply the project manager and not the employee manager – it wasn’t my job nor likely would it have been appreciated if I addressed career or morale issues.

There was a growing concern amongst the three of us that neither of us had been told of any career path after the shipment of VFP 9. Management either had no plan or hadn’t mapped it out well enough to divulge it to us.

In late June, I saw that we needed to play to our individual strengths and re-engineered test specifications and testing into a factory process and our productivity started to rise. It was simply a matter of having folks doing what they did best. The productivity breakthrough this achieved was, in large part, ignored by management. It’s hard to get kudos for work like this when lingering under a preconception that you’re dirt.

In July or August came utter disaster. All three of us full-time employees were told we were performing barely adequately and all three of us received poor to lukewarm reviews. We were told our metrics were poor (with no basis for justification), and were all compared unfavorably to our brethren on the VS Data side of the team….to be fair to them, they had nothing to do with this slight.

Each of us was told our bug statistics were deficient. This was due to many factors: The tools we were now employing caught many more bugs before they became issues and reduced the number of bugs we were likely to find in ad-hoc testing. Each of us had many more responsibilities than we had during the previous product cycle and, therefore, had less time to spend spelunking for bugs randomly. Finally, I and my fellow testers were pretty convinced that the product was just that much more stable and there were fewer bugs to be found as easily as before.

Of course, we were not supposed to know that each of us was dinged this way, but as in all organizations we shared information like this privately. It was pretty amazing the uniformity of the criticism we all had received.

In many ways, and not unusually for corporations, Microsoft’s review process is highly subjective. If a manager wants to make you look good, he’ll find ways. If he wants to make you look bad, he’ll find ways for that, too. I’ll leave it to the reader and simple logic which way management was predisposed to the Fox testers.

We all reacted differently. I have to admit that I simply “lost it” and ranted and raved to the point that I was reprimanded by Human Resources. Except for the time management issues I have previously discussed and an inability on my part to be consistent with status reports, I believed – and do to this day – that I had overcome immense hurdles to keep VFP 9 on track with as many features as we were planning to roll out. I also believed, strongly, that one of the other full-time testers had performed above-and-beyond average and I could not believe the outcome of his review as well, although my ability to intervene on his behalf was essentially nil since I was not his manager and I had my own injustices to deal with.

I believe at least one of the other two testers filed complaints with Human Resources, although I’m not certain about that and it wouldn’t be fair to divulge who.

In August, I began to have panic attacks. Not knowing what they were, I was hospitalized twice before it was accurately diagnosed. My doctor ran some tests and determined that I had acute Bipolar Disorder. It probably explained the earlier insomnia and fatigue to a degree but had been brought out into full latency – likely due to the extreme personal and professional stress I had suffered recently.

Starting in September, I went on a pretty nasty pill regimen. Funny – the first day at the company I made the mistake of taking all of my pills at once, after lunch. Fifteen minutes later I had to be driven home…I have never felt so stoned in my life!

I knew that the pills were going to become an issue. I tried getting some informal recognition from my management of possible disabilities but they wanted no part of any informal deal. Human Resources wanted to know the exact terms of accommodation I might need. I couldn’t give them exact terms because my condition and the pills caused my daily moods and energy levels to swing dramatically. One day I’d be a saint and the next writing the most ripping, snarling emails to management. The constant, often senseless interactions between HR, management, me, and my doctor was a joke and nothing was ever done to allot for my issues besides putting a burden on me that I couldn’t fulfill.

During all this time I was very open to management as to where I was in my treatment and what my current issues were. I communicated every word of doctors advice or insight I could offer on my ongoing treatment and prognosis.

Around this time, management started to require that I “clock in/clock out” and notify them by email of my comings and goings – to the point where I had to use sick or vacation time for doctor’s appointments. This is, as far as I know, unheard of there.

The pill regimen really started to get to me. I remember a meeting with my manager in which he asked me if I had kicked off a previously scheduled event that day (a “bug bash”) and I could nothing but stare at him. I had completely forgotten and it took me a bit just to remember what he was talking about.

And that was the nut of my problem from then on – I was being watched over and threatened with poor performance reports for issues that I didn’t have complete control over. It was almost as if they wanted me to fail and made life as difficult as they could – although perhaps that’s paranoia which is not one of my symptoms.

I grew increasingly desperate over my career as the VFP 9 product cycle was coming to a close. I could not, and still do not, understand how we testers could all be considered mediocre and yet we were maintaining a very high quality bar for what is one of the most feature-laden versions of Visual FoxPro ever. It seemed that everyone – peers, other Team members, and customers - thought we were doing a great job except for our immediate management. It’s like, “Well, John, things are looking good for VFP but you were ½ hour late today and we just can’t have that, can we?”

I made the mistake in late October of going off my medications completely to try to get a grip on things and get rid of the fogginess. The problem with psychotropic drugs is that when they’re titrated right and the mood swings are more-or-less handled, you tend to convince yourself that you don’t really need them. Also, a key element to my particular form of BPD is what is known as “hypomania” in which you are, essentially, judgment-impaired when it’s in full force and all ideas sound like good ideas including going off of one’s medications.

As an aside, if you want to read about a fascinating mental illness, look up “hypomania” on the web. In mild cases, it’s the only actually beneficial mental disorder.

By early November, my lack of keeping up with my drugs caught up to me and I suffered what I can only term a mild nervous breakdown. I was out of work for 3 weeks and probably returned before I should have just because it was a critical time in the product cycle. Believe it or not, in my next formal performance review, I was dinged for having left at this time and forcing the manager to, God forbid, actually manage for a time. Yes, this was in writing in my mid-year review; it seems so unbelievable.

I think around the time of the full July review Mike Stewart just stopped caring. I didn’t recognize it at the time although if I had been his manager perhaps I would have seen it. From that point on, I believe Mike was just waiting to be let go or to be given an excuse to make his own exit – which eventually happened in February 2005. Mike has already returned to the company as a vendor and is rapidly rising through the ranks of responsibility.

My other compatriot, Chandra, simply resolved at that point to get out as soon as he could. He managed to do so in November, 2004, and was hired as a developer in the Windows Division. He recently received his first review in this role and it was outstanding. It’s a private joke of ours that he’s well appreciated as a developer in a critical area of the company yet was kicked around as a tester on the relatively unimportant VFP product.

So, in early 2005, I was the “last man standing”. My contractor budget had run out at the end of 2004 and, so, there were no contractors. Mike had gone; Chandra moved to greener pastures. I tried to make light of it, in fact putting a sign on my office door reading “VFP World Test Headquarters”.

Around that time I began to make noise about being promoted to the formal title of “Lead”. It wasn’t a money issue; I just wanted some recognition of the responsibilities I had in what ultimately was a very successful product launch. Essentially, I was reminded that I was a piece of crap and then divested of VFP testing responsibilities. Another team tester came in to learn VFP and VFP testing.

For my last few months with the company, I busted butt to learn how to be a VS Data tester and the VB .Net automation tools and procedures. To their credit, management paid for whatever training or materials I requested. I never fully got into it, though, as there were just too many pre-existing VFP responsibilities I had that I couldn’t yet hand over to my replacement.

Don’t get me wrong – the tester who replaced me is exceptionally sharp and will do a great job in the long term and enjoys my utmost confidence.

In June, my wife became ill and was hospitalized. I needed to stay out of work to help take care of the kids – her parents came to help but they don’t speak English – and to taxi the family to visit her at her hospital daily, which was 40 miles away in heavy traffic.

Around the beginning of July I realized that I was in a lose-lose situation. My wife’s long-term prognosis was unclear and I hadn’t yet caught up to my peers in terms of VB testing. The track record was that, of course, I would be slammed in my next full review for not only the issues I’d already been hit with, but likely my output versus the other testers in VS Data since I was still battling a learning curve as well as vestigial VFP responsibilities.

So I tendered my resignation. I could not guarantee 100% participation in the future with my illness and now my wife’s illness, so the fair thing seemed to be to resign and free up the headcount for someone who could come to the team with skills more rooted in .Net.

On one of my last days there, when discussing all of the unpaid leave I had to take with my wife’s illness, my manager told me that if it was some consolation, I was going to receive a performance bonus since I had remained employed beyond the end of the fiscal year (June 30).

A day before the bonuses were to be paid, I received an email that I would not be receiving one. When I asked for further information, I was informed that they had told me only that I was eligible for one (ahem – my memory serves different) and that my performance and behavior made me ineligible. I have asked for details and specifics of where my performance did not meet my personal goals but no information has been received.

They’re nothing if not consistent, I guess.

So what is the complete truth? This is my side of the story, with omissions due to confidentiality agreements, and they’ll have their side of the story – which I doubt will ever see the light of day. Sometimes, when my mood swings downward, I begin to doubt my contributions and my role for the last few years.

But then I think of the hundreds and hundreds of good comments I have personally received on the stability and richness of VFP 9. I think of the confidence I enjoyed from my peers; Randy, Calvin, Ken, Richard, and Aleksey. In the weekly leads meeting I was Mr. Quality Assurance and I believed – and it was true – that I was personally responsible for the quality every single change for VFP 9.

I also believe that something over there began to go deeply wrong around two years ago. If I was sitting here writing this as the odd-man out maybe I’d feel differently – but not a single one of us remains from early 2004 to now. That should be telling.

Management would never say it, but VFP 9 owes a lot, if the face of an increasingly hostile environment, to Chandra, Mike, and to our primary contractors the last year: David Anderson, Garrett Fitzgerald, and Jay Jones (who is now an employee).

These folks pulled it off in spite of what it was costing them just because they happened to be where they were and doing what they were doing. All of us; all of us were (and most of us remain) passionate about the product and our customers. I personally participated with gusto in every community event or initiative I could: The team blog, MVP summits, code competitions, minority student events, and others. I single-handedly found and filed 200+ documentation bugs in my first few months with the company and led an initiative with the documentation manager (since departed) to create good code samples for language elements that didn’t have them or were outdated.

Naturally, my efforts in these areas were denigrated at the time of evaluation and not considered germane to my assessments. Sigh; so much for supporting company and departmental initiatives – no direct management support whatsoever. Community activities were sneered at; documentation bugs were not “real” bugs.

Of the three employee testers, all of us skilled, knowledgeable, and extremely enthusiastic as of January 2004….by a little more than 12 months later, one was (perhaps) fired, one left in disgust, and I believed resignation was my only sane (no pun intended) option.

To be as fair as I can, I know that I was a very difficult person to deal with considering all of my “issues”. But I met virtually all of my strategic goals.

I am left with no alternative than to consider that the ultimate destruction of the Fox test team was engineered for reasons that I don’t know and hesitate to speculate on. I could surmise it has to do with the high visibility of the VS Data side of operations versus the continual irritation of VFP, but it would be crass to think that we would have all been maligned simply for working with a less strategic product, wouldn’t it?

What is the effect on Visual FoxPro and what is the future for Fox? I can’t say. There are things I know and things I don’t know, but I swore confidentiality and these are issues I cannot and will not discuss. I also will not name names when it comes to management and who did what…it would not be fair. In some cases I’m not sure whose hand was holding the hilt of the knife in my back.

Not long after I joined Microsoft, there was a customer event. I was chaperoning a group of our customers around and two turned to me and said (I’m paraphrasing), “We appreciate you being here. We consider you one of us and not one of them and we know you’ll protect our interests.”

It brought tears to my eyes. Well, now I’m back to being one of “you” after a few years in hell. And I’m happy to be back.
.topic 14100
Conference Topic Description

Here is my description for my Session:

Mind's Eye Report Engine PDF Output and Report Preview ActiveX Control
Quickly generate reports at runtime that include Charts, Barcodes, Images and Rotated Text in Visual FoxPro or .NET. Then email your reports or send them to a memory stream or file as a PDF document WITHOUT installing a PDF Printer Driver using the built in Email and PDF Rendering Engines. Come see PDF documents generated at Warp Speed!

Learn how to use the MERE ActiveX control's built in PDF Engine in Visual FoxPro or .NET to generate multi-page PDF reports . PDF output can even be sent as a stream to a variable at runtime. NO PDF Printer Drivers Required!

Mind's Eye Company Description
Mind's Eye, Inc. develops the Mind's Eye Report Engine ActiveX Control that can be used to programmatically Generate, Preview and Print Reports at runtime and save them as PDF Documents blazingly fast without using a PDF Printer Driver, which is great for web servers. Stop by our booth and see why Everyone will want to use MERE with VFP 9.
.topic 1055
PropertiesChartAddXYData Method (PRO Version Only)

Description:
The ChartAddXYData Method will add a data point to the currently selected chart.

Syntax:

oReportEngine.ChartAddXTData(nX, nY, cLegend, nColor)

Return Type:
Numeric - Index Reference number of object on page.

Parameters:
cName			String		A name identifying the object that allows for searching for the object by name at runtime. Optional.

nChartType		Numeric	Specifies the Chart Type.

                    Valid Chart Types
                    0 - Line Series
                    1 - Vertical Bar Series
                    2 - Horizontal Bar Series
                    3 - Area Series
                    4 - Point Series
                    5 - Pie Chart Series

nHPos			Numeric	Specifies the location of the horizontal position on the report surface in inches up to 10,000th of an inch.

nVPos			Numeric	Specifies the location of the vertical position on the report surface in inches up to 10,000th of an inch.

nWidth			Numeric	Specifies the Width of the Chart object on the report surface in inches up to 10,000th of an inch.

nHeight		Numeric	Specifies the Height of the Chart object on the report surface in inches up to 10,000th of an inch.

Example:
oReportEngine.AddChart("", 1, 1.0, 1.0, 5, 5)
oReportEngine.ChartAddXYData(100,0,'Software',RGB(255,0,0))
oReportEngine.ChartAddXYData(220,0,'Hardware',RGB(255,0,0))
oReportEngine.ChartAddXYData(850,0,'Consulting',RGB(255,0,0))

This adds a Vertical Bar Series Chart to the current Report Page at a Horizontal position of 1 inch and a Vertical position of 1 inch with a width and height of 5 inches. The ChartAddXYData() Method adds data points to the Vertical Bar Chart that will be displayed when the report page is refreshed or scaled.

Adding Multiple Charts
Multiple Charts can be added to a single page. Simply call the AddChart() Method again to add another chart to the current page. Once you have added a new chart to the current page, calling the ChartAddXYData() Method will add data points to the most recent chart. In order to add more data points to a chart that already exists on the current page call the ChartSelect(n) Method with a number ranging from 1 to the number of charts on the current page. You can first determine the number of charts on the current page by calling the ChartGetCount() Method. The ChartGetCount() Method will return the total number of charts on the current page.

Example Showing Multiple Charts:
oReportEngine.AddChart("", 1, 1.0, 1.0, 5, 5)
oReportEngine.ChartAddXYData(100,0,'Software',RGB(255,0,0))
oReportEngine.ChartAddXYData(220,0,'Hardware',RGB(255,0,0))
oReportEngine.ChartAddXYData(850,0,'Consulting',RGB(255,0,0))

* Now add a second chart to the current page.
oReportEngine.AddChart("", 1, 1.0, 6, 4, 4)
oReportEngine.ChartAddXYData(1250,0,'Contracting',RGB(255,0,0))
oReportEngine.ChartAddXYData(350,0,'Internet Services',RGB(255,0,0))

* Now select the first chart and add more data points to that chart
oReportEngine.ChartSelect(1)
oReportEngine.ChartAddXYData(675,0,'Other',RGB(255,0,0))

.topic 11100
Enter topic text here.
.topic 11200
BASEMENT STUFF TO DO
Finish Putting up FOAM in Bathroom Area
Finish Screwing the 2x3 Metal Studs
Finish Pulling Wiring for the Electrical for first inspection
Put up walls for the Bathroom and put in piping
Design the Basement bathroom to use WOOD for the walls

.topic 10600
Enter topic text here.
.topic 8900
DAILY TO DO LIST

**** JANUARY 8 - 9 AMERICA'S CENTER HEALTH EXPO - FREE

BUSINESS STUFF TO DO
CURT HAMLIN CODE CHECK
BILL KARPEL FOR JANUARY TIME
BILL CARIBBEAN CREME FOR DECEMBER TIME
FAX BC/BS APPEALS ON CHARGES
LOOK FOR SARA'S EOB from BC/BS
Apply for new domains for new business
Begin Work on VFP 9 REPORTLISTENER
DONE: Contact RUSS SWALL about working on projects for Russ

Renew GoDaddy Domain
Clean up Website and move to GoDaddy

Get back to the CORCC for speaking engagements
Plan a speaking Tour for the different VFP User Groups
DONE: Get back to BILL ANDERSON for Speaking Engagements
DONE: PAY BUSINESS BANK ONE CC 2005-01-18
DONE: SEND REMINDER LETTER TO DAVID KOLS
DONE: Install MONEY 2005
DONE: Install TURBOTAX

THINGS TO ORDER
CAMERA / NOTEBOOK BAG for Nikon and Thinkpad and lenses
NIKON Speed Light for D70 (Sigma or Nikon)
JTL Studio Strobes and Reflectors
Studio Backdrops
DONE: Order TONER for OKI
DONE: ORDER DELPHI 2005

POTENTIAL NEW BUSINESS
AMAZON.COM Affiliate Program
BUY.COM Affiliate Program
Photography
Send Test Photos to SAMSCLUB.COM
Find Photo House for processing Photos as a photographer
Go to Sears or Penney's websites and check out their studio equipment
Setup to Touch Up Photos
TAPE TO DVD CONVERSION AND DUPLIATION SERVICES BUSINESS (Need more DVD Recorders)

PROJECT WORK TO DO LIST
Work on Dan's Report Change
Work on Williams Patent Crusher Project
Work on House Beautiful Project
FINISH REPORTS FOR MEDICAL MANAGER SOFTWARE
START ON TIMEX DATA RECORDER PROGRAM
DESIGN: IMAGE BROWSER PROGRAM for browsing the Picture information from the pictures. This program should be able to control the Camera for taking photos.
Work on Father John's Code

Setup as a Reseller/VAR for Web Hosting
Talk to Bo
Look at GoDaddy's Reseller Plans
Prepare Budget
CONTACT POTENTIAL CUSTOMERS ABOUT PURCHASING
Switch Web Hosting to GODADDY
Call Stan at Copier Place
Lookup the EXCHANGE SERVER settings for Clyde to receive EMAIL on the ES
DONE: OFFER SALE ON WEBSITE UNTIL END OF YEAR
DONE: Spreadsheet out all CREDIT CARD ACCOUNTS
DONE: BILL TIME for Michael Hogan for November!
DONE: Email Michael Hogan about Open Invoice

WELLS FARGO CREDIT LINE INCREASE DECLINED on 2004/12/23 due to increase in July 2004 must wait until at least February
Call 866-200-6020 for FREE Credit Report from Experian or go on line

MERE RELATED ITEMS TO DO
UPDATE THE MERE LICENSE TO READ THAT USE OF THE PRODUCT WITHOUT PURCHASING AFTER 30 DAYS IS RESTRICTED
Generate a Discount Price and Post on Website as well as Email to Prospects the discount price which will last through July 31, 2004

WEBSITE UPDATES TO DO

HOME STUFF TO DO
CAMERA TRADE INS
NIKON N2000 35mm SLR Camera Body
Tokina AT-X 35-70mm 1:2.8 62mm (Nikon N/AI mount) Serial #:8509762
Tokina RMC 80-200mm 1:3.5-4.5 55mm (Nikon N/AI Mount) Ser #:8603505
TIFFEN 62mm UV Protector Filter
PENTAX SF1 35mm SLR Camera Body

CREATE A DAILY SCHEDULE IN SPREADSHEET FORMAT
Determine Budget for December and January
Set up the TV Downstairs
Clean up the Desks in the Basement for working on
DONE: BC/BS - REVIEW the BC/BS App and send in to Kenneth Mann
DONE: REPAIR Hot Water Heater and Furnace
DONE: Estimate 2004 TAX REFUND
DONE: Purchase Turbo Tax 2004
DONE: Take Folder Unit to Church
DONE: Prepare to pay off Home Depot Credit (Due in January)
DONE: CALL PUBLIC WATER about Water Pressure
DONE: PAY CAR INSURANCE
DONE: PAY DISCOVER CARD
DONE: Call BCBS and ask about the Health Savings Account

OTHER HOME STUFF TO DO
New Digital Camera
Pentax *ist DS Digital SLR ($999 - Creve Cour Camera) ($1099 - CAMETA CAMERA on EBAY.COM)
Konica Minolta Z3 $436 - $499 ($369.95 - NEWEGG) ($436.12 - BUY.COM)
Panasonic Lumix DMC-FZ20 (5 MP - 12X) $599 ($549 - BUY.COM)
Panasonic Lumix DMC-FZ15 (4 MP - 12X) $499 ($459 - BUY.COM)
FujiFilm S5100 (4 MP - 10X) $379 ($349 - BUY.COM) ($323.95 - NEWEGG)
Fuji FinePix S7000 (6MP - 6X) ($479 - NEWEGG)
Canon EOS-D20 - $1599
Nikon D70 $1299
Purchase Slide and Film Scanner (Konica Minolta USB $256)
DONE: Send in Trend Micro Rebate - $15
DONE: Send in TrendMicro Competitive Rebate - $25
DONE: Send in BENQ Rebate - $20
DONE: Send in OKI Rebate - $100
DONE: TARGET: AIR HOGS ON SALE AT TARGET $9.99
DONE: 27" TV for Bedroom (MAIL IN $15 REBATE)

.topic 9900
COMPANY PURCHASES TO BE DONE
SSL CERT FROM GODADDY FOR WEBSITE $29
MOVE WEBSITE TO GODADDY

Order TONER for Okidata Copier
Order Duplex Unit for Okidata

.topic 11700
SEE MIND'S EYE REPORT ENGINE SECTION
.topic 11600
WEBSITE TO DO ITEMS
Improve the Item Feature List
Add COOL STUFF to the List
Add WISHLIST REQUEST FORM onto the MERE Site
Move the Website over to GODADDY
CALL FIRSTCLASS SOLUTIONS and Shutter the Website before the next billing period

DONE: Add a Special Price for End Of Year Purchases between now and the end of the year.

.topic 11500
Enter topic text here.
.topic 11400
Enter topic text here.
.topic 11300
Enter topic text here.
.topic 9700
MARKETING EFFORTS
Market that we offer Development Time for integration of the Report Engine into apps
Items to point out:
Not just a PDF Engine
Printing Features
Searching Features

.topic 5900

PRONTO FIXES AND TESTS
68.166.53.35 - USERNAME: ddodge PASSWORD:testpass

+++ BUGS TO FIX 05/17/2004 +++++
FIXED: NEW: Add the PDF Security Properties to the OCX
Correct the VCX as sent to me by for the JPG images

BUGS TO FIX 03/17/2004 (FINAL DEBUG)

BUGS IN REPORT CHECKOUT
FIXED: NEW: CHART PROPERTY to control the 3-D effect of the Lines in a Line Chart. Also the depth of the chart.
NEW: Add a ROTATED TEXT Example to the Preview.
FIXED: NEW: Modify the code so that a COMPRESSED string of the copy protection is stored in the OCX and then decrypt it on the fly.
BUG: LABELS NOT PRINTING IN PAGE FOOTER
SOLUTION: The TOP and BOTTOM Flag swap in the PAGE FOOTER SHOULD NOT ALLOW for a BOTTOM = .T. in a PAGE FOOTER object. (This needs to be checked in VFP 8 though due to the ability to stretch.)
Values that are different:
NOT WORKING:
TOP = .F.
BOTTOM = .T.
SUPALWAYS = .T.
SUPOVFLOW = .F.
SUPRPCOL = 3
SUPGROUP = 0
SUPVALCHANG = .F.
SUPEXPR = ""
AFTER SAVING AND WORKING
TOP = .T.
BOTTOM = .F.
SUPALWAYS = .T.
SUPOVFLOW = .T.
SUPRPCOL = 0
SUPGROUP = 6
SUPVALCHANG = .F.
SUPEXPR = ""

NEW: Add in AUTOMATIC ZIP Support for EMAIL ATTACHMENTS to automatically
BUG: Saving a LANDSCAPE REPORT to 2 PAGE per page in PDF Output DOES NOT properly scale and locate the pages.
BUG: Fix the PREVIEW so that when select FIT IN WINDOW and the user RESIZES the Form that the FIT IN WINDOW REMAINS in place and automatically resize the FORM. Also this should CHECK the FIT IN WINDOW button down.
NEW: Add a Property to Control whether or not the COPY TO CLIPBOARD uses a TRANSPARENT Page or Not.
NEW: PROPERTY: Create a PROPERTY to turn off Hot Tracking.
NEW: Add a Property to DISABLE POPUP MENUS.
NEW: METHOD: Add STATUS BAR Capabilites to support placing some of the information into the STATUS BAR at the bottom like the PAGE SIZE information, Current Page, Page Particular Printer Information such as PAPER BIN, DUPLEX, Etc.
NEW: METHOD: AddPaperStyle(lcString) - Would take a string of drawing primitives to be used for painting a page background like NOTEBOOK PAPER, GREENBAR, etc. This would allow for some cool things to happen when printing and PDFing. This would be similar to loading up a PDF form in the Background for a report. This Method would also need to optionally support Multiple Pages in the STYLE so that a document could span multiple pages like a 2 Page Form.
DESIGN FEATURES
Support Multi-Page Layouts of forms for drawing primitives
Support adding in Fill in Fields to the document.
NEW: METHOD: Add in a Method to transport a document via FTP back to a webserver similar to a POST command. This would be used on a Web Page scenario where the user could input data to a Form like Adobe and then transmit it back to a Server.
NEW: PROPERTY: To support PRINT TO WHOLE PAGE which would then subtract off the PHYSICALOFFSETX and PHYSICALOFFSETY when printing so it is aligned to 0,0 on the page when printing. This would be similar to a NEGATIVE NXPRINTOFFSET to compensate for the PHYSICALOFFSETX and PHYSICALOFFSETY.

FIXED: NEW: MODIFY the SENDMAIL Method to embed in a String into the SUBJECT and/or BODY Text when sending an email that states that this is sent from the DEMO VERSION of the Mind's Eye Report Engine
FIXED:BUG: SHLOMO has a Report not COLLAPSING DATA BANDS and Looking Double Spaced.
FIXED: NEW: Add a new Parameter to the end of the PRINTREPORT to pass in DUPLEX STYLE for the Report. So, it can be printed in DUPLEX without User Intervention.
FIXED: NEW: Add in a EMAILADDAttachment(cFileName) Method to add in additional attachments to the email.
FIXED: NEW: Add EMAIL SUPPORT to NOT send a PDF Attachment from the control.

BUG: VERNON HOPE
FIXED:BUG: PRINT REPEATED VALUES =NO and (ALSO PRINT WHEN GROUP CHANGES at a certain Level)

BUG: CURT HAMLIN == VERTSPACING  FOLDER - RHC4.FRX
FIXED: PRNTMAST - INVALIDSUBSCRIPT FOLDER - The WHILE Expression needs to be checked before adding a new page.
FIXED: BUG: FOOTER DATA is INCORRECT. Look at the WRONGFOOTER Folder and run the example there. When painting the footer the record has already been advanced and is printing the data for the next record.
FIXED: BUG: SWO Objects that are multiple Lines Tall that don't have enough text to fill the height are not properly sizing the VERTICAL HEIGHT. If the EXPR is drawn 3 lines tall but only 1 Line of Text occupies the Expression. IT SHOULD STILL PRINT 3 LINES TALL!
FIXED: BUG: When the LINE Field is EMPTY(), NO LINE SPACING OR VERTICAL POSITION IS INCREMENTED IN THE BANDS.

FIXED: BUG: CURT HAMLIN == VERTSPACING  FOLDER - Not Wrapping correctly
FIXED: BUG: PRINT REPEATED VALUES set to NO are PRINTING and SHOULD NOT!
FIXED: BUG: FIX PRINT REPEATED VALUES WHEN OVERFLOW TO A NEW PAGE (This will require tracking of overflow to a New Page as well).

FIXED: CHART FIX to change the TITLE PROPERTIES to support MULTIPLE LINES by parsing the strings and looking for CHR(13) to convert to a STRINGLIST.
BUG: Stretched Lines are Not Stretching and causing the STRETCH CODE to STRETCH THE LINES. Look at VERNON HOPE'S HEADERMISSING FOLDER

FIXED:LINES and SHAPES that are set to stretch into other bands are causing the VERTPOSMAX to be moved down by the total height of the shape.
LINES and SHAPES that SPAN BANDS need to have objects added into each band that they span as a Normal Object in the band so they can be drawn as a normal object. However, they need to reference back to the original FRXRECORD to know whether or not the object is to be drawn.

PAINTGROUPHEADERS - BEFORE PRINTING A GROUP HEADER WE NEED TO SEE IF IT IS SUPPOSED TO BE REPEATED.

When we try to paint RECORD 17, the output is TOO TALL to fit on the page and the __LNRESULT = 1 and then we go into an ENDLESS LOOP because it never slices up the band enough to draw a partial record.

BUGS TO FIX
When painting MULT-LINE TEXT OBJECTS, the line spacing between lines is not correctly getting painted height wise. VFP is rendering a taller interline spacing than MERE.
FIXED: CURT HAMLIN: USING REPORT VARIABLES, Create a way to Highlight Multiple Records using a PRINT WHEN Rather Than a UDF by trying to RESET the variable at the end of the GROUP FOOTER. Currently, Curt is using UDF and adding 1 to it each time it reaches the GROUP FOOTER.

REPORTCHECKOUT FOLDER BUGS
BUG: VERNON HOPE: Footer Folder: The Line Spacing is crappy on the INSPUTSUMMDRAWLJPC.FRX. There is extra gaps between the lines that are being stretched Vertically.
BUG APPEARS TO BE DUE TO THE EXTRA 96/TH OF AN INCH ADDED IN BETWEEN LINES BECAUSE THE FONT IS SO SMALL.

 BUG: FIX THE INTERLINE SPACING WHEN THERE IS A STRETCHED FIELD. THE SPACE LEFT BELOW THE STRETCH IS LOST AND THE LINES END UP OVERWRITING EACH OTHER.

BASICGROUPSTRETCH3DEEP - Not Drawing all of the STRETCHED LINES or SHAPES
A00000ATESTREPORTVARIABLES - The INITIAL REPORT VARIABLES values were not being added in to the SUM or checked in the LOWEST and HIGHEST values.
There is still a bug in the Rounding of the AVERAGE VALUES which uses the SET DECIMALS for the REPORT VARIABLE when outputting the number. This will have to be updated in the UPDATEFRXDATA Method.

NEW FEATURES TO ADD OR SUPPORT

VFP FORMAT AND PICTURE PROPERTY CORRECTIONS
The SCIENTIFIC NOTATION is still not properly cleaned up to cut off the E+00 values at the end of the line and trim the length of the output.

REPORT PREVIEW HYPERLINK SUPPORT
DESIGN GOALS
Need Fast Object searching capabilities when scanning the page with the Mouse Over looking for objects underneath the mouse
Make it easy to track the Objects and Object Types
Allow the User to Specify the Mouse Over Cursor Style or Bitmap
Support Selecting or Moving Objects that were placed on the Page at Runtime
Support PDF Field Editing of Objects on a Page from a PDF Document
Find out what other Forms Editing tools are out there that are popular that we may want to be able to load and then export as a PDF document

Add a Memory Array of Integers to the PAGE OBJECT to reference those objects that have HyperLink Support added to them for the page. This will reduce the amount of objects that we have to scan for as the mouse moves over the Page searching for Objects.
Attaching the HotSpot Array to the Page Object will work best when we want to instantiate multiple pages on the Preview Simultaneously for painting.

The Memory Array is a reference point for all objects on the current page.

ONMOUSEOVER
Add support to modify the color of the text or highlight an object during a MouseOver
Add an event that fires when the mouse is over an object in the Previewer

GENERAL STUFF TO DO

Digitally Sign the Control
FIX THE IMAGESCALING = 0 (CLIP) to work properly to clip BIG IMAGES and SMALL IMAGES TO ONLY HAVE THE WIDTH AND HEIGHT OF THE IMAGE.

Fix the FONT Measurement system by creating a FONT REPORT OBJECT ARRAY to store all of the widths for all objects in the report with the Font
Printer PAPERBIN is not working correctly in BETA 10A.

Add support for the PRINTER BIN ID NUMBERS and PRINTER BIN NAMES.

REPORT ENGINE OBJECT ENHANCEMENTS
Figure out How To Intercept the Keyboard Messages going to the Parent Window
Add WATERMARK IMAGE Support
Add a ReportInfo() Method to return Information about the current status of the Report Engine Object Such as:
FontCount
PrinterCount
PageCount
ReportCount - The number of Reports Loaded into the ReportEngine
ActiveReport - The Report Currently Active if more than one is loaded into memory.

NEW STORAGE SUPPORT
Add support to save the current report to a file that can be reloaded in from disk and then modified again or added to. This could be done using the TSTREAM.SaveToFile and TSTREAM.LoadFromFile Methods. However, we might want to compress the storage of the report data and we also need a way to storage the Image content into the report itself unless the images are saved to disk in a folder.

PREVIEW ENHANCEMENTS
Add in the TABBED Interface with a Property to turn it ON/OFF
Improve the FIND feature. Possibly include a separate Pane on the Right Side of the window for searching.
FIND needs to highlight only the word or text string that was searched on.
Add Support for HIDING PAGES
Add Support for Hiding Layers
Add Support for LOCKING PAGES (NO MODIFICATIONS CAN BE MADE TO THE PAGE TYPE SUPPORT)

NEW PAGE INSERTION IMPROVEMENTS
Allow the user to Set the Properties for the New Page to be Inserted into the Report by adding in a new FORM for the User to display from the Popup Menu
Allow the User to Insert the Page at the Current Location rather than Appending to the End of the Report at Preview Time.
Allow the User to select the Page Size and Orientation

RUNTIME USER PREVIEW MODS
Add support to allow the User to change the Color of the Page from a new Dialog Box
Add Registry or INI Support for the Toolbar Layout. This would need to be customized on an Application by Application basis so multiple Software packages could be running on the same box without conflict.

AUTOMATIC IMAGE PREVIEW REPORTING
Add in a Report Support to paint all of the images like a Thumbnail sheet automatically into the Report Engine for a particular folder that could then be saved into a PDF document and then emailed or printed. However, make sure that the images added per page are THUMBNAILED IMAGE OBJECTS so they don't take up so much disk space in the PDF.

PDF ENGINE ENHANCEMENTS
Add a Checkbox to the PDF Options Dialog to support saving the Highlighted text during the Save
Add PDF Engine Properties to Support the PDF Reader Startup Options
SELECT PAGE RANGE SUPPORT in SAVE TO PDF OPTIONS DIALOG

PRINTER SUPPORT ENHANCEMENTS
Add a PRINTERINFO() Method to get information back like the PRTINFO() Method in VFP.
Make improvements to the PRINT QUALITY support
Make sure that settings modified in the PRINTER PROPERTIES... Window are reflected back to the Report Engine before printing.
Add a Checkbox to the Printer Options Dialog Box to support saving the Highlighted text during the Save

NEW PRINTER DIALOG BOX

   [PICTURE clip0008.bmp]

.topic 12500
APRIL 14, 2005 TO DO LIST DEADLINE

MERE ITEMS TO DO LIST

BUGS IN FONT PAINTING AND PDF ISSUES (04/14/2005)
FIXED: BUG: GROUPSTRETCH.FRX VERTICAL LINE BUG: Vertical Lines in the GROUPSTRETCH.FRX test are showing lines that are DIAGONAL rather than VERTICAL.
BUG/NEW: Check out the STRCONV() Method used in the RENDER() Method of the MERE_ReportListener to see why it is not properly mapping into the MERE engine using the ADDTEXT() Method. We may need to modify the ADDTEXT() Method to support DOUBLE BYTE or UNICODE or we may need to make a UNICODE or DOUBLE BYTE version of the ADDTEXT() Method.
Review the output from the LABEL command in the
FIXED: The WIDTHS are being calculated incorrectly for the MARLETT Font when being used on the PDF output. They are not matching the widths coming out of iSED QuickPDF.
The MARLETT Text needs to be LOWERCASE characters in order to display any output on the PREVIEW. I thought it was a WIDESTRING issue but it appears to be that it is the limited Character Set of the Font itself. Therefore, all of the font characters must be mapped into the available Character Mappings for the font. This would also appear to be the case for the WINGDINGS font as well.
PDF FONTMAPPING CHANGES: Change the code to detect ONLY the CHARACTERS for the current Font that should be mapped into the PDF document. Take a look at the MARLETT FontDescription Information output by the QUICKPDF program.
USE CHARACTER MAP Program to diagnose and Review the available Characters for different Fonts and then determine how to handle the correct mapping for both the PREVIEW and the PDF output.

MARCEL ROY - (MERE)
FIXED: POSTNET FONT Embedding and display problem (Fonts are on disk)
DONE: FONT SPACING on the MEMO Field when printing lines. (It is possible that this is related to the LINESPACING FIELD inside of the FRX)

CURT HAMLIN

MERE PRE-SALES WORK TO DO
JOSEPH CALDWELL - (NTS DATA)
BRIAN HIATT
PIERRE SAUVE
STEVEN BERNHARDSON
Craig Mesa [craig@mesa-consulting.net] - Interested in Purchasing
James Blackburn - Fixes for 9 and VFP 8 and below
Mike McCann - NEW PURCHASE - Multiple Users
SOLD: J. Keith Lansden - Scaling issues and such
DONE: DOUG COOMBS - Multiline Problem in the memo fields

KARPEL COMPUTERS
CARL REHMER

MIND'S EYE MEDICAL OFFICE
DONNA (DR. WON'S OFFICE)
LISA - ADD BOX 19 (LOCAL OFFICE NOTES) SUPPORT to the INVOICE

CARRIBEAN CREME
DAN - Fix the lost links of serial numbers that were moved from one customer to another.

DONE: IRS 1120 TAX EXTENSION FILING

.topic 12400
MONDAY FEBRUARY 21, 2005
06:45AM - 07:00AM  0.25hrs
Worked on the SEARCH HIGHLIGHT feature. Adding code to track by PAGE/OBJECT/SUBSTRING OCCURANCE within the strings.

.topic 12300
GENERAL FIELD FORMAT:

General Header:
Long - Field Type
Long - Field Size
20 Bytes - ????
String - Application
String - OLE Class
12 Bytes - ????
String - OLE Class 2
4 bytes - ????
Long - Type (1 - Linked, 3 - Embedded)
4 bytes - ????

IF OLE Class 2 = "PBrush"
  Long - File size
  Byte[File size - 2] - BMP data

.topic 12200
Tuesday 2005-02-15 - 10:36AM
- 6163: 10:36AM
- 6168: 06:53PM

.topic 12000
MERE HELP FILE ITEMS TO ADD
Add an entry describing how to paint pages programmatically.

.topic 11000
NEW IDEAS!

Add a new Method to Populate an internal array of EMAIL Addresses to choose from for the EMAIL TOOLBAR UI Dialog box.
Create a SELECT NAMES Form to match MS Outlook or OE to select Email Addresses From.

Form Designer Tools
Template Designed Report Widget Components that can be dropped onto the Report Designer to automatically support things like Invoices, Purchase Orders, Etc.

EXPORT PLUG IN SUPPORT
Design a way to

.topic 10800
VFP 9 REPORT LISTENER ISSUES AND TO DO LIST

VFP 9 TO DO LIST ITEMS
NEW: Add Support for the DYNAMIC REPORT PROPERTIES in VFP 9

VFP 9 RENDERING BUGS
BUG: ADDTEXT() Method manually with DEFAULT values is not allowing for the FIND HIGHLIGHTER to work.
BUG: COPY PAGE TO CLIPBOARD is not properly wrapping text that was wrapped with the new GDI+ ADDTEXT()
BUG: COPY PAGE TO CLIPBOARD - SHAPES with white backgrounds is being rendered into the EMF with a BLACK SOLID Background.
BUG: Vertical Placement of LABEL text IS NOT Properly positioned Vertically on the Page. This could be a difference between drawing using GDI+ text and GDI Text. Currently the GDI+ Text is being Drawn TOO HIGH on the page.
BUG: Output to PDF VERTICAL TEXT POSITION is incorrect.
BUG: VERTICAL LINES are being drawn as DIAGONAL Lines. (BasicGroupStretchNestedGroups.FRX)
FIXED: BUG: Cutting off the Last Character of the Last Line of Labels
DONE: BUG: Labels are sometimes wrapping lines where there is a line ending in a carriage return of a long text on a single line cool.
DONE: BUG: Keep running the FONT SIZE TESTING.FRX report until we get all of the LABEL Measuring, Line Spacing and Alignment BUGS worked out.
DONE: BUG: Labels are not supporting RIGHT or CENTER Alignment
DONE: BUG: Labels are not supporting LINE SPACING of 1 1/2 and DOUBLE

REPORT EXPRESSIONS AND LABELS
NEW: Add Code to Translate the TOP of the TEXT BOUNDING BOX down to the BASELINE for the passed in Font. This can probably done in the ADDTEXT() Method of the MERE OCX. Currently, the Bounding Box passed is the top of the text and not the baseline so we will need to MOVE the object TOP passed to match the baseline.

TRIMMING ISSUES for long text lines

SHAPE OBJECTS

MERE ENHANCEMENTS REQUIRED
NEW: ALPHA LEVEL SUPPORT for color definition of objects.
NEW: Add BOOKMARK Support to Reports.
NEW: Add support for Annotating Report Pages on the fly.

DONE: NEW: Add a new Parameter to the ADDSHAPE() Method to support CONTINUATION Flags for drawing the Shapes such as the rectangle where a Shape can have a COMPLETE, START and END settings for Drawing Complete Shapes, Shapes thjat are only showing the top of the shape and for shapes that are the bottom of the shape.
DONE: NEW: Add code to compute the amount of text that should be rendered for the current height using GDI+

ADDTEXT() METHOD MODIFICATION
DONE: Add support for the cSubType Parameter to process the text using a GDI+ call similar to VFP 9 using the MeasureString Method

CHANGES TO MAKE
NEW: Modify the ADDTEXT() Method to make nFontSize a REAL #
NEW: TextRenderingMode:
0 = Fill Text
1 = Stroke Text
2 = Fill, then Stroke Text
3 = Neither Fill nor Stroke Text (invisible)
4 = Fill text and add to path for clipping
5 = Stroke Text and Add to Path for Clipping
6 = Fill, then Stroke Text and add to path for clipping
7 = Add text to path for clipping
NEW: Add TRIMSTYLE to the AddText() Method Parameters

.topic 10400
MERE REFACTORING ANALYSIS

Report Band Triggers
Report Object Triggers

IMMEDIATE BUGS TO FIX

RECORD PROCESSING SIMPLIFICATION
Look at using SCAN/ENDSCAN
Analyze processing loop for record movement so duplicates are not made

DUPLICATING REPORT BAND RECORDS DURING OUTPUT
Report Object SEMICOLON RESOLUTION
Stretch With Overflow Issues
NO REPEAT ISSUES

.topic 10700
GENERAL BUGS
(Vernon Hope) - LICENSE File not properly reading on RUSSIAN Language Systems
VB6 Usage Bug - MERE cannot be saved in a VB6 Form.
SAVE TO PDF DIALOG Pops Up in the Wrong Monitor in a DUAL MONITOR Display setup when the ActiveX control is being hosted in the #2 monitor. The SAVE TO PDF PROGESS WINDOW also shows up in the #1 Monitor as well.
BUG: Correct the PRINT DIALOG box to properly display the PRINTER PORT (ie. USB, LPT1, COM1, etc.)

.topic 7000
Objects That Span Bands ISSUES

Slicing up Objects to Span multiple Bands causes overwrite issues
Slicing up CIRCLES and ROUNDED RECTANGLES is not an easy task

.topic 8000
PDF ENGINE BUGS

NOVEMBER 5, 2004
Font Embedding Support

BUG: PDF Engine is not Rendering the FILL PATTERNS such as Diagonal Lines, etc.
[PICTURE VFP Dynamic Property Expression Example.jpg]

PDF SECURITY OPTIONS ENHANCEMENT

PDFCanPrintLevel = (0, 1, 2)
PDFCanChange
PDFAllowAssembly
PDFAllowContentExtraction
PDFAllowContentExtractionForAccessability
PDFAllowCommenting
PDFAllowFieldFilling
PDFAllowAddingNotes

PDFDisplaySecurityOptions
PDFSetPermissions(nPrintLevel, lAllowCopying, lAllowChanges, lAllowCommenting, lAllowFillingFormFields, lAllowCopyingAccessibility, lAllowAssembling)

PDFAllowPrintingLevel (0 = NO PRINTING, 1 = LOW-RES PRINTING, 2 = HIGH RES PRINTING)
PDFAllowCopying
PDFAllowChanges
PDFAllowCommenting
PDFAllowFillingFormFields

PDFAllowCopyingAccessibility
PDFAllowDocumentAssemby

PDFCanComment

Acrobat 3.0 Security
PRINTING: NONE / HIGH RES
FILLING IN FORM FIELDS AND SIGNING
COMMENTING FILLING IN FORM FIELDS AND SIGNING
ANY EXCEPT EXTRACTING PAGES
ENABLE COPYING OF TEXT, IMAGES AND OTHER CONTENT AND ACCESS FOR VISUALLY IMPAIRED

Acrobat 5.0 Security
PRINTING ALLOWED: NONE / LOW-RES / HIGH RES
CHANGES ALLOWED:
Inserting, Deleting and Rotating Pages
Filling in Form Fields amd Signing
Commenting, Filling in Form Fields and Signing
Any, Except Extracting Pages
Enable Copying of Text, Images and other Content
Enable Text Access for Screen Reader Devices for the visually impaired

Acrobat 6.0 Security
PRINTING ALLOWED: NONE / LOW-RES / HIGH RES
CHANGES ALLOWED:
Inserting, Deleting and Rotating Pages
Filling in Form Fields amd Signing
Commenting, Fillig in Form Fields and Signing
Any, Except Extracting Pages
Enable Text Access for Screen Reader Devices for the visually impaired
ENABLE PLAINTEXT METADATA

.topic 10000
MERE CUSTOMERS TO GET BACK TO

DAN WALTERS
JOEL CHABAN - Wants to test with VFP 5.0
JIM DEVANNEY - McCequip.COM - Wants to test with VFP 5.0
MARCEL ROY - New Prospect in Florida needed PAPERBIN switching
MATTHEW CURLAND - New Prospect but has a current RLIB issue
ERIC MARROQUIN - Waiting for VFP 9 version and if it DOES NOT WORK WILL NEED A REFUND!
ART BERGQUIST
BUD WHEELER
VERNON HOPE: - DEMO WATERMARK being displayed on some systems despite having the License Embedded properly. The problem seems to be with DOUBLE BYTE code processing. The string being returned may be a double byte string and we need to check the validation code in the OCX as to what it is processing.
DONE: KEN GREEN -

CREATE A NEW BUILD WITH THE LATEST CODE FOR VFP 5

.topic 5800

SOFTWARE ITEMS TO ADD/OR SUPPORT
Purchase the full blown TChart component. Then we could use and distribute it with the TIMEX BodyLink software as well as adding in new Chart support.
Add in the Direct FAX Rendering Support as an Add on

NEW FEATURES TO ADD
LAYER SUPPORT
LOAD/PREVIEW PDF DOCUMENTS
LOAD/PLACE EMF Documents onto MERE Pages

NEW: ADD METHOD AND/OR PROPERTY TO TURN OFF THE RIGHT CLICK MENU
NEW: Add a method to retrieve different PRINTER INFORMATION based upon the PARAMETER Passed:
PRINTER BIN COUNT
PRINTER BIN ID
PRINTER BIN NAME
PRINTER PHYSICALOFFSETX, PHYSICALOFFSETY
PRINTER MEDIA COUNT
PRINTER PAPER SIZE COUNT
NEW: MARK McCASLAND: Add SUMMARY REPORT Support
!!!! NEW: Modify the SendMail() Method so that we DO NOT CREATE ANY FILES ON DISK!!!!!
!!!! NEW: Add a New OnHelp EVENT that fires when the Help Toolbar Button is clicked on. This can allow for the Developer to intercept the Help Request.
NEW: Add a new Method to support for rendering pages to a DeviceContext directly by passing in the DC and the scaling ratio.
NEW: Add support to allow WaterMark Images to be placed onto pages.
NEW: Modify the LICENSE/COPY PROTECTION Scheme so that the Popup about the Report Engine being a DEMO is displayed Every Time that the Save TO PDF Button or the PRINT BUTTON is clicked on and then also have the Countdown Timer Displayed before going on to the PRINT or SAVE TO PDF command.
NEW: Modify the COPY PROTECTION WaterMark so that it prints all across the page when Printing and also across the PDF multiple times when saving to a PDF so that it is more noticable than a Single Watermark.
NEW: Add a nPaperSize Property to specify the DEFAULT PAPER SIZE for adding new pages by paper size and then allow for the nPaperSize Parameter to be optional.
NEW: Add a New Toolbar Button for setting OPTIONS of MERE. This may also require a way to save the options to a file and read them back in on the fly.
NEW: Add a New EVENTS for most all of the BUTTONS on the Toolbar so they can be intercepted.
NEW: Add CARET Support within the Report Page which would allow for highlighting a Section of Text and then cutting and pasting this to another page like a Word Processor.
NEW METHOD: AddMenuItem Method
NEW METHOD: AddPopupMenuItem Method
NEW EVENT: OnMenuItemClick
NEW EVENT: OnPopupMenuItemClick
NEW: COMMENTING OBJECTS like those in Acrobat where a simple Object can be dropped onto a Report. For instance a SIGN HERE, INITIAL HERE, etc. objects that can be drawn and placed onto a Report Page at Runtime. These Objects could be stored in a Collection that could be added to from an Object Creation File. A standard could be made for generating these Objects and other companies could even sell Objects for MERE. It would be easiest to just load in EMF Objects though to be used by MERE since they are scalable.

WEDNESDAY DECEMBER 01, 2004
BUG: GENERAL USER: Move the CHECKFORCANCEL() Method outside of the MAIN DETAIL RECORD LOOP to both speed up the process and to also lessen the chance for getting errors.
BUG: CURT HAMLIN: CORRECT the GROUP FOOTER incorrectly printing the wrong record. This was found while working on Curt Hamlin's problem.
BUG: ALLYN MOSHER: BEFOREOPENTABLES METHOD SUPPORT needs to be added. However, this won't work if the DE is created and the methods are expected to be in the DE as well as the properties.
BUG: JOHN ST. ANDRIA - PAGE BREAK NOT OCCURRING FOR NESTED GROUPS.
BUG: KEN GREEN: - Add support to DISABLE RIGHT CLICK MENU BY WEDNESDAY DECEMBER 1, 2004
BUG: CURT HAMLIN: Fix the TOOLBAR for Curt Hamlin
BUG: Fix the IIF(_PAGENO=X,"Something","Something 2") Expression processing problem
FIXED: NEW:  Please change the Send Email dialog to include a switch to allow the properties to be either Read-Only, Hidden or Editable
FIXED: NEW: EMAILSMTPHostDisplayStyle Property  - 0 = Show and Edit, 1 = Show, 2 = Hidden
FIXED: NEW: EMAILFromDisplayStyle Property - 0 Show and Edit, 1 = Read Only, 2 = Hidden
FIXED: NEW: ADD PrintDuplex Property to allow Presetting the DUPLEX Check Box in the Printer Dialog Box.
FIXED: NEW: Improve Text Search Engine to match FireFox style Searching.
FIXED: NEW: DELETEPAGE(nStartPage, nEndPage) - Needs to be documented and add support to delete the Page Ranges.

NEW: NEW PRINTER DIALOG BOX

   [PICTURE clip0008.bmp]

PAGE NAVIGATION IMPROVEMENTS
LEFT and RIGHT ARROW KEY MODIFIERS to support Jumping to PAGE BREAKS within a Report. This could also support jumping by Chapter Points if this was a book.

WEDNESDAY JUNE 28, 2004
FIXED: BUG: Fix the VERTICAL POSITION of the ANNOTATION RENDERER in the new HYPERLINK CODE
FIXED: NEW: GARYMARTIN@CENTURYTEL.NET - Add in the HYPLERLINK Support ASAP
FIXED: NEW: Add support for the MEDIA TYPE for Dan and Vicki at VLM Consulting.

MONDAY JUNE 28, 2004
FIXED: NEW: ADD DUPLEX SUPPORT ON THE FLY as an Optional Parameter or a PROPERTY

EXPOSE REPORT OBJECTS AS A COLLECTION

NEW IDEAS
Create REPORT OBJECT Class to mimic the REPORT itself

Features Needed
An Event to Fire On Each Page
Event to Hook into a Progress Bar
FIXED: Easy Ability to set the WaterMark Properties on a Page by Page Basis

Modify the GoToPage() Method to support jumping to

CHART STUFF TO ADD
NEW: Chart Properties
ChartLeftWallDark3D
ChartBottomWallDark3D
ChartBackWallDark3D
FIXED:ChartLeftWallTransparent
FIXED: ChartLeftWallColor
FIXED: ChartLeftWallSize (0 - 100)
FIXED: ChartBottomWallTransparent
FIXED: ChartBottomWallColor
FIXED: ChartBottomWallSize (0 - 100)
FIXED: ChartBackWallTransparent
FIXED: ChartBackWallColor
FIXED: ChartBackWallSize (0 - 100)

.topic 10500
MERE WISHLIST ITEMS

INTERFACE FEATURES
TEXT and OBJECT Selection Support for Dragging into WORD, EXCEL, etc. (Improve upon the Crystal Reports support)
MOUSEWHEEL SUPPORT over Page
LAYER SUPPORT
Add the ability to have LAYERS in the reports that can be SHOWN/HIDDEN
AddLayer()
ShowLayer()
HideLayer()
RemoveLayer()
HIGHLIGHT SUPPORT (The ability to draw a bounding box and highlight text the same as in Adobe PDF Reader)

NON-INTERFACE FEATURES
3-D Barcodes
NEW: Add an IMAGEDPI Property so it can be specified when render Image files rather than the fixed SCREEN DPI

.topic 9400
TEXT SEARCHING IMPROVEMENTS

TEXT SEARCH IMPROVEMENTS REQUIREMENTS LIST
ABILITY TO HIGHLIGHT JUST THE PHRASE FOUND OR SEARCHED
ABILITY TO HIGHLIGHT ONLY ONE OBJECT.
ABILITY TO MOVE TO THE NEXT OBJECT.
*** 4. ABILITY TO POSITION THE PAGE SO THE OBJECT HIGHLIGHTED IS SHOWN.
ABILITY TO SEARCH BACKWARDS THROUGH THE OBJECTS
ABILITY TO HIGHLIGHT ALL OBJECTS ON A PAGE AT ONCE.
ABILITY TO TURN THE ALL HIGHLIGHT OFF AND ON WITH A FLAG.

IMPROVEMENTS
Add a PAGE POSITION Method or modify the ZOOM() Method to support Zooming into a Particular Place on the page at an ZoomTo(X,Y, nScale). This would support Scrolling the Page Left/Right and Up/Down to a particular location on the Page so that we can zoom to that spot.
Highlight ONLY the Text String from the Search rather than the Entire Object
Have a flag to allow for Cummulative Searching and highlighting or just Normal Searches
Ability to HIGHLIGHT ONLY ONE OBJECT
Ability to Search for Objects by NAME or COMMENT
Ability to Turn the HIGHLIGHT ON/OFF via a Button or Property
Ability to DOCK the FIND WINDOW at the TOP or BOTTOM of the Preview Window
CTRL+ENTER to Enable or Disable HIGHLIGHT while in the TEXT WINDOW
When hitting the CTRL+F, the Next Object is Highlighted and if the HIGHLIGHT Button is DOWN then the next Object is Highlighted in GREEN rather than YELLOW.
Ability to SCROLL the Pages Up and Down to display the Next or Previous Found Object.
(OPTIONAL) Add Properties to set the Highlight Color

FUNCTIONALITY DESIGN SPECS
NEED TO TRACK CURRENTLY FOUND OBJECT ON THE PAGE
Need way to CLEAR all Highlighted Text Programmatically and via UI
Add a Property to select the FIND TEXT Style between OLD and NEW.
Possibly add in a Property on a Page to tell the PAGE that a SEARCH is in Progress and that it needs to quickly search the page before displaying the page on the screen.

PROGRAMMING REQUIREMENTS
NEED TO TRACK CURRENTLY FOUND OBJECT ON THE PAGE
NEED TO TRACK THE CURRENT PAGE FOUND IN THE SEARCH

NEW METHODS
FindAgain(nDirection) - Finds the next occurance of the current Text
    nDirection = 1 - Find Next Occurrance
    nDirection = -1 - Find Previous Occurance

NEW PROPERTIES
DisplayFindToolbar - Displays the Find Toolbar on the MERE Preview Window
            Valid Values: 0 = Do Not Display, 1 = Display at Bottom, 2 = Display At Top
FindText - The Text to Display in the Find Toolbar to be used for searching.

.topic 15500
http://www.systemnetmail.com/

Below is the source code and simple test class for creating and displaying emails. It uses the MAPI API and is therefore not subject to the same restrictions as the "mailto" shell extension.

Using the MapiMailMessage you can set the title, subject, recipients and attach files. Then show the resulting email to the user, ready for them to send. This class is very useful for supporting applications and enriching addins.

Note, that the class is a port from a VB version I had and although it does have comments, it is not up to my usual standard. I will be revisiting this and tidying it up shortly.

using System;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;

#region Test Class

public class TestMapiMessageClass
{
    /// <summary>
    /// Test method to create and show an email
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
        MapiMailMessage message = new MapiMailMessage("Test Message", "Test Body");
        message.Recipients.Add("Test@Test.com");
        message.Files.Add(@"C:\del.txt");
        message.ShowDialog();
        Console.ReadLine();
    }
}
#endregion Test Class

#region Public MapiMailMessage Class

/// <summary>
/// Represents an email message to be sent through MAPI.
/// </summary>
public class MapiMailMessage
{
    #region Private MapiFileDescriptor Class

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
    private class MapiFileDescriptor
    {
        public int reserved = 0;
        public int flags = 0;
        public int position = 0;
        public string path = null;
        public string name = null;
        public IntPtr type = IntPtr.Zero;
    }

    #endregion Private MapiFileDescriptor Class

    #region Enums

    /// <summary>
    /// Specifies the valid RecipientTypes for a Recipient.
    /// </summary>
    public enum RecipientType : int
    {
        /// <summary>
        /// Recipient will be in the TO list.
        /// </summary>
        To = 1,

        /// <summary>
        /// Recipient will be in the CC list.
        /// </summary>
        CC = 2,

        /// <summary>
        /// Recipient will be in the BCC list.
        /// </summary>
        BCC = 3
    };

    #endregion Enums

    #region Member Variables

    private string _subject;
    private string _body;
    private RecipientCollection _recipientCollection;
    private ArrayList _files;
    private ManualResetEvent _manualResetEvent;

    #endregion Member Variables

    #region Constructors

    /// <summary>
    /// Creates a blank mail message.
    /// </summary>
    public MapiMailMessage()
    {
        _files = new ArrayList();
        _recipientCollection = new RecipientCollection();
        _manualResetEvent = new ManualResetEvent(false);
    }

    /// <summary>
    /// Creates a new mail message with the specified subject.
    /// </summary>
    public MapiMailMessage(string subject)
        : this()
    {
        _subject = subject;
    }

    /// <summary>
    /// Creates a new mail message with the specified subject and body.
    /// </summary>
    public MapiMailMessage(string subject, string body)
        : this()
    {
        _subject = subject;
        _body = body;
    }

    #endregion Constructors

    #region Public Properties

    /// <summary>
    /// Gets or sets the subject of this mail message.
    /// </summary>
    public string Subject
    {
        get { return _subject; }
        set { _subject = value; }
    }

    /// <summary>
    /// Gets or sets the body of this mail message.
    /// </summary>
    public string Body
    {
        get { return _body; }
        set { _body = value; }
    }

    /// <summary>
    /// Gets the recipient list for this mail message.
    /// </summary>
    public RecipientCollection Recipients
    {
        get { return _recipientCollection; }
    }

    /// <summary>
    /// Gets the file list for this mail message.
    /// </summary>
    public ArrayList Files
    {
        get { return _files; }
    }

    #endregion Public Properties

    #region Public Methods

    /// <summary>
    /// Displays the mail message dialog asynchronously.
    /// </summary>
    public void ShowDialog()
    {
        // Create the mail message in an STA thread
        Thread t = new Thread(new ThreadStart(_ShowMail));
        t.IsBackground = true;
        t.ApartmentState = ApartmentState.STA;
        t.Start();

        // only return when the new thread has built it's interop representation
        _manualResetEvent.WaitOne();
        _manualResetEvent.Reset();
    }

    #endregion Public Methods

    #region Private Methods

    /// <summary>
    /// Sends the mail message.
    /// </summary>
    private void _ShowMail(object ignore)
    {
        MAPIHelperInterop.MapiMessage message = new MAPIHelperInterop.MapiMessage();

        using (RecipientCollection.InteropRecipientCollection interopRecipients
                    = _recipientCollection.GetInteropRepresentation())
        {

            message.Subject = _subject;
            message.NoteText = _body;

            message.Recipients = interopRecipients.Handle;
            message.RecipientCount = _recipientCollection.Count;

            // Check if we need to add attachments
            if (_files.Count > 0)
            {
                // Add attachments
                message.Files = _AllocAttachments(out message.FileCount);
            }

            // Signal the creating thread (make the remaining code async)
            _manualResetEvent.Set();

            const int MAPI_DIALOG = 0x8;
            //const int MAPI_LOGON_UI = 0x1;
            const int SUCCESS_SUCCESS = 0;
            int error = MAPIHelperInterop.MAPISendMail(IntPtr.Zero, IntPtr.Zero, message, MAPI_DIALOG, 0);

            if (_files.Count > 0)
            {
                // Deallocate the files
                _DeallocFiles(message);
            }

            // Check for error
            if (error != SUCCESS_SUCCESS)
            {
                _LogErrorMapi(error);
            }
        }
    }

    /// <summary>
    /// Deallocates the files in a message.
    /// </summary>
    /// <param name="message">The message to deallocate the files from.</param>
    private void _DeallocFiles(MAPIHelperInterop.MapiMessage message)
    {
        if (message.Files != IntPtr.Zero)
        {
            Type fileDescType = typeof(MapiFileDescriptor);
            int fsize = Marshal.SizeOf(fileDescType);

            // Get the ptr to the files
            int runptr = (int)message.Files;
            // Release each file
            for (int i = 0; i < message.FileCount; i++)
            {
                Marshal.DestroyStructure((IntPtr)runptr, fileDescType);
                runptr += fsize;
            }
            // Release the file
            Marshal.FreeHGlobal(message.Files);
        }
    }

    /// <summary>
    /// Allocates the file attachments
    /// </summary>
    /// <param name="fileCount"></param>
    /// <returns></returns>
    private IntPtr _AllocAttachments(out int fileCount)
    {
        fileCount = 0;
        if (_files == null)
        {
            return IntPtr.Zero;
        }
        if ((_files.Count <= 0) || (_files.Count > 100))
        {
            return IntPtr.Zero;
        }

        Type atype = typeof(MapiFileDescriptor);
        int asize = Marshal.SizeOf(atype);
        IntPtr ptra = Marshal.AllocHGlobal(_files.Count * asize);

        MapiFileDescriptor mfd = new MapiFileDescriptor();
        mfd.position = -1;
        int runptr = (int)ptra;
        for (int i = 0; i < _files.Count; i++)
        {
            string path = _files[i] as string;
            mfd.name = Path.GetFileName(path);
            mfd.path = path;
            Marshal.StructureToPtr(mfd, (IntPtr)runptr, false);
            runptr += asize;
        }

        fileCount = _files.Count;
        return ptra;
    }

    /// <summary>
    /// Sends the mail message.
    /// </summary>
    private void _ShowMail()
    {
        _ShowMail(null);
    }

    /// <summary>
    /// Logs any Mapi errors.
    /// </summary>
    private void _LogErrorMapi(int errorCode)
    {
        const int MAPI_USER_ABORT = 1;
        const int MAPI_E_FAILURE = 2;
        const int MAPI_E_LOGIN_FAILURE = 3;
        const int MAPI_E_DISK_FULL = 4;
        const int MAPI_E_INSUFFICIENT_MEMORY = 5;
        const int MAPI_E_BLK_TOO_SMALL = 6;
        const int MAPI_E_TOO_MANY_SESSIONS = 8;
        const int MAPI_E_TOO_MANY_FILES = 9;
        const int MAPI_E_TOO_MANY_RECIPIENTS = 10;
        const int MAPI_E_ATTACHMENT_NOT_FOUND = 11;
        const int MAPI_E_ATTACHMENT_OPEN_FAILURE = 12;
        const int MAPI_E_ATTACHMENT_WRITE_FAILURE = 13;
        const int MAPI_E_UNKNOWN_RECIPIENT = 14;
        const int MAPI_E_BAD_RECIPTYPE = 15;
        const int MAPI_E_NO_MESSAGES = 16;
        const int MAPI_E_INVALID_MESSAGE = 17;
        const int MAPI_E_TEXT_TOO_LARGE = 18;
        const int MAPI_E_INVALID_SESSION = 19;
        const int MAPI_E_TYPE_NOT_SUPPORTED = 20;
        const int MAPI_E_AMBIGUOUS_RECIPIENT = 21;
        const int MAPI_E_MESSAGE_IN_USE = 22;
        const int MAPI_E_NETWORK_FAILURE = 23;
        const int MAPI_E_INVALID_EDITFIELDS = 24;
        const int MAPI_E_INVALID_RECIPS = 25;
        const int MAPI_E_NOT_SUPPORTED = 26;
        const int MAPI_E_NO_LIBRARY = 999;
        const int MAPI_E_INVALID_PARAMETER = 998;

        string error = string.Empty;
        switch (errorCode)
        {
            case MAPI_USER_ABORT:
                error = "User Aborted.";
                break;
            case MAPI_E_FAILURE:
                error = "MAPI Failure.";
                break;
            case MAPI_E_LOGIN_FAILURE:
                error = "Login Failure.";
                break;
            case MAPI_E_DISK_FULL:
                error = "MAPI Disk full.";
                break;
            case MAPI_E_INSUFFICIENT_MEMORY:
                error = "MAPI Insufficient memory.";
                break;
            case MAPI_E_BLK_TOO_SMALL:
                error = "MAPI Block too small.";
                break;
            case MAPI_E_TOO_MANY_SESSIONS:
                error = "MAPI Too many sessions.";
                break;
            case MAPI_E_TOO_MANY_FILES:
                error = "MAPI too many files.";
                break;
            case MAPI_E_TOO_MANY_RECIPIENTS:
                error = "MAPI too many recipients.";
                break;
            case MAPI_E_ATTACHMENT_NOT_FOUND:
                error = "MAPI Attachment not found.";
                break;
            case MAPI_E_ATTACHMENT_OPEN_FAILURE:
                error = "MAPI Attachment open failure.";
                break;
            case MAPI_E_ATTACHMENT_WRITE_FAILURE:
                error = "MAPI Attachment Write Failure.";
                break;
            case MAPI_E_UNKNOWN_RECIPIENT:
                error = "MAPI Unknown recipient.";
                break;
            case MAPI_E_BAD_RECIPTYPE:
                error = "MAPI Bad recipient type.";
                break;
            case MAPI_E_NO_MESSAGES:
                error = "MAPI No messages.";
                break;
            case MAPI_E_INVALID_MESSAGE:
                error = "MAPI Invalid message.";
                break;
            case MAPI_E_TEXT_TOO_LARGE:
                error = "MAPI Text too large.";
                break;
            case MAPI_E_INVALID_SESSION:
                error = "MAPI Invalid session.";
                break;
            case MAPI_E_TYPE_NOT_SUPPORTED:
                error = "MAPI Type not supported.";
                break;
            case MAPI_E_AMBIGUOUS_RECIPIENT:
                error = "MAPI Ambiguous recipient.";
                break;
            case MAPI_E_MESSAGE_IN_USE:
                error = "MAPI Message in use.";
                break;
            case MAPI_E_NETWORK_FAILURE:
                error = "MAPI Network failure.";
                break;
            case MAPI_E_INVALID_EDITFIELDS:
                error = "MAPI Invalid edit fields.";
                break;
            case MAPI_E_INVALID_RECIPS:
                error = "MAPI Invalid Recipients.";
                break;
            case MAPI_E_NOT_SUPPORTED:
                error = "MAPI Not supported.";
                break;
            case MAPI_E_NO_LIBRARY:
                error = "MAPI No Library.";
                break;
            case MAPI_E_INVALID_PARAMETER:
                error = "MAPI Invalid parameter.";
                break;
        }

        Debug.WriteLine("Error sending MAPI Email. Error: " + error + " (code = " + errorCode + ").");
    }
    #endregion Private Methods

    #region Private MAPIHelperInterop Class

    /// <summary>
    /// Internal class for calling MAPI APIs
    /// </summary>
    internal class MAPIHelperInterop
    {
        #region Constructors

        /// <summary>
        /// Private constructor.
        /// </summary>
        private MAPIHelperInterop()
        {
            // Intenationally blank
        }

        #endregion Constructors

        #region Constants

        public const int MAPI_LOGON_UI = 0x1;

        #endregion Constants

        #region APIs

        [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
        public static extern int MAPILogon(IntPtr hwnd, string prf, string pw, int flg, int rsv, ref IntPtr sess);

        #endregion APIs

        #region Structs

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
            public class MapiMessage
        {
            public int Reserved = 0;
            public string Subject = null;
            public string NoteText = null;
            public string MessageType = null;
            public string DateReceived = null;
            public string ConversationID = null;
            public int Flags = 0;
            public IntPtr Originator = IntPtr.Zero;
            public int RecipientCount = 0;
            public IntPtr Recipients = IntPtr.Zero;
            public int FileCount = 0;
            public IntPtr Files = IntPtr.Zero;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
            public class MapiRecipDesc
        {
            public int Reserved = 0;
            public int RecipientClass = 0;
            public string Name = null;
            public string Address = null;
            public int eIDSize = 0;
            public IntPtr EntryID = IntPtr.Zero;
        }

        [DllImport("MAPI32.DLL")]
        public static extern int MAPISendMail(IntPtr session, IntPtr hwnd, MapiMessage message, int flg, int rsv);

        #endregion Structs
    }

    #endregion Private MAPIHelperInterop Class
}

#endregion Public MapiMailMessage Class

#region Public Recipient Class

/// <summary>
/// Represents a Recipient for a MapiMailMessage.
/// </summary>
public class Recipient
{
    #region Public Properties

    /// <summary>
    /// The email address of this recipient.
    /// </summary>
    public string Address = null;

    /// <summary>
    /// The display name of this recipient.
    /// </summary>
    public string DisplayName = null;

    /// <summary>
    /// How the recipient will receive this message (To, CC, BCC).
    /// </summary>
    public MapiMailMessage.RecipientType RecipientType = MapiMailMessage.RecipientType.To;

    #endregion Public Properties

    #region Constructors

    /// <summary>
    /// Creates a new recipient with the specified address.
    /// </summary>
    public Recipient(string address)
    {
        Address = address;
    }

    /// <summary>
    /// Creates a new recipient with the specified address and display name.
    /// </summary>
    public Recipient(string address, string displayName)
    {
        Address = address;
        DisplayName = displayName;
    }

    /// <summary>
    /// Creates a new recipient with the specified address and recipient type.
    /// </summary>
    public Recipient(string address, MapiMailMessage.RecipientType recipientType)
    {
        Address = address;
        RecipientType = recipientType;
    }

    /// <summary>
    /// Creates a new recipient with the specified address, display name and recipient type.
    /// </summary>
    public Recipient(string address, string displayName, MapiMailMessage.RecipientType recipientType)
    {
        Address = address;
        DisplayName = displayName;
        RecipientType = recipientType;
    }

    #endregion Constructors

    #region Internal Methods

    /// <summary>
    /// Returns an interop representation of a recepient.
    /// </summary>
    /// <returns></returns>
    internal MapiMailMessage.MAPIHelperInterop.MapiRecipDesc GetInteropRepresentation()
    {
        MapiMailMessage.MAPIHelperInterop.MapiRecipDesc interop = new MapiMailMessage.MAPIHelperInterop.MapiRecipDesc();

        if (DisplayName == null)
        {
            interop.Name = Address;
        }
        else
        {
            interop.Name = DisplayName;
            interop.Address = Address;
        }

        interop.RecipientClass = (int)RecipientType;

        return interop;
    }

    #endregion Internal Methods
}

#endregion Public Recipient Class

#region Public RecipientCollection Class

/// <summary>
/// Represents a colleciton of recipients for a mail message.
/// </summary>
public class RecipientCollection : CollectionBase
{
    /// <summary>
    /// Adds the specified recipient to this collection.
    /// </summary>
    public void Add(Recipient value)
    {
        List.Add(value);
    }

    /// <summary>
    /// Adds a new recipient with the specified address to this collection.
    /// </summary>
    public void Add(string address)
    {
        this.Add(new Recipient(address));
    }

    /// <summary>
    /// Adds a new recipient with the specified address and display name to this collection.
    /// </summary>
    public void Add(string address, string displayName)
    {
        this.Add(new Recipient(address, displayName));
    }

    /// <summary>
    /// Adds a new recipient with the specified address and recipient type to this collection.
    /// </summary>
    public void Add(string address, MapiMailMessage.RecipientType recipientType)
    {
        this.Add(new Recipient(address, recipientType));
    }

    /// <summary>
    /// Adds a new recipient with the specified address, display name and recipient type to this collection.
    /// </summary>
    public void Add(string address, string displayName, MapiMailMessage.RecipientType recipientType)
    {
        this.Add(new Recipient(address, displayName, recipientType));
    }

    /// <summary>
    /// Returns the recipient stored in this collection at the specified index.
    /// </summary>
    public Recipient this[int index]
    {
        get
        {
            return (Recipient)List[index];
        }
    }

    internal InteropRecipientCollection GetInteropRepresentation()
    {
        return new InteropRecipientCollection(this);
    }

    /// <summary>
    /// Struct which contains an interop representation of a colleciton of recipients.
    /// </summary>
    internal struct InteropRecipientCollection : IDisposable
    {
        #region Member Variables

        private IntPtr _handle;
        private int _count;

        #endregion Member Variables

        #region Constructors

        /// <summary>
        /// Default constructor for creating InteropRecipientCollection.
        /// </summary>
        /// <param name="outer"></param>
        public InteropRecipientCollection(RecipientCollection outer)
        {
            _count = outer.Count;

            if (_count == 0)
            {
                _handle = IntPtr.Zero;
                return;
            }

            // allocate enough memory to hold all recipients
            int size = Marshal.SizeOf(typeof(MapiMailMessage.MAPIHelperInterop.MapiRecipDesc));
            _handle = Marshal.AllocHGlobal(_count * size);

            // place all interop recipients into the memory just allocated
            int ptr = (int)_handle;
            foreach (Recipient native in outer)
            {
                MapiMailMessage.MAPIHelperInterop.MapiRecipDesc interop = native.GetInteropRepresentation();

                // stick it in the memory block
                Marshal.StructureToPtr(interop, (IntPtr)ptr, false);
                ptr += size;
            }
        }

        #endregion Costructors

        #region Public Properties

        public IntPtr Handle
        {
            get { return _handle; }
        }

        #endregion Public Properties

        #region Public Methods

        /// <summary>
        /// Disposes of resources.
        /// </summary>
        public void Dispose()
        {
            if (_handle != IntPtr.Zero)
            {
                Type type = typeof(MapiMailMessage.MAPIHelperInterop.MapiRecipDesc);
                int size = Marshal.SizeOf(type);

                // destroy all the structures in the memory area
                int ptr = (int)_handle;
                for (int i = 0; i < _count; i++)
                {
                    Marshal.DestroyStructure((IntPtr)ptr, type);
                    ptr += size;
                }

                // free the memory
                Marshal.FreeHGlobal(_handle);

                _handle = IntPtr.Zero;
                _count = 0;
            }
        }

        #endregion Public Methods
    }
}

#endregion Public RecipientCollection Class.
.topic 5300
Martin Salias for creating bitmaps for the new toolbar icons.
Doug Dodge
Robert Pierce
Doug Hennig
Barb Peisch
Jim Balk
Bo Durbin
Alex Sosa

.topic 8
PropertiesFontName Property
The FontName property is used to set the default font to be used when new text is added to the control when the FontName is not specified in the AddText method. This must be a TrueType font available on the current system.

Data Type - String

Read / Write at Runtime

Possible Values

Default Value
"Arial"

.topic 9
PropertiesFontSize Property
The FontSize property is used to set the default font size to be used when new text is added to the control when the FontSize is not specified in the AddText method.

Data Type - Long

Read / Write at Runtime

Possible Values

Default Value
10

.topic 3900
1.	Is it possible to set the Background color of a single Cell, Row or Column of a table rather than the entire table?
2.	Is it possible to insert another table within a cell of a table?
3.	Is there a way to select multiple cells within a table such as multiple rows or columns and then Delete only those Rows or Columns from a table rather than having to do this one at a time?
4.

.topic 1031
PropertiesKnown Limitations

There are known limitations as to how the control functions and what it can handle at this point in time.

Source Code Unavailable in Reports built with DEBUG INFO OFF
Compiling reports into an application without DEBUG INFO checked and with method code in the DataEnvironment will cause the code not to run. Apparantly, whenever VFP BUILDS an application or standalone executable, the source code in the DE is removed at build time and therefore unavailable for use by the MindsEyeReportEngine when needed later at runtime. Therefore it is important that you either compile with DEBUG INFO checked or that you place any code needed to run your report outside of the DataEnvironment INIT Method.

.topic 5600
Supports Shrink To Fit Page Printing
This feature allows the Report Engine to automatically scale any page being printed to fit within the Printable Area of the current page being printed to. Therefore a report page that was designed as an 11 inch x 17 inch page can be printed onto an 8.5 inch x 11 inch sheet of paper. The Report Engine automatically measures all objects on the page before printing and determines how much to automatically scale down the page to fit within the printable area.

Each Report Page can be assigned to print from a Specific Paper Bin
This feature allows you to assign which Paper Bin each individual page of a report will be printed from. This feature can be used to print the first page of a report from a pre-printed letter head page that is loaded into a specific printer tray and then have all subsequent pages printed from the default tray. Or, you can have each page that starts a new group be printed on the letter head as well.

Print All Pages, a Range of Pages or Just the Current Page
The Report Engine supports the ability to programmatically or interactively select the pages that you want to have printed when printing your document.

Print Even and Odd Pages, Odd Pages Only or Even Pages Only

Print pages in Reverse Order for outputting to Ink jets so the pages are ordered correctly in the stack

Print Multiple copies with or without collation without specific printer support
Set the Caption of the Printing dialog box to your choosing
Suppress the Printing dialog box
Specify the name of your Print Jobs via a Property

.topic 2600
Mind's Eye Report Engine Revision History

September 8, 2004
OCX Changes
Modified the AddText Method when the nAlignment parameter is set to 2 for CENTERED text. The nHPos value is used as the center point for Center Aligned text as opposed to computing the center between the Left and Left + Width values. This makes it easier to place text at a central point on the page.

March 4, 2004
VCX Changes
Corrected Report Variables processing to store the Initial Value for SUM, LOWEST and HIGHEST Values.

February 2, 2004
OCX Changes
Added the ability to Print to a File similar to the REPORT FORM SomeReport TO FILE command in Visual FoxPro. This was done by adding a new parameter to the PrintReport Method. The new parameter is cFileName which is used to specify the name of the file to print to. Printing to a File causes the Printer Driver to redirect it's output to a File rather than to the Print Spooler. This file can then later be printed to the same type printer by using the COPY command and specifying the port or sharename to print to.
Improved support for Chart manipulation by adding some new Chart Properties as well as implementing some Chart Properties that were available but not fully functional.
Added a new LanguageIndexID value (7) to support Turkish translation.
Modified the SCALE Property to support predefined Zoom Levels such as Fit To Width, Fit To Window and Zoom. (0 = ZOOM, 1 = FIT TO WINDOW, 2 = FIT TO WIDTH)

VCX Changes
Created a work around so the FRXUpdateDataFields Method could handle issues with SET DATE SHORT or SET DATE LONG causing Invalid Date/Time errors that are documented within the SET DATE command in Visual FoxPro.
Made improvements to the ReportEngine method to check for and respond to a Cancel Report quicker.

January 28, 2004
Released BETA 10 of the Mind's Eye Report Engine to the website
Documented more of the Methods and Properties in the ActiveX control so that Intellisense would display the information
Added in the new PrinterAddForm and PrinterDeleteForm Methods for adding Custom Forms to Windows NT/2K/XP.

January 17, 2004
OCX Changes
Modified the SCALE Property to support predefined Zoom Levels such as Fit To Width, Fit To Window and Zoom. (0 = ZOOM, 1 = FIT TO WINDOW, 2 = FIT TO WIDTH)

January 14, 2004
VCX Changes
Added a new NBOTTOMMARGIN Property so that the amount of Vertical Space on a page could be set to control the amount of data that would be rendered per page. The Bottom Margin value is measured in inches and is subtracted from the available height of the page for determining the cutoff for rendering objects onto the page. Since the original intent of the Report Engine was meant to be printer independent all rendering was normally done with a 0.25 inch margin at the bottom of the page. Now the amount of margin can be set in the VCX prior to running a report by setting the NBOTTOMMARGIN property. The range for the NBOTTOMMARGIN is from 0 to 3 inches. The default value is 0.25 inches.

December 8, 2003
OCX Changes
Improved VFP FRX Report Rendering where SUMMARY BAND height was being checked for all Detail Band records and was therefore causing reports to print one or very few Detail Band records per page.
Added new Logical Property called DISPLAYLICENSEINFO which allows Licensed Developer's to hide the LICENSED TO: Information on the ABOUT Dialog Box.
Improved the VFP Code Parser Engine to support either Single or Double Quote strings.

December 1, 2003
OCX Changes
Modified PDF Engine to optimize Image storage within a PDF document by reusing Images with the same file name rather than creating new objects for each and every image file.
Improved the AddText() Method by now pre-parsing the text and word wrapping the text ahead of time to the specified Width and Height specified.

November 27, 2003
OCX Changes
Fixed issue with handling WINGDINGS and other fonts in the PREVIEW mode. The CHARACTER SET was incorrectly getting set to ANSI_CHARSET instead of DEFAULT_CHARSET. This problem was introduced in BETA 5.

VCX Changes
Fixed problem with processing of Report Pictures using Variables or Properties to set the Filename for the Report Picture. This was broken when the VCX Report Engine was refactored.

November 25, 2003 (BETA 6)
OCX Changes
Began adding in Mouse Wheel support for scrolling through pages in the Report Engine.
Corrected issue causing the Report Engine Control not to instantiate when NO Printers were installed on the system. This was caused when the Printer Listbox was added.
Corrected issue with Charts on a page not rendering to the Clipboard or to an Image File.
Corrected issue causing a FATAL EXCEPTION error while running a STRETCH WITH OVERFLOW objects on a page.

November 10, 2003 (BETA 5)
VCX Changes
Refactoring of the Report Engine improved performance of the rendering of VFP FRX Reports between 3 to 6 times or more depending on the complexity of the report.
Support was added for handling multicolumn reports both Vertical and Horizontal Column Ordering.
Improvements made to the BETA version for Report Variables and Calculated Fields as well as Record Pointer in the Page Footer bands.
Several other fixes made.

OCX Changes
Added new methods for saving Report Pages using the following methods: SaveToBitmap(), SaveToJPEG(), SaveToMetafile() and SaveToPNG().
Added a new method SaveToWord() that saves a Report to a Microsoft Word document using OLE Automation by saving writing each Report Page to a Metafile object and placing the Metafile Object on the Clipboard and then Pasting each page into an MS Word document with one Method Call.
Added a CopyPageToClipboard() Method that supports rendering the current page or the specified page to the Clipboard so that it can then be placed into other software applications supporting Clipboard Objects such as MS Word, Publisher or Visio.
Added an AddFromClipboard() Method that supports adding a Metafile or Image Object from the Clipboard to current page.
Other minor improvements made.

October 24, 2003 (BETA 4)
VCX Changes
Fixed the handling of Negative numbers to not include the negative sign as well as placing the parenthesis right around then number rather than the spaces that VFP pads the parenthesis with.

October 23, 2003
VCX Changes
Fixed the processing of the records in the Page Footer so that the record pointer is still on the same record as VFP when in the Page Footer Band.

October 8, 2003
OCX Changes
Added support for TIFF and PNG images to be Previewed as well as saved into PDF documents.
Added in support for GDI+ drawing. There is a new GDIPlusSupport Read Only Property that can be checked to determine if GDI+ is supported on the current system. GDI+ IS NOT REQUIRED for the control to work. However, additional support is added when it is available. TIFF and PNG images are supported with GDI+.
Added a new DisplayPrinterMargins Property to display Printer Margins showing the printable area of the page. These are the margins that the PrintShrinkToFit property will squeeze the printed output into.
Added a new DisplayPrinterList Property to show or hide a combo dropdown list of the printers on the current system which allows selecting the current printer for printing. This can be used to view the different Printer Margins quickly.
Fixed an issue with saving Gray Scale JPEG images to PDF documents.

October 3, 2003
OCX Changes
Improved the PrintShrinkToFit support to handle printers that don't have equal margins. A lot of inkjet printers have this problem and this corrects for this problem.

October 1, 2003
OCX Changes
Tweaked the line thicknesses output for painting PDF lines and shapes. They were previously printing about 30% thicker than they should have.
Added in support for the PrintShrinkToFit Property to support automatic scaling of the print outs to fit within the Printable Area of the specified Page.
Added in support for the PrinterScale Property which allows scaling of the print out. Scaling below 100 percent will shrink the printout. Scaling above 100% will increase the size of the printout but as of yet will not print into a Poster mode which will be supported in the future. This means that a single page can be enlarged and printed across several pages and then taped together to create a poster size printout.
Fixed the handling of lines and shapes stretching over Group Bands that was throwing an Exception Error.

VCX Changes
Modified the UpdateFRXDataFields method to better handle the NEGATIVE formatting with the parenthesis.
Fixed the support for Reprint Group Headers on a new page. This was not working in the previous BETA release.

September 22, 2003
VCX Changes
Modified the UpdateFRXDataFields method to support SET POINT TO better for Localized versions of report output. Instead of searching for the '.', it now searches for SET('POINT') values to locate the Decimal Position.

September 17, 2003
OCX Changes
Added a new PAPERBIN Property to support changing Paper Bins on each individual page in a report. The PAPERBIN values are defined the same as the DMBIN_X values in the Win32 API headers. See the Help file for more information.
Fixed problem with the Save To PDF Command Button not automatically restoring the Current Directory after the user clicked on the ellipses button to change Directories.

September 14, 2003
OCX Changes
Fixed a bug in BETA when outputting to PDF with Watermarks that caused a Catastrophic Failure error.
Fixed a bug in BETA where Detail Band output was not properly counting all band objects as being completed and caused the report to output infinite pages and eventually crash.

September 11, 2003
OCX Changes
Modified an internal routine that calculates the line breaks for multi-line and/or stretch with overflow text to replace any CR+LF strings with just CR to eliminate double spacing the text.

August 28, 2003
OCX Changes
Modification was made to match VFP's output when a Report Expression's Height is defined shorter than the actual Font Height defined for the Report Expression. VFP's preview automatically corrects the defined height so it will display the entire font height of the object.

August 25, 2003
VCX Update
Modified the Group Triggers check to handle NULL values properly. If a Group Expression had a NULL value, it would not trigger the Group Trigger.

August 22, 2003
OCX Version 1.1.0.285
Made improvements to the Stretch With Overflow text algorithms for long memos.
Fixed an overflow problem in the Stretch With Overflow problem when call the GetTextExtentExPoint API function call. In Win 95/98/ME the limit of characters is 8192 bytes and in Win2K/XP it is 128KB.
Improved speed significantly with long Stretch With Overflow text.
Improved vertical height positioning in multi line text object output in PDF documents.
Made corrections to the Spanish and German translation of some of the tooltip text.

August 11, 2003
VCX Update
Fixed an issue when using the FOR Clause along with GROUP BAND triggers to reset the Page or Column. The first record of the new Group was being printed with the last Group. This has been corrected.

August 10, 2003
OCX Version 1.1.0.275
·	Added support for VFP report bands that have the CONSTANT BAND HEIGHT checked. This disables any stretching of objects or remove line if blank support for all objects contained within that band.

VCX UPDATE
Added support for ONENTRY and ONEXIT events in all VFP FRX Report Bands.
Added support for Multi Column Reports.

August 8, 2003
OCX Version 1.1.0.265
Added support for VFP Left Margin so that all objects placed onto the page will be shifted to the right by the Left Margin.
Resolved a problem with fonts not setting width and height properly between page changes. This affected the FontMetric Height and Width. This was resolved by forcing the Device Context Canvas to refresh after all font changes.
Fixed an issue with the Page Footer being placed to low on the page when processing VFP Reports.

August 7, 2003
OCX Version 1.1.0.261
Added Barcode support to the PDF Export Engine. So, now PDF documents will now have Barcodes added to them from the Report Engine without requiring any fonts.
Fixed a problem causing the control to produce an Exception Error when no printers were installed on the system running the control.

Visual FoxPro Specific Issues Fixed
Fixed problem with REMOVE LINE IF BLANK support where Bands that did not have any objects printed but were all set to REMOVE LINE IF BLANK did not remove the band entirely causing unnecessary blank lines in reports.
Fixed problem with PRINT REPEATED VALUES in GROUP HEADER bands that were sometimes suppressing repeated values even though there was a PRINT WHEN expression. This occurred because the PRINT REPEATED VALUES flag was not being ignored when there was a PRINT WHEN expression.

VCX UPDATE
Fixed problem with SHAPE Objects that were set to TRANSPARENT with a SOLID FILL not displaying a Solid Fill. This fix was made in the READFRX Method.
Fixed problem with LABELS and EXPRESSIONS in FRX Reports that had OPAQUE BACKGROUND set and was not displaying the opaque background. This fix was made in the READFRX Method.
Modified the UpdateFRXDataFields Method so that LEFT padded strings were not processed with an ALLTRIM(). This was broken recently in an update when a fix was introduced for handling really long PICTURE formatting.
Modified the UpdateFRXDataFields Method to properly handle decimal places which were getting truncated to the current SET DECIMALS setting rather than testing for the number of decimal places from the TRANSFORM function.
Fixed problem with Report Variables that initial values relied upon a table that was used by the report.
Removed the MindsEyeReportPreviewForm Form Class from the MindsEyeReportEngine Class Library and placed it into a separate Class Library to make it easier to update the Mind's Eye Report Engine. By removing the MindsEyeReportPreviewForm Form Class from the library, quick updates to the MindsEyeReportEngine can be done without requiring the MindsEyeReportPreviewForm Form Class to be rebranded with your license each time an update is performed. Prior to splitting out the Form Class, each update to the MindsEyeReportEngine Class Library required removing the ActiveX control from the Form Class and then adding it back so that each developer's license was re-embedded into the Form Class.
Fixed problem with processing PRINT WHEN Expressions where the expression had more than one expression being evaluated in the expression. For example: (X > Y) AND (Y < Z). I added in a parenthesis to bracket the Macro Substitution.
Fixed typo in the UpdateFRXDataFields Method where variable lcExpr should have been __lcExpr.

June 22, 2003
OCX Version 1.0.0.232
Fixed a problem causing the control to produce an Exception Error when no printers were installed on the system running the control.
Added new PrintShrinkToFit Property to support shrinking of printed output to the printable page size available.
Fixed alignment and positioning of Shapes and Lines coming from VFP Reports.
Improved Email support for Exchange Server logins by explicitly calling MAPILogon API function.
Made changes to the EMAIL Editor Forms providing a different dialog depending on whether the EMAILMessagingType Property is set to 0 – SMTP or 1 - MAPI. There isn't a need to display the SMTP Host or From address when using MAPI Email.
Added in a check to the EMAIl Message Editor Forms to make sure that the Recipients Address is not empty before sending.
Fixed PDF Filename being different when clicking on the ellipses button from the PDF Document Options dialog.
Other minor enhancements made.

VCX UPDATE
Fixed problem with endless loop when SET SKIP TO in effect. There was a GOTO statement that was resetting the record pointer in the child table of the SET SKIP.
Placed a MessageBox() into the ReportFormPreview Method to alert developers that this is an old method and that they should now use the ReportFormObject Method.
Other minor enhancements made.

May 21, 2003
OCX Version 1.0.0.221
Fixed problem with printing pages of different Orientation. Pages were not properly rotating if changed after the first page.
Other minor enhancements made.

VCX UPDATE
Fixed problem with run away reports that was induced from the addition of the SCOPE clause support.

April 29, 2003
OCX Version 1.0.0.218
Minor fixes made.

VCX UPDATE
Fixed problem with running reports with GROUP processing that caused the Report output to quit after the first page was rendered sometimes. This bug was induced when the SCOPE, FOR, and WHILE support was added.

April 24, 2003
OCX Version 1.0.0.216
Made fixes to the Calendar Overlay to place the dates properly onto the calendar.
Made fixes to the REMOVE LINE IF BLANK algorithms to fix SHAPE and LINE objects that were set to REMOVE LINE IF BLANK and not always properly being displayed when a PRINT WHEN Expression was in place.
Made fixes to the MAPI Email support by adding a call to the MAPILOGON API to make sure that the user gets logged into the MAPI Messaging system when the default email client set up in the Internet Explorer Tools is switched from the default configuration.

VCX UPDATE
Added support for SCOPE and FOR and WHILE statements via Properties in the VCX. See the Help File for details.

April 19, 2003
VCX UPDATE
Modified the MindsEyeReportPreviewForm to search for the MindsEyeReportPreviewToolbar object rather than storing an Object Reference Property to the MindsEyeReportPreviewForm.
Modified the UpdateFRXDataFields Method to properly handle the LEADING ZEROS PICTURE format.
Modified the ReportFormObject Method to release the oCanvas Property Object Reference to the MindsEyeReportEngine ActiveX control so the form would Close when the MindsEyeReportEngine object was still instantiated.
Modified the ReportFormObject Method so that the MindsEyeReportPreviewToolbar is not instantiated until the MindsEyeReportPreviewForm is Activated. This keeps it in line without having any UI until specified by the developer using the SHOW Method or setting the VISIBLE Property to TRUE.

April 18, 2003
OCX Version 1.0.0.214
Made several improvements to the Printing algorithms for printing EVEN, ODD and BOTH pages as well as the Pages Per Page capabilitities.
Completed the code in the PrintReport(Printer, nStartPage, nEndPage, nPageType) Method to support the optional parameters for the method. The PrintReport method now supports printing without a User Interface or prompt. The Printer parameter accepts either a Numeric or a String value. A Numeric Printer value chooses the printer by number on your system. A String Printer value chooses the printer by Name on your system including network printers.
Examples are:
PrintReport(1, 1, 20)  - This would print the current report from pages 1 to 20 to the first printer on the system.
PrintReport('HP LaserJet 4')  - This would print all pages of the current report to the "HP LaserJet 4" printer on the system. The name IS NOT Case Sensitive.
Added support for several of the other PrinterXXXXXX Properties such as PrinterID, PrinterName, PrinterCopies, PrinterCollatePages and more.

April 15, 2003
OCX Version 1.0.0.210
Fixed several issues with the SendMail Method and when sending Emails using the Email Button on the Toolbar when the Filename did not include the Full Path. It now supports Attachment Filenames with or without the Path included in the Attachment Filename.

April 14, 2003
OCX Version 1.0.0.206
Added support for MAPI Email. To select between SMTP and MAPI, set the EmailMessagingType Property.
Cleaned up the Email Message Editor Form to correct TAB ORDER of the controls.

VCX Update
Started adding and testing support for SCOPE clauses.

April 11, 2003
OCX Version 1.0.0.202
Modified the SendMail Method so that ALL parameters are now optional. The method will now use the EMAIL Properties unless overridden by the Parameters passed to the method.
Fixed the SendMail Method to properly support SMTP Authorized Logins.

VCX Update
Fixed the UpdateVariables Method in the MindsEyeReportEngine Class to properly handle Report Variables that were based upon other Report Variables.

April 10, 2003
OCX Version 1.0.0.200
Made a correction to the PDF Output Engine when drawing small circles and rounded rectangles.

April 09, 2003
VCX Update
Added a new method called AppendReportToObject(), which takes an Object Reference variable to a MindsEyeReportEngine ActiveX Object or it's Parent Form and a VFP FRX Report File Name as parameters and appends a report to the Report Object passed. This adds the ability to merge mulitple FRX Reports into a Single Report before making the Report Preview visible.

April 05, 2003
OCX Version 1.0.0.198
Added support for GIF Images to be placed onto Report Pages. Only the first image of a multi-image GIF file is supported. Sorry, no animated GIFs on printed paper. Maybe someday.

VCX Update
Added a new method called ReportFormObject(), which returns an Object Reference to the MindsEyeReportPreviewForm which is created when calling the ReportFormObject() Method. This method then allows for the oReportEngine Object to be manipulated that is contained on the MindsEyeReportPreviewForm Form. With this object reference you can add Pages, Text, Pictures Charts, etc to the FRX Report that was generated all without showing the Form. The Preview Form is not shown until the Visible Property is set to TRUE or the SHOW() Method is called.

April 02, 2003
OCX Version 1.0.0.196
Made more improvements to the STRETCH WITH OVERFLOW and FLOAT algorithms in the Report Engine. Also improved word break search for long strings that had to be wrapped.
Added a new LanguageIndexID Property to support automatic Localization to one of 7 built in languages: 0 - ENGLISH, 1 - SPANISH, 2 - FRENCH, 3 - GERMAN, 4 - PORTUGUESE, 5 - DUTCH and 6 - ITALIAN.
Also added a new Method called SetReportEngineText(nIndexID, cNewString). This method allows the developer to change the text for most Tooltips and other text strings within the Report Engine to whatever they wish to support other languages that have not been built into the control already using the LanguageIndexID preset values.

VCX Update
Added a LOG FILE capability to the MindsEyeReportEngine Class definition to help in debugging any Report Engine problems. Set the lCreateLogFile Property to TRUE to enable the Log File.
Added more Properties to the VCX that get automatically mapped to the MindsEyeReportEngine ActiveX control for presetting things like Toolbar Buttons to Display.
Made other minor fixes to Report Variable processing.
Made a fix to processing padded strings in RIGHT JUSTIFIED STRETCH WITH OVERFLOW text in the UpdateFRXDataFields Method.

March 27, 2003
OCX Version 1.0.0.192
Made more improvements to the STRETCH WITH OVERFLOW and FLOAT algorithms in the Report Engine. Also improved word break search for long strings that had to be wrapped.
Fixed Find method to properly find and mark Case Sensitive text.
Corrected PDF Engine to more accurately draw UnderScore and StrikeOut lines for thickness and Width of UnderScore and StrikeOut lines.
Fixed the SaveToPDF Method of the ActiveX control to open the PDF if a filename was not originally passed to the control but was then prompted for and created. This also fixed creating PDF Documents from the VFP Toolbar that is created by the VCX library.
Improved vertical spacing in Preview for multi-line text. Now text is positioned in inches and then converted to a pixel placement.

VCX Update
Added new Properties for Email, PDF and Help properties to the VFP MindsEyeReportEngine Class definition. You can now preset these Properties in the MindsEyeReportEngine VFP Class and then have those properties automatically set on the Report Engine ActiveX control when it is instantiated by the MindsEyeReportEngine VCX Class.
Added a new SetupReportEngineControl() Method to support subclassing of the control to override or add additional setup support in your own subclasses. This makes the Report Engine more flexible.
Added support to handle REPORT PICTURES that are referenced by Variables rather than referencing directly a Picture by a File Name.
Added explicit releasing of LOCAL VFP variables to help VFP in garbage collection to reduce any C5 errors.

March 11, 2003
OCX Version 1.0.0.188
Corrected an issue with the STRETCH WITH OVERFLOW and FLOAT code.

March 10, 2003
OCX Version 1.0.0.186
Modified the PDF Output Engine to more accurately define PDF pages by placing objects with real numbers verses integer values.
Improved the STRETCH WITH OVERFLOW and FLOAT algorithms to remove a rounding error which caused some stretched objects to not accurately be located. Some objects were also not being floated due to positional computations for objects above other objects due to not subtracting the Font Ascent Height from the vertical position of text.

March 9, 2003
OCX Version 1.0.0.184
Added support to the PDF Engine for outputting charts to PDF Documents.
Font scaling has been corrected for Chart printing. Fonts were previously not being scaled to reflect the printer resolution.
Corrected printer resolution scaling issues to handle printer drivers that returned a resolution of zero thus causing blank Report Previews and blank pages on print outs.
Improved STRETCH WITH OVERFLOW algorithms to handle text strings with lines composed of only Carriage Returns without containing any text. This was causing a FATAL ERROR in the Delphi OCX engine on occasion.
Fixed problem with Images in VFP FRX Reports not transferring the Image Scaling from the FRX General field which controls whether the image is Clipped, Scale and Retain Shape or Scale and Fill Frame. This was causing images in PDF output to be incorrectly sized.
Corrected problem with Report Labels not displaying in the Detail Band.
Corrected problem with License File not being properly read upon multiple instances of control in development environment. This was causing the non-licensed watermark to appear on subsequent instances of the control.

VCX Update
Fixed problem with Relative Path issues in passing image filenames to the OCX engine.
Improved formatting of numbers in FRX Report Expressions where the PICTURE Format was empty. The UpdateFRXDataField() method used to use the TRANSFORM() function but now uses PADR() to fix the problem with numeric values that end in X.000. TRANSFORM truncates values ending in zero.
Modified the ReportToPDF and ReportToPrinterPrompt Methods to use the MindsEyeReportPreviewForm Form Class rather than instantiating the control directly. This was done so these methods could be used in a runtime application where the License file would not be available at instantiation of the ActiveX Control.

Updated the Help File to better document the distribution of the control and add Frequently Asked Questions.

February 19, 2003
OCX Version 1.0.0.176
Printed Paper Sizes and Paper Orientation is now setting and changing correctly. PDF Export of Page Size and Orientation was already working properly. There was a bug in resetting the DEVICE CONTEXT and therefore the printer was not properly setting or changing the paper size or orientation between pages during print outs only.

February 16, 2003
OCX Version 1.0.0.174
VCX Update 09:30PM CST
Many improvements made to the VFP Report Engine code to handle many of the tricks that make the standard VFP Report Writer jump through hoops. Check it out and let me know if you find any issues for me to fix or handle.
Improvements were made to the VFP FRX Report Engine portion of the code namely in GROUP BAND and REPORT VARIABLE handling.
A fix was made to GROUP BAND Calculations were also fixed to properly process calculations prior to printing the GROUP FOOTER BAND.
Added code to completely remove the entire GROUP BAND rather than just shrinking it if all objects were marked as REMOVE LINE IF BLANK and none of the objects were printed.

February 12, 2003
OCX Version 1.0.0.170
Added SMTP Email Support for sending PDF Documents from within the Report Engine. Just click on the EMail Icon in the Toolbar to send the contents to an email address.
Improvements made to the PRINT REPEATED and PRINT WHEN handling. All of the PRINT REPEATED Values were moved over into the Delphi engine thus improving performance.

February 11, 2003
OCX Version 1.0.0.168
Fixed issue with the new text truncation code which was not properly freeing GDI resources causing graphics painting problems.

February 9, 2003
OCX Version 1.0.0.166 - 11:37PM CST
Improved handling of Report Field Expressions with text that was wider than the Report Field Expression. It is now truncated at the width of the field and properly truncated or wrapped accordingly for Report Field Expressions that were taller than one line height and were not Stretch With Overflow Fields.

February 7, 2003
OCX Version 1.0.0.164 - 03:30PM CST
Fixed bug with SaveToPDF() Method that was failing due to a PagesPerSheet not being set and causing endless loop when using the SaveToPDF() Method. Clicking Save To PDF button on toolbar still worked correctly..
Fixed bug with Calendar overlay that was shared among multiple Report Engine instances.

February 6, 2003
OCX Version 1.0.0.162
Added support for GROUP RESET PAGE TO ONE using the automatic processing of "Page X of Y" support. Support was done by adding a new method to the ActiveX control called SetPageNumberToOne(nPageNumber). Page Number Reset processing is done using an array of Page Breaks that mark which pages in the document are to start counting over at page one.

January 26, 2003
OCX Version 1.0.0.154 - 11:27PM CST
VCX Update 11:27PM CST
Improved VFP Report Engine processing in both the VCX and ActiveX control mostly in GROUP BAND processing.

January 25, 2003
OCX Version 1.0.0.152 - 09:40AM CST
Added _PAGENO and _PAGETOTAL automatic processing of "Page X of Y" support from VFP Reports. Automatic Page X of Y DOES NOT require multiple passes of the report. It works by dynamically evaluating the total number of pages in the Report Engine.

January 22, 2003
Improved the Barcode support and fixed Postnet barcode printing. Enhanced the MindsEyeReportEngine VCX and help file documentation.

December 20, 2002
OCX Version 1.0.0.140 - 01:20AM CST
Added support for CHARTS/GRAPHS into the Report Engine OCX control. Also, renamed the OCX to MINDSEYEREPORTENGINE1.OCX. Download the new install file which now includes a Demo showing the Reports. There is currently support for Line, Vertical Bar, Horizontal Bar, Area, Point Series and Pie Charts.

December 11, 2002
OCX Version 1.0.0.130 - 01:20AM CST
Added built in support for printing up to 8 Report Pages per single sheet of paper. Even save your documents to PDF with multiple pages per page. The pages are automatically scaled down to fit.

December 9, 2002
OCX Version 1.0.0.128 - 06:40PM CST
VCX Update - 06:40PM CST
Fixed a PREVIEW and PDF output issues concerning Font DPI settings in the Screen Display Properties.
Modified the VCX to support table openings when already in use.

OCX Version 1.0.0.126 - 12:22AM CST
VCX Update - 01:00AM CST
Added DEFLATE Compression for PDF Output which is ON by default. To turn off compression set the PDFCompress Property to .F.
Added the ability to JUSTIFY Report Expressions when set to STRETCH WITH OVERFLOW and a Report Directive of FJ in the COMMENT Field of the Report Expression.
Added a new ReportToPrinterPrompt() Method to the VCX class so there is no UI when printing.

December 6, 2002
OCX Version 1.0.0.124 - 06:00PM CST
VCX Update - 06:00PM CST
Added New Support for JUSTIFY Text on Report Field Expressions that you want to have Right and Left Aligned. This Alignment currently only works in PREVIEW and PRINTED Output but not in the PDF Output. I will added that in the next day or so. In order to use this feature, set the Text to STRETCH WITH OVEFLOW and place 'FJ' into the COMMENT Field of the Report Expression as a Report Directive without the quotes. This will automatically pad the text with spaces so that the Left and Right edges of the Text in the output will aligned. The Report Directive may change in future releases but will be documented.
Also added more support in the VCX to clean up the DataSessions when using the DS Data Session Property.

December 3, 2002
OCX Version 1.0.0.121 - 10:00PM CST
VCX Update - 11:50PM CST
Added a new method to the VCX to generate PDF files without a user interface called ReportToPDF(cFRXFile, cPDFFile, lOpenPDF)
Added a new DS property to support running the Report Engine from a Form with a PRIVATE DATASESSION. Just set the DS property to the DataSession of the Form before calling the ReportFormPreview Method.
Added code to the VCX to remove .NULL. values from Report output.

November 28, 2002
OCX Version 1.0.0.116 - 02:14AM CST
VCX Update - 02:14AM CST
Added support for REMOVE LINE IF BLANK option for Report Expressions, etc.
Added support to Close or leave Open tables after Report runs.
Fixed a bug in Title Band and Page Header bands which was broken on the 1.0.0.114 release.

November 27, 2002
OCX Version 1.0.0.114 - 01:14AM CST
VCX Update - 01:14AM CST
Added support for Semi-colons and Commas in Report Expressions to translate them into CHR(13) and SPACE in the VCX Class Library.
Made corrections to the Stretch With Overflow option for PDF Output. It now wraps text the same as it does on the Report Preview Window.
Added support for REMOVE LINE IF BLANK and made updates to the VCX Class Library as well for support to have tables closed or left open after running reports.

November 26, 2002
OCX Version 1.0.0.112 - 01:30AM CST
Fixed SUMMARY BAND output so that it now prints on the page.
Made corrections to the Stretch With Overflow option for PDF Output. It now wraps text the same as it does on the Report Preview Window.

November 25, 2002
OCX Version 1.0.0.110 - 05:14PM CST
VCX Update - 5:14PM CST
More improvements made to Print When handling.

OCX Version 1.0.0.109 - 01:14AM CST
VCX Update - 01:15AM CST
Made improvements to Group Band and Print When handling. There is still some more cleanup to be done to the Group Bands when overflowing at the bottom of the page.
Fixed Text Alignment on labels. Alignment on Labels were not working.
Made Fixes and Improvements to Report Variable handling.
Added a save option to the PDF Output so the user could be prompted for Title, Author, Subject, etc.

November 22, 2002
11/22/2002
OCX Version 1.0.0.107 - 10:00AM CST
VCX Update - 10:00AM CST
Made updates to fix the AppendReport() VCX method which was incorrectly positioning the first appended page onto page 2.
Add new Find Method for locating text in the Report Preview. Text objects containing found text will be highlighted. More work will be needed to only highlight the string found.

November 15, 2002
VCX Update - 10:35AM CST
Added shortcut keys to the Report Preview to mimic native Report Preview such as Page Up, Page Down, etc. Also, added '+' and '-' for ZOOM IN and ZOOM OUT too.

November 14, 2002
OCX Version 1.0.0.100 - 10:14PM CST
Improved text Justification and corrected some text cutoff issues with different scaling factors.
Added Zoom option and fixed Fit Width and Actual Size on popup menus

November 13, 2002
OCX Version 1.0.0.98 - 07:35PM CST
Resolved C5 Errors which were related to printer drivers as usual.
Fixed Landscape Reports after 1st page problem that wasn't keeping the correct orientation due to new SWO code.

OCX Version 1.0.0.94 - 03:20AM CST
Updated the OCX Control and VCX Class Library to try to reduce any C5 errors in VFP.

November 12, 2002
OCX Version 1.0.0.90  -  3:00PM CST
Fixed a Divide By Zero error caused by some Printer Drivers that returned a Vertical Resolution of Zero which then caused a Divide By Zero which would eventually lead to a C5 error in VFP.
Fixed the Page Navigation Slider Toolbar at the top of the control which was broken due to new code in the Stretch With Overflow code.

OCX Version 1.0.0.88 - 11:50PM CST
Added VFP Picture/Image support to the VFP Class Library and ActiveX Control. So now Images (BMP and JPG) will display from VFP Reports using PICTURE FROM FILE.
Modified the VCX Class to automatically remove the Report Preview Toolbar when the last VFP Report Preview is closed.
Made improvements to the STRETCH WITH OVERFLOW (SWO) and FLOAT code and added the SWO Support to the TITLE BAND and PAGE HEADER bands. So now SWO works in TITLE BAND, PAGE HEADER BAND and DETAIL BAND.
Started working on partial object printing of when reaching the bottom of the page so that partial lines from an SWO field can be printed on one page and then continued on the next page.

November 11, 2002
OCX Version 1.0.0.84
Added support for the STRETCH WITH OVERFLOW (SWO) and Object Position algorithms to the ActiveX control. Currently the SWO code is only running in the Detail Band but will be fully implemented soon. The SWO code has not been fully implemented in the PDF Export yet either.

November 7, 2002
Modified the Report Preview Toolbar to support VFP6 and above.

November 6, 2002
Made improvements to DataEnvironment Tables support in the VFP Report Engine VCX Class Library. Also, improved Report Variable handling as well as fixing GROUP Expressions that used Report Variables. Now more VFP FRX Reports should run or run better now.

November 4, 2002
New VCX Methods
AppendReport(cReportFileName) - Appends another VFP Report to the Current Report.
DemoIT() - Demonstrates the ActiveX Controls capabilities using VFP to Automate the control calling it's Methods. This Method adds some dummy report pages to the control and then scrolls through those pages, ZOOMS IN and OUT, then adds a Watermark to the first page and then dynamically changes the Rotation Angle of the Watermark on the fly, then it adds Watermarks to every other page, then clears the report pages and then adds pages of different Orientations into a single report, finally 1000 pages are added to the Report to show how fast scrolling through pages can be.

September 11, 2002
First public release of the control in a VFP application was posted to the web for download. It consisted of the OCX control and a VFP compiled executable that demonstrated scripting of the ActiveX control and running some simple VFP Reports.


Default Line Properties (COPY)

Mind's Eye Report Engine Default Line Properties

 Top

DEFAULT LINE PROPERTIES

Property Name | Data Type | Description
LinePenColor | Numeric | Specifies the default PenColor to be used for Line objects placed onto the Report Engine control using the AddLine Method.
LinePenStyle | Numeric | Specifies the default PenStyle to be used for Line objects placed onto the Report Engine control using the AddLine Method.
LinePenWidth | Numeric | Specifies the default PenWidth to be used for Line objects placed onto the Report Engine control using the AddLine Method.


Default Shape Properties (COPY)

Mind's Eye Report Engine Default Shape Properties

 Top

DEFAULT SHAPE PROPERTIES

Property Name | Data Type | Description
ShapeBackStyle | Numeric | Specifies the default BackStyle to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeBorderStyle | Numeric | Specifies the default BorderStyle to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeBorderWidth | Numeric | Specifies the default BorderWidth to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeCurvature | Numeric | Specifies the default Curvature to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeFillColor | Numeric | Specifies the default FillColor to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapeFillStyle | Numeric | Specifies the default FillStyle to be used for Shape objects placed onto the Report Engine control using the AddShape Method.
ShapePenColor | Numeric | Specifies the default PenColor to be used for Shape objects placed onto the Report Engine control using the AddShape Method.


Default Text Properties (COPY)

Mind's Eye Report Engine Default Text Properties

 Top

DEFAULT TEXT PROPERTIES

Property Name | Data Type | Description
TextFontBackColor | Numeric | Specifies the default Back Color to be used for Text placed onto the Report Engine control using the AddText Method.
TextFontForeColor | Numeric | Specifies the default Fore Color to be used for Text placed onto the Report Engine control using the AddText Method.
TextFontName | String | Specifies the default Font Name to be used for Text placed onto the Report Engine control using the AddText Method.
TextFontSize | Numeric | Specifies the default Font Size to be used for Text placed onto the Report Engine control using the AddText Method.
TextFontStyle | String | Specifies the default Font Style to be used for Text placed onto the Report Engine control using the AddText Method. Any of the values listed below can be combined together. Valid Values are: "" - Normal "B" - Bold "I" - Italic "U" - Underline "S" - Strikeout


Distributing the Report Engine with Visual FoxPro

Distributing the Report Engine Control with Your Applications

 Top

In order to use the Mind's Eye Report Engine control in your applications, you must distribute the MindsEyeReportEnginePro1.OCX and/or the MindsEyeReportEngineStd1.OCX files with your application. At this time, no other files are required to be distributed with your application for the Mind's Eye Report Engine to be used in your application. The Software License Agreement DOES NOT allow you to distribute the MindsEyeReportEnginePro1.LIC or MindsEyeReportEngineStd1.LIC files with your applications. The license files are only to be used in a development environment.

In order to use the Mind's Eye Report Engine Control in Visual FoxPro, you must first place the control onto a VFP Form or subclass the control by creating a new OLECONTROL class using the control. This will give you the ability to add new methods and place code in the controls Events to respond to them. When VFP 8 is shipping, you will be able to use BINDEVENT but until now you will have to place the code in the events. Then you can then use this new OLECONTROL class to use the AddObject() Method to add the control to a form at runtime. The main reason for doing this is so that your developer's license file information gets embedded into the SCX or VCX during design time that can then be used later at runtime to verify the control.

Visual FoxPro Application Distribution (VERY IMPORTANT)

To distrubute the control with your Visual FoxPro application, your developer's license must be properly embedded into an SCX or VCX in order to avoid your end users seeing the Demo Watermark or the About Box. This requires that your License file is properly installed onto your development PC in the same folder that the ActiveX control has been installed before adding the control to a form or creating a class containing the control.

Therefore, in order to use the ReportFormPreview Method in your production application you MUST remove the MindsEyeReportEngine ActiveX control from the MindsEyeReportFormPreview Form Class contained in the MindsEyeReportEngine Visual Class Library and then with your Licensed copy of your control you must then add the Mind's Eye Report Engine ActiveX Control back to the MindsEyeReportFormPreview Form Class. Below are the steps to properly embed the control with your developer's license.

STEPS TO PROPERLY EMBED YOUR DEVELOPER'S LICENSE FOR USING THE CONTROL

1. Open the MindsEyeReportPreviewForm Form Class contained in the MindsEyeReportEngine Visual Class Library.
2. Remove the MindsEyeReportEngine ActiveX control from the MindsEyeReportFormPreview Form Class and Save the Form Class. You MUST save the Form Class prior to adding the MindsEyeReportEngine ActiveX Control back onto the form otherwise VFP will not properly embed the license due to caching of the license by VFP.
3. Open the MindsEyeReportPreviewForm Form Class again.
4. Now add the MindsEyeReportEngine ActiveX control onto the Form Class.
5. Next rename the MindsEyeReportEngine ActiveX control from Olecontrol1 to oReportEngine.
6. Now Save the MindsEyeReportPreviewForm Form Class.

If your License file was located in the same folder as the MindsEyeReportEnginePro1.OCX and/or MindsEyeReportEngineStd1.OCX files and named the same as the control being placed it will now have the license properly embedded into the VFP Form Class.

Visual Basic Application Distribution

Visual Basic will automatically embed your License file information into your Visual Basic application whenever you Build the application as long as the License file is located in the same folder as the Mind's Eye Report Engine ActiveX Control.


Emailing Reports as PDF Attachments

EmailButtonIcon Emailing Reports as PDF Attachments

Top

The Mind's Eye Report Engine makes it very easy to email your reports directly from the Report Engine. There are two different ways of emailing your reports. First in the User Interface the user can click on the Email Report as PDF button on the toolbar. As a developer you can use the SendMail() Method of the ActiveX control to pass in the SMTP Host, From Address, Recipients, Subject, Body Text and Attachment File Name.

In order to hide the prompt for the SMTP Host Name, you must pre-populate the EMAILSMTPHost Property on the control programatically or when placed onto a Form or Form Class. Also, if your SMTP Server requires Authenitication you must set the EMAILSMTPAutenticationType = 1 and you must then set the EMAILSMTPUserID and EMAILSMTPPassword Properties as well before the user can click on the Send Email button or before calling the SendMail() Method.

See Also:


Frequently Asked Questions

 Top

How do I remove the Report Engine Demo Watermark?

Once you purchase a development license, you will be sent a License File named, MindsEyeReportEnginePro1.LIC. This file needs to be copied into the same folder as the MindsEyeReportEnginePro1.OCX file where it is registered.

You Development Tool is programmed to look for a License File for ActiveX controls that are built as needing a license. So, when

During development, the liand then add the control to a Form, Form Class or Container Class, the watermark will be removed. Please see the instructions on Distrbuting the Report Engine Control with your Applications.


How do I send an email that requires authentication?

 Top

Before answering this question, we do well to state that Authentication was never in the original SMTP protocol. When RFC 821 was written in 1982, third-party SMTP servers and gateways had to relay messages between other hosts and the other hosts would act as an intermediaries between the originating SMTP servers and the intended destination. That was how E-Mail worked at the time. As time went on, the need for intermediate SMTP servers to relay messages between an originating server and a destination server faded and as the internet opened up to the general public, the capability to relay messages from a client on a different network to a destination outside of the SMTP server's network only became a security hazard that was exploited by spammers and others out to abuse E-Mail.

There are several ways that the security threat was addressed.

• The SMTP server was configured to simply send mail to other networks that originated only from specific I.P. Addresses in the server's network.

• The SMTP servers would require the client sending the outgoing E-Mail to authenticate by logging into the POP3 (Post Office Protocol 3) server and immediately afterwards, send the E-Mail to the SMTP server.

• The third-way is by adding some extensions to the SMTP protocol that would use various Simple Authentication and Security Layer (SASL) mechanisms to ensure that the client is authorized to send outgoing E-Mail and these extensions and SASL mechanisms were formalized into standards.

Since the first two methods are relatively straightforward, we will only discuss how to use Indy's RFC 2554 support.

For Indy 8.0 and 9.0

Indy's TIdSMTP component has only limited RFC 2554 support in that it can only support one SASL mechanism called LOGIN. There are other SASL mechanisms that can be used such as CRAM-MD5, Digest MD5, Kerberos 4, GSSAPI (Generic Security Service Application Program Interface), and S/Key. Those SASL mechanisms are not supported in that version.

To use Indy's LOGIN SASL support, simply set the TIdSMTP UserName property to the username, and password property to the user's account password, and the AuthenticationType property to atLogin. Then send the E-Mail as you normally would. You can also use Indy to determine if LOGIN authentication support is available on the SMTP server and using it if it is available by using the AuthSchemesSupported property with code like this:

IdSMTP1.AuthenticationType := atNone;

IdSMTP1.Connect;

try if

IdSMTP1.AuthSchemesSupported.IndexOf('LOGIN')>-1 then

begin

IdSMTP1.AuthenticationType := atLogin;

IdSMTP1.Authenticate;

end;

IdSMTP1.Send(IdMessage1);

finally

IdSMTP1.Disconnect;

end;

For Indy 10

You can use simple AUTH LOGIN similarly to Indy 9.0. Set TIdSMTP.AuthType to atDefault. Then set the Username and password properties in TIdSMTP.

This provided for backwards compatibility. For many programs which are distributed to the public or on a mass scale, we recommend that you use Indy 10's SASL framework for authentication so your program can support a wide variety of SMTP servers. Our expanded SASL framework supports TIdSMTP, TIdPOP3, and TIdIMAP4. This framework has plug-in SASL mechanism components for CRAM (Challenge-Response Authentication Mechanism) MD5 SASL (RFC 2195), Anonymous SASL (RFC 2245), External SASL (RFC 2222), Login, One-Time-Only-Password - OTP (RFC 2444), Plain SASL (2595), and S/Key (RFC 2222). You can also write your own SASL mechanism component by writing a descendent of TIdSASL (located in IdSASL). To use this with framework with TIdSMTP:

1. Drop a SASL mechanism component on your form. Those components are located on the new Indy SASL tab in the component palette.

2. In TIdSMTP, set the AuthType property to atSASL.

3. In TIdSMTP, click the button beside the SASLMechanisms property. An editor will appear.

4. Select the SASL mechanism components you wish to use with TIdSMTP from the available listbox.

5. Click the RIght arrow to move those to the Assigned listbox.

6. Click Ok when you are finished.


I am using the TIdSMTP but when I try to send mail I get an error message such as: "521 potserver.organization.com access denied" or "'572 Relay Not Authorized."

 Top

It means that you have been denied access to that SMTP server by its administrator. Administrators prevent abuses of their SMTP relay servers by requiring:

• That you send E-Mail only from a computer connected to their network.

• That you use some type of authentication.

Talk to the server's administrator and ask what are the requirements for connecting to the server. Sometimes, the server may need to be reconfigured.


Mind's Eye Report Engine Test Tool

 Top

TO DO LIST

· Add in INI Support to allow for configuration changes to the APP
· Add in a check for checking the version of the MERE OCX
· Add in a CODE WINDOW so the user can type in Code to run before running a test report for both VFP or Mind's Eye
· Add a button to save the CODE WINDOW code to a PRG
· Add a Tab for Rendering Options for the FRX Engine

BUGS TO FIX

· BUG: Adding a SPINNER CONTROL to the Form to remotely move the page pointer caused the focus to get shifted to the PAGE POSITION in the control and then it never let the focus go in spite of the fact that the control was on a DIFFERENT FORM. SOLVE THE FOCUS ISSUE ON CONTROLS!
·


PDF Document Properties (COPY)

Mind's Eye Report Engine PDF Document Properties

 Top

PDF DOCUMENT PROPERTIES

The following properties can be used to specify what is stored into a PDF document when it is created using the SaveToPDF Method or clicking on the Save To PDF command button by the user.

Property Name | Data Type | Description
PDFAuthor | String | The Author of the PDF Document. Default value: ""
PDFBitmapQuality | Numeric | The Quality Level to use for compressing BITMAP images between 1 and 100 using JPEG compression. Default Value: 100
PDFCompress | Boolean | Flag to indicate if the PDF document will be compressed when saved. Default Value: TRUE
PDFCompressBitmaps | Boolean | Flag to indicate whether or not BITMAP images will be compressed when saved into the PDF document. Default value: TRUE
PDFCreator | String | The Creator of the PDF document. Default value: "Mind's Eye Report Engine Control"
PDFEmbedFonts | Boolean | Flag to indicate whether Fonts marked for embedding will be embedded into the PDF document when generated. Embedding True Type fonts into a document will ensure that the document will appear properly when loaded into a PDF Viewer tool when viewed on a computer that does not have those fonts installed. However, embedding fonts can increase the file size between 60KB to 500KB per font on average within a document. Set this value to TRUE to embed True Type Fonts. NOTE: Individual Fonts must be flagged to be embedded using the PDFFontMetric Method. Default Value: FALSE
PDFEncrypt | Boolean | Flag to indicate whether or not the PDF Document is encrypted when it is saved. Default Value: 0 - No Encryption 1 - 40 Bit 2 - 128 Bit (Not Currently Supported)
PDFFontCount | Numeric | The number of unique PDF Fonts in the report currently. This value is increased automatically as new text is added to a report using the AddText() Method. If running reports using the Visual FoxPro Class Library, this property will be automatically increased as well. This property can be used along with the PDFFontMetricMethod to determine all of the unique PDF Fonts in the current report (Read Only)
PDFJPEGQuality | Numeric | The Quality Level to use for compressing JPEG images between 1 and 100 using JPEG compression. Images that are already compressed at a lower quality than the specified quality will not be modified. Default value: 90.
PDFKeywords | String | A comma delimted list of Keywords for the PDF Document. Default value: ""
PDFMargin | Numeric | The PDF Margin in inches used when saving the PDF document for both the top and left margin of the page. Changing the PDFMargin Property sets the PDFXOffset and PDFYOffset to the PDFMargin value. To override the individual margins use the PDFXOffset and PDFYOffset Properties. Default Value: 0.25
PDFOwnerPassword | String | The Owner Password to be used when creating a PDF Document and the document is to be encrypted by MERE. Default Value: ""
PDFSubject | String | The Subject of the PDF document when saved. Default Value: ""
PDFTitle | String | The Title of the PDF document when saved. Default Value: ""
PDFUserPassword | String | The User Password to be used when encrypting a PDF document to disk. Default Value: ""
PDFXOffset | Numeric | The X Offset of the Left Margin in inches used when saving the PDF document for all pages within the report. This will shift ALL pages within the document left or right by the amount specified when the PDF Document is generated. This Property does not affect the Preview or Printing of reports.
PDFYOffset | Numeric | The Y Offset of the Top Margin in inches used when saving the PDF document for all pages within the report. This will shift ALL pages within the document Up or Down by the amount specified when the PDF Document is generated. This Property does not affect the Preview or Printing of reports.


BLOGS - Report Engine DAILY BLOG

 Top

PRODUCT GOALS

To build the best Report Preview and Rendering Tool.

TUESDAY MAY 33, 2005

· 6443 DOWNLOAD LINKS on UT

VISUAL FOXPRO 9 REPORT PREVIEW TIP

To keep Visual FoxPro 9's Report Preview from crashing VFP with an ERROR 43 "Not enough memory to complete this operation." while using SET REPORTBEHAVIOR 90 and simply using the REPORT FORM MyReport.FRX TO PRINTER PROMPT PREVIEW, you need to modify the ReportListener class used by the

* VFP 9 REPORT PREVIEW BUG/LIMITATION USING SET REPORTBEHAVIOR 90

*

* THE PROBLEM:

* ============

* WHEN PREVIEWING A REPORT WITH MORE THAN 4500 TO 4800 PAGES OR MORE WILL

* CAUSE VISUAL FOXPRO TO BEGIN PAINTING TO THE DESKTOP INCORRECTLY AND WILL

* EVENTUALLY CRASH REPORTING THE FOLLOWING ERROR:

*

* ERROR 43: "Not enough memory to complete this operation."

*

* CAUSE OF CRASH:

* ===============

* VISUAL FOXPRO EXCEEDS THE 10,000 GDI OBJECT HANDLE ALLOCATION LIMITATION OF THE

* OPERATING SYSTEM.

*

* BY DEFAULT, WHEN VISUAL FOXPRO 9 RENDERS A REPORT PREVIEW USING THE FOLLOWING COMMANDS:

*

* SET REPORTBEHAVIOR 90

* REPORT FORM Report.FRX TO PRINTER PROMPT PREVIEW

* THE ENTIRE REPORT IS RENDERED INTO MEMORY PAGE BY PAGE AS EMF IMAGES AND EACH PAGE RENDERED

* ALLOCATES 2 GDI OBJECT HANDLES PER PAGE. THE PROBLEM OCCURS IN THAT THE OPERATING SYSTEM

* HAS A LIMIT OF 10,000 GDI OBJECT HANDLES PER PROCESS WHEN USING WINDOWS 2000 AND ABOVE.

* WITH EARLIER VERSIONS OF WINDOWS THIS 10,000 GDI OBJECT HANDLE LIMIT IS SHARED ACROSS PROCESSES.

*

* VISUAL FOXPRO 9 DOES NOT CURRENTLY TRAP FOR THIS LIMITATION WHEN RENDERING A REPORT PREVIEW

* AND WILL CRASH AS STATED ABOVE. HOWEVER, THE CRASH CAN BE AVERTED BY PLACING AN API CALL TO

* GetGuiResources() INTO THE BEFOREBAND METHOD OF THE REPORTLISTENER CLASS AND CHECKING THE

* NUMBER OF GDI OBJECT HANDLES IN USE BY THE CURRENT PROCESS AND NOT ALLOWING IT TO EXCEED THE

* 10,000 HANDLE LIMIT. GetGuiResources(-1,0) RETURNS THE NUMBER OF GDI OBJECT HANDLES IN USE.

*

* STEPS TO REPRODUCE:

* ===================

* TO TEST THIS PROBLEM CREATE A SIMPLE REPORT THAT WILL PRODUCE MORE THAN 5000 PAGES BY CREATING

* A CURSOR OF 5000 ROWS IN THE INIT OF THE DATAENVIRONMENT WITH A VERY TALL DETAIL BAND SO THAT

* EACH PAGE WILL CONTAIN A SINGLE DETAIL BAND AND PREVIEW THE REPORT WITH SET REPORTBEHAVIOR 90.

* OPEN UP TASK MANAGER BEFORE RUNNING THE REPORT AND SELECT THE PROCESSES TAB AND SELECT ADD COLUMN

* FROM THE VIEW MENU OPTION AND ADD GDI OBJECTS TO THE COLUMNS DISPLAYED. THEN AS YOUR REPORT

* RUNS YOU WILL BE ABLE TO SEE THE GDI OBJECTS BEING ALLOCATED BY THE VFP9 PROCESS UNTIL IT

* EVENTUALLY REACHES 10,000 AND BEGINS PAINTING INCORRECTLY ON THE DESKTOP.

*

* WORKAROUND:

* ===========

* ADD THE FOLLOWING CODE TO THE INIT EVENT OF YOUR REPORTLISTENER:

*

DECLARE LONG GetGuiResources IN USER32 LONG, LONG

*

* THEN, TO KEEP VFP FROM CRASHING VIOLENTLY DURING A REPORT PREVIEW YOU SHOULD ADD THE CODE LISTED

* BELOW TO THE BEFOREBAND METHOD AND WARN THE USER THAT THE REPORT PREVIEW WAS TERMINATED EARLY AND

* THAT ALL PAGES OF THEIR REPORT WERE NOT ABLE TO BE LOADED INTO THE PREVIEW.

*

* YOU COULD OFFER YOUR USERS A WAY TO PREVIEW A RANGE OF PAGES TO GET AROUND THIS ISSUE OR USE

* SET REPORTBEHAVIOR 80 WHICH DOES NOT EXHIBIT THIS ISSUE.

IF GetGuiResources(-1,0) > 9000

MESSAGEBOX("Warning! You are about to exceed the Page Limit in the VFP 9 Report Preview!"+CHR(13)+CHR(13)+;

"Report Preview halted early. Not all report pages have been displayed.",48,;

"Visual FoxPro 9 Report Preview Limitation!")

THIS.CancelReport()

ENDIF

ENDIF

Sergio,

You have been able to create a Printer DeviceContext with VFP ever since you could declare Win32 API DLLs. So, writing directly to a printer DC is straight forward. Painting to a Printer DC in memory does not have the same problem as painting to a VFP Form. When you paint onto a Printer DC just the drawing is not erased until the DC is either cleared or printed unlike a Form that is always getting repainted when other forms are moved in front it.

So, writing to a VFP Form directly using GDI/GDI+ API calls presents a problem, because the VFP Form does not persist the GDI drawing commands for you on the Form and each time the form needs to be refreshed like when another form moved over the top of your form, all of the GDI drawing commands have to be redrawn onto the Form. And the problem with this is that prior to VFP 9, the OnPaint event didn't fire as reliably for performance issues and so your code in the OnPaint Event might not fire and your drawing appears to have disappeared.

However, a workaround would be to paint onto an Image Object because VFP does persist that object on the form and repaints it as needed when it has been overwritten by another object.

MONDAY MAY 30, 2005

· Added support to CANCEL out of a large Multi-Page Save As Image output.
· Talked to Bo about supporting HTML drawing of text inside of the MERE engine. Bo was able to get an HTML page rendered to an EMF. Discussed the ways that an EMF could be rendered to a MERE PAGE of Continuous Length and then be split by checking the VPOS of all of the objects and then slicing the page up into smaller chunks and moving the objects to individual pages using MARGIN settings to control how much will be painted onto each individual page.
·
·

Wednesday April 28, 2004

· Learned that the SPACING field in the FRX can sometimes be set to 2 depending on the version of VFP. However, in VFP 7, when a Field is added it defaults to 0 which represents Single Line Spacing. Also, the LINE SPACING CANNOT be changed for a FIELD.
· Spacing Field is used for LABEL Objects where 0 = Single Line Spacing, 1 = 1 1/2 Line Spacing and 2 = Double Line Spacing
·

Saturday January 29, 2005

· Working on support for GDI+ within the MERE ActiveX control. DrawString and DrawLine are not working properly. The DrawString Method is not drawing anything onto the CurrentCanvas surface as well as causing all subsequent lines to be drawn as if their location was being shifted on the fly.

Sunday January 30, 2005

· I found the solution to the GDI+ DrawString support by looking at the examples in the GDI+ library in the Delphi Downloads folder. I was not creating a FontFamily Object to define the font.
·

Tuesday April 19, 2005

· BUGS: COPYPAGETOCLIPBOARD is not drawing the same as the regular engine anymore for text and for shapes that are getting Filled. Check out the Demo.
· Fixed the _PAGENO and _PAGETOTAL processing in the MERE_ReportListener Class.
· NEED TO FIX:
· BUG: Need to fix the TRIMMING STYLE code to match VFP.
· BUG: _PAGENO and _PAGETOTAL by themselves need to be RIGHT ALIGNED NUMERIC
· BUG: FONT SIZE TESTING.FRX : Fix the LINE SPACING on multiple space lines.
· BUG: CARRIAGERETURNTEST.FRX Demonstrates the TRIMMING STYLE BUG: Need to fix the TRIMMING STYLE code to match VFP.
· BUG: SIMPLE WITH IMAGE.FRX has a bug in that the Lines in the Report Header are not matching the bottom of the Fonts of the REPORT HEADER Title Band.
· NEW: Add Support for switching between GDI+ and GDI printing for Text as a Property so older Adobe PDF Writers work properly with the DRAWSTRING() Command.
· NEW: Finish adding in the DPE Support to the MERE_RL
· NEW: Add a progress Bar Support for the Report Engine.
· NEW: Add support for the CommandClauses Properties that might be useful.
· REMOVE: Remove the SaveToPDF and AddText() Methods on the PreviewForm
·


Report Properties (COPY)

Mind's Eye Report Engine Report Properties

 Top

REPORT PROPERTIES

Property Name | Data Type | Description
nBackgroundColor | Numeric | Specifies the background color behind the page area in the Report Engine Preview.
nCurrentPageHeight | Numeric | The page height of the current page.
nCurrentPageOrientation | Numeric | The Orientation of the current page.
nCurrentPageWidth | Numeric | The page width of the current page.
nGridColor | Numeric | Specifies the color to display the grid bars.
nLastError | Numeric | The last error that occurred while processing a request.
nPageNumber | Numeric | The current page number being displayed in the Report Engine Preview.
nPageOrientation | Numeric | Specifies the current orientation of the current page as either Portrait or Landscape.
nPaperColor | Numeric | Specifies the color of the paper on the Report Engine Preview.
nPrintScale | Numeric | Specifies the amount of scaling when printing report pages. This property is not currently used.
nReportObjects | Numeric | The number of Report Objects on the current page.
nTotalPages | Numeric | The number of pages currently loaded into the Report Engine. Read/Only


Using the Report Engine Control

 Top

The Report Engine control is an ActiveX control that can be placed onto a form in VFP, VB, Delphi, C++, etc. for Creating, Previewing and Printing Reports.

The control can be scripted to precisely add Text, Lines, Shapes and Pictures onto Report Pages. The control is a container for a Report Object. The Report Object contains Page Objects and each Page Object contains Report Display Objects. Report Display Objects can be added to a particular Report Page by calling the AddText, AddReportField, AddLine, AddPicture and AddShape methods of the control. These methods allow for placing objects onto a Page Object with 10,000th of an inch precision.

The control does not require that it be used with a User Interface. There is an example of this in the ReportToPDF() Method in the MindsEyeReportEngine Visual Class Library.


VFP Rendering BUGS

 Top

BUGS REPORTED

THURSDAY September 23, 2004

· BUG: COLUMN HEADER SHAPE Objects are NOT properly stretching.
· BUG: UNSELECTING GrayScale Printing on the Canon from the PROPERTIES Button DOES NOT feed back the COLOR setting back to the MERE Printer Dialog box after the selection.
· BUG: MERE IS NOT Preserving the GAP at the Bottom of the DETAIL BAND SWO Object in the Multi-Column Report like VFP is.
·

Wednesday May 19, 2004

· BUG: Space at Bottom of GROUP FOOTER IS NOT BEING PRESERVED. (Dan Elek)
· BUG: PRINT WHEN on GROUP HEADER and DO NOT REPEAT IS BEING Repeated. (SHLOMO)

·

PRIOR RENDERING BUGS

· BUG: Fix the PDF BARCODE output as per Dennis Jordahl
· BUG: 1 1/2 and DOUBLE SPACE not being supported properly.
· BUG: BASICREPORTFORMATS.FRX - The GROUP HEADER GAP IS NOT BEING RESPECTED and Added into the VERTICAL GAPS BETWEEN RECORDS
· BUG: TESTLINESTRETCH.FRX is not printing STRETCHED FIELDS IN THE PAGE FOOTER.

BAND OBJECT RENDERING

RENDERING BUGS

· REPORTCHECKOUT FOLDER BUGS
· BASICGROUPSTRETCH.FRX - The GAP AFTER THE GROUP FOOTER is not being preserved between BANDS.
· BUG: VERTICAL POS IS NOT TRACKING PROPERLY WHEN ONLY TEXT IN A BAND AND THERE IS A GAP BETWEEN THE BOTTOM OF THE TEXT AND THE START OF THE NEXT BAND.
· BUG: REMOVE LINE IF BLANK ISSUE. BANDS ARE NOT REMOVING OBJECTS WITH RLIB OBJECTS IN THEM.
· BUG: CREATE RULE TO DETERMINE WHEN BANDS COLLAPSE AT BOTTOM WITH RLIB
· BUG: VERNON HOPE: SUMMDRAW FOLDER - After fixing the problem with the really long stretches over bands causes this one to draw only one line per page after the first page.
· BUG: You can see lines creeping up the page when objects extend past multiple pages.
·

FIXED BUGS

· FIXED: 00RLIBMEITEST.FRX - Text is overlapping after a STRETCH in the DETAIL BAND. The GROUP FOOTER BAND is overwriting the DETAIL BAND as if it wasn't tracking how tall it got. There was an RLIB Line that moved up all of the items in the DETAIL BAND and thus caused the VERTMAXPOS to not update tall enough.
· FIXED: RUNAWAY REPORT: T34B_O2.FRX - The report just runs and runs and runs and never finishes the pages as complete. When the DETAIL BAND was shortened a slight amount, the DB Data fit onto the page. However, if it was lengthened by 0.2 inches the DB Data DID NOT FIT and then we had a runaway condition. This needs to be trapped and returned as an error.


VFP Rendering Engine To Do List

 Top

DAN SUTHERLAND RENDERING BUGS

· RLIB: Lines NOT MOVING UP when rendering where the lines are deleted between do to a PRINT WHEN.
· BUGGY REPORTS:
· BUG: Fix 1 1/2 and DOUBLE LINE SPACING Labels
· BUG: 00MEITESTT24X_18.FRX - The Lines are not collapsing completely when there is multiple lines of text being deleted. This Example has 3 RE's Stacked on top of each other with a Line Below them. The 2 middle RE's are EMPTY and are set to RLIB and are not removing enough space between themselves and the line below. The line below should be pulling up more.
· PROBLEM: The RLIB CONFLICT CHECKER IS NOT PROPERLY DOING AN ALIGNMENT TEST FOR CONFLICTS BECAUSE IT IS PLACING A TEXT OBJECT IN CONFLICT WITH A LINE EVEN THOUGH THE TEXT OBJECT IS ABOVE THE LINE. THEREFORE IT HAS TO DO WITH THE VPOSTOP AND HEIGHT.
· BUG: 00MEIRLIB_18.FRX - The Lines are not STACKED ON TOP OF EACH OTHER.
·

·

RENDERING COLUMNS

· HORIZONTAL COLUMN RENDERING
· RULES
· NO STRETCHING ALLOWED IN ANY BANDS
· VPOS Only Updated when in LAST COLUMN
·
·
· VERTICAL COLUMN RENDERING
· RULES
· STRETCHING ALLOWED IN BANDS DOWN THROUGH THE GROUP FOOTER, NO STRETCHING IN COLUMN FOOTER OR PAGE FOOTER
· VPOS always updated
·

REMOVE LINE IF BLANK RULES

BOTTOM GAP PRESERVATION:

If there is a GAP Between the bottom of the Bottom Object in the BAND it is Preserved.

· Track the Vertical Position down then band as we are drawing down the Band. Then we need to track how far down the BAND we have drawn and measure that distance to the bottom of the BAND and add that difference into the VPOS adjustment.
· As we track the objects as we paint down the page we have to know the objects completed to know where to draw next.
·

NEED TO TRACK

· DID BAND COMPLETE
· Last Height Printed
· Need to Know if Last Band was Completed
· Need to Know those Objects that need to be Reprinted when DETAIL OVERFLOWS to NEW PAGE/COLUMN
· Need to see if we can skip updating ALL Objects wen rerendering
·


Visual FoxPro Use and How it Works

 Top

A Visual FoxPro Class Library called MindsEyeReportEngine was written to call the Methods of the Mind's Eye Report Engine ActiveX Control. A separate VIsual FoxPro Class Library called MindsEyeReportPreviewForms was also created that includes two Visual FoxPro Form Classes named MindsEyeReportPreviewForm and a subclass of this form named MindsEyeReportPreviewTopLevelForm. The only change to the MindsEyeReportPreviewTopLevelForm is that it has the ShowWindow Property set to 2 - As Top-Level Form. The MindsEyeReportPreviewForm Form Class is used to host an in instance of the Mind's Eye Report Engine ActiveX (Olecontrol) Control. In order for the MindsEyeReportEngine Class to function properly, the name of the Mind's Eye Report Engine ActiveX control placed on the MindsEyeReportPreviewForm Form Class must be named oReportEngine.

The MindsEyeReportEngine class has custom Methods and Properties that can read a VFP FRX Report and process the Report Metadata.

Running VFP FRX Reports

The method to call to execute a VFP Report is:

ReportFormPreview(cReportFileName, nShowWindow, nLeft, nTop, nWidth, nHeight)

This method will open the FRX Report File passed and run the Report and load the output into the Report Engine/Preview ActiveX Control which has already been placed onto the MindsEyeReportPreviewForm FORM Class defined in the MindsEyeReportEngine Class Library. It is very important for the MindsEyeReportEngine Class's Methods to work properly that the name of the OLECONTROL on the MindsEyeReportPreviewForm FORM Class be named: oReportEngine. If you replace the OLECONTROL with an update of the control that needs to be added in order to embed your LICense file, make sure that you rename the control to oReportEngine from the default name of OLECONTROL1. Additionally, you can specify the exact Location and Size of the Report Preview Form that is created.

Appending VFP Reports

You can easily load multiple VFP Reports into the Report Preview. Simply call the AppendReport(cReportFileName) Method after your first report to run and load another VFP FRX Report. Each report can have a different Page Size and Orientation. You are only limited to the number of pages by the amount of memory on your PC.

A custom Toolbar class was also created to mimic the VFP Report Preview Toolbar called MEIReportPreviewToolbar. This toolbar will automatically be created when the ReportFormPreview method is called. The Report Preview Toolbar buttons call the REPC's Methods to Navigate Pages, Print the Report, Save the Report to PDF, and Close the Report Preview.

Most of the VFP Report processing code was written in Delphi to improve performance. However, you could actually write new methods all in VFP to run a VFP FRX Report and load the output into the Report Engine/Preview Control. This would then permit the creation of Subreports and other features to be added where you are only limited by your imagination.

Since the REPC has the ability to move from page to page at any time and have objects added you can process a complete VFP Report and then go back to Page 1 and add some more text or titles, etc.


Visual FoxPro 9 Support

 Top

Visual FoxPro 9 is best supported using the new Mind's Eye Report Engine ReportListener Class. Visual FoxPro 9 introduces the new ReportListener class which directly interfaces with the native Visual FoxPro Report Writer Engine. As Visual FoxPro 9 renders a report, the ReportListener exposes several events of the native Visual FoxPro Report Writer which allows MERE to intercept what was rendered by the VFP 9 RW and pass this output information into MERE. This allows MERE to run at near native VFP RW speed since all of the rendering calculations and work load are now left with Visual FoxPro's native Report Writer engine. MERE simply adds the output objects into a MERE report.

Mind's Eye Report Engine Visual FoxPro 9 Benefits

· Improved Performance
· Improved Rendering Accuracy
· Lower Memory Overhead using MERE over VFP native Preview
· All rendering calculations are now performed by Visual FoxPro
· All Report Variables and Calculated Fields are handled by Visual FoxPro

Visual FoxPro 9 renders each page in a report preview as an Enhanced Metafile image in memory which contains a lot of overhead especially for reports using images.


Visual FoxPro Issues, Limitations and Workarounds

Visual FoxPro FRX Report Engine Known Issues and Limitations

 Top

The following topics discuss the running of Visual FoxPro reports using the MindsEyeReportEngine Visual Class Library and the VFP Report support built into the Mind's Eye Report Engine ActiveX control. The rendering of Visual FoxPro Reports is done completely without using of the REPORT FORM command in Visual FoxPro. The Rendering Engine is a mixture of Visual FoxPro code which reads the report's FRX Table and then interprets the layout of the report from the FRX. The MindsEyeReportEngine Class then opens the tables in the DataEnvironment of the FRX or uses the tables already open and then begins processing the data and sending the output to the ActiveX control for rendering into the ActiveX control's Report Engine Page Collection. Measuring of text widths and breaking up text strings into multiple lines is all handled in the ActiveX control for maximum performance. There is a lot of looping code that runs in order to count the width of every single character in each string to see if it will fit within the given string width on the report.

If a Report Field object is not set to stretch it will be truncated as close

_PAGENO and _PAGETOTAL Max Values are 32,767

The _PAGENO variable is used in Visual FoxPro to track what the current PAGE NUMBER is for the Report Writer. However, it has a limited range value of between 1 and 32,767. Therefore if any reports are ran that use the _PAGENO Report Variable and their report is expected to go over 32,767 pages, you may have unexpected results. Therefore, if you are expecting to run reports that will exceed the 32,767 limit of the _PAGENO variable, it is advised to create your own Report Variable and update it in the Page Header or Page Footer band since these bands will fire for each and every page.

The same limitation exists in VFP 5 through VFP 8 for the _PAGENO variable. The _PAGETOTAL variable was not introduced into the VFP language until VFP 8. It also has the same value limitations as the _PAGENO variable.

Rendering Visual FoxPro Reports

The Mind's Eye Report Engine renders Visual FoxPro Reports independently of the selected printer. This is by design just like other tools that create PDF documents. However, it is possible to control the amount of space used on the page for rendering an FRX report using the nBottomMargin Property of the MindsEyeReportEngine Class. The nBottomMargin Property be default is set to 0.25 inches and can be set between 0 and 3 inches before rendering your report.

nBottomMargin


Visual FoxPro Native Report Writer Anomolies

 Top

Line Stretching Issues

There are several line stretching issues that I have observed in my development of the FRX support of the Mind's Eye Report Engine.