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.

    Code

    #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.

    Code

    #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.

    Code

    #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

    Concepts

    Using GDI+ in Reports

    Reference

    ReportListener Object

    CommandClauses Property

    ListenerType Property

    LoadReport Event

    OutputPageCount Property

    PageNo Property

    Shape Control

    Container Object

    The Preview Container API

    Other Resources

    Methods (Visual FoxPro)

    Language Reference (Visual FoxPro)