Resolved Create a form that cannot be close under certain condition

Joined
Dec 21, 2020
Messages
14
Programming Experience
Beginner
Hi, I am trying to create a time recorder which I do not want to accidentally close the program while the is not finish the counting. So I was try to hide the top bar this.FormBorderStyle = FormBorderStyle.None;of the program but it make me cannot move the window and also look ugly as well.
Is that possible to make the top right close button cannot be clicked ,or make a message box pop up and then forced to cancel the close?
 

Attachments

  • Dont let me click close button.png
    Dont let me click close button.png
    57 KB · Views: 11
Handle the FormClosing event and add logic to determine whether the form can close, setting e.Cancel to true if it can't. Be sure to use e.CloseReason to make sure that you don't prevent the form closing because Windows is shutting down or the like.
 
If you want to prevent the Close button being used at all, here's a class that I created over a decade ago that you can use:
SystemMenuManager Class:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    /// <summary>
    /// Removes and disables the Move and Close items in a form's system menu.
    /// </summary>
    public sealed class SystemMenuManager
    {
        /// <summary>
        /// The possible states of a menu item.
        /// </summary>
        public enum MenuItemState
        {
            /// <summary>
            /// Appears normal and responds to clicks.
            /// </summary>
            Enabled = MF_ENABLED,
            /// <summary>
            /// Appears greyed out and does not respond to clicks.
            /// </summary>
            Greyed = MF_GRAYED,
            /// <summary>
            /// Appears normal but does not respond to clicks.
            /// </summary>
            Disabled = MF_DISABLED,
            /// <summary>
            /// Is not present.
            /// </summary>
            Removed
        }

        /// <summary>
        /// Represents the Move menu item.
        /// </summary>
        private const int SC_MOVE = 0xF010;
        /// <summary>
        /// Represents the Close menu item.
        /// </summary>
        private const int SC_CLOSE = 0xF060;

        /// <summary>
        /// Indicates that a menu item is identified by command ID.
        /// </summary>
        private const int MF_BYCOMMAND = 0x0;

        /// <summary>
        /// Indicates that a menu item is enabled.
        /// </summary>
        private const int MF_ENABLED = 0x0;
        /// <summary>
        /// Indicates that a menu item is greyed out.
        /// </summary>
        private const int MF_GRAYED = 0x1;
        /// <summary>
        /// Indicates that a menu item is disabled.
        /// </summary>
        private const int MF_DISABLED = 0x2;

        /// <summary>
        /// The form whose menu is being managed.
        /// </summary>
        private Form target;
        /// <summary>
        /// The state of the form's Close menu item.
        /// </summary>
        private MenuItemState closeState;
        /// <summary>
        /// The handle of the menu being managed.
        /// </summary>
        private IntPtr menuHandle;

        [DllImport("user32.dll")]
        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("user32.dll")]
        private static extern int EnableMenuItem(IntPtr hMenu, int wIDEnableItem, int wEnable);

        [DllImport("user32.dll")]
        private static extern bool DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);

        public SystemMenuManager(Form target, bool movePresent)
            : this(target, movePresent, MenuItemState.Enabled)
        {
        }

        public SystemMenuManager(Form target, MenuItemState closeState)
            : this(target, true, closeState)
        {
        }

        public SystemMenuManager(Form target, bool movePresent, MenuItemState closeState)
        {
            this.target = target;
            this.closeState = closeState;

            this.target.Load += new EventHandler(target_Load);
            this.target.Resize += new EventHandler(target_Resize);
            this.target.KeyDown += new KeyEventHandler(target_KeyDown);

            this.menuHandle = GetSystemMenu(target.Handle, false);

            if (!movePresent)
            {
                // Remove the Move menu item.
                DeleteMenu(this.menuHandle, SC_MOVE, MF_BYCOMMAND);
            }

            if (closeState == MenuItemState.Removed)
            {
                // Remove the Close menu item.
                DeleteMenu(this.menuHandle, SC_CLOSE, MF_BYCOMMAND);
            }
            else
            {
                this.RefreshCloseItem();
            }

            if (closeState != MenuItemState.Enabled)
            {
                // Set the Keypreview to True so that the Alt+F4 key combination can be detected.
                target.KeyPreview = true;
            }
        }

        /// <summary>
        /// Sets the state of the Close menu item if present but not enabled.
        /// </summary>
        private void RefreshCloseItem()
        {
            if (this.closeState == MenuItemState.Disabled || this.closeState == MenuItemState.Greyed)
            {
                EnableMenuItem(this.menuHandle,
                               SC_CLOSE,
                               MF_BYCOMMAND | (int)this.closeState);
            }
        }

        private void target_Load(object sender, EventArgs e)
        {
            // Refresh the initial state of the Close menu item.
            RefreshCloseItem();
        }

        private void target_Resize(object sender, EventArgs e)
        {
            // If present, the Close item will be re-enabled after a resize operation so refresh its state.
            RefreshCloseItem();
        }

        private void target_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.F4 &&
                e.Alt &&
                this.closeState != MenuItemState.Enabled)
            {
                // Suppress the Alt+F4 key combination.
                e.Handled = true;
            }
        }
    }
}
Here's a usage sample that removes the Close item from the system menu, which also disables the Close button:
Sample Usage:
public partial class Form1 : Form
{
    SystemMenuManager menuManager;
 
    public Form1()
    {
        InitializeComponent();
 
        // Remove the Close menu item.
        this.menuManager = new SystemMenuManager(this, SystemMenuManager.MenuItemState.Removed);
    }
}
 
Back
Top Bottom