2010-04-08 30 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。