Thursday, November 20, 2003

Disabling the Window Close Button and System Close menu in a Windows Form

Ran into one of those common scenarios today where you have to dive into P/Invoke land for something that should be a lot easier to do than it is. Requirement was to disable the Window close button while a processing thread was active, re-enable when the processing thread was stopped. Found a nice solution through Google on Cory Smith's blog. Ported the code to C# and encapsulated as part of the form instead of a separate class with a little clean up of the API declaration types. The basic steps to re-use are below. You could also make this a base class type that derives from Form that you then derive your form classes from, but then you have to deal with the IDE designer going stupid sometimes.

This is the kind of silliness that comes up all the time in real apps that I hope goes away in Longhorn since the OS API is all managed. One would expect to see these kinds of capabilities exposed as part of the Form class or its equivalent in Avalon.

Basic steps are to bring in the APIs and constants as part of the form class and wrap toggling the enabled state of the close command with a property (that should have been a member of the base Form class!!).

// Declare P/Invoke methods

[DllImport("user32")]

private static extern IntPtr GetSystemMenu(IntPtr hWnd, int revert);

[DllImport("user32")]

private static extern int EnableMenuItem(IntPtr hWndMenu, int itemID, int enable);

// Declare constants to pass to the methods

private const int SC_CLOSE = 0xF060;

private const int MF_ENABLED = 0;

private const int MF_GREYED = 1;

private const int MF_BYCOMMAND = 0;

// Declare a flag to track the enabled state

private bool m_bCloseEnabled = true;

private System.Windows.Forms.Button btnToggleState; // default for WinForms

public bool CloseEnabled

{

get

{

// Return the internal flag state

return m_bCloseEnabled;

}

set

{

// Decide on the state to pass based on the value being set

int setting;

if (value) // Enabling

{

setting = MF_BYCOMMAND | MF_ENABLED;

}

else

{

setting = MF_BYCOMMAND | MF_GREYED;

}

// Make the update

EnableMenuItem(GetSystemMenu(this.Handle,0),SC_CLOSE,setting);

// Update the internal flag state

m_bCloseEnabled = value;

}

}

 

Then added a handler for the SizeChanged event to handle minimize/maximize redrawing of the menu to reset the state to the internally maintained state:

private void OnSizeChanged(object sender, System.EventArgs e)

{

// Reset the state with the internally maintained state

CloseEnabled = m_bCloseEnabled;

}

 

Then you can simply set the state of the CloseEnabled property whenever you want to change the state of the close button.



Thursday, November 20, 2003 2:38:16 AM (GMT Standard Time, UTC+00:00)
Comments [0]  | 


Comments are closed.















February, 2012 (1)
January, 2012 (1)
November, 2011 (4)
October, 2011 (1)
September, 2011 (2)
August, 2011 (1)
July, 2011 (1)
May, 2011 (5)
March, 2011 (4)
February, 2011 (2)
January, 2011 (3)
November, 2010 (4)
October, 2010 (1)
September, 2010 (5)
August, 2010 (5)
July, 2010 (6)
June, 2010 (8)
May, 2010 (2)
April, 2010 (2)
January, 2010 (1)
December, 2009 (3)
November, 2009 (2)
October, 2009 (3)
September, 2009 (3)
August, 2009 (2)
July, 2009 (3)
May, 2009 (3)
April, 2009 (2)
March, 2009 (1)
February, 2009 (2)
January, 2009 (2)
December, 2008 (1)
November, 2008 (2)
October, 2008 (5)
September, 2008 (4)
August, 2008 (2)
July, 2008 (1)
June, 2008 (2)
May, 2008 (2)
April, 2008 (3)
February, 2008 (6)
January, 2008 (3)
December, 2007 (1)
November, 2007 (1)
October, 2007 (5)
September, 2007 (1)
July, 2007 (3)
June, 2007 (8)
April, 2007 (2)
March, 2007 (4)
February, 2007 (1)
December, 2006 (2)
November, 2006 (9)
October, 2006 (5)
September, 2006 (3)
August, 2006 (2)
July, 2006 (4)
June, 2006 (5)
May, 2006 (10)
April, 2006 (4)
March, 2006 (2)
February, 2006 (12)
January, 2006 (7)
December, 2005 (2)
November, 2005 (15)
October, 2005 (6)
September, 2005 (7)
August, 2005 (3)
July, 2005 (10)
June, 2005 (11)
May, 2005 (7)
April, 2005 (8)
March, 2005 (6)
February, 2005 (2)
January, 2005 (6)
December, 2004 (3)
November, 2004 (5)
October, 2004 (2)
September, 2004 (5)
August, 2004 (13)
July, 2004 (6)
June, 2004 (14)
May, 2004 (17)
April, 2004 (12)
March, 2004 (8)
February, 2004 (10)
January, 2004 (14)
December, 2003 (9)
November, 2003 (13)
October, 2003 (3)





Sign In
Copyright © 2006-2007 Brian Noyes. All rights reserved.

designed by NUKEATION STUDIOS