locked
How to remove short cut keys in GetSystemMenu? RRS feed

  • Question

  • How to get system menu without any shortcut keys?

    When I call GetSystemMenu win 32 API it retrieves list of items with short-cut/Accelarator keys. How to get rid of this keys?

    Thanks

    PRE

    Monday, July 16, 2012 11:28 AM

Answers

  • Finally I was able to resolve the problem. Please find the updated code below which worked for me..

    1. With old code, bitmaps did not display properly and separator were missing. So, used menuInfo.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_BITMAP to rectify it

    2. Also default enable/disable state issue was solved. This happened because in legacy code someone has set GetSystemMenu(TRUE) before calling GetSystemMenu(FALSE) and so last state was destroyed. So, removing GetSystemMenu(TRUE) resolved it.

    3. I've to define my own version of MENUITEMINFO98 because original windows MENUITEMINFO was not having hbmpItem item. It is there but winuser.h has enabled this version only if WINVER >= 0x0500. So, i;ve to define my custom version for this.

    And final running code is below. I just modified **existing** menu items. And everything looks fine now. Please review and let me know if it is fine.

    struct MENUITEMINFO98
    {
        UINT    cbSize;
        UINT    fMask;
        UINT    fType;          // used if MIIM_TYPE (4.0) or MIIM_FTYPE (>4.0)
        UINT    fState;         // used if MIIM_STATE
        UINT    wID;            // used if MIIM_ID
        HMENU   hSubMenu;       // used if MIIM_SUBMENU
        HBITMAP hbmpChecked;    // used if MIIM_CHECKMARKS
        HBITMAP hbmpUnchecked;  // used if MIIM_CHECKMARKS
        DWORD   dwItemData;     // used if MIIM_DATA
        LPWSTR  dwTypeData;     // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
        UINT    cch;            // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
        HBITMAP hbmpItem;       // used if MIIM_BITMAP
    };

    HMENU hMenu = ::GetSystemMenu( m_hWnd, FALSE);

            int itemCount = ::GetMenuItemCount(hMenu);
            TCHAR menuItemText[_MAX_PATH];

            for (int item = 0 ; item < itemCount ; item++)
            {
                ::GetMenuString(hMenu, item, menuItemText, _MAX_PATH, MF_BYPOSITION);

                unsigned int itemID = ::GetMenuItemID(hMenu, item);

                CString itemText = menuItemText;

                // remove any accelerator key mnemonics
                itemText.Replace(_T("&"), _T(""));

                MENUITEMINFO98 menuInfo;
                ZeroMemory(&menuInfo, sizeof(MENUITEMINFO98));
                menuInfo.cbSize = sizeof(MENUITEMINFO98);
                menuInfo.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_BITMAP;
                if (::GetMenuItemInfo(hMenu, itemID, FALSE, (MENUITEMINFO*)&menuInfo))
                {
                    // replace the system menu text without shortcut keys
                    ::ModifyMenu(hMenu, itemID, MF_BYCOMMAND | MF_STRING , itemID, itemText);

                    // set the original state of the menu item including the bitmap
                    ::SetMenuItemInfo(hMenu, itemID, FALSE, (MENUITEMINFO*)&menuInfo);
                 }
            } //for



    • Marked as answer by Pervez Rehman Tuesday, July 17, 2012 7:54 PM
    Tuesday, July 17, 2012 6:56 PM

All replies

  • Monday, July 16, 2012 12:42 PM
  • Thanks Ranjith. Why can't we useModifyMenu? I tried to modify the close menu item as below. Text changed with below changes, but close/exit functionality was broken. Is it possible to pass the orginal Id of close in below function (4th parameter to make below functionality to work)

    ::ModifyMenu(hMenu, SC_CLOSE, MF_BYPOSITION | MF_STRING , 0, "Close");  // Text changed so that it does not have shortcut key, but close event is broken

    Monday, July 16, 2012 4:31 PM
  • Try the following sample

    http://msdn.microsoft.com/en-us/library/89c2aa4b%28v=vs.80%29.aspx

    I think you need to remove the current menu and add your own menu. Then you need to implement each command.


    Thanks, Renjith V R

    Monday, July 16, 2012 4:57 PM
  • I'm able to resolve above issue with below code. I was able to modify the text of ***existing**** menu item with below code.

    Now new issue. The default enable/disable of each sub menu item is broken after this change. Any clue?

           int itemCount = ::GetMenuItemCount(hMenu);
            TCHAR menuItemText[_MAX_PATH];

            for (int item = 0 ; item < itemCount ; item++)
            {
                ::GetMenuString(hMenu, item, menuItemText, _MAX_PATH, MF_BYPOSITION);

                unsigned int itemID = ::GetMenuItemID(hMenu, item);

                // process any item other than separator in system menu
                if (SC_SEPARATOR != itemID) {

                    CString itemText = menuItemText;

                    // remove any accelerator key mnemonics
                    itemText.Replace(_T("&"), _T(""));

                    // replace the system menu text without shortcut keys
                    ::ModifyMenu(hMenu, itemID, MF_BYCOMMAND, itemID, itemText);
                }
            }

    Monday, July 16, 2012 4:58 PM
  • Which one is not working. For me all enable/disable is working. I am using VC6 and i have done in it Dialog::OnInitDialog(). Could you please explain the issue more?


    Thanks, Renjith V R

    Monday, July 16, 2012 5:26 PM

  • When i do Modifymenu the default icons associated with the system menu are gone and the default enable/disable feature (depending on the state of child window like minmize/maximize/restore) are also broken
    Tuesday, July 17, 2012 10:27 AM
  • I have used same code you provided. But it is working.When i maximize, maximize option is automatically disabled.
    	HMENU hMenu = ::GetSystemMenu( m_hWnd, FALSE);
    	
    	
    	int itemCount = ::GetMenuItemCount(hMenu);
    	TCHAR menuItemText[_MAX_PATH];
    	
    	for (int item = 0 ; item < itemCount ; item++)
    	{
    		::GetMenuString(hMenu, item, menuItemText, _MAX_PATH, MF_BYPOSITION);
    		
    		unsigned int itemID = ::GetMenuItemID(hMenu, item);
    		
    		// process any item other than separator in system menu
    		if (SC_SEPARATOR != itemID) {
    			
    			CString itemText = menuItemText;
    			
    			// remove any accelerator key mnemonics
    			itemText.Replace(_T("&"), _T(""));
    			
    			
    			// replace the system menu text without shortcut keys
    			::ModifyMenu(hMenu, itemID, MF_BYCOMMAND, itemID, itemText);
    		}
    	}


    Thanks, Renjith V R

    Tuesday, July 17, 2012 5:13 PM
  • Finally I was able to resolve the problem. Please find the updated code below which worked for me..

    1. With old code, bitmaps did not display properly and separator were missing. So, used menuInfo.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_BITMAP to rectify it

    2. Also default enable/disable state issue was solved. This happened because in legacy code someone has set GetSystemMenu(TRUE) before calling GetSystemMenu(FALSE) and so last state was destroyed. So, removing GetSystemMenu(TRUE) resolved it.

    3. I've to define my own version of MENUITEMINFO98 because original windows MENUITEMINFO was not having hbmpItem item. It is there but winuser.h has enabled this version only if WINVER >= 0x0500. So, i;ve to define my custom version for this.

    And final running code is below. I just modified **existing** menu items. And everything looks fine now. Please review and let me know if it is fine.

    struct MENUITEMINFO98
    {
        UINT    cbSize;
        UINT    fMask;
        UINT    fType;          // used if MIIM_TYPE (4.0) or MIIM_FTYPE (>4.0)
        UINT    fState;         // used if MIIM_STATE
        UINT    wID;            // used if MIIM_ID
        HMENU   hSubMenu;       // used if MIIM_SUBMENU
        HBITMAP hbmpChecked;    // used if MIIM_CHECKMARKS
        HBITMAP hbmpUnchecked;  // used if MIIM_CHECKMARKS
        DWORD   dwItemData;     // used if MIIM_DATA
        LPWSTR  dwTypeData;     // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
        UINT    cch;            // used if MIIM_TYPE (4.0) or MIIM_STRING (>4.0)
        HBITMAP hbmpItem;       // used if MIIM_BITMAP
    };

    HMENU hMenu = ::GetSystemMenu( m_hWnd, FALSE);

            int itemCount = ::GetMenuItemCount(hMenu);
            TCHAR menuItemText[_MAX_PATH];

            for (int item = 0 ; item < itemCount ; item++)
            {
                ::GetMenuString(hMenu, item, menuItemText, _MAX_PATH, MF_BYPOSITION);

                unsigned int itemID = ::GetMenuItemID(hMenu, item);

                CString itemText = menuItemText;

                // remove any accelerator key mnemonics
                itemText.Replace(_T("&"), _T(""));

                MENUITEMINFO98 menuInfo;
                ZeroMemory(&menuInfo, sizeof(MENUITEMINFO98));
                menuInfo.cbSize = sizeof(MENUITEMINFO98);
                menuInfo.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_BITMAP;
                if (::GetMenuItemInfo(hMenu, itemID, FALSE, (MENUITEMINFO*)&menuInfo))
                {
                    // replace the system menu text without shortcut keys
                    ::ModifyMenu(hMenu, itemID, MF_BYCOMMAND | MF_STRING , itemID, itemText);

                    // set the original state of the menu item including the bitmap
                    ::SetMenuItemInfo(hMenu, itemID, FALSE, (MENUITEMINFO*)&menuInfo);
                 }
            } //for



    • Marked as answer by Pervez Rehman Tuesday, July 17, 2012 7:54 PM
    Tuesday, July 17, 2012 6:56 PM