2010-04-08 53 views
5

在Microsoft Windows,这个工程:如何禁用移动系统菜单项?

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

但是,这并不工作:

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

因此我知道如何禁用窗口的“关闭”系统菜单项,而不是“移动“项目。我怎么做?

更新

当然一个替代使用非常漂亮的功能EnableMenuItem,是使用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); 

但是这又完全适用于SC_CLOSE,但不是在所有的SC_MOVE!

更新2

即使问题是在这个意义上解决了工作代码已被发现,“做工作”,可以这么说,这将是有趣的,听到了关于原因的假设问题:为什么SC_CLOSE工作,但不是SC_MOVE?

回答

3

这是一个有点神秘,但它的工作原理,如果你使用ModifyMenu或DeleteMenu:

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

或:

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

是的,两者都有效。但第一个会改变项目的标题,除了取消它,第二个将完全删除该项目...我只想禁用它...当然,我可以查找什么“移动”在本地被称为语言并使用第一种选择,但它肯定不像人们希望的那样直截了当。 [顺便说一下:在第二个选项中,你可能不是指“或MF_GRAYED”。] – 2010-04-08 19:30:25

+0

在修改菜单项之前,可以使用GetMenuInfo()读取字符串。如果你想“或”,不要忘记正确标记问题。 – 2010-04-08 19:42:31

+0

是的,这可能是以正确的语言获得“移动”的最佳方式。我不太清楚你的第二条评论的意思。我知道编程语言之间的区别。而且因为这个问题是关于Windows API的,所以如果你使用Delphi,C,VB或者其他语言,那就没有关系。但你可能的意思是 DeleteMenu(mnu,SC_MOVE,MF_BYCOMMAND); 而不是 DeleteMenu(mnu,SC_MOVE,MF_BYCOMMAND | MF_GRAYED); 我不明白什么“或MF_GRAYED”(或“| MF_GRAYED”)意味着在第二个选项。 – 2010-04-08 19:57:40

4

如果你破坏使用DeleteMenu()菜单项,你会做应用程序无法移动(即使使用游标)。

关键是要暂时删除的项目。

首先,使用下面的语句保存 “移动” 项的标题:

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

然后从菜单中删除项:

RemoveMenu(hMenu, SC_MOVE, MF_BYCOMMAND);

,当你需要在 “移动” 项背,只需使用InsertMenu()

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

PS。