Déclarer et afficher un menu dans une fenêtre
Déclaration dans la classe
En général, il n'y a qu'un menu par application. Dans ce cas, le menu sera déclaré directement dans la classe de votre fenêtre.
Un nom de menu est créé dans le script
du menu:
monmenu MENU [...]
Vous pouvez donc l'utiliser de la manière suivante: wndclass.lpszMenuName = "monmenu";
Mais vous pouvez aussi utiliser un numéro. Dans ce cas, il faudra utiliser
la macro MAKEINTRESOURCE:
wndclass.lpszMenuName = MAKEINTRESSOURCE (numéro);
ou équivalent mais à éviter, c'est juste pour information:
wndclass.lpszMenuName = "#numéro";
où numéro est un nombre !
Je reprends l'exemple HelloEx du chapitre sur les bases et je lui ajoute simplement le menu créé dans le chapitre script de notre menu.
Ce qui donne :
Déclaration à la création d'une instance de fenêtre
Il est aussi possible de définir un menu sur l'instance
de fenêtre en phase de création:
Vous utiliserez la fonction LoadMenu():
hMenu = LoadMenu (hInstance, "monmenu");
où encore si numéro:
hMenu = LoadMenu (hInstance, MAKEINTRESSOURCE
(numéro));
Puis lors de la création de l'instance, n'oubliez pas de passer le handle du menu:
Ici avec la fonction CreateWindow, mais rien de bien difficile avec CreateWindowEx:
HWND hWnd;
hWnd=CreateWindow( "nom_de_notre_classe",
"Titre de notre fenêtre",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
hMenu,
hInstance, NULL );
Il est possible de mettre LoadMenu (hInstance, MAKEINTRESSOURCE (numéro))
directement dans CreateWindow à
la place de hMenu.
Le menu indiqué deviendra alors prioritaire sur tous les menus spécifiés dans la classe.
Voici un exemple:
RessourceInclude
(toujours
les mêmes)
et le code Fenêtre
Déclaration d'un menu après la création d'une fenêtre
Si dans la classe et l'instance de la fenêtre, les menus sont positionnés à NULL, il restera possible de définir un menu après création en utilisant SetMenu (hwnd, hMenu) (Evidemment, utilisez LoadMenu pour connaître le handle comme dans Déclaration à la création d'une instance de fenêtre ci-dessus !);
Ce qui permettra aussi de changer dynamiquement le menu ! Mais attention, dans
ce cas, il ne faut pas oublier de détruire le menu par l'instruction
DestroyMenu (hMenu);
avant la fin du programme.
Voici un exemple:
RessourceInclude
(toujours
les mêmes)
et le code Fenêtre
L'affichage
Concernant l'affichage ou non des menus, il sera géré automatiquement par Windows. Vous n'avez donc plus rien à faire...sauf si vous voulez faire évoluer votre menu:
- Griser ou non une option, marquer ou non une autre ...
Dans ce cas, il pourra être nécessaire de forcer le réaffichage du menu. En effet, si la fenêtre ne se redessine pas, le menu s'affichera toujours avec ses anciennes caractéristiques.
On peut comprendre que dans ce genre de manipulations, Windows ne gère pas automatiquement le réaffichage, car rien ne vous empêche d'effectuer plusieurs opérations sur la totalité du menu et il aurait été alors gourmand de le redessiner à chacunes des manipulations.
Vous utiliserez DrawMenuBar (hwnd); en précisant bien le handle de la Window et non celui du menu, car vous informez Windows qu'il doit redessiner une fenêtre avec son menu associé.