| auteur : Farscape | 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 :
class CMyDlgbar : public CDialogBar
{
public :
CMyDlgbar ();
|
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.
int CChildFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct)
{
if (CMDIChildWnd:: OnCreate (lpCreateStruct) = = - 1 )
return - 1 ;
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 ;
}
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 :
CMultiDocTemplate * pTemplate;
pTemplate = new CMultiDocTemplate (
IDR_TESTMDTYPE,
RUNTIME_CLASS (CTestMdiDoc),
RUNTIME_CLASS (CChildFrame),
RUNTIME_CLASS (CTestMdiView));
AddDocTemplate (pTemplate);
|
|
| auteur : 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)
BEGIN_MESSAGE_MAP (CMyDlgbar, CDialogBar)
ON_BN_CLICKED (IDC_BUTTON2, OnButton2)
ON_UPDATE_COMMAND_UI (IDC_BUTTON2, OnUpdateButton2)
END_MESSAGE_MAP ()
void CMyDlgbar:: OnUpdateButton2 (CCmdUI* pCmdUI)
{
}
void CMyDlgbar:: OnButton2 ()
{
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.
|
| auteur : Farscape |
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.
|
| auteur : 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 Comment rendre flottante une barre de dialogue ?
Ensuite :
l'affichage d'une barre de dialogue se gère avec la fonction :
CFrameWnd:: ShowControlBar
void ShowControlBar ( CControlBar* pBar, BOOL bShow, BOOL bDelay );
|
Il suffit de disposer du pointeur sur la Mainframe ou MDIChild en MDI :
CMainFrame * pFrame= static_cast < CMainFrame * > (AfxGetMainWnd ());
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 .
pFrame- > ShowControlBar (& pFrame- > m_wndToolBar,
! pFrame- > m_wndToolBar- > IsWindowVisible () ,FALSE);
|
Dernière fonction pour savoir si la barre est flottante :
CControlBar:: IsFloating
BOOL IsFloating ( ) const ;
|
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:
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:
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.
|
lien : Comment rendre flottante une barre de dialogue ?
|
| auteur : Farscape | Une barre de dialogue CDialogBar peut 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 :
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 ;
}
m_wndDlgBar.EnableDocking (CBRS_ALIGN_ANY);
EnableDocking (CBRS_ALIGN_ANY);
DockControlBar (& m_wndDlgBar);
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.
|
| auteur : alice9 | 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:
CTestMDI_DlgBar:: CTestMDI_DlgBar ()
{
}
|
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
LONG CTestMDI_DlgBar:: OnInitDialog ( UINT wParam, LONG lParam)
{
BOOL bRet = HandleInitDialog (wParam, lParam);
if (! UpdateData (FALSE))
{
TRACE0 (" Warning: UpdateData failed during dialog init.\n " );
}
return bRet;
}
BOOL CTestMDI_DlgBar:: Create (CWnd* pParent, UINT nIDTemplate, UINT nStyle, UINT nID)
{
BOOL bReturn = CDialogBar:: Create (pParent, nIDTemplate, nStyle, nID);
if (bReturn)
{
}
return bReturn;
}
|
-> ajouter dans le message_map (transformation de la fonction virtuelle en afx_msg): 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 :
m_pdlgBarTest = new CTestMDI_DlgBar ;
if (! m_pdlgBarTest- > 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 ;
}
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.
|
Consultez les autres F.A.Q.
|
|