Foxite.COM Community Weblog

Foxite.COM Community Weblog - free weblog service for the Visual FoxPro Community.
Welcome to Foxite.COM Community Weblog Sign in | Join | Help
in
Home Blogs Forum Photos Forum Archives

VFP IMAGING



Gradient Backgrounds in your forms with GDI+

This one goes to Bernard Bout.

After reading this post check also: Gradient Backgrounds in your forms with GDI+ Part 2

GDI+ allows to create many cool effects such as Gradient Colors. This feature was not included in _gdiplus.vcx, but can also be accessed easily with a simple call to the Flat API. A great part of the codes below that are related to the creation of the Gradient Brush is from Bo Durban.

To apply this to forms is really easy. Add the codes below to the LOAD, RESIZE AND DESTROY events of any form:

Load Event

LOCAL lcGradFile
lcGradFile = ADDBS(SYS(2023))+SYS(2015)+".bmp"
This.AddProperty("cTempGradFile",lcGradFile)

IF FILE(lcGradFile)
 CLEAR RESOURCES (lcGradFile)
ENDIF

LOCAL lnRGBColor1
lnRGBColor1 = RGB(60,30,180)
&& Blue

* Create Gradient Image
SET CLASSLIB TO HOME() + "ffc/_gdiplus.vcx" ADDITIVE

* Declare API
DECLARE Long GdipCreateLineBrushI IN GDIPLUS.dll ;
   String point1, String point2, ;
   Long color1, Long color2, ;
   Long wrapMode, Long @lineGradient

* Create a colorObject and store ARGB color values to variables
LOCAL loClr AS GpColor OF HOME() + "ffc/_gdiplus.vcx"
LOCAL lnColor1, lnColor2
loClr = CREATEOBJECT("gpColor")
loClr.FoxRGB = lnRGBColor1
lnColor1 = loClr.ARGB
loClr.FoxRGB = RGB(255,255,255) && White
lnColor2 = loClr.ARGB

* Create a bitmap
LOCAL loBmp AS GpBitmap OF HOME() + "ffc/_gdiplus.vcx"
loBmp = CREATEOBJECT("gpBitmap")
loBmp.Create(1,Thisform.Height)

* Get a bitmap graphics object
LOCAL loGfx AS GpGraphics OF HOME() + "ffc/_gdiplus.vcx"
loGfx = CREATEOBJECT("gpGraphics")
loGfx.CreateFromImage(loBmp)

* Get a gradient brush
LOCAL loBrush as GpBrush OF HOME() + "ffc/_gdiplus.vcx"
LOCAL hBrush && Brush Handle
hBrush = 0
GdipCreateLineBrushI(BINTOC(0,"4rs")+BINTOC(0,"4rs"), ;
      BINTOC(0,"4rs")+BINTOC(Thisform.Height,"4rs"), ;
      lnColor1, lnColor2, 0, @hBrush)
loBrush = CREATEOBJECT("gpBrush")
loBrush.SetHandle(hBrush, .T.)

* Fill the bitmap with our gradient
loGfx.FillRectangle(loBrush,0,0,1,Thisform.Height)
loBmp.SaveToFile(lcGradFile,"image/bmp")

Thisform.AddObject("ImgBackGround","Image")
WITH Thisform.ImgBackGround
   .Stretch = 2
   .Width = Thisform.Width
   .Height = Thisform.Height
   .Picture = lcGradFile 
   .Visible = .T.
ENDWITH
RETURN

 

Resize Event

Thisform.ImgBackGround.Width = Thisform.Width
Thisform.ImgBackGround.Height = Thisform.Height

 

Destroy Event

WITH Thisform
   IF FILE
(.cTempGradFile)
      CLEAR RESOURCES (.cTempGradFile)
      ERASE (.cTempGradFile)
  
ENDIF
ENDWITH

 

NEW GDI+ CLASSES

The code I presented in the LOAD event works pretty fine, but sounds really ugly, when comparing to what we will be able to do when the new Sedna-X GDI+ classes will be released:

The code below will substitute all codes related to the creation of the gradient color in the LOAD event.

I just can't wait until the classes are finished !

Their work is really brilliant, and will add much more than a wrapper class ! 

* Create GDI+ Linear Gradient Image using xfc GDI+ classes from Bo Durban and Craig Boyd
DO LOCFILE("System.App")

LOCAL loBmp AS xfcBitmap
LOCAL loGfx AS xfcGraphics
LOCAL loBrush AS xfcBrush
WITH _Screen.System.Drawing 
     loBmp = .Bitmap.New(1, Thisform.Height
     loGfx = .Graphics.FromImage(loBmp) 
     loBrush = .Drawing2D.LinearGradientBrush.New( ; 
        .Rectangle.New(0, 0, 1, Thisform.Height), ; 
        .Color.FromRGB(lnRGBColor1), .Color.White, 1) 
     loGfx.FillRectangle(loBrush, loBrush.Rectangle) 
     loBmp.Save(lcGradFile, .Imaging.ImageFormat.Bmp) 
ENDWITH

Click to download the source code of this form example

Published Tuesday, June 13, 2006 6:37 AM by cesarchalom
Filed Under:
Attachment(s): gradient.zip

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Craig Bailey said:

Fantastic. I love your blog and your great examples. This is a good one. Too easy!
June 13, 2006 10:09 AM
 

Craig Boyd said:

Great post Cesar. I believe this is one of the first examples using the new GDIPlusX library that has been posted outside of SednaX. You've made my day.
June 13, 2006 11:34 AM
 

Bernard Bout said:

Hey Thanks Cesar. My question about using RGB colours has been answered by this:
.Color.FromRGB(lnRGBColor1),

I saw the Method but did not know how to use it.

Also a tutorial on how the xfc classes are instantiated using XFCSystem :
and how the _access events are used to create new objects, etc.

I am totally confused.

Hey Bernard, I'm glad to know it helped you. There's still a lot of work to do in the new classes. But you can easily get great information from MSDN. Their target is to immitate the GDI+ classes from VB .NET. In MSDN and in other links you'll find lots of examples using these classes. Start using the keywords "system.drawing".

Regards

Cesar

June 13, 2006 12:24 PM
 

Cesar Chalom said:

June 13, 2006 2:39 PM
 

Craig Bailey on Visual FoxPro » Blog Archive » LINK: Cesar Chalom VFP Gradient background forms said:

June 13, 2006 6:14 PM
 

Malcolm Greene said:

Cesar!

Yes! Another exciting code example! Beautiful!!! For those following this thread, Cesar's technique can also be used to add gradient backgrounds to containers as well.

Obrigado!

Some additional ideas:

1. You can eliminate your Resize() code using VFP 9's awesome Anchor property:

* make following changes to Load method
*!* .Width = Thisform.Width
*!* .Height = Thisform.Height
.Move( 0, 0, Thisform.Width, Thisform.Height )
.Anchor = 15

2. You can eliminate your Destroy() code using VFP 9's not-so-awesome PictureVal property:

* make following changes to Load method
*!* .Picture = lcGradFile
.PictureVal = filetostr( lcGradFile )
delete file (lcGradFile)

The reason I say 'not-so-awesome' is that using the PictureVal property *significantly* slows down form painting during a form resize and, interestingly enough, also seems to display a slightly different appearance than when the image is loaded from file via .Picture.

Anyone have any feedback on why PictureVal performs so poorly and/or a workaround? Intuitively, I would have thought that PictureVal would have been faster than Picture since the image is in memory vs. on disk.

3. If you have a fixed size form (or container!) you can skip the image object altogether and set the form's or container's Picture property directly to the gradient file you generated (lcGradFile).

4. If you're thinking about using this technique in many areas, Cesar's code is perfect for building a self-contained image gradient class that sizes (and anchors) to its parent and whose destroy event automatically deletes the temp gradient file.

A question for you and your audience:

Any ideas on a technique for generating gradients that match XP color schemes? Office 2003 and many 3rd party menu/toolbar components use a technique that generates various types of gradients based on the current XP theme colors. Since all these applications do this consistently, there must be a common technique being used.

If we (VFP community) want to make our applications look like a million dollars then this is the MILLION DOLLAR question :)

Thanks again Cesar!

Malcolm
June 15, 2006 8:23 PM
 

Cesar Chalom said:

Thank you all for the kind words.

Craig Boyd, you don't need to be so humble, because your and Bo's great work is going to change the lives of VFP users completely. In my honest opinion, after you release the new GDI+ classes, we will be able to tell the world that VFP10 was released. I'm a big fan of you both. You can't imagine how much I've learned just looking at your code. Thank you. Thank you. Thank you.
June 16, 2006 5:50 AM
 

Cesar Chalom said:

Hey Malcolm,
All your comments, ideas and fixes are always welcome !
I hope to apply your ideas in my next post.
Regards
Cesar
June 16, 2006 5:54 AM
 

Claudio Z said:

Cool.
How can I make the gradient be in the diagonal ?
June 18, 2006 10:37 PM
 

Cesar Chalom said:

Hi Claudio,
Pls Check this link for diagonal LinearGradientBrushes
http://weblogs.foxite.com/cesarchalom/archive/2006/06/22/1906.aspx
June 22, 2006 8:51 AM
 

wopos eking said:

good job ,thanks
June 27, 2006 9:14 AM
 

Cesar Chalom said:

Unfortunately, a strange error occured for some people when using some of the samples for the creation...
January 24, 2007 4:00 PM
 

ss said:

cool!!!!!!!!!!!!!!
February 4, 2007 10:12 AM
 

Noel said:

I try using this codes for making my forms more beautifull, but when i build a executable then it doesnt work, i dont know what else i should do, i just copy and pasted the code in my forms

You probably need to add the library _gdiplus.vcx to your project. What's the error you are getting ?

April 22, 2007 6:49 PM
 

Ana María Bisbé said:

Versión en Español de este artículo en / Spanish version at http://www.portalfox.com/article.php?sid=2248
July 24, 2007 6:58 PM

What do you think?

(required) 
(optional)
(required)