如何在源头处理关闭(大X)按钮?

时间:2010-04-22 17:09:00

标签: .net winforms

我们希望在某些情况下阻止标题栏中关闭按钮的操作。问题是它是一个MDI应用程序,似乎我们必须在每个表单中添加代码以取消Closing事件处理程序中的操作。似乎儿童表格是第一个接收该事件的人。无法在单个位置添加代码以取消关闭操作。有关如何将关闭事件传播到子表单的信息将受到欢迎。有没有一种简单的方法可以做我们想做的事情?

2 个答案:

答案 0 :(得分:3)

Windows提供了一种方法,您可以修改系统菜单。提供良好的反馈,关闭按钮实际上看起来禁用。您可以在系统菜单中禁用SC_CLOSE命令。使用示例表单进行最佳演示,通过在其上放置一个按钮开始:

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;
    }
}

答案 1 :(得分:1)

迈克尔已经在评论中写了答案(只是将其添加到答案中):

创建一个BaseFormsClass,在其中覆盖行为,然后从新的BaseFormsClass中继承类。