Destrucción de menús

Los menús asociados a ventanas se destruyen automáticamente cuando se destruyen las ventanas, de modo que sólo es necesario destruir los menús que no estén asociados a ninguna ventana, en general, serán los que usemos como menús flotantes, o como menús alternativos, por ejemplo, si disponemos de diferentes versiones de menús para nuestras ventanas, y los usamos aternativamente, en función de las circunstancias.

Para destruir uno de esos menús se usa la función DestroyMenu.

Mensajes de menú

Ya hemos visto algunos de los mensajes que generan los menús, en concreto los que generan cuando se seleccionan ítems:

Función Descripción
WM_COMMAND Es enviado cuando el usuario selecciona un comando de un ítem de un menú.
WM_SYSCOMMAND Cuando el usuario elige un comando desde el menú de ventana.

Pero hay más, algunos de los más interesantes pueden ser:

Función Descripción
WM_INITMENU Se envía cuando un menú se va a activar. Eso ocurre cuando el usuario hace clic sobre un ítem de la barra de menú o cuando presiona la tecla de menú. Nos permite modificar el menú antes de que se muestre.
WM_INITMENUPOPUP Se envía cuando un menú emergente o un submenú va a ser activado. Esto permita a una aplicación modificar el menú antes de que sea mostrado, sin modificar el menú completo.
WM_MENUSELECT Se envía a la ventana cuando el usuario selecciona un ítem del menú.
WM_CONTEXTMENU Notifica a una ventana que el usuario ha hecho clic con el botón derecho del ratón en la ventana.

Mapas de bits en ítems de menú

hay varios modos de incluir mapas de bits en ítems de menú, en este capítulo veremos dos de ellos, dejaremos el métodp owner-draw para capítulos posteriores.

Modificar mapas de bits de check

Una de las formas de insertar mapas de bits, sin modificar el resto del ítem, es cambiar las marcas de chequeo por defecto por las diseñadas por nosotros. Esto se consigue con la función SetMenuItemBitmaps o con SetMenuItemInfo.

Mapas de bits
Mapas de bits
   static HBITMAP hSi;
   static HBITMAP hNo;
...
      hSi = LoadBitmap(hInstance, "si");
      hNo = LoadBitmap(hInstance, "no");

      infoMenu.cbSize = sizeof(MENUITEMINFO);
      infoMenu.fMask = MIIM_CHECKMARKS;
      infoMenu.hbmpChecked = hSi;
      infoMenu.hbmpUnchecked = hNo;
      for(i = 0; i < 3; i++)
         SetMenuItemInfo(GetSubMenu(GetMenu(hwnd),0), 
            i, TRUE, &infoMenu);
...
      DeleteObject(hNo);
      DeleteObject(hSi);

Lo mismo, usando la función SetMenuItemBitmaps:

...
      hSi = LoadBitmap(hInstance, "si");
      hNo = LoadBitmap(hInstance, "no");
      for(i = 0; i < 3; i++)
         SetMenuItemBitmaps(GetSubMenu(GetMenu(hwnd),0), 
            i, MF_BYPOSITION, hSi, hNo);
...

Primero deberemos diseñar los mapas de bits del tamaño adecuado para ambas marcas, o al menos para la marca de check, ya que la correspondiente al ítem no marcado puede dejarse en blanco. Para conseguir el tamaño de los mapas de bits se puede usar la función GetMenuCheckMarkDimensions.

      wsprintf(mensaje, "%d %d",
         HIWORD(GetMenuCheckMarkDimensions()),
         LOWORD(GetMenuCheckMarkDimensions()));
      MessageBox(hwnd, mensaje, "Medidas de mapas de bits", MB_OK);

Items de mapas de bits

También se pueden usar mapas de bits en lugar de texto en los ítems de menú. Para hacerlo hay que crear o modificar los ítems en la ejecución del programa, ya que no es posible hacerlo al crear el fichero de recursos.

Items de mapas de bits
Items de mapas de bits

Como siempre, disponemos de dos formas de hacerlo, mediante las funciones AppendMenu, InsertMenu y ModifyMenu, o mediante InsertMenuItem y SetMenuItemInfo, y la estructura MENUITEMINFO.

Recordemos el proceso para crear un mapa de bits durante la ejecución:

  1. Usar la función CreateCompatibleDC para crear un contexto de dispositivo compatible con el usado por la ventana principal de la aplicación.
  2. Usar la función CreateCompatibleBitmap para crear un mapa de bits compatible con la ventana principal de la aplicación o user la función CreateBitmap para crear un mapa de bits monocromo.
  3. Usar la función SelectObject para seleccionar el mapa de bits en el contexto de dispositivo compatible.
  4. Usar las funciones de trazado del GDI, como Ellipse, LineTo o BitBlt, para generar una imagen dentro del mapa de bits.

En el primer caso, insertaremos o modificaremos los ítems indicando que son de tipo MF_BITMAP, e indicando como nuevo ítem un manipulador de mapa de bits.

   InsertMenu(hmenu, 0, MF_BYPOSITION | MF_BITMAP, 
      CM_OPCION, (LPCTSTR)(hBitmap));

En el segundo caso, insertaremos o modificaremos los ítems de tipo MFT_BITMAP, e indicando un manipulador de mapa de bits.

   infoMenu.cbSize = sizeof(MENUITEMINFO);
   infoMenu.fMask = MIIM_TYPE | MIIM_ID;
   infoMenu.fType = MFT_BITMAP; 
   infoMenu.wID = CM_OPCION;
   infoMenu.dwTypeData = (LPSTR) (hBitmap); 
   InsertMenuItem(hmenu, 0, TRUE, &infoMenu);

Ejemplo 47


  Nombre Fichero Fecha Tamaño Contador Descarga
D Ejemplo 47 win047.zip 2004-07-23 28715 bytes 230