How to Disable the Move System Menu Item?

5.2k views Asked by At

In Microsoft Windows, this works:

 mnu := GetSystemMenu(h, false);
 EnableMenuItem(mnu, SC_CLOSE, MF_BYCOMMAND or MF_GRAYED);

But this does not work:

 mnu := GetSystemMenu(h, false);
 EnableMenuItem(mnu, SC_MOVE, MF_BYCOMMAND or MF_GRAYED);

Hence I know how to disable the "Close" system menu item of a window, but not the "Move" item. How do I do that?

Update

Of course one alternative to using the very nice function EnableMenuItem, is to use SetMenuItemInfo:

  FillChar(info, sizeOf(info), 0);
  with info do
  begin
    cbSize := sizeOf(info);
    fMask := MIIM_STATE;
    fState := MFS_GRAYED;
  end;
  SetMenuItemInfo(mnu, SC_MOVE, false, info);

But this again works perfectly for SC_CLOSE, but not at all for SC_MOVE!

Update 2

Even though the problem is resolved in the sense that a working code has been found that "does the job", so to speak, it would be interesting to hear hypotheses regarding the cause of the problem: Why does SC_CLOSE work but not SC_MOVE?

2

There are 2 answers

4
Hans Passant On BEST ANSWER

It's a bit of a mystery but it works if you use ModifyMenu or DeleteMenu:

   HMENU mnu = GetSystemMenu(hWnd, false);
   DeleteMenu(mnu, SC_MOVE, MF_BYCOMMAND);

or:

   HMENU mnu = GetSystemMenu(hWnd, false);
   MENUITEMINFO info = { sizeof(MENUITEMINFO) };
   TCHAR name[256] = _T("Cannot move");
   info.fMask = MIIM_TYPE;
   info.dwTypeData = name;
   info.cch = sizeof(name) / sizeof(TCHAR);
   GetMenuItemInfo(mnu, SC_MOVE, false, &info);
   ModifyMenu(mnu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED, 0, info.dwTypeData);
0
Punit Shah On

If you destroy the menu item using DeleteMenu(), you'll make the application unable to move (even using cursor).

The key is to remove the item temporarily.

First, save the caption of the "Move" item using the following statement:

GetMenuString(hMenu, SC_MOVE, szMoveCaption, MAX_PATH, MF_BYCOMMAND);

Then remove the item from the menu:

RemoveMenu(hMenu, SC_MOVE, MF_BYCOMMAND);

and when you need the "Move" item back, just use InsertMenu()

InsertMenu(hMenu, 0, MF_BYPOSITION, SC_MOVE, szMoveCaption);

PS.