Click here to Skip to main content
Licence 
First Posted 23 Aug 2000
Views 59,391
Bookmarked 27 times

Tool Group Manager

By Craig Henderson | 23 Aug 2000
A reusable template class for managing multiple toolbars, only one of which is displayed at a time.
1 vote, 33.3%
1

2

3
2 votes, 66.7%
4

5
3.54/5 - 10 votes
μ 3.54, σa 3.03 [?]
  • Download source files - 3 Kb
  • Download demo project - 28 Kb
  • Sample Image - ToolGroupManager.gif

    Introduction

    Toolbars are a great user interface widget, but when an application has a large number of toolbars they can quickly become unmanageable. Providing facilities for the user to toggle toolbars on and off is all very well. The downside is that the use of the facility distracts the user from their task. I ran into exactly this problem in a recent application, and attempted to find a solution. Ultimately I came up with the Tool Group Manager that I present here.

    The idea is to have a high level toolbar that present the user with overall options, rather than specific options. On selecting an overall option, another toolbar is displayed subdividing the group into specifics. The last specific option is maintained automatically to minimize user effort.

    In the article Changing toolbars dynamically at runtime by Masoud Samimi, it shows how to dynamically replace toolbars at runtime. As it turns out, these two articles are very similar, but it is still appropriate to present my alternative. I do not profess this method to be in any way better than Masoud's, simply an alternative that I developed for my own needs.

    How to use the class

    As much of the functionality as possible is wrapped into a single template class called TToolGroupManager. A few changes are must be made to the main window. The class has a very small public interface, consisting of a constructor, destructor and two alternative methods of adding toolbars.

    template<class FRAMEWND>
    class TToolGroupManager : public CCmdTarget
    {
        ...
    
      public:
        TToolGroupManager(FRAMEWND *pFrameWnd);
        virtual ~TToolGroupManager();
        void AddToolGroup(WORD wID, CToolBar *pToolBar);
        void AddToolGroups(const WORD wIDs[], CToolBar *pToolBar, int nCount);
    
        ...
    };
    

    In the true tradition of MFC, I have declared a macro to make implementation easier. In the frame window of your application, instantiate the template class and add the IMPLEMENT_TOOLGROUPMANAGER macro. You will also need to create an array of CToolBar objects for the dynamic toolbar controls.

    class CMainFrame : public CFrameWnd
    {
      private:
        CToolBar m_tbTool[3];
        TToolGroupManager<CMainFrame> m_ToolGroupManager;
    
        ...
    
        IMPLEMENT_TOOLGROUPMANAGER
        DECLARE_DYNCREATE(CMainFrame)
        DECLARE_MESSAGE_MAP()
    };
    

    Now, in you main frame's implementation (.cpp) file, declare an array of WORDs containing the resource IDs of the main tool groups (The resource IDs do not have to be contiguous). Next, create a MFC message map for the template containing an ON_COMMAND and ON_UPDATE_COMMAND_UI entry for each of the array entries. Currently this is the easiest way to automate this process, as the information is required at compile time to build MFC's message map array.

    const WORD nToolGroup[] = { ID_TOOL1, ID_TOOL2, ID_TOOL3 };
    BEGIN_MESSAGE_MAP(TToolGroupManager<CMainFrame>, CCmdTarget)
        //{{AFX_MSG_MAP(TToolGroupManager)
        //}}AFX_MSG_MAP
        ON_COMMAND(nToolGroup[0], OnToolGroup)
        ON_COMMAND(nToolGroup[1], OnToolGroup)
        ON_COMMAND(nToolGroup[2], OnToolGroup)
        ON_UPDATE_COMMAND_UI(nToolGroup[0], OnUpdateToolGroup)
        ON_UPDATE_COMMAND_UI(nToolGroup[1], OnUpdateToolGroup)
        ON_UPDATE_COMMAND_UI(nToolGroup[2], OnUpdateToolGroup)
    END_MESSAGE_MAP()
    

    The TToolGroupManager constructor requires a pointer to the main window, modify your CMainFrame's constructor as shown below

    #pragma warning(disable : 4355)
    CMainFrame::CMainFrame() : m_ToolGroupManager(this)
    {
    }
    #pragma warning(default : 4355)
    

    The #pragma prevents a compiler warning about using the this pointer in a constructor list

    The main frame implementation needs to pass command messages to our tool group manager. Use ClassWizard to add an override for the OnCmdMsg member function and call the tool group manager class as follows:

    BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) 
    {
        return m_ToolGroupManager.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)  ||
               CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
    }
    

    Finally, in the OnCreate member function of the main frame, create the toolbars as you would normally. Then add them to the tool group manager. This can be done in one of two ways.

    First you can add each toolbar individually, like the following example shows:

    int nIndex;
    
    for (nIndex=0; nIndex < sizeof(nToolGroup)/sizeof(nToolGroup[0]); nIndex++)
        m_ToolGroupManager.AddToolGroup(nToolGroup[nIndex], &m_tbTool[nIndex]);
    

    Or you can let the tool group manager do the work for you, like the following example shows:

    m_ToolGroupManager.AddToolGroups(nToolGroup, m_tbTool, sizeof(nToolGroup)/sizeof(nToolGroup[0]));
    

    The AddToolGroup method is provided for simplicity, in the case where the toolbars are not in an array. Generally I would suspect that the AddToolGroups method would be commonly used.

    Summation

    That sums it up. I hope that some of you find it useful, and easy to use. Please post your comments, good or bad. Preferably good ;)

    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

    About the Author

    Craig Henderson

    Other
    Centrix Software
    United Kingdom United Kingdom

    Member

    Follow on Twitter Follow on Twitter
    Craig graduated with a B.SC. Honours in Computing for Real Time Systems from the University of the West of England, Bristol in 1995 after completing an HND in Computing in 1993.

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    You must Sign In to use this message board. (secure sign-in)
     
    Search this forum  
     FAQ
        Noise  Layout  Per page   
      Refresh
    QuestionHi Craig, Have you tested it? PinsussMasoud Samimi9:47 28 Aug '00  
    AnswerRe: Hi Craig, Have you tested it? PinsussCraig Henderson4:24 11 Sep '00  

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

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

    Permalink | Advertise | Privacy | Mobile
    Web01 | 2.5.120210.1 | Last Updated 24 Aug 2000
    Article Copyright 2000 by Craig Henderson
    Everything else Copyright © CodeProject, 1999-2012
    Terms of Use
    Layout: fixed | fluid