Search Wiki:
Resource Page Description
Visual FoxPro 9.0 introduced the ReportListener class, which allows you to affect the output of a report while it is running. This sample uses the open-source GDIPlusX library, providing a set of wrapper classes to GDI+, to change the trimming behavior of strings in the report.

Before running this code, download the GDIPlusX libraries from CodePlex at http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX, unzip them, and make sure that the location is in the search path.

StringTrimOutput.png
*****Start of code*****
#DEFINE FRX_OBJCOD_DETAIL 4
 
LOCAL i as Integer ;
 , loListener as ReportListener ;
 , loExc as Exception 
 
CREATE CURSOR crsrRLStringTrim (cField C(240))
FOR i = 1 TO 5
 *!* http://www.baen.com/library/1011250002/1011250002.htm
 INSERT INTO crsrRLStringTrim VALUES ;
  ("Peace to you, small lady, he thought to Raina. " + ;
  "You've won a twisted poor modern knight, to wear your " + ;
  "favor on his sleeve.")
ENDFOR
 
*!* Passing oListener to the REPORT FORM command below will cause the
*!* report to display with 9.0 behavior regardless of the setting here:
*!* CREATE REPORT, though, doesn't know about the listener, so we need
*!* to change SET REPORTBEHAVIOR.
SET REPORTBEHAVIOR 90
 
CREATE REPORT RLStringTrim FROM crsrRLStringTrim
MODIFY REPORT RLStringTrim NOWAIT
 
SUSPEND
*!* While you're suspended here, change the field in the report so that it
*!* doesn't stretch with overflow. Then close and save the report, and resume.
 
loListener = CREATEOBJECT("RLStringTrim")
 
*!* This initializes the GDIPlusX classes. If it's not in your path, run it
*!* manually and continue.
DO system.prg
 
TRY
 REPORT FORM RLStringTrim OBJECT loListener
CATCH TO loExc
 MESSAGEBOX(loExc.Message)
ENDTRY 
 
DEFINE CLASS RLStringTrim AS REPORTLISTENER
 oGraphics = .NULL.
 oFont = .NULL.
 oFormat = .NULL.
 oBrush = .NULL.
 
 lDetail = .F.
 
 ListenerType = 1
 
 PROCEDURE Init
  *!* Unfortunately, StringTrimming isn't just a property we can flip.
  *!* It's part of the formatting we use to draw a string. Hence, to
  *!* change this, we need to do all the work needed to actually
  *!* draw the string.
 
  WITH _SCREEN.System.Drawing AS xfcDrawing OF system.drawing.prg
   This.oGraphics = .Graphics.New()
   This.oFont = .FONT.New("Courier New", 10, .FontStyle.Regular, .GraphicsUnit.POINT)
   This.oFormat = .StringFormat.New()
   This.oBrush = .Brushes.Black
  ENDWITH
 ENDPROC
 
 PROCEDURE Destroy
  This.oGraphics = .NULL.
  This.oFont = .NULL.
  This.oFormat = .NULL.
  This.oBrush = .NULL.
 ENDPROC
 
 *!* In here, we only want to change the text in the detail lines. So,
 *!* on the way into the detail band, we set a property to tell us
 *!* that we're in that band. On the way out, we turn it back off.
 PROCEDURE BeforeBand
  LPARAMETERS nBandObjCode, nFRXRecNo
 
  IF nBandObjCode = FRX_OBJCOD_DETAIL
   This.lDetail = .T.
  ENDIF
 
  DODEFAULT(nBandObjCode, nFRXRecNo)
 ENDPROC
 
 PROCEDURE AfterBand
  LPARAMETERS nBandObjCode, nFRXRecNo
 
  IF nBandObjCode = FRX_OBJCOD_DETAIL
   This.lDetail = .F.
  ENDIF
 
  DODEFAULT(nBandObjCode, nFRXRecNo)
 ENDPROC
 
 PROCEDURE Render
  LPARAMETERS nFRXRecNo ;
   , nLeft, nTop, nWidth, nHeight ;
   , nObjectContinuationType ;
   , cContentsToBeRendered ;
   , GDIPlusImage
 
  IF This.lDetail
   WITH _SCREEN.System.Drawing AS xfcDrawing OF system.drawing.prg
    *!* Tell the graphics class what we're drawing on
    This.oGraphics.Handle = This.GdiPlusGraphics
 
    *!* Set the string trimming feature to one of the 5
    *!* non-default values. Each record should be set
    *!* differently, so using RECNO() is a quick-and-
    *!* dirty way to get the values.
    This.oFormat.Trimming = RECNO()
 
    *!* Create a GDI+ Rectangle which specifies where on the
    *!* surface we're drawing the text.
    loRect = .Rectangle.New(nLeft, nTop ;
     , nWidth, nHeight)
 
    *!* cContentsToBeRendered, in a field object, contains a
    *!* Unicode string, instead of the ASCII we typically work
    *!* with. Therefore, since the GDIPlusX DrawString method
    *!* is expecting a regular DBCS string, we need to convert
    *!* it back.
    This.oGraphics.DrawString(STRCONV(cContentsToBeRendered, 6) ;
     , This.oFont, This.oBrush ;
     , loRect, This.oFormat)
   ENDWITH
  ELSE
   *!* If we're not in the detail band, let Fox draw the text as
   *!* usual.
   DODEFAULT(nFRXRecNo ;
    , nLeft, nTop, nWidth, nHeight ;
    , nObjectContinuationType, cContentsToBeRendered, GDIPlusImage)
  ENDIF
 
  *!* Since we already drew the text, we don't want the default
  *!* behavior to occur.
  NODEFAULT
 ENDPROC
ENDDEFINE
*****End of code*****
Last edited Feb 4 at 10:21 PM  by SarekOfVulcan, version 7
Updating...
Page view tracker