This is a deprecated post. Please search in this blog for the next posts, for the improved gradient objects and background classes.
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, not to be used in production. 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
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/vfpimaging/gradobjects/gradobjects.zip
When running the form "testgradbuttons", please pass the mouse over the buttons and also click the "disable" button.
Terrific!
ReplyDeleteBeautifull !!! Great visual class is amazing and easy utility.Thank you for it. And you keeping gating better.
ReplyDeleteI feel good
ReplyDeleteGrande Cesar!
ReplyDeleteO Mr. GDI
Muito bom exemplo,
Parabéns
Show de bola !
ReplyDeleteVou pegar o código para ver se aprendo um pouco :-)
Abração
UPDATED VERSION OF THE CLASS
ReplyDeleteI'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
Looks very nice on these pictures!
ReplyDeleteGreat 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.
ReplyDeleteParabéns César!
ReplyDeleteBelo trabalho!!!
Gracias Luis !
ReplyDeleteI've already updated the class, fixing that bug, and some few enhancements.
Thanks for testing !
http://www.geocities.com/macmarbr/gradcmdbutton6.zip
Cesar
Hi Cesar,
ReplyDeleteFantastic 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
Hi Keith,
ReplyDeleteGreat 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
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.
ReplyDeleteMaybe 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.
ReplyDeleteI 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
Sure, can you be the leader? maybe we can make a schedule to define the steps to follow.
ReplyDeleteYes, we can work together on that.
ReplyDeleteKeith 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
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?
ReplyDeleteGracias.
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.
Hernan,
ReplyDeletePls 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
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:
ReplyDeletehttp://weblogs.foxite.com/cesarchalom/archive/2006/07/26/2076.aspx
Sorry to post this here but i didn't finf how to contact cesar chalom
ReplyDeleteI 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}
Hi Jean Pierre,
ReplyDeleteThis 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 !
OMG, I feel in heaven ... these are just great
ReplyDeleteCesar you're great man ... and FoxPro just ROOOOCKS
Hola Cesar. Excellent work.
ReplyDeleteBased 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
Cesar you are indeed a top man. Your product is great.
ReplyDeleteMost 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
Versión en Español de este artículo en / Spanish version at http://www.portalfox.com/article.php?sid=2257
ReplyDeletewhen i try to put the command button gradbuttons in my form, a screenn error display
ReplyDelete"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
it doesn'n accept wordwrap caption.
ReplyDeletethanks in advance
Rivo
When I use wordwrap with the command button it become .F. when running
ReplyDeletethank youu
ReplyDeletehi
ReplyDeletei 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.
que bonita classe la verdad ya la probe y funciono de maravilla, lastima la nueva version que ya no existe para verla.
ReplyDeleteya no puedes subir nuevamente la nueva versión?
ReplyDeleteWow me gusta mucho la programacion, pero apenas bengo empesando a estudiar y cada vez me gusta mas y mas .....espero que sigan dedicando tiempo a estas paginas web porque son buenisimas.....Felicidades,,,.....
ReplyDelete