Haga clic y arrastre un formulario Delphi sin la barra de subtítulos

click fraud protection

La forma más común de mover una ventana es arrastrarla por su barra de título. Siga leyendo para descubrir cómo puede proporcionar capacidades de arrastre para Delphi formularios sin una barra de título, para que el usuario pueda mover un formulario haciendo clic en cualquier lugar del área del cliente.

Por ejemplo, considere el caso de un Aplicación de Windows que no tiene una barra de título, ¿cómo podemos mover esa ventana? De hecho, es posible crear ventanas con una barra de título no estándar e incluso formas no rectangulares. En este caso, ¿cómo podría saber Windows dónde están los bordes y las esquinas de la ventana?

El mensaje de Windows WM_NCHitTest

los Sistema operativo Windows está fuertemente basado en manejo de mensajes. Por ejemplo, cuando hace clic en una ventana o un control, Windows le envía un mensaje wm_LButtonDown, con información adicional sobre dónde está el cursor del mouse y qué teclas de control están actualmente presionado. ¿Suena familiar? Sí, esto no es más que un evento OnMouseDown en Delphi.

instagram viewer

Del mismo modo, Windows envía un mensaje wm_NCHitTest cada vez que un evento del mouse se produce, es decir, cuando el cursor se mueve o cuando se presiona o suelta un botón del mouse.

Código de entrada

Si podemos hacer que Windows piense que el usuario está arrastrando (ha hecho clic) la barra de título en lugar del área del cliente, entonces el usuario podría arrastrar la ventana haciendo clic en el área del cliente. La forma más fácil de hacer esto es "engañar" a Windows para que piense que realmente está haciendo clic en la barra de título de un formulario. Esto es lo que tienes que hacer:

1. Inserte la siguiente línea en la sección "Declaraciones privadas" de su formulario (declaración del procedimiento de manejo de mensajes):

procedimiento WMNCHitTest (var Msg: TWMNCHitTest); mensaje WM_NCHitTest; 

2. Agregue el siguiente código en la sección "implementación" de la unidad de su formulario (donde Form1 es el nombre supuesto del formulario):

procedimiento TForm1.WMNCHitTest (var Msg: TWMNCHitTest);

empezar

heredado;

Si Msg. Resultado = htClient luego Msg. Resultado: = htCaption;

final; 

La primera línea de código en el controlador de mensajes llama al método heredado para obtener el manejo predeterminado para el mensaje wm_NCHitTest. La parte If del procedimiento intercepta y cambia el comportamiento de su ventana. Esto es lo que realmente sucede: cuando el sistema operativo envía un mensaje wm_NCHitTest a la ventana, junto con las coordenadas del mouse, la ventana devuelve un código que indica qué parte de sí misma tiene sido golpeado La información importante, para nuestra tarea, está en el valor del mensaje. Campo de resultados. En este punto, tenemos la oportunidad de modificar el resultado del mensaje.

Esto es lo que hacemos: si el usuario ha hecho clic en el área del cliente del formulario, hacemos que Windows piense que el usuario hizo clic en la barra de título. En Objeto Pascal "palabras": si el valor de retorno del mensaje es HTCLIENT, simplemente lo cambiamos a HTCAPTION.

No más eventos de mouse

Al cambiar el comportamiento predeterminado de nuestros formularios, eliminamos la capacidad de Windows de notificarle cuando el mouse se encuentra sobre el área del cliente. Un efecto secundario de este truco es que tu forma ya no generará eventos para mouse mensajes

Ventana sin subtítulos sin bordes

Si desea una ventana sin bordes sin título similar a una barra de herramientas flotante, establezca el Título del formulario en una cadena vacía, desactive todos los BorderIcons y establezca BorderStyle en bsNone.

Un formulario se puede cambiar de varias maneras mediante la aplicación de código personalizado en el método CreateParams.

Más trucos de WM_NCHitTest

Si observa más detenidamente el mensaje wm_NCHitTest, verá que el valor de retorno de la función indica la posición del punto caliente del cursor. Esto nos permite jugar un poco más con el mensaje para crear resultados extraños.

El siguiente fragmento de código evitará que los usuarios cierren sus formularios haciendo clic en el botón Cerrar.

Si Msg. Resultado = htCerrar luego Msg. Resultado: = htNowhere; 

Si el usuario intenta mover el formulario haciendo clic en la barra de título y arrastrando, el código reemplaza el resultado del mensaje con un resultado que indica que el usuario hizo clic en el área del cliente. Esto evita que el usuario mueva la ventana con el mouse (opuesto a lo que estábamos haciendo al principio del artículo).

Si Msg. Resultado = htCaption luego Msg. Resultado: = htClient; 

Tener componentes en un formulario

En la mayoría de los casos, tendremos algunos componentes en un formulario. Digamos, por ejemplo, que un objeto Panel está en un formulario. Si la propiedad Alinear de un panel se establece en alClient, el Panel llena el área completa del cliente, de modo que es imposible seleccionar el formulario principal haciendo clic en él. El código anterior no funcionará, ¿por qué? Se debe a que el mouse siempre se mueve sobre el componente Panel, no sobre el formulario.

Para mover nuestro formulario arrastrando un panel en el formulario, debemos agregar algunas líneas de código en el procedimiento de evento OnMouseDown para el componente Panel:

procedimiento TForm1.Panel1MouseDown

(Remitente: TObject; Botón: TMouseButton;
Shift: TShiftState; X, Y: entero);
empezar

 ReleaseCapture;

 SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);

final; 

Nota: Este código no funcionará con controles que no sean ventanas, como Componentes TLabel.

instagram story viewer