Pour combiner la fonctionnalité d'un menu et d'un bouton nous avons la classe CMFCMenuButton
Ici nous voudrions afficher un menu lorsque l'on clique sur un bouton et d'intercepter les clicks
sur les commandes de menu.
Soient une boite CMyDlg dérivant communément de CDialog
et d'un bouton sur cette boite.
1. On associe à l'aide du Wizard une variable de type CButton à notre bouton
ensuite on remplace CButton par CMFCMenuButton. Dans ce cas le bouton est muni d'une petite flêche.
2. On déclare une variable de type CMenu qui sera associé au bouton
Voici les déclarations :
3. Je construit un menu simple dans l'éditeur de ressource on avec par exemple pour identifiant IDR_MENU_BTN
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 class CMyDlg : public CDialog { // .. CMFCMenuButton m_btnMenu; // variable associé au bouton CMenu m_menu; // menu que l'on va associer au bouton
Soient un menu de 4 commandes, des Item x avec leurs IDs des ID_ITEM_X :
4. Dans notre OnInitDialog() de notre boite nous chargeons notre menu ainsi:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 IDR_MENU_BTN MENU BEGIN POPUP "Dummy" BEGIN MENUITEM "Item &1", ID_ITEM_1 MENUITEM "Item &2", ID_ITEM_2 MENUITEM "Item &3", ID_ITEM_3 MENUITEM "Item &4", ID_ITEM_4 END END
5. Je définit le comportement du click sur le menu bouton.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 m_menu.LoadMenu(IDR_MENU_BTN); // on charge le menu m_btnMenu.m_hMenu = m_menu.GetSubMenu(0)->GetSafeHmenu(); // on l'associe au bouton m_btnMenu.SizeToContent(); // on redimensionne le bouton à sa juste taille
5a. Soit que le click sur le bouton affiche directement le menu alors j'ai :
5b. Soit que le click sur le bouton execute la méthode associée au bouton ou bien affiche le menu lorsque l'on click sur la flêche du bouton.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 m_btnMenu.m_bDefaultClick = FALSE; m_btnMenu.RedrawWindow();
6. Je définit le comportement de l'état enfoncé du menu bouton.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 m_btnMenu.m_bDefaultClick = TRUE; m_btnMenu.RedrawWindow();
7. Je choist l'alignement du menu par rapport au bouton.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 // si TRUE, le bouton reste enfoncé pendant que je sélectionne une commande de menu sinon FALSE m_btnMenu.m_bStayPressed = TRUE;
8. Je définit la prise en charge du style du menu sur le bouton
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 // Si FALSE, le menu apparait en bas du bouton, sinon il apparait à droite m_btnMenu.m_bRightArrow = FALSE; m_btnMenu.Invalidate(); // invalide pour déclencher la peinture du bouton.
Si le menu n'a besoin d'aucun style particulier et ne comporte pas d'images associé aux commandes de menus comme ceux d'Office 2003, 2007 ou VS 2005 alors j'ai:
9. Je définit la façon dont les clicks sur les commandes de menu sont interceptés
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 m_btnMenu.m_bOSMenu = TRUE; // si non FALSE dans le cas contraire.
Et Voilà
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 void CMyDlg::OnBnClickedMenuButton() // Gestionnaire de message associé au click sur notre bouton. { CString strItem; switch (m_btnMenu.m_nMenuResult) // m_nMenuResult renvoie l'id de la commande de menu { case ID_ITEM_1: strItem = _T("Item 1"); break; case ID_ITEM_2: strItem = _T("Item 2"); break; case ID_ITEM_3: strItem = _T("Item 3"); break; case ID_ITEM_4: strItem = _T("Item 4"); break; default: // cas où m_btnMenu.m_bDefaultClick = TRUE; if( !m_btnMenu.m_bDefaultClick) return; strItem = _T("Default Menu Button Action"); break; } MessageBox(strItem); }
Partager