Ítems por defecto

Para cada popup se puede marcar un ítem para que sea el ítem por defecto. Cuando hagamos doble clic sobre el popup, será como si hubiésemos seleccionado el ítem por defecto. Para indicar al usuario cual es ese ítem, aparecerá marcado en negrita.

Ítems por defecto
Ítems por defecto

El ítem por defecto hay que marcarlo durante la ejecución, ya hemos visto que no se puede hacer en el fichero de recursos. Para hacerlo disponemos de la función SetMenuDefaultItem.

Pero esta función hay que manejarla con cuidado, ya que en cada menú desplegable sólo puede haber un ítem por defecto, como primer parámetro deberemos pasar un manipulador del submenú donde se encuentre el ítem. Como además, no tiene mucho sentido marcar un ítem por defecto en una barra de menú (ya que siempre será accesible mediante un clic, y un doble clic sobre una barra de menú no hace nada), generalmente deberemos usar la función GetSubMenu para obtener un manipulador al submenú que contiene el ítem a marcar por defecto. Esto se debe hacer aunque el identificador del ítem a marcar sea único:

   SetMenuDefaultItem(GetSubMenu(GetMenu(hwnd),0), CM_OPCION, FALSE);

Este ejemplo marcará el ítem con el identificador CM_OPCION en el primer submenú del menú de la ventana hwnd.

Para obtener el ítem por defecto de un submenú podemos usar la función GetMenuDefaultItem, con las mismas precauciones:

   id = GetMenuDefaultItem(GetSubMenu(GetMenu(hwnd),0), FALSE, GMDI_GOINTOPOPUPS);

El primer parámetro es un manipulador de submenú, el segundo indica el tipo de valor devuelto: FALSE para que devuelva un identificador, y TRUE para que devuelva una posición. El tercero indica el modo de realizar la búsqueda, el valor usado en el ejemplo busca recursivamente.

También podemos usar las funciones SetMenuItemInfo y GetMenuItemInfo para hacer las mismas tareas.

En concreto, usar la función SetMenuItemInfo es más práctico, ya que no necesitamos obtener un manipulador de submenú, y marcará el ítem por defecto independientemente de cual sea el submenú donde esté:

   infoMenu.cbSize = sizeof(MENUITEMINFO);
   infoMenu.fMask = MIIM_STATE
   infoMenu.fState = MFS_DEFAULT;
   SetMenuItemInfo(GetMenu(hwnd), CM_OPCION, FALSE, &infoMenu);

Ejemplo 44


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 44 win044.zip 2004-07-22 3925 bytes 148

Menús flotantes o contextuales

Menús flotantes
Menús flotantes

Otra posibilidad de los menús es crear menús flotantes, también llamados menús de atajo o menús contextuales. Estos menús se suelen mostrar cuando el usuario hace clic con el ratón sobre distintas zonas de la ventana, y normalmente se muestran distintos menús dependiendo de la zona, o mejor dicho, del contexto.

Todo esto es responsabilidad del programador: procesar las pulsaciones de botones de ratón, decidir qué menú mostrar, y finalmente mostrarlo en pantalla.

La aplicación recibe el mensaje WM_CONTEXTMENU cuando el usuario hace clic sobre la ventana, aunque también podemos procesar los mensajes de ratón comunes.

Para mostrar el menú flotante en pantalla se usa la función TrackPopupMenuEx:

   HMENU hmenu;
...
   case WM_CREATE:
      hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
      hmenu = LoadMenu(hInstance, "menu2");
...
   case WM_CONTEXTMENU:
      TrackPopupMenuEx(GetSubMenu(hmenu, 0),
         TPM_CENTERALIGN | TPM_HORIZONTAL | TPM_RIGHTBUTTON,
         LOWORD(lParam), HIWORD(lParam),
         hwnd, NULL);
      break;
...
   case WM_DESTROY:
      DestroyMenu(hmenu);
...

El primer parámetro es un manipulador del menú popup que queremos visualizar, debe ser un manipulador de menú creado mediante la función CreatePopupMenu o, como en este ejemplo, extraído de un menú existente, que a su vez puede ser uno asignado a una ventana, o cargado de un recurso.

Hay que recordar que hay que destruir los menús que no estén asignados a una ventana mediante la función DestroyMenu.

En el ejemplo 45, que ilustra el uso de los menús flotantes, usamos un menú de recurso para crear todos los posibles menús flotantes, y elegimos el que nos interesa en cada caso mediante la función GetSubMenu.

El segundo parámetro son banderas que nos ayudan a situar el menú con relación a las coordenadas que indicamos en los parámetros tercero y cuarto.

El quinto parámetro identifica la ventana que recibirá los mensajes generados por el menú, y el sexto, nos permite definir un área de exclusión, donde no se mostrará el menú, si es posible.

Ejemplo 45


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 45 win045.zip 2004-07-23 4345 bytes 192