2010-04-08 10 views
5

En Microsoft Windows, esto funciona:Cómo deshabilitar el elemento de menú Mover sistema?

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

Pero esto no funciona:

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

De ahí que sé cómo deshabilitar la "Cerrar" del menú de sistema de una ventana, pero no el " Mover "elemento. ¿Cómo puedo hacer eso?

actualización

Por supuesto, una alternativa al uso de la muy agradable EnableMenuItem función, es utilizar 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); 

Pero esta vez funciona perfectamente para SC_CLOSE, pero no a todos por SC_MOVE!

Actualización 2

pesar de que el problema se resuelve en el sentido de que un código de trabajo ha encontrado que "hace el trabajo", por decirlo así, sería interesante escuchar hipótesis sobre la causa de el problema: ¿Por qué funciona SC_CLOSE pero no SC_MOVE?

Respuesta

3

Es un poco un misterio, pero funciona si se utiliza ModifyMenu o DeleteMenu:

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

o:

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

Sí, ambos funcionan. Pero el primero alterará el título del artículo además de desactivarlo, y el segundo eliminará completamente el elemento ... Solo quiero deshabilitarlo ... Por supuesto, podría buscar qué se llama "Mover" en el local idioma y use la primera opción, pero seguro que no es tan directo como uno desearía. [BTW: Probablemente no significa "o MF_GRAYED" en la segunda opción.] –

+0

Puede usar GetMenuInfo() para leer la cadena antes de modificar el elemento del menú. No te olvides de etiquetar la pregunta correctamente si quieres "o". –

+0

Sí, esa es probablemente la mejor manera de obtener "Mover" en el idioma correcto. No estoy seguro de qué quiere decir con su segunda observación. Sé la diferencia entre los lenguajes de programación. Y debido a que esta pregunta es sobre la API de Windows, no es relevante si usa Delphi, C, VB o cualquier otro idioma.Pero probablemente se refiera a DeleteMenu (mnu, SC_MOVE, MF_BYCOMMAND); en lugar de DeleteMenu (mnu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); No entiendo qué significa "o MF_GRAYED" (o "| MF_GRAYED") en la segunda opción. –

4

Si se destruye el elemento de menú con DeleteMenu(), que va a hacer el aplicación incapaz de moverse (incluso usando el cursor).

La clave es eliminar el elemento temporalmente.

En primer lugar, guardar el título del tema "Mover" mediante la siguiente instrucción:

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

continuación, retire el elemento del menú:

RemoveMenu(hMenu, SC_MOVE, MF_BYCOMMAND);

y cuando es necesario el ítem "Mover" hacia atrás, simplemente use InsertMenu()

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

PS.

Cuestiones relacionadas