//DESACTIVAR EL BOTÓN CERRAR Y LA FUNCIÓN DE CIERRE CON ALT+F4

//NOTA de Miliuco:
//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. El tipo IntPtr pertenece
//al espacio de nombres System

//Importar espacios de nombres necesarios para la aplicación
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

//Para leer procedimientos externos radicados en librerías de windows
using System.Runtime.InteropServices;

namespace Cerrar_desactivado
{
    /// <summary>
    /// Descripción breve de Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.ComponentModel.IContainer components;

        /// <summary>
        public Form1()
        {
            //
            // Necesario para admitir el Diseñador de Windows Forms
            //
            InitializeComponent();

            //
            // TODO: agregar código de constructor después de llamar a InitializeComponent
            //
        }

        /// <summary>
        /// Limpiar los recursos que se estén utilizando.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Código generado por el Diseñador de Windows Forms
        /// <summary>
        /// Método necesario para admitir el Diseñador. No se puede modificar
        /// el contenido del método con el editor de código.
        /// </summary>
        private void InitializeComponent()
        {
            System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
            this.button1 = new System.Windows.Forms.Button();
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.button1.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            this.button1.Location = new System.Drawing.Point(16, 24);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(152, 80);
            this.button1.TabIndex = 0;
            this.button1.Text = "Desactivar botón";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // button2
            // 
            this.button2.FlatStyle = System.Windows.Forms.FlatStyle.System;
            this.button2.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
            this.button2.Location = new System.Drawing.Point(184, 24);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(104, 80);
            this.button2.TabIndex = 1;
            this.button2.Text = "Salir";
            this.button2.Click += new System.EventHandler(this.button2_Click);
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(304, 130);
            this.Controls.Add(this.button2);
            this.Controls.Add(this.button1);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = " Botón cerrar - >";
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// Punto de entrada principal de la aplicación.
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Button button2;
        
        //Declaración de constantes necesarias (valores en hexadecimal)
        private const int MF_BYPOSITION = 0x400;
        private const int MF_REMOVE = 0x1000;
        private const int MF_DISABLED = 0x2;

        //Variable para saber si ya está desactivado el botón X
        private bool pulsado = true;

        //Importación de procedimientos externos almacenados
        //en la librería de Windows USER32.DLL

        //Quitar elementos del menú de sistema
        [DllImport("user32.Dll")]
        public static extern IntPtr RemoveMenu(int hMenu, int nPosition,long 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);

        //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 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");
            }
        }

        //Al pulsar el botón Salir
        private void button2_Click(object sender, System.EventArgs e)
        {
            //Salir de la aplicación
            Application.Exit();
        }

    }
}