IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
logo
Sommaire > Classes Fenêtres et FrameWork > Barre d'outils
        Comment ajouter une CToolbar sur une fenêtre ?
        Comment rendre inactif un bouton dans une CToolBar ?
        Comment insérer une CComboBox dans une CToolBar ?
        Comment redimensionner une CToolBar sur l'insertion dynamique d'un bouton ?
        Comment enlever le bouton de fermeture sur une CToolBar ?
        Comment construire une barre d'outils contenant n'importe quel contrôle ?
        Comment provoquer l'affichage d'une CToolbar ou CDialogBar ?
        Comment mémoriser l'emplacement des barres d'outils?
        Comment faire un bouton à deux états dans une barre d'outils ?
        Comment rafraîchir une barre d'outils flottante ?
        Comment positionner deux barres d'outils sur la même ligne ?



Comment ajouter une CToolbar sur une fenêtre ?
auteur : Farscape
Commencer par la définir dans l'éditeur de ressources.
Puis procéder à son initialisation dans la fonction OnCreate de la MdiChild qui est la classe parent (au sens Windows) de la fenêtre.

int CMyMDIChildWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if(CMDIChildWnd::OnCreate(lpCreateStruct) == -1) return -1;
    // CToolBar  m_ToolBar;
    if(!m_ToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP) || 
                                     !m_ToolBar.LoadToolBar(IDR_TOOLBAR))
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // fail to create
    }
    return 0;
}

Comment rendre inactif un bouton dans une CToolBar ?
auteur : Farscape
Il faut gérer la notification de message ON_UPDATE_COMMAND_UI .
Avec l'aide de ClassWizard :

  1. Sélectionner la classe fenêtre concernée.
  2. Sélectionner l'id de la toolbar concernée
Dans la partie droite de l'écran deux notifications sont disponibles :

  • COMMAND : pour gérer l'action du click sur le bouton.
  • UPDATE_COMMAND_UI : pour gérer l'activité du bouton.
Exemple de notification générée par ClassWizard sur l'id ID_EDIT_CUT

BEGIN_MESSAGE_MAP(CTestdlgBarMDIApp, CWinApp)
//{{AFX_MSG_MAP(CTestdlgBarMDIApp)
ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
???.
La fonction:

void CTestdlgBarMDIApp::OnUpdateEditCut(CCmdUI* pCmdUI) 
{
       // TODO: Add your command update UI handler code here
       pCmdUI->Enable(m_bTestCut); // si m_bTestCut=false bouton grisé sinon actif.
}

Comment insérer une CComboBox dans une CToolBar ?
auteur : Farscape
Principe : A la place du code classique de création de la toolbar dans la mainframe à partir de la fonction OnCreate , on écrira ceci :

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

if(!CreateToolBar()) return -1;

if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
  sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1;      // fail to create
}

// TODO: Delete these three lines if you don't want the toolbar to
//  be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);

return 0;
}
La création de la toolbar est déplacée dans une fonction de création spécifique :

// -----------------------------------------------
BOOL CMainFrame::CreateToolBar()
{
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return FALSE;      // fail to create
}

TBBUTTON button;

button.iBitmap=NULL;
button.idCommand=0;
button.fsStyle=TBSTYLE_SEP;
button.dwData=0;
button.iString=NULL;
m_wndToolBar.GetToolBarCtrl().InsertButton(0,&button);
m_wndToolBar.GetToolBarCtrl().InsertButton(0,&button);
m_wndToolBar.SetButtonInfo(0,1,TBBS_SEPARATOR,100);

CRect rect;
m_wndToolBar.GetItemRect(0,&rect);
rect.top=2;
rect.bottom=rect.top+100;

if(!m_ComboBox.Create(CBS_DROPDOWNLIST | WS_VISIBLE | WS_TABSTOP,rect,&m_wndToolBar,1))
{
TRACE0("Failed to create combobox\n");
return FALSE;      // fail to create
}

m_ComboBox.AddString("item 0");
m_ComboBox.AddString("item 1");
m_ComboBox.AddString("item 2");
m_ComboBox.AddString("item 3");
return TRUE;
}
On commence par insérer deux séparateurs avec la structure TBBUTTON et la fonction InserButton.
On fixe ensuite les infos sur le bouton à savoir son identifiant ici 1 et sa largeur en pixels :100.

Note : dans le cas d'un séparateur la fonction SetButtonInfo accepte la largeur en pixels au lieu de l'indice de l'image.
Voir documentation MSDN pour plus de détails.

Ensuite on récupère la place de l'item 0 et on lui recalcule sa hauteur.
On crée la ComboBox.
Et pour finir on l'alimente par AddString.

Pour manipuler les notifications on pourra rajouter la notification OnComboChange directement sur le message map de la mainframe :

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_GETMINMAXINFO()
//}}AFX_MSG_MAP
ON_CBN_SELCHANGE(1,OnComboChange)
END_MESSAGE_MAP()

void CMainFrame::OnComboChange()
{
// 
int nSel=m_ComboBox.GetCurSel();
if(nSel!=CB_ERR)
{
CString str;
m_ComboBox.GetLBText(nSel,str);
TRACE("\nCombo Sel:%s",(const char *)str);
}
}

Comment redimensionner une CToolBar sur l'insertion dynamique d'un bouton ?
auteur : Farscape
Proposition de classe :

/////////////////////////////////////////////////////////////////////////////
// CToolBarEx window
class CToolBarEx : public CToolBar
{
// Construction
public:
CToolBarEx();

// Attributes
public:
    void  SetSizes(SIZE sizeButton, SIZE sizeImage)
    {
        GetToolBarCtrl( ).SetButtonSize(sizeButton);
        if(GetToolBarCtrl( ).SetBitmapSize(sizeImage))
        m_sizeImage=sizeImage;
    }

   inline void InitSizes(CSize cSizeBitmapSize) 
    { 
        m_SizeButton=cSizeBitmapSize;
        SetSizes(CSize(cSizeBitmapSize.cx+7,cSizeBitmapSize.cy+6),cSizeBitmapSize); 
        GetToolBarCtrl().AutoSize();    
    }
    bool  SetButtonWidth(UINT nMinWidth,UINT nMaxWidth);
    CSize GetButtonsWidth() const;
    CSize GetButtonsSize()  const;

    bool AddButtonToolBar(int nIndexPos,int nidCommand,UINT nIdbitmap,int istring=0);
    bool DeleteButtonToolBar(int nIndexPos);

    void RedrawToolBar(BOOL bRecalcLayout=TRUE,BOOL bOnlyFrame=FALSE);
    void RedrawButton(int nIndex);
    void UpdateSizes();

    void ReCalcDynamicLayout(CRect rect,int nIndexPos=-1);

// Attributes
private:
    CSize m_sizeMiniMaxi;
    CSize m_SizeButton;
    CSize m_sizeImage;

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CToolBarEx)
//}}AFX_VIRTUAL

// Implementation
public:
virtual ~CToolBarEx();

// Generated message map functions
protected:
//{{AFX_MSG(CToolBarEx)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////
// CToolBarEx

CToolBarEx::CToolBarEx()
{
    m_SizeButton.cx=16;
    m_SizeButton.cy=15;
}

CToolBarEx::~CToolBarEx()
{
}


BEGIN_MESSAGE_MAP(CToolBarEx, CToolBar)
//{{AFX_MSG_MAP(CToolBarEx)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CToolBarEx message handlers
bool CToolBarEx::SetButtonWidth(UINT nMinWidth,UINT nMaxWidth)
{ 
    ASSERT(::IsWindow(GetSafeHwnd()));
    ASSERT(nMaxWidth-m_sizeImage.cx>=7);
    if(SendMessage(TB_SETBUTTONWIDTH, 0, MAKELPARAM(nMinWidth, nMaxWidth)))
    {
        m_sizeMiniMaxi.cx=nMinWidth;
        m_sizeMiniMaxi.cy=nMaxWidth;
        return true;
    }
    return false; 
}
//----------------------------------------------------------------
CSize CToolBarEx::GetButtonsWidth() const
{ 
    ASSERT(::IsWindow(GetSafeHwnd()));
    return m_sizeMiniMaxi; 
}
//----------------------------------------------------------------
CSize CToolBarEx::GetButtonsSize() const
{ 
    ASSERT(::IsWindow(GetSafeHwnd()));
    DWORD result=(DWORD)::SendMessage(m_hWnd,TB_GETBUTTONSIZE,0,(LPARAM)0); 
    return CSize(LOWORD(result),HIWORD(result)); 
}
//----------------------------------------------------------------
void CToolBarEx::RedrawToolBar(BOOL bRecalcLayout/*=TRUE*/, 
   BOOL bOnlyFrame/*=FALSE*/)
{
    ASSERT(::IsWindow(GetSafeHwnd()));

    if(!IsWindowVisible())return;

    if(bRecalcLayout)
    {
        CWnd *pParent=GetToolBarCtrl( ).GetParent();
        CFrameWnd* pFrameWnd=(CFrameWnd *)pParent->GetParent();
        if(pFrameWnd!=NULL)
        {
            pFrameWnd->RecalcLayout();
            for(int nIndex=0; nIndex<GetToolBarCtrl( ).GetButtonCount(); nIndex++)
            {
                RedrawButton(nIndex);
                CRect rect;
                GetItemRect(nIndex,rect);
                ValidateRect(rect);
            }
        }
    }
    else
    {
        if(!bOnlyFrame)
        {
            GetToolBarCtrl( ).RedrawWindow(NULL,NULL,
            RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE|RDW_FRAME|RDW_ALLCHILDREN);
        }
    }
    if(bOnlyFrame)
    {
        GetToolBarCtrl( ).SetWindowPos(NULL,0,0,0,0,
        SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE|SWP_DRAWFRAME);
    }
}
//----------------------------------------------------------------
void CToolBarEx::RedrawButton(int nIndex)
{
    ASSERT(::IsWindow(GetSafeHwnd()));
    
    if(nIndex<0 || nIndex>GetToolBarCtrl().GetButtonCount())
    {
        return;
    }
    CRect rect;
    GetToolBarCtrl( ).GetItemRect(nIndex,rect);
    GetToolBarCtrl( ).RedrawWindow(rect);
}
//----------------------------------------------------------------
void CToolBarEx::UpdateSizes() 
{ 
    SetSizes(GetButtonsSize(),m_sizeImage); 
    GetToolBarCtrl().AutoSize();
}
//----------------------------------------------------------------
bool CToolBarEx::DeleteButtonToolBar(int nIndexPos)
{
    CRect rect; 
    GetToolBarCtrl( ).GetWindowRect(&rect);
    
    if(!GetToolBarCtrl( ).DeleteButton(nIndexPos)) return false;
    
    // resize window 
    rect.right-=(m_SizeButton.cx+7);
    SetWindowPos(NULL,0,0,rect.Width(),rect.Height(),
    SWP_NOMOVE|SWP_NOZORDER|SWP_DRAWFRAME|SWP_FRAMECHANGED);
    
    ReCalcDynamicLayout(rect);
    return true;
}
//----------------------------------------------------------------
void CToolBarEx::ReCalcDynamicLayout(CRect rect,int nIndexPos/*=-1*/)
{
    SetWindowPos(NULL,0,0,rect.Width(),rect.Height(),
        SWP_NOMOVE|SWP_NOZORDER|SWP_DRAWFRAME|SWP_FRAMECHANGED);
    
    if(IsFloating())  
    {
        CPoint newPos(0,0);        
        ClientToScreen(&newPos);
        CRect rcNew;
        //  GetToolBarCtrl().SetRows(GetToolBarCtrl().GetRows(),TRUE, &rcNew);
        
        CalcDynamicLayout(rect.Width(),LM_HORZ | LM_COMMIT);
        
        CWnd *pParent=GetToolBarCtrl( ).GetParent();
        CFrameWnd* pFrameWnd=(CFrameWnd *)pParent->GetParent();
        
        if(pFrameWnd)
            pFrameWnd->FloatControlBar(this, newPos,CBRS_ALIGN_TOP | CBRS_SIZE_DYNAMIC);
    }
    
    RedrawToolBar();
    if(nIndexPos>0)RedrawButton(nIndexPos);
    
}
//----------------------------------------------------------------
bool CToolBarEx::AddButtonToolBar(int nIndexPos,int nidCommand,UINT nIdbitmap,int istring/*=0*/)
{
    BOOL bok;
    
    CRect rect; 
    GetToolBarCtrl( ).GetWindowRect(&rect);
    
    TBBUTTON Buttons;
    GetToolBarCtrl( ).AddBitmap(1,nIdbitmap);
    Buttons.iBitmap=nIndexPos;
    Buttons.idCommand=nidCommand;
    Buttons.fsState=TBSTATE_ENABLED;
    Buttons.fsStyle=TBSTYLE_BUTTON;
    Buttons.dwData=0;
    Buttons.iString=istring;
    bok=GetToolBarCtrl( ).AddButtons(1,&Buttons);
    
    SetButtonWidth(0,m_SizeButton.cx+7);
    
    InitSizes(m_SizeButton);
    
    // resize window 
    rect.right+=(m_SizeButton.cx+7);
    
    ReCalcDynamicLayout(rect,nIndexPos);
    return (bok?true:false);
}
Initialisations dans la mainframe:

// portion de code relatif à la CToolbarEx
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1;      // fail to create
}

m_wndToolBar.InitSizes(CSize(16,15));

m_wndToolBar.SetWindowText(_T("Toolbar"));
m_wndToolBar.UpdateSizes();
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

// TODO: Delete these three lines if you don't want the toolbar to
//  be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
Notez l'utilisation du style CBRS_SIZE_DYNAMIC ,
l'utilisation de la fonction InitSizes pour spécifier la taille des boutons , et la fonction UpdateSizes() pour la prise en compte des modifications.

Utilisation:

// rajout d'un bouton par un bitmap IDB_BITMAP1 a la position 8 associé a la commande ID_BUTTONADD
CMainFrame * pMain=(CMainFrame *)AfxGetMainWnd();  
pMain->m_wndToolBar.AddButtonToolBar(8,ID_BUTTONADD,IDB_BITMAP1);

// del d'un bouton 
CMainFrame * pMain=static_cast<CMainFrame *>(AfxGetMainWnd());  
pMain->m_wndToolBar.DeleteButtonToolBar(8);
Dans le code ci-dessus l'ajout d'un bouton prend en charge le recalcul et le dessin de la CToolBar qu'elle soit ancrée ou non.
Deux méthodes sont utilisées suivant que la CToolBar est ancrée ou non ,le détail du traitement est visible dans la fonction ReCalcDynamicLayout.


Comment enlever le bouton de fermeture sur une CToolBar ?
auteur : Farscape
En surchargeant la fonction virtuelle CalcFixedLayout pour enlever le style WS_SYSMENU à la fenêtre.

CControlBar::CalcFixedLayout
Cette méthode calcul la taille horizontal d'une barre de contrôle 
virtual CSize CalcFixedLayout(
BOOL bStretch,
BOOL bHorz ); 
Implémentation :

CSize CMyToolBar::CalcFixedLayout( BOOL bStretch, BOOL bHorz )
{
    if ( IsFloating() ) // only when we float
    GetParent()->GetParent()->ModifyStyle( WS_SYSMENU, 0 ); 
    return CToolBar::CalcFixedLayout( bStretch, bHorz );
}

Comment construire une barre d'outils contenant n'importe quel contrôle ?
Créé le 20/05/2006[haut]
auteur : Nourdine Falola
Visual C++ reconnaît les contrôles communs d'Internet Explorer. Parmi eux, la rebar (CRebar).
Ce contrôle est en fait un conteneur dans lequel on peut mettre des barres d'outils (CToolBar et CDialogBar).
On appelle bande chaque barre d'outils, et on désignera par barre d'outils l'ensemble des bandes.

Pour que l'application intègre une rebar, il faut cocher l'option "Internet Explorer Rebars" à l'étape 4 de l'AppWizard dans la section "How do you want your toolbars look ?".
A l'exécution, on voit que la barre d'outils comporte 2 bandes : la toolBar classique avec ses boutons, et une dialogBar avec la mention "A FAIRE : Disposez la barre de dialogue".

La classe MainFrame possède les données membres suivantes :
protected:  // control bar embedded members
CStatusBar  m_wndStatusBar;  // barre d'état
CToolBar    m_wndToolBar;  // barre d'outils classique
CReBar      m_wndReBar;  // la rebar
CDialogBar  m_wndDlgBar;  // la barre de dialogue
et la rebar est créée de la façon suivante :
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...

   // création de la toolbar
   if (!m_wndToolBar.CreateEx(this) ||
      !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
   { 
      TRACE0("Failed to create toolbar\n");
      return -1;      // fail to create
   }

   // création de la dialogbar
   if (!m_wndDlgBar.Create(this, IDR_MAINFRAME, 
      CBRS_ALIGN_TOP, AFX_IDW_DIALOGBAR))
   {
      TRACE0("Failed to create dialogbar\n");
      return -1;// fail to create
   }

   // création de la rebar et ajout de la toolbar et de la dialogbar
   if (!m_wndReBar.Create(this) ||
       !m_wndReBar.AddBar(&m_wndToolBar) ||
       !m_wndReBar.AddBar(&m_wndDlgBar))
   {
      TRACE0("Failed to create rebar\n");
      return -1;      // fail to create
   }

...
   
   return 0;
}
Maintenant, ajoutez les contrôles sur la dialogbar comme pour une fenêtre de dialogue classique (vous pouvez ajouter n'importe quel contrôle de base ou perso, et changer la taille de la dialogbar). Associez cette dernière à la classe CMainFrame. Dans l'éditeur double-cliquez sur la dialogbar, à l'invite "Adding a class" choisissez "Select an existing class" puis OK.
A l'invite suivante, choisissez CMainFrame dans la liste puis validez.
On choisit CMainFrame et non une nouvelle classe de dialogue car on veut ajouter une barre d'outils et non pas une nouvelle classe de dialogue.
Ensuite, programmez les gestionnaires des contrôles de la rebar (i.e. de la dialogbar de la rebar).


Comment provoquer l'affichage d'une CToolbar ou CDialogBar ?
Créé le 20/05/2006[haut]
auteur : Farscape
Les barres de dialogue ou barres d'outils sont créées habituellement dans la fonction OnCreate de la mainframe de l'application et éventuellement dans la MDIChild (en plus) dans un contexte MDI.
Ce cas de figure fonctionne très bien si le composant est visible dès sa création.
Si celui-ci est créé en mode caché ou s'il est créé à un autre moment que la fonction OnCreate celui-ci n'apparaît pas.

On utilisera alors la fonction RecalcLayout pour provoquer le rafraîchissement des barres d'outils ou barre de dialogue.

Exemple avec la création dynamique d'une barre de dialogue:

void CMyMDIChild::CreateDialogBar()
   {
       m_pDlgBar = new CDialogBar();
       m_pDlgBar->Create(this,IDD_CHILDBAR,CBRS_TOP,115);
       RecalcLayout();
   } 

Comment mémoriser l'emplacement des barres d'outils?
Créé le 22/01/2007[haut]
auteur : GuileUkow
Ou plutôt comment sauvegarder automatiquement et à chaque fermeture du programme la dernière position de toutes ses barres d'outils et de barres de dialogue? Et pas seulement la position, sa visibilité, si elle était flottante ou non, etc... Pour cela, il suffit tout simplement d'utiliser les fonctions SaveBarState() et LoadBarState() de la classe CFrameWnd.

Lorsque l'on ferme l'application, il suffit de surcharger la fonction OnClose() de la classe CMainFrame() comme suit :

void CMainFrame::OnClose()
{
// TODO: Add your message handler code here and/or call default

/*
* Ici on ajoute la sauvegarde de toutes les barres d'outils présentes
* dans le projet grâce à la fonction SaveBarState. Cette fonction
* prend comme argument le nom de la clef dans lequel sera stocké
* les informations dans la base de registres.
*/
this->SaveBarState("Clef_Ammont\\Ici_Ma_Sauvegarde");

CMDIFrameWnd::OnClose(); // appel de la fonction de base
}

Cette fonction n'est pas présente par défaut, il faut rajouter un "handler" en utilisant le wizard de visual c++ sur le message WM_CLOSE.

Voilà pour la sauvegarde, et maintenant pour récupérer les données il suffit de faire lors de la création des barres d'outils dans la MainFrame l'opération inverse à un détail près.
Il faut effectivement lors de la création des barres d'outils renseigner celles-ci de leur propre ID, car hélas, pour des raisons obscures, ils ne sont pas mémorisés lors de l'appel de la fonction Create()...
Pour cela, il suffit d'appeler la fonction SetDlgCtrlID du contrôle de la barre pour leur affecter leur propre ID après que celle-ci ait été créée.
Le plus souvent, la création des toolbars se fait dans la fonction OnCreate() du MainFrame.
Ainsi, il suffit de la modifier comme suit pour obtenir le fonctionnement désiré :

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;

if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |
WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |
CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}

/*
* Attribution de l'ID au control car n'est pas effectué lors de la
* création. Il faut impérativement le faire sinon cela fera planter
* le programme lorsque plusieurs toolbars seront flottantes!!
* Il faut également s'assurer que les ids soient différents d'une
* barre à l'autre!!
*/
m_wndToolBar.SetDlgCtrlID(IDR_MAINFRAME);

if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |
WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |
CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar2.LoadToolBar(IDR_MAINFRAME2))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}

/*
* Attribution de l'ID au control car n'est pas effectué lors de la
* création. Il faut impérativement le faire sinon cela fera planter
* le programme lorsque plusieurs toolbars seront flottantes!!
* Il faut également s'assurer que les ids soient différents d'une
* barre à l'autre!!
*/
m_wndToolBar2.SetDlgCtrlID(IDR_MAINFRAME2);

if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}

/*
* La barre de status n'a pas besoin d'être mémorisée, sa position
* ne varie pas car elle n'est pas "Dockable".
*/

// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
DockControlBar(&m_wndToolBar2);

/*
* C'est ici, APRES toutes les initialisations que doit être effectué
* la récupération des positions des barres d'outils. Assurez-vous
* que les barres soient créées avant que cette fonction soit appellée
* et avant que EnableDocking soit appellé également.
*/
LoadBarState("Clef_Ammont\\Ici_Ma_Sauvegarde");

return 0;
}

Voilà, il n'y a plus qu'à compiler et à essayer!! Je n'ai eu aucun problème avec Visual C++ V6.
Ceci fonctionne avec toutes les classes dérivées de CControlBar.
Note : Cela n'a d'intérêt que si les barres d'outils sont "Dockables"!! Voir la fonction EnableDocking() pour plus d'infos.


Comment faire un bouton à deux états dans une barre d'outils ?
Créé le 22/01/2007[haut]
auteur : Farscape
Il est parfois utile de disposer pour le bouton d'une barre d'outils d'un deuxième état.
L'exemple le plus simple étant par exemple un bouton avec une icône de lecture par défaut et lorsqu'il est actionné l'image stop apparaît.
Ou un cadenas ouvert puis fermé indiquant visuellement qu'une action est interdite.

Le principe :
Il suffira de rajouter un bitmap pour visualiser le nouvel état du bouton dans la barre d'outils
Et de le permuter avec l'image initiale après que le bouton ait été pressé .

Concrètement le traitement se passera dans la MDIChild dans le cas d'un projet MDI où la MainFrame pour un projet SDI.
On pourra aussi faire une classe dérivée de CToolBar et inclure ces fonctionnalités dedans..


class CChildFrame : public CMDIChildWnd
{
    DECLARE_DYNCREATE(CChildFrame)
public:
    CChildFrame();

// Attributes
public:
CToolBar    m_wndToolBar;

// Operations
public:
    struct CUSTOMBT
    {
        int nIndiceOrg;
        int nIndiceNew;
        CString strNewTxt;
        CString strOldtxt;
    };
    // fixe le deuxieme etat (bitmap) pour le bouton nIDBt.
    void      SetButton(int nIDBt,UINT nBitmapID,const char *szNextText);

    // mise à jour de l'état du bouton 
    int        UpdateButton(int nIDBt);

    // fixe le numero d'image pour le bouton nIDBt
    BOOL    SetButtonImage(int nIDBt,int nImage);

   // recupere le numero d'image pour le bouton nIDBt
    BOOL    GetButtonImage(int nIDBt,int &rnImage);

    // rajoute un bitmap à la barre d'outils.
    BOOL    AddBitmapToolBar(int nNumButtons,UINT nBitmapID );

    // fixe l'etat visuel du bouton dans la barre d'outils pressé/non préssé.
    BOOL    SetButtonPressed(int nIDBt,bool bPressed=true);

    // met a jour le statut du bouton et renvoie TRUE si il est pressé.
    BOOL IsButtonPressed(int nIDBt,bool bMajBt=true);

   // renvoie le nombre de button dans la barre d'outil.
    int       GetButtonCount();

private:
    CMap<UINT ,UINT ,struct CUSTOMBT ,struct CUSTOMBT> m_mapCustomBt;
//......................
code:

//----------------------------------------------------------------
int CChildFrame::UpdateButton(int nIDBt)
{
    struct CUSTOMBT custom;

    if(!m_mapCustomBt.Lookup(nIDBt,custom)) return -1;

    int rnImage;
    if(GetButtonImage(nIDBt,rnImage))
    {                    
        rnImage=(rnImage==custom.nIndiceNew?custom.nIndiceOrg:custom.nIndiceNew);

        SetButtonImage(nIDBt,rnImage);
        
        // met le bouton enfoncé dans le cas du deuxieme etat.
        SetButtonPressed(nIDBt,rnImage==custom.nIndiceNew);
        return (rnImage==custom.nIndiceNew);
    }
    return -1;
}
//----------------------------------------------------------------
void CChildFrame::SetButton(int nIDBt,UINT nBitmapID,const char *szNextText)
{
    struct CUSTOMBT custom;

    int nNumButtons=m_wndToolBar.GetToolBarCtrl().GetImageList()->GetImageCount();
    custom.nIndiceNew=AddBitmapToolBar(nNumButtons,nBitmapID);

    custom.strNewTxt=szNextText;
    
    GetButtonImage(nIDBt,custom.nIndiceOrg);

    m_mapCustomBt.SetAt(nIDBt,custom);
}
//----------------------------------------------------------------
BOOL CChildFrame::SetButtonImage(int nIDBt,int nImage)
{
    
    TBBUTTONINFO tbbi;
    tbbi.dwMask = TBIF_IMAGE;
    tbbi.cbSize = sizeof tbbi;

    BOOL b=m_wndToolBar.GetToolBarCtrl().GetButtonInfo(nIDBt, &tbbi );
    if(b)
    {
        tbbi.iImage=nImage;        
        b=m_wndToolBar.GetToolBarCtrl().SetButtonInfo(nIDBt,&tbbi);
        m_wndToolBar.GetToolBarCtrl().RedrawWindow();
    }
    return (b && b!=-1);
} 
//----------------------------------------------------------------
BOOL CChildFrame::GetButtonImage(int nIDBt,int &rnImage)
{
   char sztext[256];

   TBBUTTONINFO tbbi;
   tbbi.dwMask = TBIF_IMAGE;
   
   tbbi.cbSize = sizeof tbbi;

   BOOL b= m_wndToolBar.GetToolBarCtrl().GetButtonInfo(nIDBt, &tbbi );

   rnImage=tbbi.iImage;

   
   return (b && b!=-1);
} 
//----------------------------------------------------------------

BOOL CChildFrame::AddBitmapToolBar(int nNumButtons,UINT nBitmapID )
{     
   return m_wndToolBar.GetToolBarCtrl().AddBitmap(nNumButtons,nBitmapID);
}
//----------------------------------------------------------------
int CChildFrame::GetButtonCount()
{
    // nombre de boutons dans la toolbar separateur compris.
    int nct=m_wndToolBar.GetToolBarCtrl().GetButtonCount();
    int nCount=0;
    TBBUTTON tb;
    for(int i=0;i<nct;i++)
    {
        m_wndToolBar.GetToolBarCtrl().GetButton(i,&tb);
        // si l'indice commande du bouton est valide ok on a bien un bouton.
        if(tb.idCommand) nCount++;
    }
    return nCount;
}
//----------------------------------------------------------------
BOOL CChildFrame::SetButtonPressed(int nIDBt,bool bPressed/*=true*/)
{
   int nState=TBSTATE_ENABLED ;
   if(bPressed) nState|=TBSTATE_PRESSED;

   return m_wndToolBar.GetToolBarCtrl().SetState(nIDBt,nState);
}
//----------------------------------------------------------------
BOOL CChildFrame::IsButtonPressed(int nIDBt,bool bMajBt/*=true*/)
{
    if(bMajBt) UpdateButton(nIDBt);
    return m_wndToolBar.GetToolBarCtrl().IsButtonPressed(nIDBt);        
}

Utilisation dans la vue:

void CTestToolBarView::OnInitialUpdate()
{
    CFormView::OnInitialUpdate();
    ResizeParentToFit();

    // acces à la frame (parent de la classe fenetre).
    CChildFrame *pChild=static_cast<CChildFrame *>(GetParentFrame());
    
    // ajout du bitmap en fin de toolbar .

    pChild->SetButton(ID_BUTTONOPENCLOSE,IDB_BITMAPCLOSE,"");
    pChild->SetButton(ID_BUTTONOPENCLOSE2,IDB_BITMAPCLOSE2,"");
}
//----------------------------------------------------------------
void CTestToolBarView::OnButtonopenclose() 
{
    // TODO: Add your command handler code here
    int rnImage;
    CChildFrame *pChild=static_cast<CChildFrame *>(GetParentFrame());  
    if(pChild->IsButtonPressed(ID_BUTTONOPENCLOSE))
    {
        TRACE("\nID_BUTTONOPENCLOSE:Pressé");
    }
    else
    {
        TRACE("\nID_BUTTONOPENCLOSE:relaché");
    }
}

void CTestToolBarView::OnButtonopenclose2() 
{
    // TODO: Add your command handler code here
    int rnImage;
    CChildFrame *pChild=static_cast<CChildFrame *>(GetParentFrame());      
    if(pChild->IsButtonPressed(ID_BUTTONOPENCLOSE2))
    {
        TRACE("\nID_BUTTONOPENCLOSE2:Pressé");
    }
    else
    {
        TRACE("\nID_BUTTONOPENCLOSE2:relaché");
    }    
}

L'utilisateur définit pour le bouton spécifié le nouveau bitmap.

Exemple:

http://farscape.developpez.com/Samples/TestsToolbar.zip


Comment rafraîchir une barre d'outils flottante ?
Créé le 22/01/2007[haut]
auteur : Farscape
On procédera comme suit :

if(pToolBar->IsFloating())
{
    CRect rect;
    pToolBar->GetWindowRect(rect);            

    pToolBar->SetWindowPos(NULL,0,0,rect.Width(),rect.Height(),
     SWP_NOMOVE|SWP_NOZORDER|SWP_DRAWFRAME|SWP_FRAMECHANGED);

    CPoint newPos(0,0);
    pToolBar->ClientToScreen(&newPos);
    CRect rcNew;

    pToolBar->CalcDynamicLayout(rect.Width(),LM_HORZ | LM_COMMIT);

    ParentWindow->FloatControlBar(pToolBar, newPos,
         CBRS_ALIGN_TOP | CBRS_SIZE_DYNAMIC); 
}



Comment positionner deux barres d'outils sur la même ligne ?
Créé le 22/01/2007[haut]
auteur : Farscape
Par défaut lorsqu'on déclare deux barres d'outils dans la MainFrame le positionnement se fait sur deux lignes.
Pour positionner les deux barres d'outils sur la même ligne on procédera comme suit :

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // fail to create
    }

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }    
    m_wndToolBar.SetWindowText(_T("Toolbar"));    
    m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
    
// deuxieme toolbar .
    if (!m_wndToolBar2.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar2.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // fail to create
    }
    
    m_wndToolBar2.SetWindowText(_T("Toolbar2"));    
    m_wndToolBar2.SetBarStyle(m_wndToolBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

    // TODO: Delete these three lines if you don't want the toolbar to
    //  be dockable
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
        m_wndToolBar2.EnableDocking(CBRS_ALIGN_ANY);

       EnableDocking(CBRS_ALIGN_ANY);
       DockControlBar(&m_wndToolBar); //placement 1 toolbar

       CRect RectOne,RectTwo;
       RecalcLayout();

    m_wndToolBar.GetWindowRect(&RectOne);
    
    m_wndToolBar2.GetWindowRect(&RectTwo);
    int nWidth=RectTwo.Width();
    int nHeight=RectTwo.Height();

// calcul emplacement de la toolbar2 a droite de la 1 toolbar
    RectTwo.left=RectOne.right;
    RectTwo.right=RectTwo.left+nWidth;
    RectTwo.top=RectOne.top;
    RectTwo.bottom=RectTwo.top+nHeight;

// placement final.
    DockControlBar(&m_wndToolBar2,(UINT)0,RectTwo);
    RecalcLayout();    
    
    return 0;
}


Dans mon exemple c'est la même barre d'outils qui est associée à deux variables différentes.



Consultez les autres F.A.Q.


Valid XHTML 1.0 TransitionalValid CSS!

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 © 2004 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni 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.