How to handle the close button (large X) at the source?

In some cases, we would like to block the action of the close button in the title bar. The problem is that these are MDI applications, and it seems that we will need to add code in each form to cancel the operation in the event handler Closing. It seems that the forms of the child are the first to receive this event. Unable to add code in one place to cancel the close operation. Information on how a common event propagates to a child form will be appreciated. Is there an easy way to do what we want to do?

+3
source share
2 answers

Windows provides a way to do this, you can mess with the system menu. Provides good feedback, the close button actually looks off. You can disable the SC_CLOSE command in the system menu. It’s best to demonstrate a sample form, start by clicking the button on it:

using System.Runtime.InteropServices;
...

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
        button1.Click += new EventHandler(button1_Click);
    }

    private bool mCloseEnabled = true;
    public bool CloseEnabled {
        get { return mCloseEnabled; }
        set {
            if (value == mCloseEnabled) return;
            mCloseEnabled = value;
            setSystemMenu();
        }
    }

    protected override void OnHandleCreated(EventArgs e) {
        base.OnHandleCreated(e);
        setSystemMenu();
    }
    private void setSystemMenu() {
        IntPtr menu = GetSystemMenu(this.Handle, false);
        EnableMenuItem(menu, SC_CLOSE, mCloseEnabled ? 0 : 1);
    }
    private const int SC_CLOSE = 0xf060;
    [DllImport("user32.dll")]
    private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool revert);
    [DllImport("user32.dll")]
    private static extern int EnableMenuItem(IntPtr hMenu, int IDEnableItem, int wEnable);

    private void button1_Click(object sender, EventArgs e) {
        CloseEnabled = !CloseEnabled;
    }
}
+3
source

Michael already wrote the answer in the comments (just to add it to the answers):

Create a single BaseFormsClass where you override the behavior, and then subclass your classes from the new BaseFormsClass.

+1
source

Source: https://habr.com/ru/post/1742320/


All Articles