Está en la página 1de 7

Interfaces

Avanzadas
[Formas con diseño avanzado]
Fecha: 13/May/2005 (04-Mayo-2005)
Autor: Ewing Morales (ewingmarx@yahoo.com)

Muchas veces hemos tenido la necesidad o la curiosidad impactar a la gente a la


que van dirigidas nuestras aplicaciones, y muchos no solo ponen énfasis en la
funcionalidad de la aplicación sino además en como luce la misma. A nosotros
mismo nos agrada mas trabajar con interfaces no solo funcionales sino además
agradables a la vista.

Desafortunadamente Windows tiene sus limitaciones y nosotros como


desarrolladores tenemos que aprender a trabajar con ellas y tratar de solventar
estas con un poco de imaginación.

Intentaré (en una serie de colaboraciones) mostrar como poder elaborar interfaces
de aplicaciones que impacten no solo a los neófitos sino también a los doctos, en
espera que el camino que yo ya recorrí en mi aprendizaje de VB.Net y k.o. le sirva
a los demás para lograr de manera más rápida y sencilla su objetivo.

En términos generales van a haber dos entregas:

 La primera les mostrara como hacer que las aplicaciones se vean como uno
quiere y no como Windows puede.
 La segunda mostrara como hacer un botón realmente personalizado por medio
de una imagen.

[Primera Parte] Formularios con diseño avanzado


Antes de seguir hablando dejen mostrarles lo que pueden lograr con el código que
les estoy compartiendo:
Como pueden ver, el formulario tiene formas suaves (no aserradas), sombras y
semitransparencias (entre otras cosas).

Como se logro esto, bueno, no es mas que un conjunto de trucos, pero eso si, muy
buenos y que no solo les pueden servir para esto sino para mas cosas que deseen
hacer.

El truco consiste en copiar la imagen que se encuentra detrás de nuestro


formulario, pintarla en un lienzo (Rectangle) nuevo y después pintar sobre el
mismo lienzo la imagen PNG (mezcla de imágenes). Esto permitirá que se respeten
todas las características de la imagen que se definieron en el editor gráfico.

Descripción de componentes

1) Antes que nada necesitamos un buen diseño grafico, yo diseño con photoshop
(de cuya introducción saque la idea del formulario), pero pueden utilizar cualquier
otra aplicación que les permita guardar PNGs (en el código va el png que utilizo).

2) Necesitan un formulario con las mismas medidas que la imagen PNG (en
realidad eso no es necesario pero para casos de aprender, háganlo así). Definan su
propiedad FormBorderStyle como None y asignen a BackgroundImage el png
que crearon.

3) Agreguen un control de tipo Panel, pónganle como nombre LTitulo, hagan que
sea transparente y ubíquenlo sobre la porción de imagen que deseen que sea su
barra de control que les permita arrastrar la ventana del formulario.
4) Creen ahora un botón (por ahora trabajaremos con los normales y feos) que se
llame Cerrar para que cuando le demos Click se cierre el formulario.

Hasta ahora no hemos visto nada de código pero a continuación mostramos que se
puede hacer con el panel LTitulo y el botón Cerrar.

#region "Codigo para Drag Form"


//
======================================================================
====

private Boolean arrastrar;


private Point pointMD;
private Point pointFM;
private int xDelta, yDelta;
private Boolean activo;

private void LTitulo_MouseDown(object sender,


System.Windows.Forms.MouseEventArgs e)
{
arrastrar = true;
pointMD = MousePosition;
pointFM = this.Location;
xDelta = pointMD.X - pointFM.X;
yDelta = pointMD.Y - pointFM.Y;

this.Opacity = 0.20;
MuestraImagen(true);
}

private void LTitulo_MouseMove(object sender,


System.Windows.Forms.MouseEventArgs e)
{
Point pointNP = new Point();
if (arrastrar)
{
pointNP.X = MousePosition.X - xDelta;
pointNP.Y = MousePosition.Y - yDelta;
this.Location = pointNP;
}
}
private void LTitulo_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
arrastrar = false;
MuestraImagen(false);
}

private void Cerrar_Click(object sender, System.EventArgs e)


{
this.Close();
}

//
======================================================================
====
#endregion

Vemos en el código los eventos Down, Up y Move del ratón para nuestro panel
LTitulo, por lo tanto debemos hacer la correspondiente asociación eventos -
funciones para que pueda funcionar, así mismo para el evento Click del botón
Cerrar que definimos. La manera más rápida de hacer esto es desde el panel de
propiedades de la interfaz de desarrollo como se muestra a continuación (fíjense en
los iconos que tengo seleccionados de este panel para poder hacerlo):

5) Necesitamos inicializar algunas variables antes de que pueda funcionar todo en


conjunto, esto lo haremos en el evento Load del formulario, además agregaremos
un comportamiento específico del formulario cuando este se encuentre activo
(Activated) y cuando este no sea la ventana que tiene el foco en Windows
(Deactivate). Pero sobre todo, necesitamos nuestra función que se llama
MuestraImagen que nos permite hacer el copiado de lo que se haya detrás de
nuestro formulario. Acá el código:

#region "Variables de Control Grafico"


private Image img;
private Image result;
private Rectangle rectangle;
#endregion

#region "Funciones de Actualizado de Formulario"


private void MainForm_Load(object sender, System.EventArgs e)
{
// Inicializacion de variables
img = this.BackgroundImage;
result = new System.Drawing.Bitmap(img.Width, img.Height);
rectangle = new
System.Drawing.Rectangle(0,0,img.Width,img.Height);
MuestraImagen(false);
activo = true;
}

private void MainForm_Activated(object sender, System.EventArgs e)


{
if (activo == false)
{
MuestraImagen(false);
activo = true;
}
}

private void MainForm_Deactivate(object sender, System.EventArgs e)


{
this.Opacity = 0.50;
activo = false;
}

private void MuestraImagen(Boolean mueveForma)


{
System.Drawing.Graphics
graphics = System.Drawing.Graphics.FromImage(result);

if (mueveForma)
{
graphics.Clear(Color.White);
}
else
{
CapturaForm.Control(this);
graphics.DrawImage(this.BackgroundImage,
rectangle,
0, 0, img.Width, img.Height,
System.Drawing.GraphicsUnit.Pixel);
}
graphics.DrawImage(img,
rectangle,
0, 0, img.Width, img.Height,
System.Drawing.GraphicsUnit.Pixel);

graphics.Dispose();

this.BackgroundImage = result;
this.Refresh();
}
#endregion

Acuérdense de asociar los eventos Load, Activated y Deactivate del formulario a las
funciones correspondientes que aparecen en el código anterior.

6) Como les decía en un principio, la función MuestraImagen lo que hace primero


es obtener un nuevo fondo a través del método Control de la clase CapturaForm
que aun no hemos visto. Si el formulario esta por moverse las imágenes a mezclar
(dibujar una sobre otra) son un fondo blanco y nuestro PNG, además se cambia la
opacidad de la forma a un 20% (vean LTitulo_MouseDown, que es la única vez que
se envía true como parámetro a la función). Cuando uno cambia a otra ventana de
Windows, el formulario se vuelve transparente a un 50% (vean
MainForm_Deactivate). Cuando uno deja de arrastrar el formulario se efectúa el
siguiente proceso: se oculta por un momento el formulario, se copia el fondo, se
dibuja el fondo en nuestro lienzo temporal (rectangle), se encima la imagen PNG en
el lienzo, se cambia el fondo del form por el nuevo lienzo, se refresca la imagen del
form aun estando oculto a la vista y por ultimo se hace visible el form.

Todo lo anterior es apenas perceptible por el usuario aunque si existe un pequeño


parpadeo, pero bueno, hay que pagar algunas cosas por disfrutar de una interfaz
así... ¿no creen?

La siguiente imagen les puede dar una idea de como se vería el formulario al
arrastrarlo (y es cuando nuestro truco queda un rato al descubierto).

7) Por ultimo, necesitas las funciones y agregados para poder realizar las capturas
de pantalla. Yo encontré estas funciones en la red y es software libre (PSDLA: en el
código viene una breve descripción de los términos) publicado por Excellence
Foundation (Don@xfnd.org). Las funciones originales permiten otros tipos de
capturas, pero especialmente la adecuación que yo hice nos sirve para estos fines
en específico, ni más ni menos. Estas librerías están definidas bajo los namespaces
Captura y Dll y se encuentran en el propio código principal, para que no batallen
con dlls externas. Las puse bajo un grupo región a cada una para que en tu código
solo las veas de la siguiente manera:

+ "NameSpace Captura"
+ "NameSpace DLL"

¿Puedes ver el código? ¿Puedes modificarlo? Por supuesto que si. Simplemente no
me meto a explicarlo porque es mejor que los veamos como auxiliares y no como el
núcleo de la aplicación.

También es importante que su definición vaya hasta lo último del código ya que al
parecer existe un bug en el Visual Studio tal que si lo pones al principio, empiezas a
tener problemas con las imágenes que utilices en tus controles. ¿Por qué? No tengo
idea pero al menos pasa aquí en mi maquina. De cualquier manera pónganlos al
final.
Personalicen

Pueden personalizar sus formularios, agregando mas PNGs, solo recuerden que
deben ponerlos como imágenes de fondo de objetos tipo Panel. Los objetos como
Label o PictureBox tienen sus propias deficiencias que no permiten explotar al
máximo una aplicación gráfica como esta que queremos implementar. En mi caso la
idea es hacer un informador del clima, el cual me mostrará el clima actual y su
pronóstico. Por entendido se da que la información vendrá lo mas gráfico que se
pueda (vean el informador del clima del Dashboard de Apple OSX).

La aplicación que les envío se debe ver hasta ahora así:

Espacios de nombres usados en el código de este artículo:

System.Runtime.InteropServices

También podría gustarte