C# - Cómo modificar el comportamiento del botón minimizar, maximizar, etc.
Avanzado
Para cambiar el comportamiento del botón minimizar se debe recurrir a un mecanismo pocas veces utilizado por los desarrolladores de código administrado, hay que acceder al bucle de mensajes del sistemas de ventana de ventanas, más conocido como WndProc.
En Windows Forms esta es una tarea relativamente sencilla, la cual veremos unas líneas más adelante.
Cómo sabe una ventana que se debe maximizar o minimizar?
El bucle de mensajes
Las ventanas – y los demás controles – funcionan gracias a un bucle de mensajes, todo lo que manejamos nosotros como eventos : click del mouse, mover, cerrar, cambiar tamaño, maximizar etc, realmente es controlado por un bucle en donde se envían diferentes mensajes a la ventana, esta a su vez tiene un procedimiento que recibe estos mensajes y con base a los mensajes recibidos puede hacer una u otra cosa según se programe.
Si, para algunos esto ya debe estar sonando a cuento, pero las cosas son así por debajo de lo que usamos tradicionalmente. El tema del artículo no es explicar como funciona un ciclo de mensajes así que por el momento lo dejaremos hasta allí y quien quiera profundizar puede consultar esta fuente en internet https://www.winprog.org/tutorial/message_loop.html.
Por el momento lo que si nos interesa del bucle de mensajes es que algunos de esos mensajes se utilizan para maximizar y minimizar las ventanas, es decir cuando uno utiliza alguna funcionalidad para minimizar una ventana, lo que ocurre realmente es que se envía el mensaje que dice: hey! minimízate y ya el manejador de la ventana hará lo necesario para minimizarse.
Los Mensajes
Cada vez que se presiona cualquiera de los botones del marco de la ventana (maximizar, minimizar, restaurar, cerrar, etc.) o que se ejecute alguna acción sobre el menú de la ventana, el sistema mensajes envía a la ventana el mensaje WM_SYSCOMMAND
, este mensaje esta definido dentro de la API de Windows de esta manera
const int WM_SYSCOMMAND = 0x112;
Este mensaje a su ves esta acompañado de un parámetro WParam
el cual contiene información relevante a que acción se ha realizado con el menú o los botones de la ventana, entre estos mensajes encontramos
const int SC_MINIMIZE = 0xF020;
const int SC_MAXIMIZE = 0xF030;
const int SC_CLOSE = 0xF060;;
WndProc en Windows Forms
Para acceder a este procedimiento desde Windows Forms basta con sobre escribir el método WndProc
:
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
}
Implementación
Para encajar las piezas lo que se debe hacer es preguntar dentro de WndProc acerca de que mensaje se ha recibido, si el mensaje es WM_SYSCOMMAND
entonces se pregunta acerca del parámetro LParam
para verificar que comando ha sido enviado, es allí donde podemos interceptar el mensaje que nos interesa.
Siempre es necesario llamar al código base cuando no vayamos a hacer nada con un mensaje para que de esta forma la ventana se comporte de manera normal.
const int WM_SYSCOMMAND = 0x112;
const int SC_MINIMIZE = 0xF020;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SYSCOMMAND)
{
if (m.WParam == (IntPtr)SC_MINIMIZE)
MessageBox.Show("Hacer lo que quieras en vez de minimizar");
base.WndProc(ref m);
}
else
base.WndProc(ref m);
}