One of the most interesting additions that the GdiPlusX library brings is the ImageCanvas object. It’s a subclass of the VFP’s original image object, that allows to draw directly on the image object using the graphics commands from GDI+ without accessing the disk. It renders images super fast, and brings many new possibilities for VFP users.
The ImageCanvas class permits rendering graphics on a VFP form, bringing the possibility to draw directly to a VFP Image control, instead of drawing using the form’s HWnd. This way developers don’t need to worry about the Windows Paint updates. It works super fast ! Images are stored in memory, avoiding disk access and performance loss.
Basically, the created image is saved to a stream. Streams are similar to standard files but they are stored in the memory. The image is retrieved from the memory, and stored in the PictureVal property of the Image object.
In this short tutorial I'll show how you can draw directly to the Image object, taking benefits from Intellisense. At the end of the sample code you'll find some code that shows how you can save the just created image to a file, and print it !
IMPORTANT:
All samples below use the new GDIPlus-X library, that is still in ALPHA version, but is already stable and reliable to do the majority of GDI+ tasks. Download the latest stable release from Codeplex:
http://www.codeplex.com/Wiki/View.aspx?ProjectName=VFPX&title=GDIPlusX
Properties
| oGfx |
The GDI+ Graphics object that we will use to direct draw on the canvas |
| oBmp |
The Bitmap object associated to this canvas |
| Rectangle |
Returns a GDI+ rectangle object with the dimensions of this ImgCanvas |
Some other secondary properties available that deal directly with the Graphics object, like: InterpolationMode, RenderMode, SmoothingMode and TextRenderingHint. You can find some complete information about these on MSDN.
Methods
| BeforeDraw |
Here you will place all codes that will create your image. |
| Draw |
Call this method to make the ImageCanvas execute the code placed in “BeforeDraw”. Have in mind that this method is fired when the ImgCanvas is initialized. |
| AfterDraw |
Method is executed after the Draw method is finished |
Below is a simple tutorial showing how you can work with the ImageCanvas:
1 - Create a new form, “TestCanvas.scx”
2 - Open the Project Manager of the latest GdiPlusX library, select the “Classes” tab, expand “GdiPlusX”, selecting the ImgCanvas Object

3 - Drag and Drop the “ImgCanvas” object to the form.
4 - DoubleClick on the image object, select the “BeforeDraw” method.
5 - To make our drawings easier, let's enable Intellisense for the Graphics - oGfx - Property of the Image Canvas.
Now, start adding some code:
WITH _Screen.System.Drawing
* To allow Intellisense for "This.oGfx"
Local loGfx As xfcGraphics
loGfx = This.oGfx
* Test Intellisense for "This.oGfx"
* Type letter by letter the text below:
loGfx.
This simple trick will bring Intellisense to us every time that we will type “loGfx.”
I also strongly recommend that you have a look at this previous post, that shows some other Intellisense tips when working with the GdiPlus-X library, "Be more productive with GdiPlus-X".
6 - Now let’s add some code to the “BeforeDraw” method to see our Canvas in action (you can see immediately each part of code the resulting image that was created):

Copy and paste the code below to the BeforeDraw() method of the Image Canvas:
WITH _Screen.System.Drawing
* To allow Intellisense for "This.oGfx"
Local loGfx As xfcGraphics
loGfx = This.oGfx
* Create a Linear Gradient Brush
Local loGradBrsh As xfcLinearGradientBrush
loGradBrsh = .Drawing2D.LinearGradientBrush.New(;
This.Rectangle, .Color.LightBlue, .Color.DarkBlue, 1)
* Draw a rectangle using the whole rectangle from the canvas and the Gradient Brush
loGfx.FillRectangle(loGradBrsh, This.Rectangle)
* Draw a Triangle
Dimension laPoints(3)
laPoints(1) = .Point.New(20, 100)
laPoints(2) = .Point.New(90, 100)
laPoints(3) = .Point.New(55, 40)
loGfx.FillPolygon(.Brushes.Green, @laPoints)
* Draw two Rectangles
loGfx.FillRectangle(.Brushes.Yellow, 20, 100, 70, 50)
loGfx.FillRectangle(.Brushes.Gray, 90, 100, 100, 50)
* Draw a Trapeze
Dimension laPoints(4)
laPoints(1) = .Point.New(55, 40)
laPoints(2) = .Point.New(90, 100)
laPoints(3) = .Point.New(190, 100)
laPoints(4) = .Point.New(155, 40)
loGfx.FillPolygon(.SolidBrush.New(.Color.FromRGB(128,0,0)), @laPoints)
* Create a path containing two curves
Local myPath As xfcGraphicsPath
myPath = .Drawing2D.GraphicsPath.New()
myPath.StartFigure()
Dimension points(4)
points(1) = .Point.New(45, 150)
points(2) = .Point.New(65, 170)
points(3) = .Point.New(45, 190)
points(4) = .Point.New(65, 210)
myPath.AddCurve(@points)
myPath.AddLine(.Point.New(65,210), .Point.New(85, 210))
points(1) = .Point.New(85, 210)
points(2) = .Point.New(65, 190)
points(3) = .Point.New(85, 170)
points(4) = .Point.New(65, 150)
myPath.AddCurve(@points)
myPath.AddLine(.Point.New(65,150), .Point.New(45, 150))
* Draw the path
loGfx.FillPath(.Brushes.Orange, myPath)
loGfx.DrawPath(.Pen.New(.Color.Black, 1), myPath) && Black Border

* Draw the Sun
Local loPath As xfcGraphicsPath
loPath = .Drawing2D.GraphicsPath.New()
loPath.AddEllipse(280, 20, 40, 40)
Local loPathGradBrush As xfcPathGradientBrush
loPathGradBrush = .Drawing2D.PathGradientBrush.New(loPath)
loPathGradBrush.CenterColor = .Color.Red
loPathGradBrush.SurroundColors[1] = .Color.Yellow
loGfx.FillEllipse(loPathGradBrush, 280, 20, 40, 40)
* Draw a string
loGfx.DrawString("GdiPlusX is cool !!!", ;
.Font.New("Tahoma", 20), .Brushes.Red, 110, This.Height - 40)

* Save the Image to Disk
This.oBmp.Save("String.png", .Imaging.ImageFormat.Png)
* Print the Image
This.oBmp.ToPrinter()
ENDWITH
Run the form to see the output from the above code:

There are lots of things that you can do with the canvas. Almost all the samples from the GdiPlus-X library use the ImageCanvas object, due to all the facilities it brings for drawing.
After you understand how it works, drawing with GDI+ will be just like cutting a piece if cake !