C#: botón cerrar

C# – Desactivar el botón cerrar de la barra de título de la ventana

Un programador desea que una aplicación arranque sin que pueda ser terminada por el usuario pulsando el botón Cerrar (el aspa de la esquina derecha) de la Barra de título del formulario ni mediante la pulsación de las teclas ALT+F4. El código en C# que se presenta en este artículo desactiva ese botón y el efecto de las teclas ALT+F4.

Microsoft tiene un ejemplo de este tipo referido a una aplicación de consola, puede ser consultado aquí.

Si alguien desea profundizar sobre este asunto ha de buscar información sobre las API de Windows porque en realidad lo que se hace es utilizar procedimientos externos a C# existentes en librerías del sistema. En este ejercicio se leen procedimientos de la librería user32.dll, y con ellos se actúa sobre el llamado Menú de sistema de las ventanas, el que provee de funcionalidad tanto a los botones de Maximizar / Minimizar / Cerrar como a los elementos que cuelgan del icono de la Barra de título: Restaurar / Mover / Tamaño / Minimizar / Maximizar / Separador / Cerrar.

En primer lugar es necesario importar procedimientos externos a .NET, almacenados en la librería de Windows llamada user32.dll, estos procedimientos permiten manipular los botones de la barra de título de las ventanas:

//Quitar elementos del menú de sistema
[DllImport("user32.Dll")]
public static extern IntPtr RemoveMenu(int hMenu, int nPosition,int wFlags);

//Obtener el menú de sistema
[DllImport("User32.Dll")]
public static extern IntPtr GetSystemMenu(int hWnd, bool bRevert);

//Obtener el número de elementos del menú de sistema
[DllImport("User32.Dll")]
public static extern IntPtr GetMenuItemCount(int hMenu);

//Redibujar la barra de título de la ventana
[DllImport("User32.Dll")]
public static extern IntPtr DrawMenuBar(int hwnd);

El método que desactiva el botón cerrar es éste:

//Método que desactiva el botón X (cerrar)
public void DisableCloseButton(int hWnd)
{
IntPtr hMenu;
IntPtr menuItemCount;
//Obtener el manejador del menú de sistema del formulario
hMenu = GetSystemMenu(hWnd, false);
//Obtener la cuenta de los ítems del menú de sistema.
//Es el menú que aparece al pulsar sobre el icono a la izquierda
//de la Barra de título de la ventana, consta de los ítems: Restaurar, Mover,
//Tamaño,Minimizar, Maximizar, Separador, Cerrar
menuItemCount = GetMenuItemCount(hMenu.ToInt32());
//Quitar el ítem Close (Cerrar), que es el último de ese menú
RemoveMenu(hMenu.ToInt32(), menuItemCount.ToInt32() - 1,MF_DISABLED | MF_BYPOSITION);
//Quitar el ítem Separador, el penúltimo de ese menú, entre Maximizar y Cerrar
RemoveMenu(hMenu.ToInt32(), menuItemCount.ToInt32() - 2, MF_DISABLED | MF_BYPOSITION);
//Redibujar la barra de menú
DrawMenuBar(hWnd);
}

Al pulsar el botón que desactiva el botón Cerrar se llama al método anterior al que se le pasa el identificador de la ventana sobre la que se actúa:

//Al pulsar el botón Desactivar
private void button1_Click(object sender, System.EventArgs e)
{
if (pulsado)
{
//Método desarrollado más arriba, pasando como parámetro
//el identificador de la ventana sobre la que vamos a actuar
DisableCloseButton(this.Handle.ToInt32());
//Aviso al usuario, no funciona el botón cerrar ni ALT+F4
MessageBox.Show ("El botón Cerrar ha sido desactivado.\nPulsa Salir para cerrar la aplicación",    "Cerrar desactivado 1");
pulsado = false;
}
else
{
MessageBox.Show ("Ya habías pulsado aquí.\nPulsa Salir para cerrar la aplicación",    "Cerrar desactivado 2");
}
}

Aplicación completa en Visual Basic 2005: Cerrar-cs.

NOTA: en esta aplicación se usa el tipo de dato IntPtr. Se ha diseñado el tipo IntPtr para que sea un número entero cuyo tamaño sea específico de la plataforma. Es decir, se espera que una instancia de este tipo tenga lugar en sistemas operativos y hardware de 32 bits, y en sistemas operativos y hardware de 64 bits.
El tipo IntPtr se puede utilizar por idiomas que admiten punteros, y como un medio común para hacer referencia a los datos entre idiomas que admiten o no punteros.
El tipo IntPtr es compatible con CLS (Common Language Specification) -> conjunto de características básicas de lenguaje englobadas en .NET Framework y pertenece al espacio de nombres System.

Los comentarios están cerrados.