jueves, 30 de agosto de 2007

Hacer Un Formulario Flotante en el Compact Framework

Bueno primero que todo!
Que es lo especial de este Código y cual es la diferencia entre hacer el formulario Flotante y Cortar hacer el formulario de tamaño inferior al de la pantalla!

OK lo primero!
Cuando haces Un formulario en el compact framework siempre te aparece en pantalla completa!
De esta manera! Lo cual nos bloquea todo el Área del formulario anterior!

Una solución rápida seria agregar este código antes de llamar el ShowDialog()

TestForm testFrm = new TestForm();
testFrm.FormBorderStyle = FormBorderStyle.None;

testFrm.Size = new System.Drawing.Size(200, 200);
testFrm.FormBorderStyle = FormBorderStyle.None;

System.Drawing.Rectangle rectS = Screen.PrimaryScreen.Bound
//Para Centralo Y que se vea Bonito
testFrm.Location = new System.Drawing.Point(Convert.ToInt32((rectS.Width - testFrm.Width) / 2), Convert.ToInt32((rectS.Height - testFrm.Height) / 2));

Esto daría un resultado como este
Ummm pero que no es lo que queremos todavía o si?
Bueno si nos fijamos bien en la esquina Superior esta el (OK) ósea que lo que hicimos fue cortar el formulario el formulario no es un dialogo completo, si es bien que vemos el formulario anterior en este caso el fondo del escritorio!, pero que pasa si queremos mover esta ventana? Pues te quedaras con las ganas porque no es posible, a asta este momento.

Ahora si vamos a explica algo de lo que vamos hacer!
Bien vamos hacer una llamada al API de Windows para hacer nuestro formulario un Formulario Flotante!

Bueno primero tenemos que definir cuales son las funciones y de donde las vamos a obtener!

Funciones
SetWindowPos, SetWindowLong del la Dll CoreDll.dll , definidas en el Winuser.h

Aquí puedes encontrar mas información sobre ellas
SetWindowLong http://msdn2.microsoft.com/en-us/library/ms961538.aspx
SetWindowPos http://msdn2.microsoft.com/en-us/library/ms961540.aspx

Y las Enumeración los valores que vamos a usar son las siguientes

Para el estilo de la ventana
public enum WS
{
BORDER = 0x00800000,
CAPTION = 0x00C00000,
DLGFRAME = 0x00400000
}

Una bandera que necesitamos para SetWindowPos
public enum SWP
{
NOACTIVATE = 0x0010
}

La usaremos como un offset para GetWindowLong()
public enum GWL
{
STYLE = -16
}

Y ahora ya sabiendo algo podemos empezar
Ahora creamos la la clase UtilForm Con el siguiente codigo!


public class UtilForm
{

public enum WS
{
BORDER = 0x00800000,
CAPTION = 0x00C00000,
DLGFRAME = 0x00400000
}

public enum GWL
{
STYLE = -16

}

public enum SWP
{
NOACTIVATE = 0x0010
}

[System.Runtime.InteropServices.DllImport("Coredll.dll", SetLastError = true)]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

[System.Runtime.InteropServices.DllImport("coredll.dll", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hwnd, int hwnd2, int x, int y, int cx, int cy, int uFlags);

public static void MakeFlotableForm(Form formToFlotable)
{
//Quitamos el Borde

formToFlotable.FormBorderStyle = FormBorderStyle.None;

//Obtenemos el Handle del formulario
IntPtr hWnd = formToFlotable.Handle;

//Obtenemos el estilo
int style = (int)(WS.BORDER | WS.CAPTION | WS.DLGFRAME

//Aplicamos el estilo magico!
int lastStyle = SetWindowLong(hWnd, (int)GWL.STYLE, style);

//Obtenemos el area de trabajo
System.Drawing.Rectangle screen = Screen.PrimaryScreen.WorkingArea;
int heightToolBar = 26;//Tamoño del ToolBar

//POnemos la ventana centrada! con la funcion SetWindowPos
bool successWindowPos = SetWindowPos(hWnd, 0,
((screen.Width - formToFlotable.Width) / 2),
((screen.Height - (formToFlotable.Height + heightToolBar)) / 2),
formToFlotable.Width, formToFlotable.Height + heightToolBar,

(int)SWP.NOACTIVATE);
}
}

Y Solo tenemos que llamar la en el Load de nuestro formulario!
De la siguiente manera

UtilForm.MakeFlotableForm(this);

Y listo tenemos el resultado!

Si notamos ahora tenemos la barra arriba de nuetro formulario y el (OK) en el lugar que lo queremos ademas de eso tambien podemos mover nuestra ventana para cualquier lugar del area de trabajo! Lo que es muy util y la razon de este pequeño Blog

Si necesitan mas informacion quizas puedan visitar el foro de la msdn el cual me inspiro a hacer este escrito ya que hay no deje muy claras las cosas de cómo funcionaba y cual era la utilidad real!

http://forums.microsoft.com/MSDN-ES/ShowPost.aspx?PostID=1524353&SiteID=11

Y hasta la proxima!

2 comentarios:

Unknown dijo...

Buenas. Me encanta la idea de tu ejemplo pero por mucho que lo intente y pegue el codigo literal no consigo que me funcione. Estoy utilizando Windows Mobile 5 y Windows Mobile 6 y nada de nada. Estoy muy interesado en esta idea y me enczntaria poder tener un ejemplo en funcionamiento.

Gracias de antemano

Un saludo

Ikercio

Steven Calderon dijo...

@iker dame unos dias y subo un ejemplo funcional a google code o codeplex, saludos!