Création de menu via les fonctions C

 

 

Les deux fonctions de bases:

CreateMenu() permet de créer un menu vide et d'obtenir un handle sur ce menu.

AppendMenu (handle de menu, MF_STRING, n°ID, le texte à afficher) pour créer un menu item
MF_STRING que l'on pourra combiner (tout comme dans un script ) en utilisant le | avec:

Nom Désignation
MF_CHECKED Marquer l'élément du petite coche
MF_UNCHECKED Supprimer le marqueur
MF_DISABLED Désactive sans griser un élément
MF_ENABLED Active un élément et supprime éventuellement le grisé
MF_GRAYED Désactive et grise un élément
MF_MENUBREAK Cet élément et les suivants apparaîtrons sur une nouvelle ligne du menu général (pour un menuitem) ou sur une nouvelle colonne pour un popup
MF_MENUBARBREAK identique que ci-dessus pour le menus popup, mais dessine une ligne verticale pour séparer la colonne rajoutée
MF_OWNERDRAW Windows envoye d'abord le message WM_MEASUREITEM pour connaître le taille en hauteur et largeur de l'élément. Le message WM_DRAWITEM sera envoyé ensuite à la procédure de notre fenêtre pour permettre à notre programme de modifier l'apparence de nos menus avant affichage.
MF_POPUP Permet d'associer un menu popup à un menu principal, popup, ou système. Dans ce cas; n°Id sera en fait le handle du menu popup. Handle de menu sera le handle de l'autre menu. Nom correspondant au nom de l'élément dans le menu.

Comme pour les scripts, certaines combinaisons ne seront évidemment pas possible (MF_CHECKED | MF_UNCHECKED par exemple !)

Il y a aussi MF_BITMAP, mais se sera vu dans le chapitre Bitmap dans les menus...

Pour créer un séparateur : AppendMenu (handle de menu, MF_SEPARATOR, 0, NULL)

Pour associer un menu popup (hMenupopup) sur un autre menu qui pourra être principal, popup, ou système (hMenu): AppendMenu (hMenu, MF_POPUP, hMenuPopup, nom);

 

Principe de création d'un menu:

Nous avons déjà indiqué que chaque menu (prinipal, popup ou systeme) avait leur propre handle de menu. (Voir principe)

Partons sur un exemple simple: Un menu général propose un option Fichier qui est en fait un menu popup dans lequel nous avons les options suivantes:Ouvrir, sauver, séparateur et quitter

hMenu = CreateMenu (); On obtient ainsi un handle sur un menu que nous qualifierons de menu principal. Les autres menus devrons donc venir se rattacher à lui. Pour le moment, il est vide.

hMenuPopup = CreateMenu(); On obtient à nouveau un handle sur un menu. Mais cette fois-ci, nous voulons faire un menu popup correspondant à Fichier.

Nous allons donc commencer par définir les éléments de ce menu popup:
AppendMenu (hMenuPopup, MF_STRING, IDM_OUVRIR, "&Ouvrir");

AppendMenu (hMenuPopup, MF_STRING, IDM_SAUVER, "&Sauver");

AppendMenu (hMenuPopup, MF_SEPARATOR, 0, NULL);

AppendMenu (hMenuPopup, MF_STRING, IDM_QUITTER, "&Quitter");

Maintenant, il va falloir associer ce menu à celui de notre menu principal:
AppendMenu (hMenu, MF_POPUP, int (hMenuPopup), "&Fichier");

 

Bon, ici nous nous avançons un peu sur le prochain chapitre, mais après avoir créer ce menu, il faudra bien l'associer à une fenêtre. Pour celà, nous utiliserons la fonction SetMenu...avant le ShowWindow:
SetMenu (hwnd, hMenu);

 

Ce qui me permet de donner un exemple maintenant et de ne pas être obligé de revenir dessus ensuite:

Image non trouvée !

 

Remarque:

Voilà, dans l'idée générale, c'est aussi simple que cela. Par contre, pour les manipulations, c'est sûrement moins évident.

En général, nous n'utiliserons pas cette méthode pour ce définir un menu, mais on passera plutôt par un script.

Mais, ces fonctions associées à des fonctions complémentaires peuvent nous permettre de modifier dynamiquement un menu. Là cela devient plus intéressant...

Les fonctions complémentaires:

DeleteMenu supprime et détruit un élément
InsertMenu insère un nouvel élément
ModifyMenu pour modifier un élément existant
RemoveMenu Supprime un élément

Image non trouvée !Pour les fonctions DeleteMenu et RemoveMenu: Si l'élément est un menu popup, DeleteMenu va le détruire, pas RemoveMenu.

BOOL DeleteMenu(

HMENU hMenu,
UINT uPosition,
UINT uFlags
);

En entrée:

hMenu handle du menu à changer

uPosition Option du menu à effacer. Position dépendant de la valeur de uFlags.
uFlags indique comment interpréter la position de l'option de menu à supprimer.

Valeur Désignation
MF_BYCOMMAND uPosition est l'identifiant de menu (Valeur par défaut)
MF_BYPOSITION Index dans le menu en commençant à 0.

 

La fonction retourne zéro si erreur.

 

BOOL InsertMenu(

HMENU hMenu,
UINT uPosition,
UINT uFlags,
PTR uIDNewItem,
LPCTSTR lpNewItem
);

En entrée:

hMenu handle du menu à changer

uPosition Option du menu à effacer. Position dépendant de la valeur de uFlags.
uFlags indique comment interpréter la position de l'option de menu à supprimer et d'autres options MF_POPUP, MF_BITMAP, MF_OWNERDRAW, ou MF_STRING.

Valeur Désignation
MF_BYCOMMAND uPosition est l'identifiant de menu (Valeur par défaut)
MF_BYPOSITION Index dans le menu en commençant à 0.

uIDNewItem Indique le nouveau identificateur du menu, ou si uFlags est à MF_POPUP, le handle du drop-down menu ou sous menu
lpNewItem Indique le contenu du menu (image, texte) par rapport à uFlags.

Si uFlag est à

MF_BITMAP alors doit contenir le handle d'une image


MF_OWNERDRAW doit contenir une valeur qui sera utilisée par le programme lors de la création ou de la màj du menu. Cette valeur sera passée dans une structure itemData dont lParam sera le pointeur. L'application recevra le message WM_MEASUREITEM ou WM_DRAWITEM

MF_STRING (Par défaut) alors doit contenir un pointeur sur une chaîne de caractère terminée par la caractère NULL.

BOOL ModifyMenu(

HMENU hMnu,
UINT uPosition,
UINT uFlags,
PTR uIDNewItem,
LPCTSTR lpNewItem
);

En entrée, même chose que la fonction précédente.

 

BOOL RemoveMenu(

HMENU hMenu,
UINT uPosition,
UINT uFlags
);

En entrée:

hMenu handle du menu à changer

uPosition Option du menu à effacer. Position dépendant de la valeur de uFlags.
uFlags indique comment interpréter la position de l'option de menu à supprimer.

Valeur Désignation
MF_BYCOMMAND uPosition est l'identifiant de menu (Valeur par défaut)
MF_BYPOSITION Index dans le menu en commençant à 0.

 

La fonction retourne zéro si erreur.

 

Image non trouvée !Si le menu est déjà dessiné à l'écran: les modifications d'une barre de menu ne seront pas visible tant que la fenêtre ne sera pas redessinée. On peut forcer le raffraichissement: DrawMenuBar (hwnd);