OutputPage Method

Provides access to the current page or the full range of pages for a report run, according to the value of the ListenerType property.

oReportListener.OutputPage(;
                  nPageNo, ;
                  eDevice, ;
                  nDeviceType ;
                 [,nleft, nTop, nWidth, nHeight ;
                 [,nClipLeft,nClipTop, nClipWidth, nClipHeight]])

Parameters

  • nPageNo
    In page-at-a-time mode (ListenerType values 0 and 2), ReportListener uses this parameter to send you the current page number as it prepares each page for output. You can request that this single page be rendered to an alternate device at this point.

    In all pages-at-once mode (ListenerType values 1 and 3), you use this parameter to send the ReportListener the page number you wish to render.

    For more information about supported ListenerType values, see ListenerType Property.

  • eDevice
    Provides a handle, reference, or filename for the device to which output is rendered.

    When its ListenerType property value is 0, ReportListener uses this parameter to send you a GDI+ graphics handle to the current printer. When its ListenerType property value is 2, output is not actually going to a printer, so ReportListener sends you the value 0.

    In all pages-at-once mode (ListenerType values 1 and 3), you use this parameter to send the ReportListener one of the following:

    • A GDI handle to a printer.

    • A GDI+ graphics handle to another output device.

    • A reference to an object derived from either the Visual FoxPro Shape or Container baseclass.

    • A filename.

    You tell the ReportListener what type of eDevice value you send in this parameter by sending an appropriate value in nDeviceType.

  • nDeviceType
    Represents the type of Device to which output is rendered.

    Value Device Type

    -1

    No device.

    The ReportListener sends this value when it triggers OutputPage in ListenerType 2.

    0

    hDC (GDI handle).

    You can send a GDI handle to the ReportListener, to send output to an alternate printer.

    1

    hGraphics (GDI+ graphics handle).

    The ReportListener sends this value when it triggers OutputPage in ListenerType 0. You can send it to the ReportListener, to send output to a different GDI+ context, such as a window.

    2

    oFoxControl.

    Use this value to tell the Report Listener to create a preview display, using a Visual FoxPro Shape or Container control.

    100

    This value specifies a filename, to be saved as image of EMF type.

    101

    This value specifies a filename, to be saved as image of TIFF type.

    102

    This value specifies a filename, to be saved as image of JPEG type.

    103

    This value specifies a filename, to be saved as image of GIF type.

    104

    This value specifies a filename, to be saved as image of PNG type.

    105

    This value specifies a filename, to be saved as image of BMP type.

    201

    This value specifies a page to be saved additively into a previously-created TIFF, generating a multi-page TIFF file.

    Tip

    The ReportListener is able to perform some extra optimization of this file format when you use this value before a report run finishes. For a ReportListener with ListenerType 0 or 2, the OutputPage event happens during this time. An example of this usage is shown below. For a ReportListener with ListenerType 1 or 3, you can call OutputPage during the AfterReport Event to take advantage of the optimization.

  • [nleft, nTop, nWidth, nHeight,[nClipLeft,nClipTop, nClipWidth, nClipHeight]]
    These optional parameters are not relevant when nDeviceType is 2 (a Visual FoxPro control surface).

    The first set of four coordinates (nleft, nTop, nWidth, nHeight) specifies the coordinates, in units of 1/960 inch (960 dpi), of the rectangle on the current device in which this occurrence of the layout element will be rendered. The second set of four coordinates (nClipLeft,nClipTop, nClipWidth, nClipHeight) allows a preview-type output device to indicate that only a portion of the page needs to be refreshed.

Return Value

None.

Remarks

Applies To: ReportListener Object.

The OutputPage method is unusual because, depending on the current ListenerType value, a ReportListener either triggers this method to signal you that a page is ready or expects you to trigger the calls yourself, to request the pages you want.

Understanding OutputPage's Two Processing Modes

In the first processing mode, the ReportListener acts in a style appropriate to printers and other output devices that handle output one page at a time. If necessary, these devices place incoming pages in a spool or queue until they are ready to handle more pages. This type of page-processing is forward-only; you cannot ask for any specific page a single time, after the ReportListener has begun rendering subsequent pages.

In the second processing mode, the ReportListener prepares all pages at once, effectively providing a queue of all pages until the device is ready to request them. You cannot request any pages until all pages are prepared. However, this type of page-processing results in a cached, or scrollable, collection of pages, as required by previewing devices; once the pages are prepared, you can request them in any order, and, you can request them multiple times.

Error-handling for OutputPage Parameters

The parameter list to OutputPage is complex and some parameters have multiple uses. For this reason, it may be difficult to interpret the errors you receive when you use the parameters incorrectly.

The following are the error messages you can expect if you send the ReportListener unexpected or inappropriate values when using this method.

Error message and number Conditions triggering this error

Must specify additional parameters (Error 94)

Triggered if you do not include all three required parameters (nPageNo, eDevice, nDeviceType).

Function argument value, type, or count is invalid (Error 11)

Triggered if nDeviceType receives an unrecognized value.

DataType property for field 'eDevice' is invalid (Error 1544)

Triggered if the eDevice argument’s data type does not match the requirements for a valid value in nDeviceType.

For example, you might receive this value if nDeviceType is 0 or 1 and eDevice is not a valid handle, or if nDeviceType is one of the filename types but eDevice is not a string representing a valid filename.

Error writing to file 'filename' (Error 1105)

Triggered if nDeviceType is one of the filename types and eDevice appears valid but the file cannot be created. For example, the user might not have permissions to create a file in the specified directory.

Output page 'pageno' is not available (Error 2194)

Triggered if nPageNo is not appropriate to the current rendered pages, or if the ListenerType value is not properly set to one of the values (0, 1, 2, or 3) in which the ReportListener renders pages.

For more information about Visual FoxPro error messages, see Error Messages Listed Numerically. For more information about what to do when errors occur when you process reports, see Handling Errors During Report Runs.

Warning

In addition to the error messages above, which you may see if you invoke OutputPage with incorrect parameters, be aware that OutputPage needs resources available to the report even when you call it after the report run concludes. For example, if image file used in a report is built into your calling application, a call to OutputPage from a PreviewContainer needs access to that image file. Although no error message is generated, your report output will not be complete if you unload the application from which the REPORT FORM or LABEL command was issued.

Examples

Example 1: OutputPage in page-at-a-time mode for image files from output pages

This sample code creates a multipage Tag Image File Format (TIFF) document from a report. It uses the native ReportListener ability to specify the OutputPage nDeviceType parameter as 101, to create a TIFF file, followed by additional calls with an eDeviceType value of 201, to add into this TIFF document for subsequent pages. This ReportListener derived class uses a ListenerType value of 2, so the native code invokes OutputPage as it prepares each page.

Tip

The ReportListener class's native ability to provide images of pages as various file types is limited to some default settings for each image type it supports. In the case of TIFFs, ReportListener provides compressed TIFFs for performance. However, you are not limited to the settings provided in the native implementation. You can give the ReportListener a GDI+ graphics handle and, in the OutputPage method, request that it render a page to this device. You can then save the result to an image file with non-default specifications. Visual FoxPro supplies a class library to help you perform this and other GDI+-related tasks. For more information, see GDI Plus API Wrapper Foundation Classes.

#define OutputNothing -1
#define OutputTIFF 101
#define OutputTIFFAdditive (OutputTIFF+100)

LOCAL oReportListener
oReportListener = NEWOBJECT("MPTiffListener")
oReportListener.Filename = "Multi"

WAIT WINDOW "Processing report to TIFF file...." NOWAIT
REPORT FORM ? OBJECT oReportListener 
WAIT CLEAR

DEFINE CLASS MPTiffListener AS ReportListener

   PROCEDURE Init
      THIS.AddProperty("Filename", "temp")
      THIS.ListenerType = 2
   ENDPROC
   
   PROCEDURE BeforeReport
      ERASE THIS.Filename
   ENDPROC

   PROCEDURE OutputPage(nPageNo, eDevice, nDeviceType)
      IF (nDeviceType == OutputNothing)
         IF (nPageNo == 1)
             nDeviceType = OutputTIFF
         ELSE 
            nDeviceType = OutputTIFFAdditive
         ENDIF
         THIS.OutputPage(nPageNo, THIS.Filename, nDeviceType)
         NODEFAULT
     ENDIF
   ENDPROC

ENDDEFINE

Example 2: OutputPage in page-at-a-time echoing output to the display

This example provides a replacement for backward-compatible reporting's echoed output to the display, when the keyword NOCONSOLE is not used on the REPORT FORM Command. It uses the OutputPage method's ability to write to a GDI+ Graphics handle. If the REPORT FORM specifies NOCONSOLE, the ReportListener object does not provide display output.

By default, this ReportListener uses a ListenerType value of 2, so it invokes OutputPage as it prepares each output page but has no native output result. It evaluates CommandClauses Property values to check for the NOCONSOLE keyword, and also to evaluate the user's specified output target. If the user chose to generate output to a printer, a file, or preview, this class adjusts its behavior to match previous versions of Visual FoxPro.

#DEFINE OUTPUTDEVICETYPE_GDIPLUS 1
#DEFINE OUTPUTTO_PRINT           1
#DEFINE OUTPUTTO_FILE            2
#DEFINE LISTENER_TYPE_PRN        0
#DEFINE LISTENER_TYPE_PRV        1
#DEFINE LISTENER_TYPE_PAGED      2
LOCAL loRL, loForm
loRL = CREATEOBJECT("EchoListener")
REPORT FORM ? OBJECT loRL && output to the console
REPORT FORM ? OBJECT loRL NEXT 1 TO PRINT && output to console and print
_SCREEN.Cls && clear screen
REPORT FORM ? OBJECT loRL PREVIEW && to preview only, no console output
loForm = CREATEOBJECT("form")
loForm.Caption = "My Output Window"
loForm.Show()
REPORT FORM ? OBJECT loRL TO FILE c:\temp\x.txt && to file and output window
REPORT FORM ? OBJECT loRL TO FILE c:\temp\x.txt NOCONSOLE && to file only

DEFINE CLASS EchoListener as ReportListener
  ListenerType = LISTENER_TYPE_PAGED 

  GP = 0
  RHeight = 0
  RWidth = 0
  
  PROCEDURE LoadReport()
    IF THIS.CommandClauses.Preview
       THIS.ListenerType = LISTENER_TYPE_PRV 
    ELSE
       IF INLIST(THIS.CommandClauses.OutputTo,OUTPUTTO_PRINT,OUTPUTTO_FILE)
          THIS.ListenerType = LISTENER_TYPE_PRN
       ENDIF
    ENDIF   
  ENDPROC   
  
  PROCEDURE BeforeReport()
     IF NOT (THIS.CommandClauses.NoConsole OR THIS.CommandClauses.Preview)
        DECLARE integer GdipCreateFromHWND IN GDIPLUS.DLL ;  
          integer hwnd, integer @ nGraphics
        LOCAL lH, nG
        nG = 0
        IF TYPE("_SCREEN.ActiveForm") = "O"
           m.lH = _SCREEN.ActiveForm.HWnd
        ELSE   
           m.lH = _SCREEN.HWnd 
        ENDIF   
       IF GdipCreateFromHWND( m.lH, @nG ) = 0
          THIS.GP = m.nG
          THIS.RHeight = THIS.GetPageHeight()/10 && convert 960 DPI to 96 DPI
          THIS.RWidth = THIS.GetPageWidth()/10
       ENDIF   
    ENDIF   
  ENDPROC

  PROCEDURE OutputPage(nPageNo, ;
                  eDevice, ;
                  nDeviceType, ;
                  nleft, nTop, nWidth, nHeight, ;
                  nClipLeft,nClipTop, nClipWidth, nClipHeight)
      IF THIS.GP # 0 
         DODEFAULT(nPageNo, THIS.GP,OUTPUTDEVICETYPE_GDIPLUS , ;
                   0,0,THIS.RWidth, THIS.RHeight, ;
                   0,0,THIS.RWidth, THIS.RHeight)            
      ENDIF             
                     
  ENDPROC
  
  PROCEDURE UnloadReport()
     * reset:
     IF NOT THIS.GP = 0
        DECLARE integer GdipDeleteGraphics IN GDIPLUS.DLL integer
        GdipDeleteGraphics( THIS.GP )
        THIS.GP = 0
     ENDIF
     THIS.ListenerType = LISTENER_TYPE_PAGED 
  ENDPROC
   
ENDDEFINE   

Example 3: OutputPage in all-pages-at-once mode

This example uses a ListenerType value of 3, so the native ReportListener class does not invoke OutputPage as it prepares pages. Instead, this derived class invokes OutputPage after the report run concludes, and displays the output to a simple preview object contained by a form. As this example shows, by varying the dimensions of the preview object, you can vary and control zoom level using any algorithm or restrictions you prefer. By passing a reference to this object in the OutputPage method, you instruct the native code what size you want for the previewed page. The native OutputPage behavior takes care of scaling the preview output appropriately.

Tip

Notice that this class's DoOutputPage wrapper code for the OutputPage method checks to see that the external call to the method has included a valid page number before invoking native OutputPage code, to avoid errors.

#DEFINE BASEPAGEHEIGHT  550
#DEFINE BASEPAGEWIDTH 425

CLEAR ALL  
oListener = NEWOBJECT("zoomListener")
oForm = CREATEOBJECT("form")

WITH oForm
   .ScaleMode = 3
   .allowOutput = .F.
   .top = 0
   .left = 0
   .height = BASEPAGEHEIGHT
   .width = BASEPAGEWIDTH
   .backcolor = RGB(255,255,255)
   .Show()
ENDWITH   

oListener.PreviewContainer = oForm
REPORT FORM ? OBJECT oListener
oListener.DoOutputPage(1,1)
WAIT window  ;
   "Previewing at 100%... " + ;
   "press any key for the next preview zoom level"
oListener.DoOutputPage(2, .21123 ) 
WAIT window ;
   "Previewing at 21.123%... " + ;
   "press any key for the next preview zoom level"
oListener.DoOutputPage(3,2.367) 
WAIT window ;
   "Previewing at 236.7%... "

DEFINE CLASS zoomListener AS ReportListener
   ListenerType = 3 

   PROCEDURE DoOutputPage(tPage, tMultiplier)
      LOCAL liPage
      IF VARTYPE(tPage) = "N" AND ;
         BETWEEN(tPage,;
                 THIS.CommandClauses.RangeFrom, ;
                 IIF(THIS.CommandClauses.RangeTo=-1, ;
                     THIS.PageTotal, ;
                     THIS.CommandClauses.RangeTo))
         liPage = INT(tPage)
      ELSE
         liPage = THIS.CommandClauses.RangeFrom    
      ENDIF               
      THIS.SetPreview(tMultiplier)   
      THIS.OutputPage(liPage,THIS.PreviewContainer.MyPreview,2) 
   ENDPROC

   PROCEDURE SetPreview(tMultiplier)
      LOCAL liHeight, liWidth
      IF TYPE("THIS.PreviewContainer.MyPreview") # "O" 
         THIS.PreviewContainer.AddObject("MyPreview","shape")       
      ENDIF
      IF VARTYPE(tMultiplier) = "N" AND ;
         BETWEEN(tMultiplier,.01, 10)
         liHeight = BASEPAGEHEIGHT * tMultiplier
         liWidth  = BASEPAGEWIDTH * tMultiplier
         WAIT WINDOW ;
            "H:" + TRANSFORM(liHeight)+ ;
          ", W:" + TRANSFORM(liWidth) TIMEOUT 1
         * note that VFP will round the pixels 
         WITH THIS.PreviewContainer
            .LockScreen = .T.            
            .MyPreview.Height = liHeight
            .MyPreview.Width = liWidth
            .Height = liHeight
            .Width = liWidth 
            .LockScreen = .F.
            .Cls()                   
         ENDWITH
      ENDIF
   ENDPROC

   PROCEDURE Destroy
      THIS.PreviewContainer = NULL
   ENDPROC

ENDDEFINE

See Also

Reference

ReportListener Object
CommandClauses Property
ListenerType Property
LoadReport Event
OutputPageCount Property
PageNo Property
Shape Control
Container Object
The Preview Container API

Concepts

Using GDI+ in Reports

Other Resources

Methods (Visual FoxPro)
Language Reference (Visual FoxPro)