FAQ VC++ et MFCConsultez toutes les FAQ

Nombre d'auteurs : 20, nombre de questions : 546, 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


SommaireClasses Fenêtres et FrameWorkBarre de Dialogue (6)
précédent sommaire suivant
 

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
3.Initialiser la CDialogBar dans la classe CMDIChildWnd associée à la view dans le cas d'un projet MDI ou dans la CMainFrame dans le cas d'un projet SDI.

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; 
}
Voir dans la documentation MSDN les différentes options pour le placement de la fenêtre ici en haut (CBRS_TOP).
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);

Mis à jour le 5 avril 2013 farscape

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"); 
}
Note:La commande ON_COMMAND_UI est une ligne de code à rajouter manuellement dans le message map en dessous de la ligne //}}AFX_MSG_MAP ,sinon elle sera effacée par ClassWizard.

Mis à jour le 6 février 2005 farscape

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); 
}
Dans l'exemple ci-dessus la variable m_Button est une donnée membre de la classe CTestDlgBarView la fonction SubclassDlgItem permet d'initialiser le contrôle directement dans la view.

Mis à jour le 5 avril 2013 farscape

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
Ensuite :
l'affichage d'une barre de dialogue se gère avec la fonction :

Code c++ : Sélectionner tout
1
2
3
  
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
4
  
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
4
  
// 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
3
  
CControlBar::IsFloating 
BOOL IsFloating( ) const;
Code c++ : Sélectionner tout
1
2
  
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
8
  
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
30
  
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.

Mis à jour le 19 septembre 2005 farscape

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 ;  
}
Note : la même technique peut être appliquée dans un contexte MDI ,le traitement se faisant cette fois dans la classe MDIChild associée à la fenêtre.

Mis à jour le 19 septembre 2005 farscape

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 
}
puis dans le messageMap : mettre CDialogBar à la place de CDialog de même pour la fonction de doDataExchange

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 
}
-> ajouter dans le message_map (transformation de la fonction virtuelle en afx_msg):

Code c++ : Sélectionner tout
ON_MESSAGE(WM_INITDIALOG,OnIntDialog)
et dans le fichier .h de la classe :
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);
De cette manière vous obtiendrez une jolie boîte que vous pouvez déplacer et faire flotter.

Mis à jour le 19 septembre 2005 Alice9

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 ça


Réponse à la question

Liens sous la question
précédent sommaire suivant
 

Les 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 © 2017 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.

 
Contacter le responsable de la rubrique C++