Add-In: How to add a menu item into Visual Studio 6.0 IDE using VC++? RRS feed

  • Question

  • How can I add a menu item into Visual Studio 6.0 IDE from an Add-In developed in Visual C++? Is it possible at all?

    When I create a simple addin using the Add-In wizard it adds a tool bar button, but not a menu item.
    I found only examples and articles related to .NET (C# and VB) and higher versions of VS.

    I appreciate your help.

    Friday, August 12, 2011 7:55 AM

All replies

  • You can do it the same way as the code that adds a toolbar item, I assume it is using DTE?  The only difference is in how you get to the CommandBarControl that represents the menu you want to add to.  The wizard code probably uses something like


    if you said


    you would get the main menu, from there you can use the Controls collection to find the specific menu you want to add to.


    Friday, August 12, 2011 3:09 PM
  • Ryan, I'm not using DTE because seems that the 6.0 version of Visual Studio doesn't offer support to it, only VS 7.1 (2003) and higher versions. (or maybe I'm wrong?)

    When I create a simple project using the wizard, I have the following interfaces for usage:

    in DsAddin.h:

    IDSAddIn - objmodel\addauto.h

    in Commands.h:


    IApplication - objmodel\appauto.h

    I couldn't find anything useful related to IApplication and menus.

    Saturday, August 13, 2011 12:50 AM
  • Hmmm, I know nothing about VS 6.0, I don't even think I could find a copy locally to install :(  What kind of methods are they calling to add to the toolbar?


    Saturday, August 13, 2011 1:21 AM
  • Hey Ryan, thanks for your time.

    AddCommandBarButton() of IApplication interface is called from OnConnection event of IDSAddIn:


    STDMETHODIMP CDSAddIn::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime, long dwCookie, 
    VARIANT_BOOL* OnConnection) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); IApplication* pApplication = NULL; if (FAILED(pApp->QueryInterface(IID_IApplication, (void**) &pApplication)) || pApplication == NULL) { *OnConnection = VARIANT_FALSE; return S_OK; } m_dwCookie = dwCookie; CCommandsObj::CreateInstance(&m_pCommands); m_pCommands->AddRef(); m_pCommands->SetApplicationObject(pApplication); VERIFY_OK(pApplication->SetAddInInfo((long) AfxGetInstanceHandle(), (LPDISPATCH) m_pCommands,
    IDR_TOOLBAR_MEDIUM, IDR_TOOLBAR_LARGE, m_dwCookie)); // The tooltip, command description, and other strings related // to this command are stored in the string table // (IDS_CMD_STRING) and should be localized. LPCTSTR szCommand = _T("MyAddinCommand"); VARIANT_BOOL bRet; CString strCmdString; strCmdString.LoadString(IDS_CMD_STRING); strCmdString = szCommand + strCmdString; CComBSTR bszCmdString(strCmdString); CComBSTR bszMethod(_T("MyAddinCommandMethod")); CComBSTR bszCmdName(szCommand); VERIFY_OK(pApplication->AddCommand(bszCmdString, bszMethod, 0, m_dwCookie, &bRet)); if (bRet == VARIANT_FALSE) { // AddCommand failed because a command with this name already // exists. You may try adding your command under a different name. // Or, you can fail to load as we will do here. *OnConnection = VARIANT_FALSE; return S_OK; } // Add toolbar buttons only if this is the first time the add-in // is being loaded. Toolbar buttons are automatically remembered // by Developer Studio from session to session, so we should only // add the toolbar buttons once. if (bFirstTime == VARIANT_TRUE) { VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie)); } *OnConnection = VARIANT_TRUE; return S_OK; }

    If it helps, here is the IApplication interface:

    // Application object
    // IApplication interface
    #undef INTERFACE
    #define INTERFACE IApplication
    DECLARE_INTERFACE_(IApplication, IDispatch)
     /* IUnknown methods */
     STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID FAR* ppvObj) PURE;
     /* IDispatch methods */
     STDMETHOD(GetTypeInfoCount)(THIS_ UINT FAR* pctinfo) PURE;
      UINT itinfo,
      LCID lcid,
      ITypeInfo FAR* FAR* pptinfo) PURE;
      REFIID riid,
      OLECHAR FAR* FAR* rgszNames,
      UINT cNames,
      LCID lcid,
      DISPID FAR* rgdispid) PURE;
      DISPID dispidMember,
      REFIID riid,
      LCID lcid,
      WORD wFlags,
      DISPPARAMS FAR* pdispparams,
      VARIANT FAR* pvarResult,
      EXCEPINFO FAR* pexcepinfo,
      UINT FAR* puArgErr) PURE;
     /* IApplication methods */
     STDMETHOD(get_Height)(THIS_ long FAR* Height) PURE;
     STDMETHOD(put_Height)(THIS_ long Height) PURE;
     STDMETHOD(get_Width)(THIS_ long FAR* Width) PURE;
     STDMETHOD(put_Width)(THIS_ long Width) PURE;
     STDMETHOD(get_Top)(THIS_ long FAR* Top) PURE;
     STDMETHOD(put_Top)(THIS_ long Top) PURE;
     STDMETHOD(get_Left)(THIS_ long FAR* Left) PURE;
     STDMETHOD(put_Left)(THIS_ long Left) PURE;
     STDMETHOD(get_Name)(THIS_ BSTR FAR* Name) PURE;
     STDMETHOD(get_TextEditor)(THIS_ IDispatch * FAR* texteditor) PURE;
     STDMETHOD(get_Version)(THIS_ BSTR FAR* Version) PURE;
     STDMETHOD(get_Path)(THIS_ BSTR FAR* Path) PURE;
     STDMETHOD(get_CurrentDirectory)(THIS_ BSTR FAR* CurrentDirectory) PURE;
     STDMETHOD(put_CurrentDirectory)(THIS_ BSTR CurrentDirectory) PURE;
     STDMETHOD(get_FullName)(THIS_ BSTR FAR* FullName) PURE;
     STDMETHOD(get_Application)(THIS_ IDispatch * FAR* Application) PURE;
     STDMETHOD(get_Parent)(THIS_ IDispatch * FAR* Parent) PURE;
     STDMETHOD(get_ActiveDocument)(THIS_ IDispatch * FAR* ActiveDocument) PURE;
     STDMETHOD(get_Windows)(THIS_ IDispatch * FAR* Windows) PURE;
     STDMETHOD(get_Documents)(THIS_ IDispatch * FAR* Documents) PURE;
     STDMETHOD(get_ActiveWindow)(THIS_ IDispatch * FAR* ActiveWindow) PURE;
     STDMETHOD(get_WindowState)(THIS_ DsWindowState FAR* windowstate) PURE;
     STDMETHOD(put_WindowState)(THIS_ DsWindowState windowstate) PURE;
     STDMETHOD(get_Debugger)(THIS_ IDispatch * FAR* ppDebugger) PURE;
     STDMETHOD(get_Projects)(THIS_ IDispatch * FAR* Projects) PURE;
     STDMETHOD(get_ActiveConfiguration)(THIS_ IDispatch * FAR* ActiveConfiguration) PURE;
     STDMETHOD(put_ActiveConfiguration)(THIS_ IDispatch * ActiveConfiguration) PURE;
     STDMETHOD(get_Visible)(THIS_ VARIANT_BOOL FAR* Visible) PURE;
     STDMETHOD(put_Visible)(THIS_ VARIANT_BOOL Visible) PURE;
     STDMETHOD(get_ActiveProject)(THIS_ IDispatch * FAR* ActiveProject) PURE;
     STDMETHOD(put_ActiveProject)(THIS_ IDispatch * ActiveProject) PURE;
     STDMETHOD(put_Active)(THIS_ VARIANT_BOOL bActive) PURE;
     STDMETHOD(get_Active)(THIS_ VARIANT_BOOL FAR* pbActive) PURE;
     STDMETHOD(GetPackageExtension)(THIS_ BSTR szExtensionName, IDispatch * FAR* pExt) PURE;
     STDMETHOD(PrintToOutputWindow)(THIS_ BSTR Message) PURE;
     STDMETHOD(ExecuteCommand)(THIS_ BSTR szCommandName) PURE;
     STDMETHOD(AddCommandBarButton)(THIS_ long nButtonType, BSTR szCmdName, long dwCookie) PURE;
     STDMETHOD(AddKeyBinding)(THIS_ BSTR szKey, BSTR szCommandName, BSTR szEditor) PURE;
     STDMETHOD(Build)(THIS_ VARIANT Configuration) PURE;
     STDMETHOD(RebuildAll)(THIS_ VARIANT configuration) PURE;
     STDMETHOD(ExecuteConfiguration)(THIS_ VARIANT Reserved) PURE;
     STDMETHOD(SetAddInInfo)(THIS_ long nInstanceHandle, IDispatch * pCmdDispatch, long nIDBitmapResourceMedium, 
    nIDBitmapResourceLarge, long dwCookie) PURE; STDMETHOD(AddCommand)(THIS_ BSTR szCmdName, BSTR szMethodName, long nBitmapOffset, long dwCookie,
    VARIANT_BOOL FAR* pbResult) PURE; STDMETHOD(EnableModeless)(THIS_ VARIANT_BOOL bEnable) PURE; STDMETHOD(Clean)(THIS_ VARIANT configuration) PURE; STDMETHOD(get_Errors)(THIS_ long FAR* nErrors) PURE; STDMETHOD(get_Warnings)(THIS_ long FAR* nWarnings) PURE; STDMETHOD(AddProject)(THIS_ BSTR szName, BSTR szPath, BSTR szType, VARIANT_BOOL bAddDefaultFolders) PURE; }; // IApplicationEvents interface



    Sunday, August 14, 2011 9:05 AM
  • Hi Paul,

    As far as I know, VC++ 6 is out of its lifecycle and out of support now.  As Ryan said, for newer version of VS, they supports DTE and Package which will make your life easier.



    Yi Feng Li [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, August 15, 2011 10:38 AM
  • I tried digging through the source code (I found it), and it doesn't appear on first glance to be supported.  If you notice there is no way to specify in AddCommandBarControl WHERE you want to put it. Internally it looks for who created the command you are placing and puts it on their toolbar, apparently in VC6 every package had their own toolbar, later versions moved to a model where you could have a toolbar if you wanted, but didn't have to, and you could contribute to any menu/toolbar in the app.


    Tuesday, August 16, 2011 4:22 PM