Resource Page DescriptionVisual 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. 
*****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*****
|