Here's the latest version of the gradientobjects class.
Many thanks to : Craig Boyd, Bo Durban, Emerson Reed, Malcolm Greene, Keith Gordijn, Luis Navas, Ana Bisbe, Ailsom Heringer, and all others that have tested the class, providing valuable suggestions and feedback.
The main modification from the previous version is the creation of a new class, as Craig Boyd suggested:
“... create a custom class that provides this functionality rather than have the code directly in the button class. A class that uses bindevents to link itself to the buttons (or whatever ui element is being used) would provide an additional level of abstraction. this would allow developers to use the class with other ui elements (such as a container) and also provide a quick and easy way to add this cool functionality to existing applications where they have their own button subclasses (or are using vfp base class) already existing. Toss the class on the form and set some properties.”
Another important modification was to “turn any optionbutton or checkbox with its style property set to graphical to a gradient button.” as Bo Durban suggested.
Emerson Reed also provided many images showing the desired behavior of the class.
drop one instance of the class in the form or container, and all buttons will be converted to gradient. applies to commandbuttons, graphical checkboxes and graphical listboxes
9 kinds of gradients
choose different backcolors when object has the focus and not.
create greyscale images for disabled buttons
converts picture borders to transparent (no matter what color is used)
hotkeys (\<) specified in the caption property display normally, and remain functional.
How it was created:
the class creates a new picture image file that will imitate the original appearance of the button, using all text properties, like caption, fontbold, fontitalic and the original picture, all redrawn in a specified gradient background.
extensive usage of gdi+ to create images, 100% with direct api calls, to obtain the maximum speed in the creation of the images that will be substituted in the buttons.
in the first moment, only the main images from the buttons are created. only when the mouse or focus is over a specific object that the class creates the “selected image”. the same happens with the “greyscale disabled pictures”
many events are controlled using bindevents, such as : mousemove, mouseenter, gotfocus, lostfocus
three different kinds of gradients were created using different functions.
for gradientmodes 1 to 4, i used gdipcreatelinebrushfromrecti, to create a simple linear gradient brush with 2 colors.
for gradientmodes 5 to 8, gdipcreatelinebrushfromrecti was again used in combination of gdipsetlinepresetblend, that according to msdn "defines arrays of colors and positions used for interpolating color blending in a multicolor gradient". it was used to create a 3 color gradient, starting with backcolor1 property, with backcolor2 in the center and again backcolor1 in the other edge.
for gradientmode 9, i created a pathgradientbrush, using gdipcreatepath, gdipaddpathrectangle, gdipcreatepathgradientfrompath, gdipsetpathgradientcentercolor and gdipsetpathgradientsurroundcolor. there is a very cool example of this usage in last craig boyd's article published in foxtalk 2.0. the surround color is defined by backcolor1 property. the center color is backcolor2.
the gdi+ imageattributes class is used to apply a color matrix to create the greyscale images for the disabled buttons. it is also used to create the transparent background of the pictures using the remap table function.
the hotkeys are enabled using the stringformathotkeyprefix
properties of the class to be set
check the favorites tab in the properties window.
backcolor1 - numeric, the rgb value of the starting color of the gradient background when the object does not have the focus and the mouse is not over it.
backcolor2 - numeric, the rgb value of the destination color of the gradient background when the object does not have the focus or the mouse is not over it.
selbackcolor1 - numeric, the rgb value of the starting color of the gradient background when the object has the focus or the mouse is over it.
selbackcolor2 - numeric, the rgb value of the destination color of the gradient background when the object has the focus or the mouse is over it.
captionforecolor - numeric, if set, overrides the forecolor originally set in the controls
captionbold - logical, if set, overrides the captionbold originally set in the controls
createborder - logical, sets the border with the color background1 color
createborder = .t.
createborder = .f.
- gradientmode - numeric, from 1 to 9, determines the gradient type to be applied to the buttons.
1 - horizontal 2 - vertical 3 - diagonal 1 4 - diagonal 2 using linear gradient brushes with 2 colors
5 - horizontal 6 - vertical 7 - diagonal 1 8 - diagonal 2 using linear gradient brushes with 3 colors, where the surrounding color is backcolor1 and the center color is backcolor2
9 - rectangular pathgradient, where the surrounding color is backcolor1 and the center color is backcolor2
reducecolorlevel - numeric, automatically sets the destination color of the gradient (backcolor2 and selbackcolor2) ranging from 0 (no change) to 100 (white). if left to .f., then no change is applied and the original values of backcolor2 and selbackcolor2 will be used.
createdisabledpicture - logical, .t. = create a greyscale picture of buttons to be used when one or more controls are disabled.
- mousedowneffect - logical, determines if the button will become darker or brighter when mouse is down
- mousedownbrightness - numeric, brightness in percentage. -100 = black; 0 = no change ; +100 = white
transpimgback - logical, determines if the picture will have its background converted to transparent (alpha = 0). by default, the class will admit that the color of the 1st pixel, coordinate (0,0) has the background color, and will substitute all pixel colors that match that color to transparent.
Redrawing a specific object
in many cases, we need to change programatically some properties of some buttons, like the caption. when using this class, you need to call the updatecontrol method of the class, like in the example below:
thisform.cmdbutton1.caption = "new caption"
thisform.cmdbutton1.fontitalic = .t.
Assigning different effects to some specific buttons
that's very easy to accomplish. put the commandbuttons in a separate container, and drop an instance of the class, setting the properties as needed.
below you can see a form in development mode and the resulting when the form is executed.
This is the first version of this class in the new aproach, and for sure it needs some more testing. if you find any bugs, please tell me ! all suggestions are very welcome and appreciated.
Link for download the class:
Some related links:
fix : hotkeys in captions "\<" now working normally.
fix : when the you pass the mouse over a button that has the focus now it keeps the selected effect.
fix : if a user deletes the backcolor property value and change it to (none) the control will force a default in this case. a safety measure, thanks to bernard bout.
update : new form showing how to add many different gradients in a form. see "twogradients.scx" in the main folder.
fix : bug in lostfocus / gotfocus
update : method "updatecontrol" allows to change the object colors
update : method "changecolors" allows values from -100 to + 100. -100 = black; 0 = no change; +100 = white
update : form "testgradanimation.scx" showing how to make a button "blink" with the effects
update : new properties "mousedowneffect" and "mousedownbrightness"
"mousedowneffect" logical, determines if the button will become darker or brighter when mouse is down
"mousedownbrightness" numeric, brightness in percentage. -100 = black; 0 = no change ; +100 = white
fix: applied fixes on string measurements to obtain more accurate measurements
fix: updatecontrol method for "mousedown"
fix: changed all gdiplus declarations to avoid confusion from vfp
fix: used bindevents to make sure the class will activate only after all objects were initialized
fix: every time that width or height is changed, the control will be redrawn in the new size.
feature: included code to allow adding new objects on the fly using the "updatecontrol" method
feature: added new class for gradientbackgrounds - version 1 - beta - using _gdiplus.vcx
feature: added memberdata scripts to ease selecting colors, opening the colorpicker when dblclick on the ellipsis
update: included new samples: "essaifondecran.scx", "addingobjects.scx", "testresizingbuttons.scx"
fix: bug in graphical optiongroups
this class is totally free. the information provided on this page and the source code related to this article comes without any warranty whatsoever. use it at your own risk.