admin 发表于 2024-9-26 10:33:16

C++和CSharp增加AutoCAD的菜单menu

void
addMenuThroughCom()
{

    AutoCAD::IAcadApplication *pAcad;
    AutoCAD::IAcadMenuBar *pMenuBar;
    AutoCAD::IAcadMenuGroups *pMenuGroups;
    AutoCAD::IAcadMenuGroup *pMenuGroup;
    AutoCAD::IAcadPopupMenus *pPopUpMenus;
    AutoCAD::IAcadPopupMenu *pPopUpMenu;
    AutoCAD::IAcadPopupMenuItem *pPopUpMenuItem;

    HRESULT hr = NOERROR;
    LPUNKNOWN pUnk = NULL;
    LPDISPATCH pAcadDisp = acedGetIDispatch(TRUE);
    if(pAcadDisp==NULL)
      return;

    hr = pAcadDisp->QueryInterface(AutoCAD::IID_IAcadApplication,(void**)&pAcad);
    pAcadDisp->Release();
    if (FAILED(hr))
      return;

    pAcad->put_Visible(true);
    pAcad->get_MenuBar(&pMenuBar);
    pAcad->get_MenuGroups(&pMenuGroups);
    pAcad->Release();
    long numberOfMenus;
    pMenuBar->get_Count(&numberOfMenus);
    pMenuBar->Release();

    VARIANT index;
    VariantInit(&index);
    V_VT(&index) = VT_I4;
    V_I4(&index) = 0;

    pMenuGroups->Item(index, &pMenuGroup);
    pMenuGroups->Release();
   
    pMenuGroup->get_Menus(&pPopUpMenus);
    pMenuGroup->Release();

    WCHAR wstrMenuName;
    #ifdef UNICODE
      _tcscpy(wstrMenuName, L"AsdkComAccess");
    #else// !UNICODE
      MultiByteToWideChar(CP_ACP, 0, "AsdkComAccess", -1, wstrMenuName, 256);
    #endif // !UNICODE

    // Enables the menu to be loaded/unloaded with the same command.
    if (!bIsMenuLoaded) {
      pPopUpMenus->Add(wstrMenuName, &pPopUpMenu);

      if (pPopUpMenu != NULL) {

            WCHAR wstrMenuItemName;
            WCHAR wstrMenuItemMacro;
            #ifdef UNICODE
                _tcscpy(wstrMenuItemName, L"&Add A ComCircle");
                _tcscpy(wstrMenuItemMacro, L"AsdkComCircle ");
            #else// !UNICODE
                MultiByteToWideChar(CP_ACP, 0, "&Add A ComCircle", -1, wstrMenuItemName, 256);
                MultiByteToWideChar(CP_ACP, 0, "AsdkComCircle ", -1, wstrMenuItemMacro, 256);
            #endif // !UNICODE

            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 0;
            pPopUpMenu->AddMenuItem(index, wstrMenuItemName, wstrMenuItemMacro, &pPopUpMenuItem);

            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 1;
            pPopUpMenu->AddSeparator(index, &pPopUpMenuItem);

            #ifdef UNICODE
                _tcscpy(wstrMenuItemName, L"Auto&LISP Example");
                _tcscpy(wstrMenuItemMacro, L"(prin1 /"Hello/") ");
            #else// !UNICODE
                MultiByteToWideChar(CP_ACP, 0, "Auto&LISP Example", -1, wstrMenuItemName, 256);
                MultiByteToWideChar(CP_ACP, 0, "(prin1 /"Hello/") ", -1, wstrMenuItemMacro, 256);
            #endif // !UNICODE

            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 2;
            pPopUpMenu->AddMenuItem(index, wstrMenuItemName, wstrMenuItemMacro, &pPopUpMenuItem);

            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = numberOfMenus - 2;
            pPopUpMenu->InsertInMenuBar(index);
   
            pPopUpMenuItem->Release();
            bIsMenuLoaded = true;
      } else {
            acutPrintf(_T("/nMenu not created."));
      }
    } else {
      VariantInit(&index);
      V_VT(&index) = VT_BSTR;
      V_BSTR(&index) = wstrMenuName;
      pPopUpMenus->RemoveMenuFromMenuBar(index);
      VariantClear(&index);
      bIsMenuLoaded = false;
    }

    pPopUpMenus->Release();
}
二 C++基于MFC的

void
addMenuThroughMfcCom()
{
    TRY
    {
      CAcadApplication IAcad(acedGetAcadWinApp()->GetIDispatch(TRUE));

      CAcadMenuBar IMenuBar(IAcad.get_MenuBar());

      long numberOfMenus;
      numberOfMenus = IMenuBar.get_Count();

      CAcadMenuGroups IMenuGroups(IAcad.get_MenuGroups());

      VARIANT index;
      VariantInit(&index);
      V_VT(&index) = VT_I4;
      V_I4(&index) = 0;

      CAcadMenuGroup IMenuGroup(IMenuGroups.Item(index));

      CAcadPopupMenus IPopUpMenus(IMenuGroup.get_Menus());

      CString cstrMenuName = _T("AsdkComAccess");

      VariantInit(&index);
      V_VT(&index) = VT_BSTR;
      V_BSTR(&index) = cstrMenuName.AllocSysString();

      IDispatch* pDisp=NULL;

      //see if the menu is already there
      TRY{pDisp = IPopUpMenus.Item(index); pDisp->AddRef();} CATCH(COleDispatchException,e){}END_CATCH;

      if (pDisp==NULL) {
            //create it
            CAcadPopupMenu IPopUpMenu(IPopUpMenus.Add(cstrMenuName));

            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 0;
            IPopUpMenu.AddMenuItem(index, _T("&Add A ComCircle"), _T("_AsdkMfcComCircle "));

            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 1;
            IPopUpMenu.AddSeparator(index);

            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = 2;
            IPopUpMenu.AddMenuItem(index, _T("Auto&LISP Example"), _T("(prin1 /"Hello/") "));

            pDisp = IPopUpMenu.m_lpDispatch;
            pDisp->AddRef();
      }

      CAcadPopupMenu IPopUpMenu(pDisp);
      if (!IPopUpMenu.get_OnMenuBar())
      {
            VariantInit(&index);
            V_VT(&index) = VT_I4;
            V_I4(&index) = numberOfMenus - 2;;
            IPopUpMenu.InsertInMenuBar(index);
      }
      else
      {
            VariantInit(&index);
            V_VT(&index) = VT_BSTR;
            V_BSTR(&index) = cstrMenuName.AllocSysString();
            IPopUpMenus.RemoveMenuFromMenuBar(index);
            VariantClear(&index);
      }
      pDisp->Release();
    }
    CATCH(COleDispatchException,e)
    {
      e->ReportError();
      e->Delete();
    }
    END_CATCH;
}

三 C#基于COM接口

usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Diagnostics;
usingSystem.Runtime.InteropServices;

usingAutodesk.AutoCAD.Interop;
usingAutodesk.AutoCAD.Interop.Common;

usingAutodesk.AutoCAD.ApplicationServices;
usingAutodesk.AutoCAD.Runtime;

namespaceCSharpCOM
{
    public class Class1
    {
      public Class1() { }

      
      public static void AddMenuCom()
      {
            AcadApplication app = (AcadApplication)Marshal.GetActiveObject("AutoCAD.Application.17");
            AcadMenuBar menuBar = app.MenuBar;
            AcadMenuGroup menuGroup = app.MenuGroups.Item(0);
            AcadPopupMenus menus = menuGroup.Menus;
            AcadPopupMenu mymenu = menus.Add("MyMenu");

            mymenu.AddMenuItem(0, "Hello", "hello");
            mymenu.AddSeparator(1);
            mymenu.AddMenuItem(2, "Hello2", "hello");
            AcadPopupMenu ext = mymenu.AddSubMenu(3, "Ext");
            ext.AddMenuItem(0, "Hello", "hello");
            ext.AddSeparator(1);
            ext.AddMenuItem(2, "Hello2", "hello");
            mymenu.InsertInMenuBar(menuBar.Count - 2);
      }

      
      public static void Hello()
      {
            AcadApplication app = (AcadApplication)Marshal.GetActiveObject("AutoCAD.Application.17");
            app.ActiveDocument.Utility.Prompt("Hello/n");
      }


    }
}


四 CSharp基于ACUI.DLL接口的

//Copyright 2005-2007 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.AUTODESK, INC.
usingSystem;
usingSystem.IO;

usingSystem.Runtime.InteropServices;
usingSystem.Text;

usingAutodesk.AutoCAD.Runtime;
usingAutodesk.AutoCAD.ApplicationServices;
usingAutodesk.AutoCAD.EditorInput;
usingAutodesk.AutoCAD.DatabaseServices;

usingAutodesk.AutoCAD.Customization;



namespaceCuiSamp
{

    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    public class CuiSamp
    {
      members

      //Default Constructor
      public CuiSamp()
      {
            // retrieve the location of, and open the ACAD Main CUI File
            string mainCuiFile = (string)Application.GetSystemVariable("MENUNAME");
            mainCuiFile += ".cui";
            cs = new CustomizationSection(mainCuiFile);

            string entCuiFile = (string)Application.GetSystemVariable("ENTERPRISEMENU");
            if (entCuiFile.Equals("."))
                entCsLoaded = false;
            else
            {
                entCs = new CustomizationSection(entCuiFile);
                entCsLoaded = true;
            }

            // Code for loading all partial CUI's listed in the main CUI file

            partials = new CustomizationSection;
            int i = 0;
            foreach (string fileName in cs.PartialCuiFiles)
            {
                if (File.Exists(fileName))
                {
                  partials = new CustomizationSection(fileName);
                  i++;
                }
            }
            numPartialFiles = i;
      }


      // Command: savecui
      // This Command saves all open CUI Files that have been modified
      
      public void saveCui()
      {
            // Save all Changes made to the CUI file in this session.
            // If changes were made to the Main CUI file - save it
            // If changes were made to teh Partial CUI files need to save them too

            if (cs.IsModified)
                cs.Save();

            for (int i = 0; i < numPartialFiles; i++)
            {
                if (partials.IsModified)
                  partials.Save();
            }

            if (entCsLoaded && entCs.IsModified)
                entCs.Save();

            // Here we unload and reload the main CUI file so the changes to the CUI file could take effect immediately.
            //string flName = cs.CUIFileBaseName;
            //Application.SetSystemVariable("FILEDIA", 0);
            //Application.DocumentManager.MdiActiveDocument.SendStringToExecute("cuiunload " + flName + " ", false, false, false);
            //Application.DocumentManager.MdiActiveDocument.SendStringToExecute("cuiload " + flName + " filedia 1 ", false, false, false);
            //Application.SetSystemVariable("FILEDIA", 1);
      }

      // Command: addmenu
      // This Command adds a new menu to all workspaces called Custom Menu, which contains 2 sub items
      // The Menu is first added to the Main CUI File and then added to all it's workspaces.
      
      public void addMenu()
      {
            if (cs.MenuGroup.PopMenus.IsNameFree("CustomMenu"))
            {

                System.Collections.Specialized.StringCollection pmAliases = new System.Collections.Specialized.StringCollection();
                pmAliases.Add("POP12");

                PopMenu pm = new PopMenu("CustomMenu", pmAliases, "CustomMenu", cs.MenuGroup);

                addItemsToPM(pm);
                addMenu2Workspaces(pm);
            }
            else
                ed.WriteMessage("CustomMenu already Exists/n");
      }


      // Add new Items to a PopMenu
      private void addItemsToPM(PopMenu pm)
      {
            PopMenuItem pmi = new PopMenuItem(pm, -1);
            pmi.MacroID = "ID_AUGI"; pmi.Name = "Autodesk User Group International";

            pmi = new PopMenuItem(pm, -1);

            pmi = new PopMenuItem(pm, -1);
            pmi.MacroID = "ID_CustomSafe"; pmi.Name = "Online Developer Center";
      }

      // Add the menu to all the workspaces
      private void addMenu2Workspaces(PopMenu pm)
      {
            foreach (Workspace wk in cs.Workspaces)
            {
                WorkspacePopMenu wkpm = new WorkspacePopMenu(wk, pm);
                wkpm.Display = 1;
            }

      }

      // Command: remmenu
      // This Command deletes the menu added above from the Main CUI File and any
      //workspaces that it was added to.
      
      public void remMenu()
      {
            // Find Index of the desired MenuItem
            // Remove it from all Workspaces that it exists in
            // Omitting this step leaves nasty left-overs in the Workspace files
            // Remove it from the Cui files' Menu List

            PopMenu pm = cs.MenuGroup.PopMenus.FindPopWithAlias("POP12");
            if (pm != null)
            {
                foreach (Workspace wk in cs.Workspaces)
                {
                  WorkspacePopMenu wkPm = wk.WorkspacePopMenus.FindWorkspacePopMenu(pm.ElementID, pm.Parent.Name);

                  if (wkPm != null)
                        wk.WorkspacePopMenus.Remove(wkPm);
                }
                cs.MenuGroup.PopMenus.Remove(pm);    // Deletes the Menu from ACAD Menu Group
            }
      }


      // Command: addtoolbar
      // Creates a new toolbar called "New Toolbar", and adds it to all workspaces.
      // This toolbar contains a Toolbar control for named view, button for drawing
      // a pline, and a flyout that uses the "Draw" tool bar.
      
      public void addToolbar()
      {
            Toolbar newTb = new Toolbar("New Toolbar", cs.MenuGroup);
            newTb.ToolbarOrient = ToolbarOrient.floating;
            newTb.ToolbarVisible = ToolbarVisible.show;

            ToolbarControl tbCtrl = new ToolbarControl(ControlType.NamedViewControl, newTb, -1);

            ToolbarButton tbBtn = new ToolbarButton(newTb, -1);
            tbBtn.Name = "PolyLine";
            tbBtn.MacroID = "ID_Pline";

            ToolbarFlyout tbFlyout = new ToolbarFlyout(newTb, -1);
            tbFlyout.ToolbarReference = "DRAW";

            foreach (Workspace wk in cs.Workspaces)
            {
                WorkspaceToolbar wkTb = new WorkspaceToolbar(wk, newTb);
                wk.WorkspaceToolbars.Add(wkTb);
                wkTb.Display = 1;
            }
      }

      // Command: remtoolbar
      // This Command removes the toolbar added above from the Main CUI File and any
      // workspaces that it was added to.
      
      public void remToolbar()
      {
            Toolbar tbr = cs.MenuGroup.Toolbars.FindToolbarWithName("New Toolbar");
            if (tbr != null)
            {
                foreach (Workspace wk in cs.Workspaces)
                {
                  WorkspaceToolbar wkTb = wk.WorkspaceToolbars.FindWorkspaceToolbar(tbr.ElementID, tbr.Parent.Name);

                  if (wkTb != null)
                        wk.WorkspaceToolbars.Remove(wkTb);
                }
                cs.MenuGroup.Toolbars.Remove(tbr);    // Deletes the toolbar from ACAD Menu Group
            }
      }


      // Command: cuiall
      // Issuing this command will run the methods to make all changes to the UI
      // This will add the custom menu, toolbar, and shortcut, as well as
      // dock the Properties palette on the right side.
      
      public void AddMenuAndToobar()
      {
            addMenu();
            addToolbar();
            saveCui();
      }

      
      public void RemMenuAndToolbar()
      {
            remMenu();
            remToolbar();
            saveCui();
      }
    }

}
页: [1]
查看完整版本: C++和CSharp增加AutoCAD的菜单menu