Click here to Skip to main content
Click here to Skip to main content

Tool Group Manager

, 23 Aug 2000 CPOL
Rate this:
Please Sign up or sign in to vote.
A reusable template class for managing multiple toolbars, only one of which is displayed at a time.

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 Wink | ;)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Craig Henderson
Technical Lead
United Kingdom United Kingdom
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.
Follow on   Twitter

Comments and Discussions

 
QuestionHi Craig, Have you tested it? PinsussMasoud Samimi28-Aug-00 9:47 
AnswerRe: Hi Craig, Have you tested it? PinsussCraig Henderson11-Sep-00 4:24 

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.

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