[FAQ][VC++]Comment travailler avec un menu associé à un bouton?
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:
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:
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:
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:
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:
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:
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:
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:
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:
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à :D