RSS 2.0 Feed
RSS 2.0


Atom 1.0 Feed
Atom 1.0

  Disabling the Windows Close action 


There are times that you'll see a Window that has a close button in the titlebar, but it is disabled. This is often found in applications where the dialog/window changes it's status past a stoppable point so the Windows close action is removed so the user cannot close the dialog to stop the process (For example when installing a Windows service pack). You might want to produce this same effect in your own applications. While there is nothing built into the .NET Framework to do so, with a few Win32API calls the task becomes simple.

The Win32API calls we'll be using will give you access to the windows system menu items. We'll remove the “Close” menu item and by doing so it will also disable all associated “Close” actions for the window. That is, not only will the “Close” item in the system menu be removed, but a side-effect is that the Close button (the 'X' in the far right of the titlebar) will also be disabled. Let's take a look at the code.


using System.Runtime.InteropServices;

// ...

[DllImport("user32.dll", EntryPoint="GetSystemMenu")]
private static extern IntPtr GetSystemMenu(IntPtr hwnd, int revert);

[DllImport("user32.dll", EntryPoint="GetMenuItemCount")]
private static extern int GetMenuItemCount(IntPtr hmenu);

[DllImport("user32.dll", EntryPoint="RemoveMenu")]
private static extern int RemoveMenu(IntPtr hmenu, int npos, int wflags);

[DllImport("user32.dll", EntryPoint="DrawMenuBar")]
private static extern int DrawMenuBar(IntPtr hwnd);

private const int MF_BYPOSITION = 0x0400;
private const int MF_DISABLED = 0x0002;

// ...

IntPtr hmenu = GetSystemMenu(this.Handle, 0);
int cnt = GetMenuItemCount(hmenu);

// remove 'close' action
RemoveMenu(hmenu, cnt-1, MF_DISABLED | MF_BYPOSITION);

// remove extra menu line
RemoveMenu(hmenu, cnt-2, MF_DISABLED | MF_BYPOSITION);

DrawMenuBar(this.Handle);

What we have going on there is we first get a handle to the system menu and get the count of items in it. Since the raw system menu will have “Close” at the bottom, we remove that but also need to move the line separator that was previously above it. BTW, I emphasized raw system menu because some applications, such as Ultramon, will all items to the system menus. That's ok and it will not screw this up. After removing those menu items we force a redraw of the menu and we've done it. As I pointed out earlier, since we remove the system menu's “Close” item, this also disables the “Close” action for the window. So as a side-effect the Close button will become disabled.

You'll see what the end result looks like. Both the Close menu is removed and you'll find that the Close button is disabled. Notice in this screenshot that even with the Ultramon menus added to the system menu that the assertion that the Close menu item is last on the list still gives us the desired results.  




                   



Leave a comment below.

Comments

  1. Matthew Douglass 6/5/2004 3:39 PM
    Gravatar
    As a note, just removing the bottom menu item may not be the best approach as there are applications out there that globally change all the system menus to add additional commands.

    For example, UltraMon is one I use for multi-monitor support and its adds a Maximize to Desktop and Restore From Desktop command after the Close command.

    Really what you should do is search through the menu and look for the menu item that specifically sends the window close command (which is I believe SC_CLOSE)
  2. Ryan Farley 6/6/2004 1:45 PM
    Gravatar
    Matthew,

    Good point. I use UltraMon too (as you can see from the screenshot), however I have the menu option set to add the UltraMon items above the close menu. If they were added under then I'd have a problem.

    SC_CLOSE is correct - that is what I would need to use, but that would change things a little. The best way to do it then would be to use a MENUITEMINFO struct and set the wID to SC_CLOSE and then pass that struct off to GetMenuItemInfo, instead of using GetSystemMenu as I am in the current example.

    Maybe it calls for reposting a new sample?

    Thanks.
    -Ryan
  3. Robert 12/23/2004 3:57 AM
    Gravatar
    Thanks for posting this. I am new to C# and I am not sure where to put the API calls. In VB.NET I would put them in a .bas module. Does this code need to go in each form created where I wish not to have the X enabled?

    Thanks
  4. Skot 3/21/2005 9:40 AM
    Gravatar
    is it possible to add a custom action to close button??
    other than the close action.

  5. Jen 4/5/2005 12:33 PM
    Gravatar
    Thanks for the post!

    I read something about CreateParams that might work as well.

    To Skot:

    You can provide a custom close action by handling the Forms.Closing event.

    Eg.
    private void InitializeComponent()
    {
    ...
    this.Closing += new System.ComponentModel.CancelEventHandler(this.MyForm_Closing);
    ...
    }

    private void MyForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
    /// stuff
    e.Cancel = true; /// Do this if you want to keep the form alive,
    /// and just hide it or something
    }
  6. vivek 10/13/2005 10:43 PM
    Gravatar
    thanks for solving my query
    my email id is
    vivek27jan@yahoo.co.in
  7. Paul Brown 1/30/2006 7:48 PM
    Gravatar
    After searching on how to disable the close button this was my first choice in Google and you were spot on!

    Cheers Mate
  8. Anders Cui 1/10/2007 7:28 AM
    Gravatar
    ???????????,??????????????????????????????,????????????,???????????????.NET Framework?????????,?????Win32 API, ???????
  9. Z.Javon 1/11/2007 2:05 AM
    Gravatar
    ???????????,??????????????????????????????,????????????,???????????????.NETFramework?????????,?????...
  10. kauj 4/5/2007 9:45 PM
    Gravatar
    nice one, the best one ive seen / tried so far.
    all the others dont work on MDI child forms but this one works.
    thanks
  11. Ian Jones 5/3/2007 3:01 AM
    Gravatar
    I am not a VB programmer or developer at all just a sys admin! But I really would like to use this as a compiled mini app to call from a command script to disable the users ability to close a window by just clicking on the 'X'. Can someone tell me if it's possible to put this code into a mini exe to run on its own and how I would do this ?

    Thanks - any suggestions welcome.
    Email: ian.jones@stevens-scanlan.co.uk
  12. Ananga Samanta 6/18/2007 11:08 PM
    Gravatar
    Internet Explorer Window Close by just clicking on the 'X', But I want to update MySQL Database when windows close, Juse Auto meticaly singn out.
  13. Ananga Samanta 6/18/2007 11:10 PM
    Gravatar
    Internet Explorer Window Close by just clicking on the 'X', But I want to update MySQL Database when windows close, Juse Auto meticaly singn out. Please advice, My E-Mail : anangahelp@yahoo.com
  14. Anoop Kumar 8/3/2007 9:17 AM
    Gravatar
    I struggled half a day to a solution to disable close button. Many of the solution i found on net was incomplete or i really struggled to implement them. But your solution worked like anything . Many thanks
  15. Naveen 12/3/2007 1:38 AM
    Gravatar
    thanks man...really helped
  16. Nir 1/3/2008 12:39 AM
    Gravatar
    how can you implement it on ALL windows on the system?
    i want to be able to control OTHER windows and to enable/disable their close button.
    have an idea?
  17. Roberto Di Mitri 3/20/2008 5:00 AM
    Gravatar
    Hello, i use your code but the Building of the solution return this error:
    'TestTrovaIP.VIDS1X.VIDS1M1' does not contain a definition for 'Handle'.

    Can you help me?
    Thanks
  18. 1/20/2009 8:25 AM
    Gravatar
    nur MinimizeBox sichtbar? | hilpers
  19. Alvin 2/25/2009 12:52 AM
    Gravatar
    Hi Jen

    I like your solutions instead of import the user32.dll.

    Cheers
  20. Ziete 7/17/2009 8:38 AM
    Gravatar
    Hi, mi question is...

    is the same code for diseble the close button in Word 2007
    for a word application?

    c# exclusive :p
  21. davetiye 10/28/2009 3:16 AM
    Gravatar
    düğün davetiyesi ve davetiye örnekleri
Comments have been closed on this topic.



 

News


Also see my CRM Developer blog

Connect:              


Sponsor

Sections