Click here to Skip to main content
15,879,348 members
Articles / Desktop Programming / MFC
Article

Changing toolbars dynamically at runtime

Rate me:
Please Sign up or sign in to vote.
4.40/5 (4 votes)
22 Aug 2000 142.6K   2.1K   33   13
A simple tutorial that shows how to dynamically replace toolbars at runtime
  • Download source files - 34 Kb
  • Dynamic Toolbar A screen shot.

    Dynamic Toolbar B screen shot.

    Dynamic Toolbar C screen shot.

    Introduction

    This tutorial and the associated sample application will teach you how to dynamically swap between three toolbars at runtime.

    The sample application I've provided shows how it is possible to toggle between the 3 toolbars by using the A, B or C buttons that are on the Main Application Toolbar. Please note that each of these dynamically created toolbars function separately from each, since they each have different button IDs and Message Maps of each button.

    This method can be very useful when we need to have less of a crowd of toolbars on the main window but at the same time have them when you need them. It is up to the user to select what toolbar He/She wants by simply clicking the related button on any other toolbar!

    Another use for this method is when we need to group/set together the related functions that can be devided into separate toolbars. For example if we have a 3D Graphic Application, We would need to Rotate, Translate or Scale the selected 3D shape.

    Knowing that in 3D we have X, Y and Z as parameters for position in space, we would need 3 Toolbars for each of Rotation, Scaling and Translation in 3D. These parameters can easily be changed by having three separate toolbars with Spinners and Edit boxes on them to modify the X, Y & Z values. The Dynamic Toolbars will come very handy in this case!

    Sample:

    The sample MFC 4.2 ( VC++ 6 SP3 ) program demontrates how to create and use this method of dynamic toolbar creation. The main toobar has three A, B and C buttons on them to toggle dynamic toolbar selection. The dynamic toolbars are A, B and C that also each have four buttons on them.

    The first button is an indicator for which dynamic toolbar is active. The other 3 buttons each change the displayed text and its color on the view window to another color. It can be any thing else as you wish for these buttons to do, you program them to melt ice and they will :)

    How it is done:

    F ollow the steps below.

    1. Create 3 separate Bitmaps in the resource editor with the size to fit the number of buttons on the target toolbar. They will be loaded as the toolbar button bitmaps later at runtime. Name them as:
      IDB_BITMAP_A
      IDB_BITMAP_B
      IDB_BITMAP_C.

    2. Add the following marked <<...>> defines in the resource header Resource.h file:

      #define IDB_BITMAP_A                    132	// The bitmap for toolbar 
      A we                    created	in the resource editor #define IDB_BITMAP_B 134 // The bitmap for toolbar
      B we                    created	in the resource editor #define IDB_BITMAP_C 133 // The bitmap for toolbar
      C we                    created	in the resource editor // << Buttons A, B & C on
      
      
      the  Main Toolbar >> #define ID_BUTTON_A 32776 #define ID_BUTTON_B 32777 
      #define ID_BUTTON_C                     32778
      // <<                     Styles
      and Buttons                     of
      
      the  Dynamic Toolbar A >> #define ID_BUTTON_STYLE_A 34500 #define 
      ID_BUTTON_A_ONE 34501               #define
      ID_BUTTON_A_TWO 34502                 #define
      ID_BUTTON_A_THREE 34503                 //
      << Styles               and
      
      Buttons  of the Dynamic Toolbar B >> #define ID_BUTTON_STYLE_B 
      34504 #define               ID_BUTTON_B_ONE
      34505 #define                 ID_BUTTON_B_TWO
      34506 #define                 ID_BUTTON_B_THREE
      34507 //               <<
      
      Styles  and Buttons of the Dynamic Toolbar C >> 
      #define ID_BUTTON_STYLE_C               34508
      #define ID_BUTTON_C_ONE                 34509
      #define ID_BUTTON_C_TWO                 34510
      #define ID_BUTTON_C_THREE               34511
    3. At the top of main frame's definition file MainFrm.h, define the followings:
      #define STYLE_A 1 // for the A toolbar
      #define STYLE_B 2 // for the B toolbar
      #define STYLE_C 3 // for the C toolbar
    4. Add the member variable as follows:
      CToolBar 	m_wndDynTB; // Dynamic toolbar's object
      UINT	 	m_nStyle; // Used for Style changing
    5. In the main frame's implementation file MainFrm.cpp, type the following codes:
      //##################################################//
      // Dynamic Toolbar button definitions array and IDs
      
      static UINT BASED_CODE ToolsA[] =
      {
      	
      	ID_BUTTON_STYLE_A,
      	ID_SEPARATOR,
      	ID_BUTTON_A_ONE,
      	ID_BUTTON_A_TWO,
      	ID_BUTTON_A_THREE,
      };
      
      
      static UINT BASED_CODE ToolsB[] =
      {
      	
      	ID_BUTTON_STYLE_B,
      	ID_SEPARATOR,
      	ID_BUTTON_B_ONE,
      	ID_BUTTON_B_TWO,
      	ID_BUTTON_B_THREE,
      };
      
      
      static UINT BASED_CODE ToolsC[] =
      {
      	ID_BUTTON_STYLE_C,
      	ID_SEPARATOR,
      	ID_BUTTON_C_ONE,
      	ID_BUTTON_C_TWO,
      	ID_BUTTON_C_THREE,
      };
    6. Create the initial dynamic toolbar like this in the main frame's OnCreate() function:
      //#####################################################
      // Dynamic Toolbar Creation
      	
      if (!m_wndDynTB.CreateEx(this, TBSTYLE_FLAT , WS_CHILD | WS_VISIBLE | CBRS_TOP
      	| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
      	!m_wndDynTB.LoadBitmap(IDB_BITMAP_A) ||
      	!m_wndDynTB.SetButtons(ToolsA, sizeof(ToolsA)/sizeof(UINT)))
      {
      	TRACE0("Failed to create the light toolbar.\n");
      	return -1;      // if failed to create
      }
      
      //#####################################################
      // Add thiese to the end of create function
      
      	m_wndDynTB.EnableDocking(CBRS_ALIGN_ANY);
      	m_wndDynTB.SetWindowText(_T("Dynamic Toolbar Style A"));
      	DockControlBar(&m_wndDynTB);
      
      //#####################################################
    7. Add the following message maps for the buttons A, B & C of the Main Toolbar and the Dynamic
      toolbars' First Buttons to indicate what Dynamic Toolbar is Active:
      BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
      	//{{AFX_MSG_MAP(CMainFrame)
      	ON_WM_CREATE()
      	ON_COMMAND(ID_BUTTON_A, OnButtonA)
      	ON_COMMAND(ID_BUTTON_B, OnButtonB)
      	ON_COMMAND(ID_BUTTON_C, OnButtonC)
      	ON_UPDATE_COMMAND_UI(ID_BUTTON_A, OnUpdateButtonA)
      	ON_UPDATE_COMMAND_UI(ID_BUTTON_B, OnUpdateButtonB)
      	ON_UPDATE_COMMAND_UI(ID_BUTTON_C, OnUpdateButtonC)
      	//}}AFX_MSG_MAP
      
      	// Dynamic Toolbar <u>First Buttons</U> Message Maps
      
      	ON_COMMAND(ID_BUTTON_STYLE_A , OnButtonStyleA)
      	ON_UPDATE_COMMAND_UI(ID_BUTTON_STYLE_A, OnUpdateButtonStyleA)
      
      	ON_COMMAND(ID_BUTTON_STYLE_B , OnButtonStyleB)
      	ON_UPDATE_COMMAND_UI(ID_BUTTON_STYLE_B, OnUpdateButtonStyleB)
      
      	ON_COMMAND(ID_BUTTON_STYLE_C , OnButtonStyleC)
      	ON_UPDATE_COMMAND_UI(ID_BUTTON_STYLE_C, OnUpdateButtonStyleC)
      
      
      END_MESSAGE_MAP()
    8. Add the following message handlers for the buttons A, B & C of the Main Toolbar and the Dynamic
      toolbars' First Buttons to indicate what Dynamic Toolbar is Active:
      /////////////////////////////////////////////////////////////////////////////
      // CMainFrame message handlers
      
      void CMainFrame::OnButtonA()
      {
      	m_nStyle = STYLE_A;//1;
      	Invalidate();
      	
      	m_wndDynTB.SetButtons(ToolsA, sizeof(ToolsA)/sizeof(UINT));
      	m_wndDynTB.LoadBitmap(IDB_BITMAP_A); 
      	m_wndDynTB.SetWindowText(_T("Dynamic Toolbar Style A"));
      	m_wndDynTB.InvalidateRect(NULL,TRUE); 
      
      }
      
      void CMainFrame::OnButtonB() 
      {
      	m_nStyle = STYLE_B;//2;
      	Invalidate();
      	
      	m_wndDynTB.SetButtons(ToolsB, sizeof(ToolsB)/sizeof(UINT));
      	m_wndDynTB.SetWindowText(_T("Dynamic Toolbar Style B"));
      	m_wndDynTB.LoadBitmap(IDB_BITMAP_B); 
      	m_wndDynTB.InvalidateRect(NULL,TRUE); 
      
      }
      
      void CMainFrame::OnButtonC()
      {
      	m_nStyle = 
      	STYLE_C;//3;
      
      	Invalidate(); m_wndDynTB.SetButtons(ToolsC,
      	sizeof(ToolsC)/sizeof(UINT)); m_wndDynTB.SetWindowText(_T("Dynamic Toolbar Style
      	C"));
      	m_wndDynTB.LoadBitmap(IDB_BITMAP_C); m_wndDynTB.InvalidateRect(NULL
      ,TRUE);
      
      } void CMainFrame::OnUpdateButtonA(CCmdUI*
      pCmdUI)
      	{pCmdUI->SetCheck(m_nStyle == 
      STYLE_A);
      
      } void CMainFrame::OnUpdateButtonB(CCmdUI*
      pCmdUI)
      	{pCmdUI->SetCheck(m_nStyle == 
      STYLE_B);
      
      } void CMainFrame::OnUpdateButtonC(CCmdUI* 
      pCmdUI)
      	{pCmdUI->SetCheck(m_nStyle == 
      
      
       STYLE_C); 
      }
      	void CMainFrame::OnButtonStyleA() { // Keep here Empty, just for
      enabling
      
      the button }
      void
      	CMainFrame::OnUpdateButtonStyleA(CCmdUI*pCmdUI) { pCmdUI->SetCheck();// Used to always check this first button as	
      an
      
      indicator } 
      void
      	CMainFrame::OnButtonStyleB() { // Keep here Empty, just for enabling	
      the
      
      button } void
      CMainFrame::OnUpdateButtonStyleB(CCmdUI*
      	pCmdUI){ pCmdUI->SetCheck();// Used to always check this first button as an	
      indicator
      
      } void
      CMainFrame::OnButtonStyleC()
      	{ // Keep here Empty, just for enabling the	
      button
      
      } void CMainFrame::OnUpdateButtonStyleC(CCmdUI*
      pCmdUI)
      	{pCmdUI->SetCheck(); // Used to always check this first button as an indicator
      }
    9. O.K., Now that our main frame coding is done and the Dynamic Toolbars are selected and updated as the codes above make them do, we will go a little further to prove 100% that this method is very useful especially in the document/view architecture.

      In the document header, add two member variables for text string and it's color like this:

      COLORREF m_crTextClr;	// Color for the dispalyed text
      CString m_strText;	// The displayed text

      And then initialize them in the document's constructor to anything ie.:

      m_crTextClr = RGB(255,0,0); // Default color set to Blue
      m_strText = _T("Masoud");   // Default text as a free poblicity!  ;-)
      

      So we can change them later by the dynamic toolbar buttons as a test!

      We therefore are going to add the message maps and handlres for the Dynamic Toolbar buttons inside the Document class like this:

      Type these message handlres by hand In the Document's header file just above the DECLARE_MESSAGE_MAP macro:

      // Generated message map functions
      protected:
      	//{{AFX_MSG(CDynamicTBDoc)
      	//}}AFX_MSG
      
      	// My Dynamic Toolbar messgae maps
      	afx_msg void OnButtonAOne();
      	afx_msg void OnButtonATwo();
      	afx_msg void OnButtonAThree();
      
      	afx_msg void OnButtonBOne();
      	afx_msg void OnButtonBTwo();
      	afx_msg void OnButtonBThree();
      
      	afx_msg void OnButtonCOne();
      	afx_msg void OnButtonCTwo();
      	afx_msg void OnButtonCThree();
      
      	DECLARE_MESSAGE_MAP()

      And in the Document's cpp file type the following lines just above the END_MESSAGE_MAP macro:

      BEGIN_MESSAGE_MAP(CDynamicTBDoc, CDocument)
      	//{{AFX_MSG_MAP(CDynamicTBDoc)
      	//}}AFX_MSG_MAP
      
      	////#############################################
      
      	ON_COMMAND(ID_BUTTON_A_ONE , OnButtonAOne)
      	ON_COMMAND(ID_BUTTON_A_TWO , OnButtonATwo)
      	ON_COMMAND(ID_BUTTON_A_THREE , OnButtonAThree)
      
      	ON_COMMAND(ID_BUTTON_B_ONE , OnButtonBOne)
      	ON_COMMAND(ID_BUTTON_B_TWO , OnButtonBTwo)
      	ON_COMMAND(ID_BUTTON_B_THREE , OnButtonBThree)
      
      	ON_COMMAND(ID_BUTTON_C_ONE , OnButtonCOne)
      	ON_COMMAND(ID_BUTTON_C_TWO , OnButtonCTwo)
      	ON_COMMAND(ID_BUTTON_C_THREE , OnButtonCThree)
      
      	////#############################################
      
      END_MESSAGE_MAP()
      
      <p>
      And in the Document's cpp file then type the following functions for message handlers 
      we declared above:
      </p>
      
      ////############# Toolbar A ####################
      
      void CDynamicTBDoc::OnButtonAOne() 
      {
      	m_crTextClr = RGB(0,255,0);
      	m_strText = _T("Samimi");
      	SetModifiedFlag();
      	UpdateAllViews(NULL);
      
      }
      
      void CDynamicTBDoc::OnButtonATwo() 
      {
      	m_crTextClr = RGB(0,255,255);
      	m_strText = _T("Test");
      	SetModifiedFlag();
      	UpdateAllViews(NULL);
      }
      
      void CDynamicTBDoc::OnButtonAThree()
      {
      	m_crTextClr = RGB(255,105,0);
      	m_strText = _T("For");
      	SetModifiedFlag();
      	UpdateAllViews(NULL);
      }
      
      ////############# Toolbar B ####################
      
      void CDynamicTBDoc::OnButtonBOne()
      {
      	m_crTextClr = RGB(128,255,128);
      	m_strText = _T("Dynamic");
      	SetModifiedFlag();
      	UpdateAllViews(NULL);
      }
      
      void CDynamicTBDoc::OnButtonBTwo()
      {
      	m_crTextClr = RGB(0,128,128);
      	m_strText = _T("Toolbar");
      	SetModifiedFlag();
      	UpdateAllViews(NULL);
      }
      
      void CDynamicTBDoc::OnButtonBThree()
      {
      	m_crTextClr = RGB(128,20,0);
      	m_strText = _T("And");
      	SetModifiedFlag();
      	UpdateAllViews(NULL);
      }
      
      ////############# Toolbar C ####################
      
      void CDynamicTBDoc::OnButtonCOne() 
      {
      	m_crTextClr = RGB(0,255,0);
      	m_strText = _T("IT");
      	SetModifiedFlag();
      	UpdateAllViews(NULL);
      }
      
      void CDynamicTBDoc::OnButtonCTwo() 
      {
      	m_crTextClr = RGB(0,255,0);
      	m_strText = _T("FULLY");
      	SetModifiedFlag(); 
      	UpdateAllViews(NULL); 
      }
      
      void CDynamicTBDoc::OnButtonCThree() 
      {
      	m_crTextClr = RGB(0,255,0); 
      	m_strText = _T("WORKSSS!!!");
      	SetModifiedFlag();
      	UpdateAllViews(NULL);
      }
      
      ////#############################################
    10. Compile and run the program and without surprises it should be completamenete allright!

    And finally, you can do anything else as you wish with this method ie. More buttons on any single toolbar, different bitmaps as you may have guessed already. And of course better code behind the buttons for much better and useful results.

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here


    Written By
    Technical Lead Samimi Information Technology
    United Arab Emirates United Arab Emirates
    My company provides services in the fields of:

    LAN/WAN Networking
    Data Management and Security
    Data Recovery
    ERP/CRM Solutions
    IT Infrastructure Solutions
    Software/Hardware Sales/Service

    Comments and Discussions

     
    QuestionHow to do this for CMFCToolBar Pin
    Michael B Pliam8-May-15 10:39
    Michael B Pliam8-May-15 10:39 
    GeneralAdd button to toolbar at runtime Pin
    tr0944216-Aug-06 2:26
    tr0944216-Aug-06 2:26 
    Generala handle to the MENU of a drop-down button Pin
    Alex Evans16-Nov-04 13:40
    Alex Evans16-Nov-04 13:40 
    GeneralyoWindows Print Button Pin
    Anonymous21-Oct-04 5:20
    Anonymous21-Oct-04 5:20 
    Generalchanging the resource of a window at runtime Pin
    danilo.it11-Oct-03 6:45
    sussdanilo.it11-Oct-03 6:45 
    GeneralChanging the caption of the toolbar Pin
    24-Apr-02 23:43
    suss24-Apr-02 23:43 
    Generalgetting the window handle to the dynamic toolbar Pin
    blanc11-Feb-02 6:03
    blanc11-Feb-02 6:03 
    Generalgetting the window handle to the dynamic toolbar Pin
    blanc11-Feb-02 6:01
    blanc11-Feb-02 6:01 
    GeneralAlternative, as requested Pin
    Craig Henderson24-Aug-00 0:09
    Craig Henderson24-Aug-00 0:09 
    GeneralRe: Alternative, as requested Pin
    2-Jan-01 9:16
    suss2-Jan-01 9:16 
    GeneralHi Craig, Pin
    Masoud Samimi23-Aug-00 23:29
    Masoud Samimi23-Aug-00 23:29 
    QuestionYou beat me to it. Idea copyright? Pin
    Craig Henderson22-Aug-00 23:34
    Craig Henderson22-Aug-00 23:34 
    AnswerRe: You beat me to it. Idea copyright? Pin
    Chris Maunder23-Aug-00 12:44
    cofounderChris Maunder23-Aug-00 12:44 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.