Sometimes users need to make some basic modifications in images that are part of the application, and it is not comfortable for them too have to look for files, choose places to save, etc... In the vast majority of cases, MS-Paint does the job, but I always needed it to be customized... and I couldn't.
After being challenged by Frank Cazabon in a Foxite thread, I finally took the courage to create my own "Paint" application, using GDI+.
VFPPaint works much like MSPaint, and creates a canvas that permits you to draw whatever you want with the mouse.
It's just one single 50k SCX file that does all the job, in partnership with the GdiPlusX library.


IMPORTANT
Requires VFP9 and GdiPlusX to run. 
The latest stable version of GdiPlusX is dated 11th May 2007 - Alpha 0.8a. Please make sure that you have the latest version, because VFPPaint uses some functions that were added recently.
http://www.codeplex.com/VFPX/Wiki/View.aspx?title=GDIPlusX&referringTitle=Home
When you run VFPPaint.SCX it will ask you to select the folder where GDIPlusX library is located.
Features:
- Draw points, rectangles lines and ellipses with the mouse.
- Text drawing, choose any font, size and style, and it will appear at the place that you click on the image. (Drag and drop to choose the best place)
- Choose any color, from the palette or directly from the loaded image or canvas and select the pen width that you want to draw.
- Select the shape or type of drawing in the graphical option buttons, and then go to the canvas (Image object) and click the left mouse button.
- Drag and drop is available for rectangles, lines and ellipses.
- Basic UNDO features
- Rotate and flip images
- Resizing images
- Printing and saving images
Basic Commands:
All images are generated without disk access, using the new pictureval property of the image control. For this specific case, I didn't use the ImageCanvas that ships with GdiPlusX because I needed some extra customization. After the latest release of GdiPlusX, getting the PictureVal property of an image has became very simplified, with the new methods added to the image class - GetPictureVal and GetPictureValfromHBitmap.
As sometimes we need to work with an image that is bigger than our screen, the drawing canvas was put in a "In TopLevelForm" that has scrollbars.
Another cool feature is the "UNDO" possibilities. VFPPaint stores the previous bitmap in a cache. This can be improved too, maybe you need to "undo" in higher level. For this, very few code is needed.
When drawing on the canvas, try dragging and dropping the objects. For this, the "undo" feature was highly used, because the shape is drawn, and when the user moves the mouse, it restores the original image from the buffer and draws again in the new position.
When a big sized image is loaded, first it asks if the canvas needs to be resized.

Scrollbars appear in the image to help dealing with it. In a first moment, I thought of using the very nice CTL32 scrollable container from Carlos Aloatti and Malcolm Greene, but I gave up because I needed the PictureVal property, that is present only in the default image control. So, there are currently 2 forms in the screenshot below. One is a "In TopLevel" form that contains just one Image object, and resides in the main VFPPaint form. The other form is a "TopLevel form". The image object from the "child form" changes its size automatically, depending on the image dimensions. When this object is resized, the child form automatically resizes itself, and shows and adjusts the scrollbars if needed.

Resizing sample:

VFPPaint also accepts that you pass an image file as a parameter. This way, you'll be able to open the form loading automatically the desired image to edit. Run the form like this:
DO FORM vfppaint WITH "eyes.gif"
In case you pass a GIF image as a parameter, it will be automatically converted to 24bpp. That's because GIFs are Indexed images. A classic example of indexed images are Monochrome. Pure monochrome images use only 1 bit per pixel. So, in just one byte you can store information of 8 pixels ! In the case of GIFs, they are usually 8 bits per pixel, so in one bit we can have a value that ranges from 0 to 255 - that's exactly the quantity of colors supported by GIFs ! Unfortunately, the redistributable version of GDI+ has a limitation when working with images created in indexed pixel formats, such as 1bppIndexed (0x00030101), 4bppIndexed (0x00030402) and 8bppIndexed (0x00030803). If you try to draw on this kind of images you'll always receive an error message when you'll create the Graphics object, that permits to you to draw on the image. More detailed info about this can be found in this post: DRAWING ON GIFS OR INDEXED PIXEL FORMAT IMAGES WITH GDI+ http://weblogs.foxite.com/cesarchalom/archive/2006/03/18/1302.aspx . That's why GIFs are converted to a 24bpp format before initializing the Painting possibilities.
This still has a lot that can be improved, like adding special effects, such as brightness, contrast, hue adjustments, cutting and pasting image portions, saving and retrieving images or pieces of image in the clipboard, etc.
But the main thing is that this totally customizable. The more important in this form is the technique that was used, and you'll see that there's not too much code there.
This still needs to be more tested. Feel free to call me if you find any problems or have suggestions. Maybe some of your needs can be of interest to be added to VFPPaint, and I'll be happy to improve it.
Any feedback is very welcome!
Download
http://weblogs.foxite.com/files/cesarchalom/vfppaint/vfppaint.zip