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

ATL COM Based Addin / Plugin Framework With Dynamic Toolbars and Menus

, 9 Dec 2004
Rate this:
Please Sign up or sign in to vote.
An article on ATL COM Based Addin / Plugin Framework With Dynamic Toolbars and Menus, based on VC++ Addin Architecture.



Building a product which suits to every customers requirement is every Companies dream. But in practice this may not be the case. This is because in most of the cases the requirement keep on changing drastically so that we have to make changes in the code level , recompile it, test it and ship it as another version. This way of development is not efficient in terms of project cost and developmental effort. This is where the Addin / Plugin architecture wins. In this article I have written a ATL COM Addin / Plugin Framework with dynamic toolbars and menu support . This framework is actually based on the VC++ 6.0 Addin Architecture which Microsoft used in every MS Office based applications (not sure of the exact implementation , just a guess work, because I followed the same path of VC++ Addin wizard generated code ). One difference, instead of adding menus , their description and other details in a new line delimited fashion in VC++ Addin , I used XML format for adding the Plugin details (Don't know why Microsoft didn't use XML?, perhaps at that time XML was not standardized , or is there any other specific reason??) along with Component Category for categorizing the plugins. Click here for seeing the XML format which I used in this project. You can add more properties as leaf nodes if you want (I followed the Idea of putting menu properties as nodes. Alternatively you can put the properties in some other fashion too).


This article assumes that you have a basic understanding of COM and MFC. This article is actually a continuation of the excellent article written by Zac Howland Pluggable Components using Component Categories - Part 1 . So the user is advised to go through this article first before coming to my article.

Using the code

The demo project attached contains 3 project workspaces written in VC++ 6.0. The application ProjectFramework is the one which loads all the addins , their menus, toolbars and other details. This application uses one core class called CAddinManager for various addin manipulations. The main header file of CAddinManager class is given below.

class CAddinManager 
    BOOL m_bLoadAllAdins;
    CArray<CAddinInfo,CAddinInfo> m_AddinInfoArray;
    CComPtr<IProjectFramework> m_ProjectFrameworkObject;
    HRESULT LoadAllAdins(BSTR strAddinLoadingInfo,
                         IProjectFramework* pProjectFramework);
    BOOL InvokeAddinMenuItem(UINT iCommandID);
    BOOL SetAddinVisible(CString strAddinName, BOOL bVisible);
    const CAddinInfo& GetAddinInformation(UINT iCommandID);
    const CAddinCommadInfo& GetAddinCommadInfo(UINT iCommandID);
    CAddinCommadInfo GetAddinCommadInfo(long iAddinIndex,long lIndex);
    BOOL AddAddinCommandInfo(long iAddinIndex, 
                             CAddinCommadInfo AddinCommadInfo);
    BOOL SetAddinCount(long lCount);
    BOOL UnloadAllAddins();
    CAddinInfo GetAddinInfo(long iAddinIndex);
    BOOL SetAddinInfo(long iAddinIndex,CAddinInfo AddinInfo);
    long GetAddinCount();
    void SetLoadAllAddinStatus(BOOL bLoadAllAddins);
    virtual BOOL GetLoadAllAddinStatus();
    CAddinInfo GetAddinIffo(CLSID clsID);

    BOOL LoadAllAddins();
    BOOL SaveAddinDefaultSettings();
    BOOL LoadAddinDefaultSettings();
    virtual ~CAddinManager();

This class uses a lot of other related classes like CAddinInfo which contains information's about each addin, IProjectFramework which is the interface exposed by the ProjectFramework application and IProjectFrameworkAddin interface which every pluggin should implement. Please see the source code for more details.The important blocks of codes in which the application built up is given below.

In CProjectFrameworkApp declare a variable of CAddinManager statically.

static CAddinManager m_AddinManager;
static CProjectFrameworkView* m_pView;


BOOL CProjectFrameworkApp::InitInstance()
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;

in CMainFrame






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

    //Load all addins

    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

    if (!m_wndStatusBar.Create(this) ||
        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


    //Remove File new and Open Commands
    return 0;

Points of Interest

In this version features implemented are.

  1. Dynamic Menus.
  2. Dynamic Toolbars.
  3. Help string and tool tip support.
  4. Invoking of methods in plugins from addin menu and toolbar.
  5. Automation support explained using a dialog box invoked from one of the plugins (Report Addin -> Sales report -> Todays Sales Report Ctrl + B menu ).
  6. Hiding of Menus and toolbar buttons (eg : File ->New and Open ).
  7. Key Board accelerator support for plugin.
  8. Loading / Unloading of addins.
  9. Connection point support for getting notification events from addins.


  • Initial Release : Dec 2, 2004
  • Added Connection Point support : Dec 10, 2004 <!------------------------------- That's it! --------------------------->


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

Chief Technology Officer KTS INFOTECH PVT LTD
India India
->9+ Years of Experience in IT Field.
->Basically a C++ Programmer migrating to .NET
->Have Masters degree in Physics and Computer Scince.
-> Doing his Ph.D(Part Time) in Optical Networking)
->Interests: Software product development,Networking, Robotics,Sports Physics, Learning musical instruments, Cricket.

->Resides in kerala ,the gods own country, with his mother and wife.

Home page

Comments and Discussions

Generalfails under VC2008 Pinmemberemmy20098-Jun-09 2:30 
Generalabout the framework Pinmemberpan xie22-Nov-07 22:46 
GeneralRe: about the framework Pinmemberthomas_tom9929-Nov-07 22:06 
Generalabout the framework Pinmemberpan xie22-Nov-07 22:45 
GeneralUsing a resource from an ATL COM MFC Component Pinmembercmacgowan7-Sep-07 10:43 
Hi thomas_tom99

Great work on this .... I have a question.

I would like to add a CFormView based object to the Addin and then access and use the view by my SDI MFC host application.

// Forms below are in DLLs.   We will need to get the handle for the
// resource in the DLL while the view is in use (selected)
hDLL = GetModuleHandle("Addin1.dll");
hEXE = AfxGetResourceHandle();
AfxSetResourceHandle((HINSTANCE) hDLL);
m_nAddin1View0 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CAddin1View0), pContext);
I get the following error:
MainFrm.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CAddin1View0::classCAddin1View0" (?classCAddin1View0@CAddin1View0@@2UCRuntimeClass@@B)
I have done this in the past with a standard MFC DLL. ??

Here is the addin and host code:

In Addin1.dll I have added the CFormView derived CAddin1View0 class.

class CAddin1View0 : public CFormView
     CAddin1View0();               // protected constructor used by dynamic creation

// Form Data
     enum { IDD = IDD_ADDIN1_VIEW0 };
          // NOTE: the ClassWizard will add data members here

// Attributes

// Operations

// Overrides
     // ClassWizard generated virtual function overrides
     virtual void OnInitialUpdate();
     virtual void DoDataExchange(CDataExchange* pDX);      // DDX/DDV support

// Implementation
     virtual ~CAddin1View0();
#ifdef _DEBUG
     virtual void AssertValid() const;
     virtual void Dump(CDumpContext& dc) const;

     // Generated message map functions
          // NOTE - the ClassWizard will add and remove member functions here.

In the host application I have a window splitter and would like one of four views to show in the horizontal pane.   I have created three test views in the host and am trying to gain access to the CFormView class using the method below.   This is how I did it with the MFC DLLs.   ???

I have removed some variable declaration and other non related code to make the test more readable.

I get the following error:
MainFrm.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CAddin1View0::classCAddin1View0" (?classCAddin1View0@CAddin1View0@@2UCRuntimeClass@@B)

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)

      if (!m_wndVerSplitter.CreateStatic(this,1,2))      // rows 1, columbs 2
           TRACE0("Failed to create split bar ");         
            return FALSE; // failed to create    


      CSize paneSize(cr.Width(), nHorizonalSplitterLoc);
      CSize paneSize1(cr.Width(), cr.Height() - nHorizonalSplitterLoc);

      // CSize cVertpaneSize(cr.Width(), nVerticalSplitterLoc);
      CSize cVertpaneSize(nVerticalSplitterLoc, cr.Height() - nHorizonalSplitterLoc);

      // create a pContext pointer if it is NULL
      if (pContext == NULL)
            pContext = new CCreateContext;

      // create the horizontal static splitter
      // We are nesting the horizontal splitter into the right pane of the
      // verital splitter.   So we have to do some messin around here
      // rows cols

     m_wndHorSplitter.CreateStatic(&m_wndVerSplitter, 2, 1, WS_CHILD | WS_VISIBLE,
                                                m_wndVerSplitter.IdFromRowCol(0, 1));

      // create the top part of right pane of the splitter (row cols)
     pContext->m_pCurrentFrame = this;
     m_wndHorSplitter.CreateView(0, 0, pContext->m_pNewViewClass, paneSize, pContext);

      // We will set up the various forms that will be able to be set
      // as the program is running.   Note:   The order of these view classes may
      // be significant.   We are doing some research.   When you put the
      // CTransactionFormView then we have some strange crashing!!

     m_nView0 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CMasConsoleTestView), pContext);
     m_nView1 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CMasConsoleTestView1), pContext);
     m_nView2 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CMasConsoleTestView2), pContext);

      // Forms below are in DLLs.   We will need to get the handle for the
      // resource in the DLL while the view is in use (selected)
      hDLL = GetModuleHandle("Addin1.dll");
      hEXE = AfxGetResourceHandle();
      AfxSetResourceHandle((HINSTANCE) hDLL);
     m_nAddin1View0 = m_wndHorSplitter.AddView(1, 0, RUNTIME_CLASS(CAddin1View0), pContext);

      nCurrentHorizHeight = 123;
     m_wndHorSplitter.SetRowInfo(0, nCurrentHorizHeight, nMinHorizHeight);



      return rc;    

void CMainFrame::SetActiveView(int nViewIndex)
     switch (nViewIndex)
          case 0:

          case 1:

          case 2:

          case 3:

          case 4:


Again, I get the following error.

MainFrm.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CAddin1View0::classCAddin1View0" (?classCAddin1View0@CAddin1View0@@2UCRuntimeClass@@B)

When I comment out referecnes to the CAddin1View0 class then I'm ok.   Any comments or ideas.  

GeneralRe: Using a resource from an ATL COM MFC Component Pinmemberthomas_tom9912-Sep-07 1:42 
QuestionHandling view related msg in Addin Pinmembersharathgowda19-Aug-07 22:44 
AnswerRe: Handling view related msg in Addin Pinmemberthomas_tom9928-Aug-07 21:15 
QuestionIs this work fine under vs2005? Pinmemberzhms25-Apr-07 6:33 
AnswerRe: Is this work fine under vs2005? Pinmemberthomas_tom9930-Apr-07 0:34 
GeneralNeed to add the project types in 2005 Pinmemberkarabagamoorthy16-Nov-06 17:46 
GeneralRe: Need to add the project types in 2005 Pinmemberthomas_tom9917-Nov-06 16:31 
Generalsupprt for controls in toolbars Pinmemberbensabat6-Nov-05 23:09 
GeneralRe: supprt for controls in toolbars Pinmemberthomas_tom9910-Nov-05 4:30 
GeneralA problem with the app toolbar Pinmemberbensabat24-Oct-05 0:08 
GeneralRe: A problem with the app toolbar Pinmemberthomas_tom9926-Oct-05 23:09 
GeneralRe: A problem with the app toolbar Pinmemberbensabat27-Oct-05 1:32 
GeneralRe: A problem with the app toolbar Pinmemberthomas_tom9927-Oct-05 2:54 
GeneralRe: A problem with the app toolbar Pinmemberbensabat27-Oct-05 3:15 
Generala Problem with MDI application Pinmemberbensabat11-Oct-05 2:27 
GeneralRe: a Problem with MDI application Pinmemberthomas_tom9912-Oct-05 20:10 
GeneralRe: a Problem with MDI application Pinmemberbensabat13-Oct-05 21:36 
GeneralRe: a Problem with MDI application Pinmemberbensabat17-Oct-05 21:31 
GeneralRe: a Problem with MDI application Pinmemberthomas_tom9927-Oct-05 3:22 
GeneralMemory leak! with fix solution. PinmemberHarveyLiu19-Aug-05 1:57 

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.150414.1 | Last Updated 10 Dec 2004
Article Copyright 2004 by thomas_tom99
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid