Publicado el 07/Ene/2005
|
El truco o el método que utilizaré aquí es el que hace años te mostré para el VB clásico y que recientemente publiqué para el Windows XP. En dicho código usamos la función SendMessage del API de Windows para "ordenarle" al formulario de que se mueva, esa orden se la daremos normalmente cuando movamos el ratón mientras mantenemos pulsado el botón izquierdo del mismo, aunque el código lo podemos usar cuando nos apetezca, pero básicamente es más obvio en esas circunstancias.
La declaración de las funciones del API se pueden hacer al estilo "clásico" de VB6, cambiando los tipos de datos, pero debido a que te mostraré también cómo hacerlo en C#, lo más lógico es hacer dichas declaraciones al estilo de .NET, incluso podemos declararlas como Sub (void en C#), ya que realmente el valor devuelto por las funciones no los tendremos en cuenta.
Aquí tienes las declaraciones de las constantes y las funciones del API para VB, (para C# las puedes ver más abajo).Private Const WM_SYSCOMMAND As Integer = &H112& Private Const MOUSE_MOVE As Integer = &HF012& ' ' Declaraciones del API al estilo .NET <System.Runtime.InteropServices.DllImport("user32.DLL", EntryPoint:="ReleaseCapture")> _ Private Shared Sub ReleaseCapture() End Sub ' <System.Runtime.InteropServices.DllImport("user32.DLL", EntryPoint:="SendMessage")> _ Private Shared Sub SendMessage( _ ByVal hWnd As System.IntPtr, ByVal wMsg As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer _ ) End SubPara utilizar estas funciones del API, he creado un método al que llamaremos cada vez que queramos que el formulario se mueva.
' función privada usada para mover el formulario actual Private Sub moverForm() ReleaseCapture() SendMessage(Me.Handle, WM_SYSCOMMAND, MOUSE_MOVE, 0) End SubEste método normalmente lo llamaremos desde el evento MouseMove del control que queramos usar para mover el formulario.
' podemos usar el mismo procedimiento de evento para mover Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles MyBase.MouseMove, Label1.MouseMove, GroupBox1.MouseMove, PictureBox1.MouseMove If e.Button = MouseButtons.Left Then moverForm() End If End Sub
Aquí tienes una captura del formulario en tiempo de diseño, en el que he añadido un Label, un PictureBox y un GroupBox, los cuales podremos usar para mover el formulario, además de pulsando en el propio formulario.
El formulario en tiempo de diseño
Y esto es todo... como ves nada del otro mundo..., una vez que se sabe cómo hacerlo.
Aquí tienes el ZIP con el código completo tanto para VB como C#:
MoverFormularioSinCaption.zip 26.7 KB
Nos vemos.
Guillermo
'------------------------------------------------------------------------------ ' Prueba de mover un formulario sin barra de textos (ni bordes) (07/Ene/05) ' Usando API de Windows ' ' ©Guillermo 'guille' Som, 2005 '------------------------------------------------------------------------------ Imports System Imports System.Windows.Forms Public Class Form1 Inherits System.Windows.Forms.Form #Region " Código generado por el Diseñador de Windows Forms " ' ... código del diseñador de Windows (no mostrado) #End Region ' ' Declaraciones del API de Windows (y constantes usadas para mover el form) ' Private Const WM_SYSCOMMAND As Integer = &H112& Private Const MOUSE_MOVE As Integer = &HF012& ' '' Declaraciones "clásicas" de VB6 'Private Declare Function ReleaseCapture Lib "user32" () As Integer 'Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ ' (ByVal hWnd As System.IntPtr, ByVal wMsg As Integer, _ ' ByVal wParam As Integer, ByVal lParam As Integer) As Integer ' ' Declaraciones del API al estilo .NET <System.Runtime.InteropServices.DllImport("user32.DLL", EntryPoint:="ReleaseCapture")> _ Private Shared Sub ReleaseCapture() End Sub ' <System.Runtime.InteropServices.DllImport("user32.DLL", EntryPoint:="SendMessage")> _ Private Shared Sub SendMessage( _ ByVal hWnd As System.IntPtr, ByVal wMsg As Integer, _ ByVal wParam As Integer, ByVal lParam As Integer _ ) End Sub ' ' función privada usada para mover el formulario actual Private Sub moverForm() ReleaseCapture() SendMessage(Me.Handle, WM_SYSCOMMAND, MOUSE_MOVE, 0) End Sub ' Private Sub btnCerrar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCerrar.Click Me.Close() End Sub ' ' podemos usar el mismo procedimiento de evento para mover Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles MyBase.MouseMove, Label1.MouseMove, GroupBox1.MouseMove, PictureBox1.MouseMove If e.Button = MouseButtons.Left Then moverForm() End If End Sub End Class
//----------------------------------------------------------------------------- // Prueba de mover un formulario sin barra de textos (ni bordes) (07/Ene/05) // Usando API de Windows // // ©Guillermo 'guille' Som, 2005 //----------------------------------------------------------------------------- using System; using System.Windows.Forms; public class Form1 : System.Windows.Forms.Form { public Form1() { // // Necesario para admitir el Diseñador de Windows Forms // InitializeComponent(); // // TODO: agregar código de constructor después de llamar a InitializeComponent // // Estas "asignaciones" suelen estar en el cuerpo del código oculto // del diseñador de Windows, pero lo pongo fuera para que se vea // que realmente capturamos todo el código en la misma función this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove); this.Label1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove); this.PictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove); // // La "captura" del evento MouseMove del GroupBox // no aparece en la lista del diseñador de formularios de C# this.GroupBox1.MouseMove += new MouseEventHandler(Form1_MouseMove); } // #region Código generado por el Diseñador de Windows Forms // Código del diseñador de formularios (no mostrado) #endregion // /// <summary> /// Punto de entrada principal de la aplicación. /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } // // Declaraciones del API de Windows (y constantes usadas para mover el form) // const int WM_SYSCOMMAND = 0x112; const int MOUSE_MOVE = 0xF012; // // Declaraciones del API [System.Runtime.InteropServices.DllImport("user32.DLL", EntryPoint="ReleaseCapture")] private extern static void ReleaseCapture(); // [System.Runtime.InteropServices.DllImport("user32.DLL", EntryPoint="SendMessage")] private extern static void SendMessage(System.IntPtr hWnd, int wMsg, int wParam, int lParam); // // función privada usada para mover el formulario actual private void moverForm() { ReleaseCapture(); SendMessage(this.Handle, WM_SYSCOMMAND, MOUSE_MOVE, 0); } // // private void btnCerrar_Click(object sender, System.EventArgs e) { this.Close(); } // podemos usar el mismo procedimiento de evento para mover private void Form1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) { moverForm(); } }