Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
ReportListener Run-Time field alignment
Message
 
To
08/10/2004 02:25:02
Walter Nicholls
Cornerstone Software Ltd
Auckland, New Zealand
General information
Forum:
Visual FoxPro
Category:
Visual FoxPro Beta
Miscellaneous
Thread ID:
00949327
Message ID:
00949927
Views:
29
Walter,

You are abosolutely right! Since I use the GDI object in several places in my custom ReportListener class, I decided to add the objects as properties of the class, then just set their properties when needed.

I added a new "object" Property to my custom ReportListener class:
oGDIObj = .NULL.
This property will act as a "container" for all my GDI objects. Each GDI object that I need to instantiate using the _GDIPluss.vcx class, will be a member of this container. (They could be instantiated as individual properties of the ReportListener itself, but I prefer this method because they are all grouped together.)

I added this code to the Init() method:
this.oGDIObj = NewObject('Empty') &&Instantiate GDI "container" object.

*Add an object for each piece of GDI functionality we need.
AddProperty(this.oGDIObj, "oGr", .NULL.)
AddProperty(this.oGDIObj, "oBounds", .NULL.)
AddProperty(this.oGDIObj, "oBrush", .NULL.)
AddProperty(this.oGDIObj, "oFont", .NULL.)
AddProperty(this.oGDIObj, "oStringFormat", .NULL.)

*Instantiate the GDI objects.
this.oGDIObj.oGr = Newobject('GpGraphics','_gdiplus.vcx')
this.oGDIObj.oBounds = Newobject('GpRectangle','_gdiplus.vcx')
this.oGDIObj.oBrush = Newobject('GpSolidBrush', '_gdiplus.vcx')
this.oGDIObj.oFont = Newobject('GpFont','_gdiplus.vcx')
this.oGDIObj.oStringFormat = Newobject('GpStringFormat','_gdiplus.vcx')

Now, these objects do not need to be created/destroyed for each Render() call that uses them.

I am using the "Directives" class Cathy Poutney discusses in her MSDN articles on the VFP 9.0 report writer. I have created a "Directive" subclass for performing text alignment manipulation. (The Directive class is called from and receives the same parameters as the Render() method.) So, the GDI part of the code in that class now looks like this:

llTextType = INLIST(Frx.ObjType, FRX_OBJTYP_LABEL, FRX_OBJTYP_FIELD)

*Text is stored as UniCode, convert.
If llTextType = .T.
lcContents = STRCONV(TRANSFORM(tcContentsToBeRendered),STRCONV_UNICODE_UTF8)

With this.oListener.oGDIObj
.oGr.SetHandle(This.oListener.GDIPlusGraphics) &&Pointto the graphics handle that the ReportListener already created.
.oBounds.Create(lnX, lnY, tnWidth, tnHeight) &&Create a rectangle object using the dimensions passed to the Render() method.
.oBrush.Create() &&Can pass ARGB or a Color object
.oStringFormat.Create()

*Apply Settings
.oBrush.BrushColor = 0xA8000000 &&66% black
.oStringFormat.Alignment = lnAlign &&Use the alignment retrieved from the data record.
.oFont.Create("Arial", 10, GDIPLUS_FontStyle_Regular, GDIPLUS_Unit_Point) &&Font name, Size in units, Attributes, Units

*Draw the String
.oGr.DrawStringA(lcContents, .oFont, .oBounds, .oStringFormat, .oBrush) &&Can avoid converting UniCode above, by using DrawStringW() here.
EndWith
EndIf

As you can see, I now only have to "set" the appropriate GDI properties. Is this what you meant, and does this logic make sense to you?

Thank You,
Paul
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform