Disable close button for Dialog box

Introduction :
There are occasions when we would like to disable the close button on a dialog or any other window. In this article I am going to show you a simple way to do that. Even though I am going to show you how to disable the close button for a dialog, this technique would work for other windows too and for other system menu commands also.

Technique :
We use GetSystemMenu function to get the handle to the Control menu. Then using that handle we either call ModifyMenu or EnableMenuItem to change the control menu.

(1) Using ModifyMenu :
Add the following code to the InitDialog handler of your class

   CMenu* mnu = this->GetSystemMenu(FALSE);
   mnu->ModifyMenu(SC_CLOSE,MF_BYCOMMAND | MF_GRAYED );
(2) Using EnableMenuItem :
Add the following code to the InitDialog handler of your class

   CMenu* mnu = this->GetSystemMenu(FALSE);
   mnu->EnableMenuItem( SC_CLOSE, MF_BYCOMMAND|MF_GRAYED);
Thus by adding a couple of lines we can disable the close button for a dialog or any other window.


Date Last Updated: March 24, 1999



Comments

  • Cool idea. Thanks. Take this snippet.

    Posted by bluredEn on 04/17/2007 03:39am

    Cool idea. Thanks.
    
    Here is a code snippet that I used for a similar
    purpose - if it may be of any use to anyone:
    
    // Customizing the Windows style - disable the Max/Min buttons
    LONG style = GetWindowLong(hWndTarget, GWL_STYLE);
    style &=~(WS_MAXIMIZEBOX);		// disable Max
    style &=~(WS_MINIMIZEBOX);		// disable Min
    SetWindowLong(hWndTarget, GWL_STYLE, style);
    
    // Customizing the dialog's System Menu
    CMenu* pSysMenu = CWnd::FromHandle(hWndTarget)->GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        //pSysMenu->ModifyMenu(SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
        pSysMenu->DeleteMenu(SC_SIZE, MF_BYCOMMAND);
        pSysMenu->DeleteMenu(SC_MINIMIZE, MF_BYCOMMAND);
        pSysMenu->DeleteMenu(SC_MAXIMIZE, MF_BYCOMMAND);
        pSysMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
        pSysMenu->DeleteMenu(SC_RESTORE, MF_BYCOMMAND);
        pSysMenu->ModifyMenu(SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
    
        CWnd::FromHandle(hWndTarget)->DrawMenuBar();
    
        CString strMenuItem, strMenuItemAlt;
    
        strMenuItem	= _T(" Minimize");		// Add our Minimize menu item
        strMenuItemAlt	= _T(" Restore");
        if(CtrlSt_Min != CTRL_HIDE) {
            if(bIsWndMin == FALSE) {
                pSysMenu->AppendMenu(MF_STRING, IDM_SYSMENU_MIN, strMenuItem);
                pSysMenu->SetMenuItemBitmaps(IDM_SYSMENU_MIN, MF_BYCOMMAND, &bmpMinUp, &bmpMinOver);
                if(CtrlSt_Min == CTRL_INACTIVE)
                    pSysMenu->ModifyMenu(IDM_SYSMENU_MIN, MF_BYCOMMAND | MF_GRAYED, IDM_SYSMENU_MIN, strMenuItem);
            } else {
                pSysMenu->AppendMenu(MF_STRING, IDM_SYSMENU_MIN, strMenuItemAlt);
                pSysMenu->SetMenuItemBitmaps(IDM_SYSMENU_MIN, MF_BYCOMMAND, &bmpMaxRestore, &bmpMaxRestore);
                if(CtrlSt_Min == CTRL_INACTIVE)
                    pSysMenu->ModifyMenu(IDM_SYSMENU_MIN, MF_BYCOMMAND | MF_GRAYED, IDM_SYSMENU_MIN, strMenuItemAlt);
            }
        }
    
        strMenuItem		= _T(" Maximize");		// Add out Maximize menu item
        strMenuItemAlt	= _T(" Restore");
        if(CtrlSt_Max != CTRL_HIDE) {
            if(bIsWndMax == FALSE) {
                pSysMenu->AppendMenu(MF_STRING, IDM_SYSMENU_MAX, strMenuItem);
                pSysMenu->SetMenuItemBitmaps(IDM_SYSMENU_MAX, MF_BYCOMMAND, &bmpMaxUp, &bmpMaxOver);
                if(CtrlSt_Max == CTRL_INACTIVE)
                    pSysMenu->ModifyMenu(IDM_SYSMENU_MAX, MF_BYCOMMAND | MF_GRAYED, IDM_SYSMENU_MAX, strMenuItem);
            } else {
                pSysMenu->AppendMenu(MF_STRING, IDM_SYSMENU_MAX, strMenuItemAlt);
                pSysMenu->SetMenuItemBitmaps(IDM_SYSMENU_MAX, MF_BYCOMMAND, &bmpMaxRestore, &bmpMaxRestore);
                if(CtrlSt_Max == CTRL_INACTIVE)
                    pSysMenu->ModifyMenu(IDM_SYSMENU_MAX, MF_BYCOMMAND | MF_GRAYED, IDM_SYSMENU_MAX, strMenuItemAlt);
            }
        }
    
        pSysMenu->AppendMenu(MF_SEPARATOR);	// Add Seperator
    
        strMenuItem = _T(" Close");
        if (CtrlSt_Close != CTRL_HIDE) {
            pSysMenu->AppendMenu(MF_STRING, IDM_SYSMENU_CLOSE, strMenuItem);
            pSysMenu->SetMenuItemBitmaps(IDM_SYSMENU_CLOSE, MF_BYCOMMAND, &bmpCloseUp, &bmpCloseOver);
            if(CtrlSt_Close == CTRL_INACTIVE) {
                pSysMenu->ModifyMenu(IDM_SYSMENU_CLOSE, MF_BYCOMMAND | MF_GRAYED, IDM_SYSMENU_CLOSE, strMenuItem);
            }
        }
    }

    • Calling this as an app from a command script

      Posted by ianj on 05/03/2007 02:40pm

      Would it be possible to do this in a mini exe so I could call this code from a command script e.g. a user's login script ? Any suggestions would be extremely helpful as I've searched loadsastuff and so far not really got anywhere.

      Reply
    Reply
  • Doing this in java ...

    Posted by Jinxeh on 04/17/2006 02:54pm

    used to be impossible. However, with SWT you have can use
    
    SWT.OS.RemoveMenu(OS.GetSystemMenu (shell.handle, false),OS.SC_CLOSE,OS.MF_BYCOMMAND);
    
    -Jinxeh

    Reply
  • Works great for property sheets!

    Posted by Legacy on 03/06/2003 12:00am

    Originally posted by: Joel

    People ask why not remove the button in the resource. Well for something like a property sheet, that doesn't work.

    The method the author has shown works great for a property sheet. Then I disabled the escape key as another person suggested, so now the user must hit the Ok or Cancel button to exit my property sheet.

    Reply
  • A way to ignore ESC and CTRL-Break in dialogs in pure Win32

    Posted by Legacy on 02/25/2003 12:00am

    Originally posted by: Ken

    By adding a WM_COMMAND message handler in the dialog box
    
    procedure, testing for only your response values to
    end the dialog (with EndDialog) and returning 0, windows
    no longer responds to ESC or CTRL-Break in a dialog box,
    the result I intended.

    /*--------------------------------------------*/
    /*DialogProc */
    /*--------------------------------------------*/
    BOOL CALLBACK DialogProc(HWND hdwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    int ReturnValue;

    switch (msg) {
    case WM_COMMAND:
    ReturnValue = (int) LOWORD(wParam);
    if((ReturnValue >= 1000) && (ReturnValue <=1032)) {
    EndDialog(hdwnd, ReturnValue);
    // ...clean up stuff here...
    }
    //return 1; // <-- don't return 1 here
    break; // simply break
    case WM_INITDIALOG:
    // ... do your initialization
    return 1;
    }
    return 0; // <-- returns 0 here and windows doesn't kill
    // dialog
    }

    This is a pure Win32 program using only API, no MFC so I
    don't have access to PreTranslateMessage, etc. IsDialogMessage gave me fits also.

    Hope this helps someone...

    ken

    Reply
  • How to disable ctrl-break in dialog-based programs?

    Posted by Legacy on 02/10/2003 12:00am

    Originally posted by: Truc

    How to prevent stopping dialog-based programs by pressing ctrl-break?

    Reply
  • ctrl-break still works!

    Posted by Legacy on 02/10/2003 12:00am

    Originally posted by: Truc

    ctrl-break still works!

    Reply
  • Disabling close button in console application, is it posible?

    Posted by Legacy on 09/16/2002 12:00am

    Originally posted by: Januar

    Can we do things like this to console application?

    thanks,
    Jan

    Reply
  • Excellent

    Posted by Legacy on 08/19/2002 12:00am

    Originally posted by: Ashkan

    Top job mate! Works really well.

    Reply
  • Thanks

    Posted by Legacy on 07/24/2002 12:00am

    Originally posted by: Zaki

    Thanks a lot for the great ideas!!
    I used the PreTranslateMessage and disabled button. It would have been nice to have removed the button completely.

    Reply
  • runtime on/off a button, or image on a button, in a dialog window, VC6

    Posted by Legacy on 03/27/2002 12:00am

    Originally posted by: xudong weng

    bodies:
    following are runtime, dialog window button, VC6 environment
    1.to put/change a image on a button, need toget button handle and call the command, very easy
    2.to enable/disable a button, or to transparent it, to gray it, you need to set the userown character and write your own code to handle the change, for the sake of convience, i put this as a simple function. see VChelp, it descripts clearly -- there are some easy ways, ie. get the button's handle,and employing the CWIN-> functions to do this. anyow, all ways go to roma

    3. jsut to say more, in VC, most of the user interface functions demand control item handles.

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

  • Today's agile organizations pose operations teams with a tremendous challenge: to deploy new releases to production immediately after development and testing is completed. To ensure that applications are deployed successfully, an automatic and transparent process is required. We refer to this process as Zero Touch Deployment™. This white paper reviews two approaches to Zero Touch Deployment--a script-based solution and a release automation platform. The article discusses how each can solve the key …

Most Popular Programming Stories

More for Developers

RSS Feeds