A partir de la experiencia adquirida en el trabajo con formularios, Cesar Chalom, vuelve a la carga para mostrarnos posibles soluciones para el empleo de colores degradados en botones de comandos.
Botones de comandos con colores degradados con GDI+
Artículo original: GRADIENT COMMAND BUTTONS WITH GDI+
http://weblogs.foxite.com/cesarchalom/archive/2006/07/11/1969.aspx
Autor: Cesar Chalom (http://weblogs.foxite.com/cesarchalom)
Traducido por: Ana María Bisbé York (amby@telefonica.net)
Para: PortalFox (http://www.portalfox.com)
Al utilizar algunas de las técnicas presentadas en mi post anterior, (lea "Gradient Backgrounds in your forms with GDI+") he creado una subclase muy sencilla del objeto commandbutton, para crear efectos de degradado de fondo.
Nota de la traductora. Ese artículo se ha traducido al español, bajo el título "Formularios con fondos de colores degradados con GDI+"
Por favor, tenga en cuenta que esta clase aun no está terminada. Lo estoy publicando para mostrar a la gente, que podemos obtener efectos maravillosos utilizando GDI+.
Realmente espero tener vuestros comentarios, opiniones o correcciones, así podré seguir adelante y mejorar este control.
Deseaba que el formulario tuviera el aspecto más parecido al resultado final.
Así es cómo se ve el formulario en modo desarrollo:

Debajo, podemos ver el formulario en ejecución, con el GDI+ que crea los fondos.

Las propiedades que necesita llenar para tener los resultados deseados son:
Caption, FontBold, FontUnderline, FontItalic, FontStrikeThru Picture, BackColor (con el color principal a ser empleado en el degradado) GradientMode (0 = NO Gradient 1 = Vertical-Default 2 = Horizontal 3 = Diagonal1 4 = Diagonal2)
¿Cómo ha sido creada la clase?
Utilicé la clase base commandbuttom, para hacerlo lo más frecuente y entendible posible, haciendo el modo desarrollo el más visible al resultado obtenido al ejecutar el formulario.
En el evento INIT de la clase, comprueba la dirección de degradado y crea una brocha con degradado lineal LinearGradient Brush utilizando un color definido en la propiedad BackColor del objeto. El segundo color está predeterminado como Blanco. Luego, dibuja un rectángulo utilizando esa brocha en una imagen que acaba de crear, que tiene las mismas dimensiones del Commandbutton.
El siguiente paso es verificar si existe una imagen asignada al botón, y si existe, dibujarla en el lado izquierdo, centrada en la vertical.
En el ejemplo, solamente estoy utilizando GIFs con fondo transparente, de tal forma que el fondo se conserve.
El código
El código principal está en el evento INIT de la subclase CommandButton.
WITH This
LOCAL lcGradFile, lnGradMode, lnGradPixels, x1, y1, x2, y2, lnWidth, lnHeight
lnGradMode = .GradientMode
IF lnGradMode = 0
RETURN && No hay fondo degradado !
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 SuperiorIzquierda -> InferiorDerecha
y1 = 0
x2 = lnWidth
y2 = lnHeight
CASE lnGradMode = 4 && Diagonal InferiorIzquierda -> SuperiorDerecha
y1 = lnHeight
x2 = lnWidth
y2 = 0
ENDCASE
* Crea una imagen degradada
SET CLASSLIB TO HOME() + "ffc/_gdiplus.vcx" ADDITIVE
* Crea un objeto Color y almacena los valores de color ARGB en 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
* Crea un bitmap
LOCAL loBmp AS GpBitmap OF HOME() + "ffc/_gdiplus.vcx"
loBmp = CREATEOBJECT("gpBitmap")
loBmp.Create(.Width, .Height)
* Crea un objeto gráfico bitmap
LOCAL loGfx AS GpGraphics OF HOME() + "ffc/_gdiplus.vcx"
loGfx = CREATEOBJECT("gpGraphics")
loGfx.CreateFromImage(loBmp)
* Declara la función API
DECLARE Long GdipCreateLineBrushI IN GDIPLUS ;
String point1, String point2, ;
Long color1, Long color2, ;
Long wrapMode, Long @lineGradient
* Obtiene una brocha con color degradado
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.)
* Llena el bitmap con nuestro color degradado
loGfx.FillRectangle(loBrush,0,0,.Width, .Height)
* Dibuja la pintura deseada
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
* Dibuja el título
#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 ; && Nombre de la fuente
, .FontSize ; && tamaño en las unidades indicadas abajo
, lnFontStyle ; && Estilo de fuente
, unitPOINT ) && Unidades
* Crea una brocha sólida - SolidBrush con la propiedad ForeColor
LOCAL loSolidBrush AS GpSolidBrush OF HOME() + "ffc/_gdiplus.vcx"
loSolidBrush = NEWOBJECT('GpSolidBrush', HOME() + 'ffc/_gdiplus.vcx','',0)
loClr.FoxRGB = .ForeColor
loSolidBrush.BrushColor = loClr
* Mide la altura del título (Caption) para calcular la posición vertical
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
* Crea PointF con la posición del título (Caption)
lcTextPoint = BINTOC(X1,'F') + BINTOC(Y1,'F')
loGfx.DrawStringA(.Caption, loFont, lctextPoint, , loSolidBrush)
ENDIF
* Guarda la imagen en un archivo
loBmp.SaveToFile(lcGradFile,"image/bmp")
.Picture = lcGradFile
ENDWITH
RETURN
En el evento DESTROY solamente eliminamos la imagen que acabamos de crear.
IF This.GradientMode = 0
RETURN && No Gradient Background !
ENDIF
WITH This
IF FILE(.cTempGradFile)
CLEAR RESOURCES (.cTempGradFile)
ERASE (.cTempGradFile)
ENDIF
ENDWITH
Pendiente por mejorar:
- PicturePosition - en este momento, siempre va a trabajar como "1 - izquierda del título, centrada relativa al título". VFP 9 ofrece 14 opciones de posiciones, esto puede hacerse fácilmente en una futura versión.
- Agregar otra propiedad que reciba un segundo color (en este momento, blanco - RGB(255,255,255) como predeterminado)
- Permitir crear gradientes de tres colores, permitiendo, por ejemplo: azul - blanco - azul
- Para trabajar con botones de comandos inhabilitados. Por favor, envíen sus sugerencias / o imágenes mostrando cómo debe lucir el control cuando está inhabilitado.
- Permitir recibir una imagen y crear la transparencia de los fondos.
Los íconos que he utilizado para crear este ejemplo se tomaron de http://www.iconbazaar.com donde se pueden encontrar muchos GIFs excelentes.
Puede descargar el código fuente utilizado para esta primera versión desde http://weblogs.foxite.com/cesarchalom/attachment/1969.ashx
07/19/2006 - Versión actualizada de la clase
Recibí muchas sugerencias, y creé una nueva versión de la clase, a la que agregué otras muchas características.
Puede descargar la versión más reciente de la clase y algunos formularios donde se utiliza desde: http://www.geocities.com/macmarbr/gradcmdbutton.zip
Al ejecutar el formulario "testGradButtons", por favor pase el ratón sobre los botones y también haga clic sobre el botón inhabilitado.
He aquí algunas capturas de pantalla de la nueva versión


Como siempre, envíenme por favor, sus comentarios, sugerencias y correcciones.
|