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 :
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
3. Je construit un menu simple dans l'éditeur de ressource on avec par exemple pour identifiant IDR_MENU_BTN
Soient un menu de 4 commandes, des Item x avec leurs IDs des ID_ITEM_X :
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
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
 
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
5. Je définit le comportement du click sur le menu bouton.

5a. Soit que le click sur le bouton affiche directement le menu alors j'ai :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
m_btnMenu.m_bDefaultClick = FALSE;
m_btnMenu.RedrawWindow();
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 = TRUE;
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
 
        // si TRUE, le bouton reste enfoncé pendant que je sélectionne une commande de menu sinon FALSE
        m_btnMenu.m_bStayPressed = TRUE;
7. Je choist l'alignement du menu par rapport au 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.
8. Je définit la prise en charge du style du menu sur le 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:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
m_btnMenu.m_bOSMenu = TRUE;  // si non FALSE dans le cas contraire.
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
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);
}
Et Voilà