2010-04-08 1 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); 

Поэтому я знаю, как отключить «Закрыть» пункт меню системы окна, но не " Переместить ". Как мне это сделать?

Update

Конечно одна альтернатива использованию очень хорошая функция 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!

Update 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

Да, оба работают. Но первый изменит заголовок элемента, кроме того, что он будет отключен, а второй полностью удалит элемент ... Я просто хочу его отключить ... Конечно, я мог бы посмотреть, что вызывает «Перемещение» в локальном язык и использовать первый вариант, но он уверен, что это не так прямолинейно, как хотелось бы. [BTW: Вероятно, вы не имеете в виду "или MF_GRAYED" во втором варианте.] –

+0

Вы можете использовать GetMenuInfo(), чтобы прочитать строку перед изменением элемента меню. Не забудьте пометить вопрос правильно, если хотите «или». –

+0

Да, это, вероятно, лучший способ получить «Переместить» на правильном языке. Я не совсем уверен, что вы подразумеваете под своим вторым замечанием. Я знаю разницу между языками программирования. И поскольку этот вопрос касается Windows API, это не имеет значения, если вы используете Delphi, C, VB или любой другой язык.Но вы, вероятно, имеете в виду DeleteMenu (mnu, SC_MOVE, MF_BYCOMMAND); , а не УдалитьMenu (mnu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); Я не понимаю, что означает «или MF_GRAYED» (или «| MF_GRAYED») во втором варианте. –

4

Если вы уничтожите пункт меню с помощью DeleteMenu(), вы будете делать приложение не может перемещаться (даже с помощью курсора).

Ключ для временного удаления предмета.

Во-первых, сохранить подпись в "Move" элемента с помощью следующего оператора:

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.