FAQ VC++ et MFCConsultez toutes les FAQ
Nombre d'auteurs : 20, nombre de questions : 545, dernière mise à jour : 5 avril 2013 Ajouter une question
Cette faq a été réalisée pour répondre aux questions les plus fréquement posées sur le forum Développement Visual C++
Je tiens à souligner que cette faq ne garantit en aucun cas que les informations qu'elle contient sont correctes ; Les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou si vous souhaitez devenir redacteur, lisez ceci.
Sur ce, je vous souhaite une bonne lecture. Farscape
- Comment ajouter une CDialogBar sur une fenêtre ?
- Comment rendre actif un bouton dans CDialogbar ?
- Comment déclarer les contrôles d'une CDialogBar dans la fenêtre View ?
- Comment cacher et faire apparaître une barre de dialogue ?
- Comment rendre flottante une barre de dialogue ?
- Comment créer une barre de dialogue personnalisée ?
Il faut :
1. Créer une nouvelle boite de dialogue dans l'éditeur de ressources.
Changer son nom en IDD_DLGBAR_xxxx pour bien les distinguer des boîtes de dialogues classiques.
Mettre le style : « Child » à la place de « popup » et enlever l'option « title bar » (barre de titre)
2.Générer par « ClassWizard » une nouvelle classe dérivée de CDialog (on n'a pas le choix ,il n'y a pas de CDialogBar dans le sélecteur de classes !).
Modifier le constructeur comme suit :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | class CMyDlgbar : public CDialogBar { // Construction public: CMyDlgbar(); // standard constructor on enlève la référence à l'id et la classe parent |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // MDI int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1) return -1; // TODO: Add your specialized creation code here // dans le header de la classe child : CMyDlgbar m_wndDlgBar; if (!m_wndDlgBar.Create(this, IDD_DLGBAR_1, CBRS_TOP|CBRS_TOOLTIPS|CBRS_FLYBY, IDD_DLGBAR_1)) { TRACE0("Failed to create DlgBar\n"); return -1; // Fail to create. } return 0; } |
Note : La classe CChildFrame correspond à la classe indiquée dans la définition du document template :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | // Extrait de InitInstance() CMultiDocTemplate *pTemplate; pTemplate = new CMultiDocTemplate( IDR_TESTMDTYPE, RUNTIME_CLASS(CTestMdiDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CTestMdiView)); AddDocTemplate(pTemplate); |
Effectivement par défaut un bouton dans une CDialogBar n'est pas actif.
Voir la note d'info MSDN : INFO: CDialogBar Button Enabled When Command Handler Present
pour résoudre le problème deux solutions:
1.Traitement du message dans la View :
Il faut déplacer (couper) à la main le message ON_BN_CLICKED et sa fonction de la CDialogbar pour les placer dans la gestion des messages de la View.
(on ne peut pas le faire directement par classwizard l'id du bouton n'apparaissant pas dans la liste).
2.Traitement du message dans la CDialogBar :
On rajoutera un message de type
ON_UPDATE_COMMAND_UI dans la CDialogBar pour activer le bouton (voir note)
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | BEGIN_MESSAGE_MAP(CMyDlgbar, CDialogBar) //{{AFX_MSG_MAP(CMyDlgbar) ON_BN_CLICKED(IDC_BUTTON2, OnButton2) //}}AFX_MSG_MAP ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButton2) END_MESSAGE_MAP() // CMyDlgbar message handlers void CMyDlgbar::OnUpdateButton2(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here } void CMyDlgbar::OnButton2() { // TODO: Add your control notification handler code here AfxMessageBox("click bouton"); } |
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | void CTestDlgBarView::OnInitialUpdate() { CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); CMainFrame *pFrame=(CMainFrame *)GetParentFrame(); pFrame->m_DlgBar.OnInitDialog(); m_Button.SubclassDlgItem(IDC_BUTTON,this); } |
La classe CDialogBar est dérivée de la class CControlBar de même que la classe CToolBar Ce qui va suive s'appliquera donc à ces deux classes.
Pour commencer il faut déclarer la barre de dialogue ancrable (docking ) Voir Comment rendre flottante une barre de dialogue ?
Ensuite, l'affichage d'une barre de dialogue se gère avec la fonction :
Code C++ : | Sélectionner tout |
1 2 | CFrameWnd::ShowControlBar void ShowControlBar( CControlBar* pBar, BOOL bShow, BOOL bDelay ); |
Il suffit de disposer du pointeur sur la Mainframe ou MDIChild en MDI :
Code C++ : | Sélectionner tout |
1 2 3 | CMainFrame *pFrame=static_cast<CMainFrame *>(AfxGetMainWnd()); // cacher la toolbar. pFrame->ShowControlBar(&pFrame->m_wndToolBar,FALSE,FALSE); |
Une autre fonction intéressante pour gérer à travers un menu disposant d'une coche la fonctionnalité de cacher / faire apparaître la barre de dialogue .
Code C++ : | Sélectionner tout |
1 2 3 | // gérer le mode SHOW/Hide sur la commande d'un menu . pFrame->ShowControlBar(&pFrame->m_wndToolBar, !pFrame->m_wndToolBar->IsWindowVisible() ,FALSE); |
Dernière fonction pour savoir si la barre est flottante :
Code C++ : | Sélectionner tout |
1 2 | CControlBar::IsFloating BOOL IsFloating( ) const; |
Code C++ : | Sélectionner tout |
pFrame->m_wndToolBar->IsFloating();
Pour finir voici l'explication du mécanisme qui gère l'affichage ou le masquage de la barre d'outils générée par le wizard d'application : La barre d'outils ou la barre de statut générée par classwizard possède un identifiant prédéterminé et connu par le framework.
Regardons par exemple le prototype de la fonction de création de la barre d'outils:
Code C++ : | Sélectionner tout |
1 2 3 4 5 6 7 | CToolBar::CreateEx virtual BOOL CreateEx( CWnd* pParentWnd, DWORD dwCtrlStyle = TBSTYLE_FLAT, DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_ALIGN_BOTTOM, CRect rcBorders = CRect( 0, 0, 0, 0 ), UINT nID = AFX_IDW_TOOLBAR ); |
L'identifiant nID est fournit par défaut avec la valeur AFX_IDW_TOOLBAR que l'on retrouve dans cet extrait de code MFC lié à la CFrameWnd:
Code C++ : | Sélectionner tout |
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 | void CFrameWnd::OnUpdateControlBarMenu(CCmdUI* pCmdUI) { ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR); ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR); ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR); CControlBar* pBar = GetControlBar(pCmdUI->m_nID); if (pBar != NULL) { pCmdUI->SetCheck((pBar->GetStyle() & WS_VISIBLE) != 0); return; } pCmdUI->ContinueRouting(); } BOOL CFrameWnd::OnBarCheck(UINT nID) { ASSERT(ID_VIEW_STATUS_BAR == AFX_IDW_STATUS_BAR); ASSERT(ID_VIEW_TOOLBAR == AFX_IDW_TOOLBAR); ASSERT(ID_VIEW_REBAR == AFX_IDW_REBAR); CControlBar* pBar = GetControlBar(nID); if (pBar != NULL) { ShowControlBar(pBar, (pBar->GetStyle() & WS_VISIBLE) == 0, FALSE); return TRUE; } return FALSE; } |
Voilà ce n'est pas compliqué,
Il est recommandé de s'inspirer de ce code pour cacher/faire apparaitre ses propres barres d'outils ou barre de dialogue par exemple dans un projet MDI.
Une barre de dialogue CDialogBarpeut aussi être ancrable au même titre qu'une CToolBar qui partage d'ailleurs la même classe de base la classe CControlBar .
Exemple d'une CDialogBar rendue flottante dans un projet SDI :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; if (!m_wndDlgBar.Create(this, IDD_DLGBAR, CBRS_RIGHT | CBRS_GRIPPER |CBRS_TOOLTIPS | CBRS_FLYBY, IDD_DLGBAR)) { TRACE0("Failed to create dialog bar m_wndDlgBar\n"); return -1; // fail to create } // permet de s'ancrer sur tous les bords de la fenêtre m_wndDlgBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndDlgBar); // met la dialogue barre flottant au demarrage. FloatControlBar(&m_wndDlgBar,CPoint(100,100)); return 0 ; } |
créer une nouvelle boîte de type CDialogBar dans VC++ 6.0 : préciser quelle sorte de boîte de dialogue l'on souhaite. Pour cela aller dans le menu et choisir Insert\ressources \
Puis choisir Cdialog:: CDialogBar
Via le plus beau des Wizard, ajouter une nouvelle classe liée à cette boîte (ctr+w sur la boîte : create a new class) qui héritera de CDialog (car pas possible de choisir CDialogBar directement)
A cette étape il faut aller dans le .cpp de la classe.
Transformer le constructeur de la classe comme suit:
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 | CTestMDI_DlgBar::CTestMDI_DlgBar() { //{{AFX_DATA_INIT(CTestMDI_DlgBar) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } |
Aller dans le fichier .h
idem que pour le .cpp, transformer les CDialog en CDialogBar et mettez à jour la déclaration du constructeur
pour pouvoir initialiser la boîte flottante :
il faut via appWizard lui mettre les fonctions liés aux évènements Create et WM_INITDIALOG
-> après il faut adapter les fonctions pour les CDialogBar
Code c++ : | Sélectionner tout |
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 34 35 36 37 38 39 40 41 42 43 44 | LONG/*BOOL*/ CTestMDI_DlgBar::OnInitDialog ( UINT wParam, LONG lParam) // ajout des paramètres // initialisation de la boîte de dialogue flottante { //CDialogBar/*CDialog*/::OnInitDialog(); // suppression de la commande par : BOOL bRet = HandleInitDialog(wParam, lParam); if (!UpdateData(FALSE)) { TRACE0("Warning: UpdateData failed during dialog init.\n"); } // TODO: Add extra initialization here /*return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE*/ // retourne le retour du création de handle sur la boîte de dialogue flottante return bRet; } // modification du OnCreate pour utilisation du CDialogBar // int MyDlgTestBar::OnCreate(LPCREATESTRUCT lpCreateStruct) -> standard BOOL CTestMDI_DlgBar::Create(CWnd* pParent, UINT nIDTemplate, UINT nStyle, UINT nID) { /*if (CDialogBar::OnCreate(lpCreateStruct) == -1) return -1;*/ // remplacement de la création de la boîte de dialogue flottante par : // TODO: Add your specialized code here and/or call the base class // création de la boîte CDialogBar BOOL bReturn = CDialogBar::Create(pParent, nIDTemplate, nStyle, nID); if(bReturn) { // initialisation des composants } // retourne si la boîte à bien été créée ou non return bReturn; // return 0 } |
Code c++ : | Sélectionner tout |
ON_MESSAGE(WM_INITDIALOG,OnIntDialog)
bien entendu modifier la déclaration des fonctions OnCreate et OnInitDialog pour être en adéquation.
transformer la fonction virtuelle OnInitDialog en afx_msg
il ne reste plus qu'à créer une instance de cette boîte dans la mainFrame (vu que ce sera sa mère) :
Dans les attributs de la classe Mainframe : déclarer un pointeur sur cette classe.
Dans la création de la fenêtre mère (OnCreate): ajout de la création de l'objet graphique :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | m_pdlgBarTest = new CTestMDI_DlgBar ; if (!m_pdlgBarTest->Create(this, IDD_DLGBAR, // collée à droite CBRS_RIGHT | CBRS_GRIPPER |CBRS_TOOLTIPS | CBRS_FLYBY,//CBRS_HIDE_INPLACE, IDD_DLGBAR)) { TRACE0("Failed to create dialog bar m_wndDlgBar\n"); return -1;// fail to create } // caractéristiques : se colle sur tous les bords de la fenêtre m_pdlgBarTest->EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(m_pdlgBarTest); |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.