views:

39

answers:

1

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?

A: 

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);
Hans Passant
Yes, both work. But the first will alter the caption of the item besides disabeling it, and the second will completely remove the item... I just want to disable it... Of course I could look-up what "Move" is called in the local language and use the first option, but it sure is not as straight-forward as one would wish. [BTW: You probably do not mean "or MF_GRAYED" in the second option.]
Andreas Rejbrand
You could use GetMenuInfo() to read the string before modifying the menu item. Don't forget to tag the question properly if you want "or".
Hans Passant
@nobugz: Yes, that is probably the best way to get "Move" in the right language. I am not quite sure about what you mean by your second remark. I know the difference between the programming languages. And because this question is about the Windows API, it is not relevant if you use Delphi, C, VB, or any other language. But you probably meanDeleteMenu(mnu, SC_MOVE, MF_BYCOMMAND);rather thanDeleteMenu(mnu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED);I do not understand what "or MF_GRAYED" (or "| MF_GRAYED") means in the second option.
Andreas Rejbrand
Awesome, another not-helpful post marked as the answer.
Hans Passant
@nobugz: Well, GetMenuItemInfo + ModifyMenu works (I eventually settled for a slightly different code than the one above, but the idea is exactly the same) and does solve the problem. But trust me, if anyone would figure out a simple way of making EnableMenuItem work, I would prefer that solution...
Andreas Rejbrand