2010-04-22 2 views
3

В некоторых случаях мы хотели бы заблокировать действие кнопки закрытия в строке заголовка. Проблема в том, что это приложения MDI, и кажется, что нам нужно будет добавить код в каждой форме, чтобы отменить операцию в обработчике событий Closing. Кажется, что формы ребенка являются первыми, кто получил это событие. Невозможно добавить код в одном месте, чтобы отменить операцию закрытия. Будет приветствоваться информация о том, как распространенное событие распространяется на дочернюю форму. Есть ли простой способ сделать то, что мы хотим сделать?Как отрегулировать кнопку закрытия (большой X) у источника?

+2

Вы можете подклассы формы, написать код для закрытия в ней, а затем использовать, что вместо формы для ваших детей. –

+0

@ Майкл. Трудность состоит в том, что это устаревшее приложение, и уже существует множество Форм. Изменение унаследованного класса не слишком сложно. Проблема в том, что каждый из этих классов имеет обработчики на 'Closing'event. Я мог бы связать их с другим пользовательским событием, вызванным из унаследованного класса. Я все еще надеюсь на лучшее решение, но это лучшее, что я получил до сих пор. –

ответ

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

Это решение, которое я наконец использовал. Он отлично работает. Благодарю. –

1

Майкл уже написал ответ в комментариях (просто добавить его здесь к ответам):

Создание единого BaseFormsClass, где вы переопределять поведение, а затем подкласс классы от новых BaseFormsClass.

+0

Я просто ответил Майклу. –

+0

Вы можете попытаться перехватить сообщения окна WM_CLOSE. Но если вы буквально не имеете тысячи существующих форм, я думаю, что подход базового класса будет самым простым и быстрым. – Foxfire

Смежные вопросы