http://weblogs.foxite.com/vfpimaging/archive/2006/06/22/1906.aspx
Autor: Cesar Ch.
Traducido por: Ana María Bisbé York
En mi entrada anterior con el mismo título, mostré cómo crear fondos con degradado VERTICAL en formularios. (Nota de la traductora: El autor se refiere a "Gradient Backgrounds in your forms with GDI+" que está traducido al español bajo el título "Formularios con fondos de colores degradados con GDI+")
Como explicó Malcolm Greene, (http://weblogs.foxite.com/vfpimaging/archive/2006/06/13/1825.aspx#comments) la misma técnica puede ser utilizada para contenedores VFP.
De acuerdo con MSDN, "La clase LinearGradientBrush define una brocha que pinta un color degradado en el que el color cambie uniformemente desde la línea de límite que comienza el degradado hasta la línea final del límite de la brocha. Las líneas de borde de un degradado lineal son dos líneas rectas paralelas. El degradado de color es perpendicular a las líneas de borde, cambiando gradualmente a través del movimiento desde la línea de borde inicial a la línea de borde final. El color degradado tiene un color en la línea de borde inicial y otro en la línea de borde final."
Los parámetros principales a pasar a LinearGradientBrush son:
- point1 Punto inicial de degradado. La línea de borde inicial pasa a través del punto inicial.
- point2 Punto final de degradado. La línea de borde final pasa a través del punto final.
- color1 Color ARGB en la línea de borde inicial de esta brocha con degradado lineal.
- color2 Color ARGB en la línea de borde final de esta brocha con degradado lineal.
¡GDI brinda además degradados lineales horizontales, verticales y diagonales! Entonces, utilizando la misma técnica podemos crear fácilmente otros efectos.
Degradado horizontal
Para el degradado horizontal necesitamos pasar como Point1 y Point2 dos coordenadas con la misma "y". Es fundamental que los dos puntos tengan la misma coordenada (Y) para hacer que la línea conecte con ellos horizontalmente.
Degradado diagonal
Para el degradado diagonal, las dos coordenadas deben crear una línea diagonal, tales como punto (0,0) y punto (50,50). Esto creará una línea diagonal entre aquellos dos puntos, comenzando desde la esquina superior izquierda hasta la esquina inferior derecha del formulario, tal y como se muestra a continuación:
Si cambiamos las coordenadas (0,50) y (50,0), la línea diagonal va a finalizar en la esquina superior del formulario
Entonces, en nuestro caso, Solamente, hice el siguiente cambio sobre el código original de la entrada anterior:
lnGradPixels = 100 && Ancho de la línea de degradado lnGradMode = 4 && Rangos desde 1 a 4 DO CASE CASE lnGradMode = 1 && Vertical x1 = 0 y1 = 0 x2 = 1 y2 = lnGradPixels CASE lnGradMode = 2 && Horizontal x1 = 0 y1 = 0 x2 = lnGradPixels y2 = 1 CASE lnGradMode = 3 && Diagonal SuperiorIzquierda -> InferiorDerecha x1 = 0 y1 = 0 x2 = lnGradPixels y2 = lnGradPixels CASE lnGradMode = 4 && Diagonal InferiorIzquierda -> SuperiorDerecha x1 = 0 y1 = lnGradPixels x2 = lnGradPixels y2 = 0 ENDCASE lnWidth = IIF(lnGradMode = 1, 1, lnGradPixels) lnHeight = IIF(lnGradMode = 2, 1, lnGradPixels)
La brocha LinearGradientBrush se creará utilizando las coordenadas (x1,y1) y (x2,y2). La imagen tendrá un tamaño lnWidth, lnHeight. La variable lnGradPixels significa el tamaño en píxeles de la imagen que se va a crear. En el envio anterior, utilicé "Thisform.Height". Después de algunas pruebas, he visto que empleando 60 píxeles creará un degradado de calidad que se expandirá por el objeto imagen hasta llenar todo el formulario.
Entonces, cree cualquier formulario y agregue el siguiente código en los eventos LOAD y DESTROY. Cambie los valores de la variable lnGradMode a cualquier valor entre 1 y 4, para ver el formulario con cuatro tipos de degradado. Cambie además lnGradPixels a 5,20 y 60. No olvide redimensionar el formulario.
Load Event
LOCAL lcGradFile, lnGradMode, lnGradPixels, x1, y1, x2, y2, lnWidth, lnHeight lcGradFile = ADDBS(SYS(2023))+SYS(2015)+".bmp" This.AddProperty("cTempGradFile",lcGradFile) lnGradPixels = 60 lnGradMode = 4 DO CASE CASE lnGradMode = 1 && Vertical x1 = 0 y1 = 0 x2 = 1 y2 = lnGradPixels CASE lnGradMode = 2 && Horizontal x1 = 0 y1 = 0 x2 = lnGradPixels y2 = 1 CASE lnGradMode = 3 && Diagonal SuperiorIzquierda > InferiorDerecha x1 = 0 y1 = 0 x2 = lnGradPixels y2 = lnGradPixels CASE lnGradMode = 4 && Diagonal InferiorIzquierda > SuperiorDerecha x1 = 0 y1 = lnGradPixels x2 = lnGradPixels y2 = 0 ENDCASE lnWidth = IIF(lnGradMode = 1, 1, lnGradPixels) lnHeight = IIF(lnGradMode = 2, 1, lnGradPixels) IF FILE(lcGradFile) CLEAR RESOURCES (lcGradFile) ENDIF LOCAL lnRGBColor1 lnRGBColor1 = RGB(0,128,255) && Azul * Crea una imagen degradada SET CLASSLIB TO HOME() + "ffc/_gdiplus.vcx" ADDITIVE * Crea un objeto Color y almacena en * variables los valores de color ARGB 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(lnWidth, lnHeight) * Obtiene un objeto gráfico bitmap LOCAL loGfx AS GpGraphics OF HOME() + "ffc/_gdiplus.vcx" loGfx = CREATEOBJECT("gpGraphics") loGfx.CreateFromImage(loBmp) * Declara API DECLARE Long GdipCreateLineBrushI IN GDIPLUS.DLL ; String point1, String point2, ; Long color1, Long color2, ; Long wrapMode, Long @lineGradient * Crea una brocha con degradado LOCAL loBrush AS GpBrush OF HOME() + "ffc/_gdiplus.vcx" LOCAL hBrush && Brush Handle hBrush = 0 GdipCreateLineBrushI(BINTOC(x1,"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 degradado loGfx.FillRectangle(loBrush,0,0,lnWidth, lnHeight) loBmp.SaveToFile(lcGradFile,"image/bmp") Thisform.AddObject("ImgBackGround","Image") WITH Thisform.ImgBackGround .Stretch = 2 && Expandir .Width = Thisform.Width .Height = Thisform.Height .Anchor = 15 && Redimensiona Ancho y Alto .Picture = lcGradFile * .PictureVal = FILETOSTR(lcGradFile) * .PictureVal = LOADPICTURE(lcGradFile) * ERASE (lcGradFile) .ZOrder(1) .Visible = .T. ENDWITH RETURN
Destroy Event
WITH Thisform IF FILE(.cTempGradFile) CLEAR RESOURCES (.cTempGradFile) ERASE (.cTempGradFile) ENDIF ENDWITH
Una ligera modificación fue agregar ZOrder(1), para asegurarse de que el objeto image agregado está al frente, y mantener al fondo de todos los objetos del formulario. ¡Gracias Aílsom !
Gracias a Malcolm Greene, el código para el evento Resize se eliminó y sustituyó por: .Anchor = 15 && Redimensiona de Ancho y de Alto. VFP9 trajo muchas novedades buenísimas, y debo admitir que hasta ahora apenas he probado algunas de ellas.
Malcom sugirió además enviar los binarios desde la imagen creada a la propiedad PictureVal del objeto imagen. No se por qué; pero en algunas PCs el dibujo aparece rotado en unos 90 grados. Además, en Windows NT, la parte blanca del degradado se sustituye por transparencia. Por tanto, de momento, mantengo el código en el evento Destroy para garantizar que la imagen creada se elimina del disco.
Estoy seguro de que existe una buena solución para esto ¿será que alguien me lo puede explicar?
Nuevas clases GDI+
Craig y Bo agregaron a la nueva biblioteca además de todas las funciones GDI+, otras clases que van a hacer, que el uso de GDI+ sea realmente sencillo y lo más importante, muy intuitivo. No habrá más necesidad de llamar directamente a las funciones API para GDI+, control de objetos. La creación de imágenes será realmente intuitiva.
Uno de los muchos agregados es la clase IMAGECANVAS. Es una subclase de la clase nativa Image que fue creada para recibir un dibujo. La ventaja de utilizar esta clase es que genera gráficos a gran velocidad (de acuerdo con Craig y Bo unas 30 veces más rápido que guardar una imagen a disco y cargar a un objeto image). No habrá acceso a disco, una vez que la imagen es manipulada directamente desde la memoria. El usuario tendrá solamente que colocar código para dibujar la imagen en el método "BeforeDraw" del objeto y es todo.
En el caso de fondos degradados en formularios, tendremos solamente que agregar el objeto "ImageCanvas" y en el método BeforeDraw de este objeto, poner el código. SÓLO 5 LINEAS!!! Gracias a Craig Boyd por enviarme este ejemplo.
BeforeDraw Event
LOCAL loBrush AS xfcLinearGradientBrush WITH _Screen.System.Drawing loBrush = .Drawing2D.LinearGradientBrush.New(This.Rectangle, ; .Color.FromRGB(0,128,255), .Color.White, ; .Drawing2D.LineargradientMode.ForwardDiagonal) This.oGfx.FillRectangle(loBrush, This.Rectangle) ENDWITH¿Cómo se siente empleando estas clases?
Existen otros muchos efectos para crear con LinearGradientBrushes. De forma predeterminada, el color en un degradado lineal cambia uniformemente. Sin embargo, es posible personalizar un gradiente lineal de tal forma que el color cambie de forma no uniforme, creando degradados que utilicen más de dos colores.
A partir de ahora, intentaré ir mostrando estas características utilizando la clase nueva. Debo confesar que no me siento muy listo al presentar este envio donde he sustituido 70 líneas por 5 !
En el archivo adjunto, estoy enviando dos formularios. El primero, Gradient.SCX crea un formulario sencillo, con código en los eventos LOAD y DESTROY. Intente también el formulario Gradient2.SCX, que permitirá personalizar al vuelo, los colores de degradado y la dirección.
Haga clic aquí para descargar el archivo
excelente!!!!
ResponderBorrar