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 COMMAND BUTTONS WITH GDI+

Using some of the techniques presented in my previous posts, (read Gradient Backgrounds in your forms with GDI+), I've created a very simple subclass of the commandbutton object, in order to create gradient background effects.

Please take note that this is an unfinished class. I'm posting it here at this moment to show to people that we can obtain very cool effects using GDI+.

This is how the form looks in development mode:

Below you can see the form running, when GDI+ creates the backgrounds.

Properties that you need to fill to have the desired results:

Caption, FontBold, FontUnderline, FontItalic, FontStrikeThru

Picture,

BackColor (with the main color to be used as background)

GradientMode (0 = NO Gradient  1 = Vertical-Default  2 = Horizontal  3 = Diagonal1  4 = Diagonal2)

 

How the class was created:

I used the CommandButton Base class, to make it have the most common usage and understanding possible, making the development mode the most seemed to the result obtained when running the form.

In the INIT event of the class, it verifies the gradient direction, and creates a LinearGradient Brush, using the color defined in the BackColor property of the object. The second color was set to white as default. Then it draws a rectangle using this brush in a picture just created, that has the same dimensions of the CommandButton.

The next step is to check if there is a picture assigned to the button; if yes, draw it to the left side, centered in the vertical.

If the Caption property was set, then draw the string, centered in horizontal and vertical.

In this example I'm only using GIFs with transparent background, so that the background is preserved..

 

The codes

The main code stays in the INIT event of the CommandButton subclass:

WITH This

LOCAL lcGradFile, lnGradMode, lnGradPixels, x1, y1, x2, y2, lnWidth, lnHeight
lnGradMode = .GradientMode
IF lnGradMode = 0
   RETURN && No Gradient Background !
ENDIF

lcGradFile = ADDBS(SYS(2023))+SYS(2015)+".bmp"
.cTempGradFile = lcGradFile

LOCAL lcPicture, lcCaption, lnRGBColor1
lcPicture = .Picture
lcCaption = .Caption
lnRGBColor1 = .BackColor

lnWidth = .Width
lnHeight = .Height

DO CASE
   CASE
lnGradMode = 1 && Vertical
     y1 = 0
     x2 = 1
     y2 = lnHeight
   CASE lnGradMode = 2 && Horizontal
     y1 = 0
     x2 = lnWidth
     y2 = 1
   CASE lnGradMode = 3 && Diagonal TopLeft -> BottomRight
     y1 = 0
     x2 = lnWidth
     y2 = lnHeight
   CASE lnGradMode = 4 && Diagonal BottomLeft -> TopRight
     y1 = lnHeight
     x2 = lnWidth
     y2 = 0
ENDCASE

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

* 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(.Width, .Height)

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

* Declare API
DECLARE LONG GdipCreateLineBrushI IN GDIPLUS.DLL ;
   STRING point1, STRING point2, ;
   LONG color1, LONG color2, ;
   LONG wrapMode, LONG @lineGradient


* Get a gradient brush
LOCAL loBrush AS GpBrush OF HOME() + "ffc/_gdiplus.vcx"
LOCAL hBrush && Brush Handle
hBrush = 0
GdipCreateLineBrushI(BINTOC(0,"4rs") + BINTOC(y1,"4rs"), ;
   BINTOC(x2,"4rs") + BINTOC(y2,"4rs"), ;
   lnColor1, lnColor2, 0, @hBrush)

loBrush = CREATEOBJECT("gpBrush")
loBrush.SetHandle(hBrush, .T.)

* Fill the bitmap with our gradient
loGfx.FillRectangle(loBrush,0,0,.Width, .Height)

* Draw the Desired picture
IF NOT EMPTY(lcPicture)
   LOCAL loPict AS GpImage OF HOME() + "ffc/_gdiplus.vcx"
   loPict = CREATEOBJECT("gpImage")
   loPict.CreateFromFile(lcPicture)

   x1 = 1
   y1 = (.Height - loPict.ImageHeight) / 2
   loGfx.DrawImageAt(loPict,x1, y1)
ENDIF

* Draw the Caption
#DEFINE fontstyleregular 0
#DEFINE fontstylebold  1
#DEFINE fontstyleitalic  2
#DEFINE fontstyleunderline 4
#DEFINE fontstylestrikeout 8

#DEFINE unitworld  0
#DEFINE unitdisplay  1
#DEFINE unitpixel  2
#DEFINE unitpoint  3
#DEFINE unitinch  4
#DEFINE unitdocument 5
#DEFINE unitmillimeter 6

IF NOT EMPTY(.Caption)
   LOCAL lnFontStyle
   lnFontStyle = fontstyleregular  + ;
      IIF(.FontBold, fontstylebold, 0) +;
      IIF(.FontItalic, fontstyleitalic, 0) +;
      IIF(.FontUnderline, fontstyleunderline, 0) +;
      IIF(.FontStrikethru, fontstylestrikeout, 0)

 LOCAL loFont AS GpFont OF HOME() + "ffc/_gdiplus.vcx"
 loFont = NEWOBJECT('GpFont', HOME() + 'ffc/_gdiplus.vcx')
 loFont.CREATE( .FontName&& font name
    , .FontSize ;       && size in units below
    , lnFontStyle ;    && fontStyle
    , unitPOINT )           && units

 * Create SolidBrush with the ForeColor
 LOCAL loSolidBrush AS GpSolidBrush OF HOME() + "ffc/_gdiplus.vcx"
 loSolidBrush = NEWOBJECT('GpSolidBrush', HOME() + 'ffc/_gdiplus.vcx','',0)

 loClr.FoxRGB = .ForeColor
 loSolidBrush.BrushColor = loClr

 * Measure the Height of the caption to calculate vertical position
 LOCAL loStringSize AS GpSize OF HOME() + 'ffc/_gdiplus.vcx'
 lostringsize = loGfx.MeasureStringA(.Caption, loFont)

 lnPictWidth = IIF(EMPTY(lcPicture), 0,loPict.ImageWidth)
 x1 = lnPictWidth + ((.Width - lnPictWidth - 1) - loStringSize.w) / 2
 y1 = (.Height - lostringsize.h) / 2

 * Create PointF with the position of Caption
 lcTextPoint = BINTOC(X1,'F') + BINTOC(Y1,'F')
 loGfx.DrawStringA(.Caption, loFont, lctextPoint, , loSolidBrush)
ENDIF

 * Save image to file
loBmp.SaveToFile(lcGradFile,"image/bmp")

.Picture = lcGradFile

ENDWITH
RETURN

 

In DESTROY event, we just delete the temporary image created

IF This.GradientMode = 0
   RETURN && No Gradient Background !
ENDIF

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

 

To be improved:

- PicturePosition - at this moment, it will always work as "1 - left of caption, centered relative to caption". VFP9 brings 14 position options, this can be done easily in a future version.

- add another property to receive the 2nd color ( at this moment, white - RGB(255,255,255) is default)

- permit to create 3 color gradients, allowing for example: blue - white - blue

- to deal with a disabled commandbuttons. Please send suggestions / or pictures showing how the control should look when disabled !

- permit to receive any image, and create the transparency of the backgrounds.

 

The icons that I used to create this example were taken from http://www.iconbazaar.com , where you can find many cool GIFs

You can download the source code from the first version of the class from here:

 

07/19/2006 - UPDATED VERSION OF THE CLASS

I've received many suggestions, and created a new version of the class, adding many other features.

You can download the most recent version of the class and some Forms using it from this link : 
http://weblogs.foxite.com/files/cesarchalom/gradobjects/gradobjects.zip

When running the form "testGradButtons", please pass the mouse over the buttons and also click the "DISABLE" button.

Here are some screenshots of the new version:

 

As always, please send your comments, suggestions and fixes !

Published Tuesday, July 11, 2006 6:55 AM by cesarchalom
Attachment(s): GradCmdButton.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

 

Plinio said:

Terrific!
July 11, 2006 2:22 PM
 

Lorenzo said:

Beautifull !!! Great visual class is amazing and easy utility.Thank you for it. And you keeping gating better.
July 11, 2006 5:07 PM
 

Plinio II said:

I feel good
July 11, 2006 5:55 PM
 

Gelson Luis Bremm said:

Grande Cesar!
O Mr. GDI

Muito bom exemplo,
Parabéns
July 12, 2006 2:33 AM
 

Carlos Fernando said:

Show de bola !

Vou pegar o código para ver se aprendo um pouco :-)

Abração
July 14, 2006 2:50 AM
 

Cesar Chalom said:

UPDATED VERSION OF THE CLASS

I've received many suggestions, and created a new version of the class, adding many other features.

I'd be grateful to receive comments, critics or suggestions, in order to improve the control.

If anyone is interested, pls download the most recent version of the class and some Forms using it from this link :
http://www.geocities.com/macmarbr/gradcmdbutton.zip

When running the form "testGradButtons", please pass the mouse over the buttons and also click the "DISABLE" button.

TIA

Cesar

July 14, 2006 6:07 PM
 

Naomi said:

Looks very nice on these pictures!
July 14, 2006 6:18 PM
 

Luis Navas said:

Great class Cesar, thanks for sharing it. When you go with keyboard to a button it applies the nice efect (like when mouse is over it) but when you pass the mouse over another button even if you dont change focus, the button with the focus loses the effect.
July 14, 2006 9:37 PM
 

Erick said:

Parabéns César!
Belo trabalho!!!
July 15, 2006 5:11 PM
 

Cesar Chalom said:

Gracias Luis !
I've already updated the class, fixing that bug, and some few enhancements.
Thanks for testing !
http://www.geocities.com/macmarbr/gradcmdbutton6.zip
Cesar
July 17, 2006 6:17 AM
 

Keith Gordijn said:

Hi Cesar,

Fantastic class, enabled me to do gradient backgrounds for any object that has a picture property.  I have also altered your code somewhat to enable printing of the hotkey character in a different color.  Parses out the \< and calculates the position to draw the character at, pretty simple really.  Not sure how to get the changes back to you.
Cheers
July 17, 2006 7:38 AM
 

Cesar Chalom said:

Hi Keith,
Great Idea !
And easy to implement indeed.
You can send your modifications to : cchalom at hotmail dot com
Thanks for testing and evaluating the class.
Cesar
July 17, 2006 2:14 PM
 

Luis Navas said:

Great that you fix the error. Hey Cesar, why don't you put this in VFPX to create a toolbox of components with gradient effects, we can have containers, Pageframes, etc. With the help of all and you we can create great stuff.
July 17, 2006 4:00 PM
 

Cesar Chalom said:

Maybe the best would be to send to VFP-X a project "MAKE IT COOL", in which people could work with all kinds of gradients, in all kinds of controls and menus. Recently, I've seen many solutions and ideas. You can visit Bernard Bout's blog entries here at Foxite too.
I also don't know if this project would fill the VFP-X prerequisites.

Maybe we can work together, adding features, using this space, UT forums, wherever. My intention is to share it with the community.
If you want to help, you can contact me directly.
Regards
Cesar

July 17, 2006 5:31 PM
 

Luis Navas said:

Sure, can you be the leader? maybe we can make a schedule to define the steps to follow.
July 18, 2006 3:02 PM
 

Cesar Chalom said:

Yes, we can work together on that.
Keith Gordijn sent me some cool modifications about to "enable printing of the hotkey character in a different color.  Parses out the \< and calculates the position"
Thanks Keith, I hope to add this feature in the next version.

Perhaps we can work together on that, also calling Bernard Bout, that has great ideas too, looking for the best performance.
Pls contact me at cchalom at hotmail dot com
July 19, 2006 3:25 PM
 

HernánCano said:

Estaba recibiendo el error que una función no estaba definida; registré la DLL y ese error ya no aparece, pero me aparece otro con respecto a una de las funciones BIN (creo que es la BINTOC); en la ayuda encontré que el segundo parámetro debe ser numérico, y en el código de la clase aparecen letras mayúsculas entre comillas.  Qué debo hacer?
Gracias.

I was receiving some error about "function not defined"; I reegistered the DLL and that error disapeared. But now I'm getting another respect to one of the BIN functions (BINTOC?, not sure this moment); on the help I found that the second parameter must be numeric, but on the class code ther are capital letters inside double comillas (I beg your pardon about my english).  What must I do?
Thanks.
July 24, 2006 11:55 PM
 

Cesar Chalom said:

Hernan,
Pls tell me exactly in which method and line the error is occurring. What VFP version are you using? The control works only with VFP9. VFP9 added some new and very important modifications in BINTOC and CTOBIN commands, that permit working with floats.

Desculpe mi portuñol,
Por favor, explique en que metodo el error esta ocorriendo.
Que version de VFP estas utilizando ?
El control funciona solamente con VFP9
July 27, 2006 2:17 PM
 

Cesar Chalom said:

I've published a new version of the class, with some new screenshots and a more detailed explanation about the features and properties to be set:
http://weblogs.foxite.com/cesarchalom/archive/2006/07/26/2076.aspx
August 1, 2006 6:04 PM
 

SENET Jean-Pierre said:

Sorry to post this here but i didn't finf how to contact cesar chalom
I have been trying to use the two classes together (gradbuttons + imgcanvas) and i get a bug saying, too many nested loop and
Fatal error: Exception code=C0000005 @ 12/13/05 08:17:56 AM. Error log file: C:\Program Files\Microsoft Visual FoxPro 9\vfp9err.log
Called from -  masterconvert.destroy line 656  {C:\Program Files\Microsoft Visual FoxPro 9\convert.prg c:\program files\microsoft visual foxpro 9\convert.app}
Called from -  convert line 143  {C:\Program Files\Microsoft Visual FoxPro 9\convert.prg c:\program files\microsoft visual foxpro 9\convert.app}


Fatal error: Exception code=C0000005 @ 05/11/2006 16:39:15. Error log file: C:\Program Files\Microsoft Visual FoxPro 9\vfp9err.log
Called from -  form1.gradobjects1.draw line 278  {c:\pressing\gradbuttons.vct c:\pressing\gradbuttons.vct}
Called from -  form1.gradobjects1.init line 117  {c:\pressing\gradbuttons.vct c:\pressing\gradbuttons.vct}


Fatal error: Exception code=C0000005 @ 05/11/2006 16:40:56. Error log file: C:\Program Files\Microsoft Visual FoxPro 9\vfp9err.log
Called from -  form1.gradobjects1.draw line 278  {c:\pressing\gradbuttons.vct c:\pressing\gradbuttons.vct}
Called from -  form1.gradobjects1.init line 117  {c:\pressing\gradbuttons.vct c:\pressing\gradbuttons.vct}


Fatal error: Exception code=C0000005 @ 05/11/2006 16:41:32. Error log file: C:\Program Files\Microsoft Visual FoxPro 9\vfp9err.log
Called from -  form1.gradobjects1.draw line 278  {c:\pressing\gradbuttons.vct c:\pressing\gradbuttons.vct}
Called from -  form1.gradobjects1.init line 117  {c:\pressing\gradbuttons.vct c:\pressing\gradbuttons.vct}


Fatal error: Exception code=C0000005 @ 17/11/2006 19:09:09. Error log file: C:\Program Files\Microsoft Visual FoxPro 9\vfp9err.log
Called from -  gesterr line 351  {c:\pressing\depart.prg c:\pressing\depart.fxp}
Called from -  ON...  line 0  { }
Called from -  xfcgraphics.fillrectangle line 35  {c:\pressing\drawing.vct c:\pressing\drawing.vct}
Called from -  form1.imgcanvas1.beforedraw line 21  {c:\pressing\menufichiers.sct c:\pressing\menufichiers.sct}
Called from -  form1.imgcanvas1.draw line 4  {c:\pressing\gdiplusx.vct c:\pressing\gdiplusx.vct}
Called from -  depart line 273  {c:\pressing\depart.prg c:\pressing\depart.fxp}
November 17, 2006 7:12 PM
 

Cesar Chalom said:

Hi Jean Pierre,
This was a bug that happened if both the class was used together with _gdiplus.vcx (FFC class). This was already fixed, please download the class again, and tell me if it's working as desired. Thanks very much for reporting !
January 28, 2007 9:52 PM
 

Cesar Chalom said:

After all those posts discussing and showing how to create gradient backgrounds for VFP forms, I decided...
February 16, 2007 5:16 AM
 

Dan said:

OMG, I feel in heaven ... these are just great
Cesar you're great man ... and FoxPro just ROOOOCKS
February 16, 2007 4:03 PM
 

Furio Filoseta said:

Hola Cesar. Excellent work.

Based on the above class (not the newer), I tried to do a "Gradient Label" class. I simply created a class based on Label and added the Init and Destroy methods above, removing the references to picture (although I want to add them back later, so I could have a Label that Depicts some text on a gradient background WITH an image), and adding the couple properties needed (gradientmode an cgradfile).

The problem is, nothing happens. I mean, the label is rendered without the gradient and with no repositioning of the Caption.

The .BMP is being generated OK, as I can see it in the TEMP directory, but it never gets rendered...

Any hints ?

Hola Furio,

I'm really not sure that I fully understood your question...

The gradient effect needs an image object. As Labels don't have a picture property, you can't directly change that. A workaround would be for you to set the original label's Visible to False, and ADDOBJECT an image, and point the picture property to the picture that you generated.

Hope this helps

Cesar

March 19, 2007 7:10 PM
 

Andy of New Zealand said:

Cesar you are indeed a top man. Your product is great.
Most of my buttons are in either containers or command groups so I have expanded the gradobjects.formafterinit method to include those.
Thanks for making my old tired app look brand new !

Hi,

I'm glad to know that it helps you. Just make sure to be using the latest release, because I'm always updating these classes. Can you better explain what you did in your case ?

Regards

Cesar

March 30, 2007 4:38 AM
 

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=2257
July 24, 2007 7:04 PM
 

Diego said:

when i try to put the command button gradbuttons in my form, a screenn error display

"Property value is out of bound"

Thanks.

Sorry for my inglish

Hola Diego,

Para ayudarle, necesito de mas informaciones, puedes enviarme un informe que muestra el error ?

Gracias

Cesar

July 25, 2007 1:58 PM
 

Rivo Raveloarijaona said:

it doesn'n accept wordwrap caption.
thanks in advance
Rivo
December 15, 2007 10:33 AM
 

Rivo Raveloarijaona said:

When I use wordwrap with the command button it become .F. when running
December 15, 2007 10:39 AM
 

parke said:

thank youu
September 1, 2008 12:04 PM
 

rüya tabirleri said:

thank youu
September 1, 2008 12:05 PM
 

kumawat said:

hi

i want to copy jpg files form my thailand server to india's server by vf6,9 coding
can u tell it can posible for me

Hi,

Sorry, but your question is out of the scope of this blog post. If you are looking for VFP support, you should visit the Foxcite forums: www.foxite.com/forum

Registration is totally free and there you'll be able to interact with brilliant and helpful developers.

October 3, 2008 6:54 AM
 

tayiogar said:

que bonita classe la verdad ya la probe y funciono de maravilla, lastima la nueva version que ya no existe para verla.
March 7, 2009 2:05 AM
 

milton said:

ya no puedes subir nuevamente la nueva versión?
October 27, 2009 8:50 PM

What do you think?

(required) 
(optional)
(required) 

This Blog

Post Calendar

<July 2006>
SuMoTuWeThFrSa
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

Syndication