views:

34

answers:

1

I have used P/Invoke to call GetSystemMenu and EnableMenuItem (win32api) to disable the close functionality. However, after minimizing or maximizing my Windows Forms application the button is re-enabled.

Obviously minimizing or maximizing is causing the behavior, but how? I'm not sure where to look to prevent this behavior.

Should I be preventing the maximize and minimize behavior or is there something particularly wrong with the way in which I P/Invoked the calls? Once the application (main form) has loaded, I call the static method from a button click.

class PInvoke
{
    // P/Invoke signatures
    [DllImport("user32.dll")]
    static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
    [DllImport("user32.dll")]
    static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);

    // SysCommand (WM_SYSCOMMAND) constant
    internal const UInt32 SC_CLOSE = 0xF060;

    // Constants used with Add/Check/EnableMenuItem
    internal const UInt32 MF_BYCOMMAND = 0x00000000;
    internal const UInt32 MF_ENABLED = 0x00000000;
    internal const UInt32 MF_GRAYED = 0x00000001;
    internal const UInt32 MF_DISABLED = 0x00000002;

    /// <summary>
    /// Sets the state of the Close (X) button and the System Menu close functionality.
    /// </summary>
    /// <param name="window">Window or Form</param>
    /// <param name="bEnabled">Enabled state</param>
    public static void EnableCloseButton(IWin32Window window, bool bEnabled)
    {
        IntPtr hSystemMenu = GetSystemMenu(window.Handle, false);

        EnableMenuItem(hSystemMenu, SC_CLOSE, MF_BYCOMMAND | (bEnabled ? MF_ENABLED : MF_GRAYED));
    }
}
+2  A: 

Each window has a window class, which defines styles for all windows of that class. You can use CS_NOCLOSE class style to remove the close button for windows of that class. See here and here for details how to set this class flag.

If this doesn't give you what you want, I wouldn't disable minimize/maximize for sake of usability, but you could listen for minimize/maximimize events and re-run the code to disable the close button. Finally, it is possible to handle the close event, and simply not close. Then you know your window will definitely not be closed, even if the close button does inadvertently become enabled.

mdma
Thank you, this will do wonderfully. Although this was a learning exercise I much prefer to remove it as opposed to disabling it. I was mainly confused that minimize/maximize would re-enable it. Thanks again!
Brainsick