vbnet 实现AutoCAD自定义菜单和工具栏

87 篇文章 16 订阅
79 篇文章 4 订阅
这个代码示例展示了如何在AutoCAD中创建自定义用户界面,包括菜单、工具栏和右键菜单。通过加载CUI文件,并添加宏来实现命令执行,如直线、多段线、矩形等绘图操作。此外,还实现了双击多段线执行自定义命令以及添加默认和对象上下文菜单,提供更便捷的用户交互体验。
摘要由CSDN通过智能技术生成
Imports System
Imports System.Collections.Generic
Imports System.Collections.Specialized
Imports System.Linq
Imports System.Text
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Customization
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Runtime
Imports AutoCAD转.DotNetARX
Imports Autodesk.AutoCAD.Windows

Namespace CUIExample
    Public Class CUIExample
        Private ReadOnly cuiFile As String = Tools.GetCurrentPath() & "\MyCustom.cui"
        Private menuGroupName As String = "MyCustom"
        Private activeDoc As Document = Application.DocumentManager.MdiActiveDocument

        Public Sub New()
            AddHandler Application.QuitWillStart, New EventHandler(AddressOf Application_QuitWillStart)
        End Sub

        Private Sub Application_QuitWillStart(ByVal sender As Object, ByVal e As EventArgs)
            '’由于触发此事件前文档已关闭,所以需通过模板重建,以便命令能够执行
            Dim doc As Document = Application.DocumentManager.Add("acadiso.dwt")
            '’获取FILEDIA系统变量的值
            Dim oldFileDia As Object = Application.GetSystemVariable("FILEDIA")
            ''
            Application.SetSystemVariable("FILEDIA", 0)
            Dim mainCs As CustomizationSection = doc.GetMainCustomizationSection()
            If mainCs.PartialCuiFiles.Contains(cuiFile) Then doc.Editor.PostCommand("cuiunload " & menuGroupName & " ")
            Application.SetSystemVariable("FILEDIA", oldFileDia)
        End Sub

        <CommandMethod("AddMenu")>
        Public Sub AddMenu()
            Dim currentPath As String = Tools.GetCurrentPath()
            Dim cs As CustomizationSection = activeDoc.AddCui(cuiFile, menuGroupName)

            cs.AddMacro("直线", "^C^C_Line ", "ID_MyLine", "创建直线段:   LINE", currentPath & "\Image\Line.BMP")
            cs.AddMacro("多段线", "^C^C_Pline ", "ID_MyPLine", "创建二维多段线:  PLINE", currentPath & "\Image\Polyline.BMP")
            cs.AddMacro("矩形", "^C^C_Rectang ", "ID_MyRectang", "创建矩形多段线:  RECTANG", currentPath & "\Image\Rectangle.BMP")
            cs.AddMacro("圆", "^C^C_circle ", "ID_MyCircle", "用指定半径创建圆:   CIRCLE", currentPath & "\Image\Circle.BMP")
            cs.AddMacro("复制", "^C^CCopy ", "ID_MyCopy", "复制对象:   COPY", currentPath & "\Image\Copy.BMP")
            cs.AddMacro("删除", "^C^CErase ", "ID_MyErase", "从图形删除对象:   ERASE", currentPath & "\Image\Erase.BMP")
            cs.AddMacro("移动", "^C^CMove ", "ID_MyMove", "将对象在指定方向上平移指定的距离:  MOVE", currentPath & "\Image\Move.BMP")
            cs.AddMacro("旋转", "^C^CRotate ", "ID_MyRotate", "绕基点旋转对象:  ROTATE", currentPath & "\Image\Rotate.BMP")
            Dim sc As StringCollection = New StringCollection()
            sc.Add("MyPop1")
            Dim myMenu As PopMenu = cs.MenuGroup.AddPopMenu("我的菜单", sc, "ID_MyMenu")

            If myMenu IsNot Nothing Then
                myMenu.AddMenuItem(-1, "直线", "ID_MyLine")
                myMenu.AddMenuItem(-1, "多段线", "ID_MyPLine")
                myMenu.AddMenuItem(-1, "矩形", "ID_MyRectang")
                myMenu.AddMenuItem(-1, "圆", "ID_MyCircle")
                myMenu.AddSeparator(-1)
                Dim menuModify As PopMenu = myMenu.AddSubMenu(-1, "修改", "ID_MyModify")
                menuModify.AddMenuItem(-1, "复制", "ID_MyCopy")
                menuModify.AddMenuItem(-1, "删除", "ID_MyErase")
                menuModify.AddMenuItem(-1, "移动", "ID_MyMove")
                menuModify.AddMenuItem(-1, "旋转", "ID_MyRotate")
            End If

            cs.LoadCui()
        End Sub

        <CommandMethod("AddToolbar")>
        Public Sub AddToolbar()
            Dim currentPath As String = Tools.GetCurrentPath()
            Dim cs As CustomizationSection = activeDoc.AddCui(cuiFile, menuGroupName)
            cs.AddMacro("直线", "^C^CModalDialog ", "ID_MyLine", "创建直线段:   LINE", currentPath & "\Image\Line.BMP")
            cs.AddMacro("多段线", "^C^C_Pline ", "ID_MyPLine", "创建二维多段线:  PLINE", currentPath & "\Image\Polyline.BMP")
            cs.AddMacro("矩形", "^C^C_Rectang ", "ID_MyRectang", "创建矩形多段线:  RECTANG", currentPath & "\Image\Rectangle.BMP")
            cs.AddMacro("圆", "^C^C_circle ", "ID_MyCircle", "用指定半径创建圆:   CIRCLE", currentPath & "\Image\Circle.BMP")
            cs.AddMacro("复制", "^C^CCopy ", "ID_MyCopy", "复制对象:   COPY", currentPath & "\Image\Copy.BMP")
            cs.AddMacro("删除", "^C^CErase ", "ID_MyErase", "从图形删除对象:   ERASE", currentPath & "\Image\Erase.BMP")
            cs.AddMacro("移动", "^C^CMove ", "ID_MyMove", "将对象在指定方向上平移指定的距离:  MOVE", currentPath & "\Image\Move.BMP")
            cs.AddMacro("旋转", "^C^CRotate ", "ID_MyRotate", "绕基点旋转对象:  ROTATE", currentPath & "\Image\Rotate.BMP")

            Dim barDraw As Toolbar = cs.MenuGroup.AddToolbar("我的工具栏")
            barDraw.AddToolbarButton(-1, "直线", "ID_MyLine")
            barDraw.AddToolbarButton(-1, "多段线", "ID_MyPLine")
            barDraw.AddToolbarButton(-1, "矩形", "ID_MyRectang")
            barDraw.AddToolbarButton(-1, "圆", "ID_MyCircle")
            Dim barModify As Toolbar = cs.MenuGroup.AddToolbar("修改工具栏")
            Dim buttonCopy As ToolbarButton = barModify.AddToolbarButton(-1, "复制", "ID_MyCopy")
            Dim buttonErase As ToolbarButton = barModify.AddToolbarButton(-1, "删除", "ID_MyErase")
            Dim buttonMove As ToolbarButton = barModify.AddToolbarButton(-1, "移动", "ID_MyMove")
            Dim buttonRotate As ToolbarButton = barModify.AddToolbarButton(-1, "旋转", "ID_MyRotate")
            barDraw.AttachToolbarToFlyout(-1, barModify)
            cs.LoadCui()
        End Sub

        <CommandMethod("AddDoubleClick")>
        Public Sub AddDoubleClick()
            Dim cs As CustomizationSection = activeDoc.AddCui(cuiFile, menuGroupName)
            Dim macro As MenuMacro = cs.AddMacro("多段线 - 双击", "^C^C_DoubleClickPline ", "ID_PlineDoubleClick", "调用自定义命令", Nothing)
            Dim action As DoubleClickAction = New DoubleClickAction(cs.MenuGroup, "优化多段线", -1)
            action.ElementID = "EID_mydblclick"
            action.DxfName = RXClass.GetClass(GetType(Polyline)).DxfName
            Dim cmd As DoubleClickCmd = New DoubleClickCmd(action, macro)
            action.DoubleClickCmd = cmd
            cs.LoadCui()
        End Sub

        <CommandMethod("DoubleClickPline")>
        Public Sub DoubleClickPline()
            Application.ShowAlertDialog("你双击了多段线!")
        End Sub

        <CommandMethod("AddDefaultContextMenu")>
        Public Sub AddDefaultContextMenu()
            Dim contextMenu As ContextMenuExtension = New ContextMenuExtension()
            contextMenu.Title = "我的快捷菜单"
            Dim mi As MenuItem = New MenuItem("复制")
            AddHandler mi.Click, New EventHandler(AddressOf mi_Click)
            contextMenu.MenuItems.Add(mi)
            mi = New MenuItem("删除")
            AddHandler mi.Click, New EventHandler(AddressOf mi_Click)
            contextMenu.MenuItems.Add(mi)
            Application.AddDefaultContextMenuExtension(contextMenu)
        End Sub

        Private Sub mi_Click(ByVal sender As Object, ByVal e As EventArgs)
            Dim mi As MenuItem = TryCast(sender, MenuItem)

            If mi.Text = "复制" Then
                activeDoc.SendStringToExecute("_Copy ", True, False, True)
            ElseIf mi.Text = "删除" Then
                activeDoc.SendStringToExecute("_Erase ", True, False, True)
            End If
        End Sub
        Private Sub miCircle_Click(ByVal sender As Object, ByVal e As EventArgs)
            activeDoc.SendStringToExecute("_Count ", True, False, False)
        End Sub

        <CommandMethod("AddObjectContextMenu")>
        Public Sub AddObjectContextMenu()
            Dim contextMenu As ContextMenuExtension = New ContextMenuExtension()
            Dim miCircle As MenuItem = New MenuItem("统计个数")

            'miCircle.Click += Sub(ByVal sender As Object, ByVal e As EventArgs)
            '                      activeDoc.SendStringToExecute("_Count ", True, False, False)
            '                  End Sub

            AddHandler miCircle.Click, New EventHandler(AddressOf miCircle_Click)

            contextMenu.MenuItems.Add(miCircle)
            Dim rx As RXClass = RXClass.GetClass(GetType(Entity))
            Application.AddObjectContextMenuExtension(rx, contextMenu)
        End Sub

        <CommandMethod("Count", CommandFlags.UsePickSet)>
        Public Sub CountEnts()
            Dim ed As Editor = activeDoc.Editor
            Dim result As PromptSelectionResult = ed.SelectImplied()
            If result.Status = PromptStatus.OK Then ed.WriteMessage("共选择了" & result.Value.Count & "个实体" & vbLf)
        End Sub
    End Class
End Namespace
Imports System.Collections.Specialized
Imports System.IO
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Customization
Imports System.Runtime.CompilerServices
Imports Autodesk.AutoCAD.EditorInput

Namespace DotNetARX
    ''' <summary>
    ''' 操作CUI的类
    ''' </summary>
    Module CUITools
        ''' <summary>
        ''' 获取并打开主CUI文件
        ''' </summary>
        ''' <param name="doc">AutoCAD文档对象</param>
        ''' <returns>返回主CUI文件</returns>
        <Extension()>
        Function GetMainCustomizationSection(ByVal doc As Document) As CustomizationSection
            ''获得主CUI文件所在的位置
            Dim mainCuiFile As String = Application.GetSystemVariable("MENUNAME") & ".cui"
            mainCuiFile = "C:\Program Files\Autodesk\AutoCAD 2012 - Simplified Chinese\UserDataCache\Support\acad.CUIX"
            Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
            ed.WriteMessage(mainCuiFile)
            ''打开主CUI文件
            Return New CustomizationSection(mainCuiFile)
        End Function
        ''' <summary>
        ''' 创建局部CUI文件
        ''' </summary>
        ''' <param name="doc">AutoCAD文档对象</param>
        ''' <param name="cuiFile">CUI文件名</param>
        ''' <param name="menuGroupName">菜单组的名称</param>
        ''' <returns>返回创建的CUI文件</returns>
        <Extension()>
        Function AddCui(ByVal doc As Document, ByVal cuiFile As String, ByVal menuGroupName As String) As CustomizationSection
            Dim cs As CustomizationSection ''声明CUI文件对象

            If Not File.Exists(cuiFile) Then ''如果要创建的文件不存在
                cs = New CustomizationSection() ''创建CUI文件对象
                cs.MenuGroupName = menuGroupName ''指定菜单组名称
                cs.SaveAs(cuiFile) ''保存CUI文件
            Else
                ''如果已经存在指定的CUI文件,则打开该文件
                cs = New CustomizationSection(cuiFile)
            End If

            Return cs ''返回CUI文件对象
        End Function
        ''' <summary>
        ''' 装载指定的局部CUI文件
        ''' </summary>
        ''' <param name="cs">CUI文件</param>
        <Extension()>
        Sub LoadCui(ByVal cs As CustomizationSection)
            If cs.IsModified Then cs.Save() ''如果CUI文件被修改,则保存
            ''保存CMDECHO及FILEDIA系统变量
            Dim oldCmdEcho As Object = Application.GetSystemVariable("CMDECHO")
            Dim oldFileDia As Object = Application.GetSystemVariable("FILEDIA")
            ''设置CMDECHO=0,控制不在命令行上回显提示和输入信息
            Application.SetSystemVariable("CMDECHO", 0)
            ''设置FILEDIA=0,禁止显示文件对话框,这样可以通过程序输入文件名
            Application.SetSystemVariable("FILEDIA", 0)
            ''获取当前活动文档
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            ''获取主CUI文件
            Dim mainCs As CustomizationSection = doc.GetMainCustomizationSection()
            ''如果已存在局部CUI文件,则先卸载
            If mainCs.PartialCuiFiles.Contains(cs.CUIFileName) Then doc.SendStringToExecute("_.cuiunload " & cs.CUIFileBaseName & " ", False, False, False)
            ''装载CUI文件,注意文件名必须是带路径的
            doc.SendStringToExecute("_.cuiload " & cs.CUIFileName & " ", False, False, False)
            ''恢复CMDECHO及FILEDIA系统变量的初始值
            doc.SendStringToExecute("(setvar ""FILEDIA"" " & oldFileDia.ToString() & ")(princ) ", False, False, False)
            doc.SendStringToExecute("(setvar ""CMDECHO"" " & oldCmdEcho.ToString() & ")(princ) ", False, False, False)
        End Sub
        ''' <summary>
        ''' 添加菜单项所要执行的宏
        ''' </summary>
        ''' <param name="source">CUI文件</param>
        ''' <param name="name">宏的显示名称</param>
        ''' <param name="command">宏的具体命令</param>
        ''' <param name="tag">宏的标识符</param>
        ''' <param name="helpString">宏的状态栏提示信息</param>
        ''' <param name="imagePath">宏的图标</param>
        ''' <returns>返回创建的宏</returns>
        <Extension()>
        Function AddMacro(ByVal source As CustomizationSection, ByVal name As String, ByVal command As String, ByVal tag As String, ByVal helpString As String, ByVal imagePath As String) As MenuMacro
            Dim menuGroup As MenuGroup = source.MenuGroup ''获取CUI文件中的菜单组
            ''判断菜单组中是否已经定义与菜单组名相同的宏集合
            Dim mg As MacroGroup = menuGroup.FindMacroGroup(menuGroup.Name)
            ''如果宏集合没有定义,则创建一个与菜单组名相同的宏集合
            If mg Is Nothing Then mg = New MacroGroup(menuGroup.Name, menuGroup)
            ''如果已经宏已经被定义,则返回
            For Each macro As MenuMacro In mg.MenuMacros
                If macro.ElementID = tag Then Return Nothing
            Next
            ''在宏集合中创建一个命令宏
            Dim MenuMacro As MenuMacro = New MenuMacro(mg, name, command, tag)
            ''指定命令宏的说明信息,在状态栏中显示
            MenuMacro.macro.HelpString = helpString
            ''指定命令宏的大小图像的路径
            MenuMacro.macro.LargeImage = imagePath
            MenuMacro.macro.SmallImage = imagePath
            Return MenuMacro ''返回命令宏
        End Function
        ''' <summary>
        ''' 添加下拉菜单
        ''' </summary>
        ''' <param name="menuGroup">包含菜单的菜单组</param>
        ''' <param name="name">菜单名</param>
        ''' <param name="aliasList">菜单的别名</param>
        ''' <param name="tag">菜单的标识字符串</param>
        ''' <returns>返回下拉菜单对象</returns>
        <Extension()>
        Function AddPopMenu(ByVal menuGroup As MenuGroup, ByVal name As String, ByVal aliasList As StringCollection, ByVal tag As String) As PopMenu
            Dim pm As PopMenu = Nothing ''声明下拉菜单对象
            ''如果菜单组中没有名称为name的下拉菜单
            If menuGroup.PopMenus.IsNameFree(name) Then
                ''为下拉菜单指定显示名称、别名、标识符和所属的菜单组
                pm = New PopMenu(name, aliasList, tag, menuGroup)
            End If

            Return pm ''返回下拉菜单对象
        End Function
        ''' <summary>
        ''' 为菜单添加菜单项
        ''' </summary>
        ''' <param name="parentMenu">菜单项所属的菜单</param>
        ''' <param name="index">菜单项的位置</param>
        ''' <param name="name">菜单项的显示名称</param>
        ''' <param name="macroId">菜单项的命令宏的Id</param>
        ''' <returns>返回添加的菜单项</returns>
        <Extension()>
        Function AddMenuItem(ByVal parentMenu As PopMenu, ByVal index As Integer, ByVal name As String, ByVal macroId As String) As PopMenuItem
            Dim newPmi As PopMenuItem = Nothing
            ''如果存在名为name的菜单项,则返回
            For Each pmi As PopMenuItem In parentMenu.PopMenuItems
                If pmi.Name = name Then Return newPmi
            Next
            ''定义一个菜单项对象,指定所属的菜单及位置
            newPmi = New PopMenuItem(parentMenu, index)
            ''如果name不为空,则指定菜单项的显示名为name,否则会使用命令宏的名称
            If name IsNot Nothing Then newPmi.Name = name
            newPmi.MacroID = macroId ''菜单项的命令宏的ID
            Return newPmi ''返回菜单项对象
        End Function
        ''' <summary>
        ''' 为下拉菜单添加子菜单
        ''' </summary>
        ''' <param name="parentMenu">下拉菜单</param>
        ''' <param name="index">子菜单的位置</param>
        ''' <param name="name">子菜单的显示名称</param>
        ''' <param name="tag">子菜单的标识字符串</param>
        ''' <returns>返回添加的子菜单</returns>
        <Extension()>
        Function AddSubMenu(ByVal parentMenu As PopMenu, ByVal index As Integer, ByVal name As String, ByVal tag As String) As PopMenu
            Dim pm As PopMenu = Nothing ''声明子菜单对象(属于下拉菜单类)
            ''如果菜单组中没有名称为name的下拉菜单
            If parentMenu.CustomizationSection.MenuGroup.PopMenus.IsNameFree(name) Then
                ''为子菜单指定显示名称、标识符和所属的菜单组,别名设为null
                pm = New PopMenu(name, Nothing, tag, parentMenu.CustomizationSection.MenuGroup)
                ''为子菜单指定其所属的菜单
                Dim menuRef As PopMenuRef = New PopMenuRef(pm, parentMenu, index)
            End If

            Return pm ''返回子菜单对象
        End Function
        ''' <summary>
        ''' 为菜单添加分隔条
        ''' </summary>
        ''' <param name="parentMenu">下拉菜单</param>
        ''' <param name="index">分隔条的位置</param>
        ''' <returns>返回添加的分隔条</returns>
        <Extension()>
        Function AddSeparator(ByVal parentMenu As PopMenu, ByVal index As Integer) As PopMenuItem
            ''定义一个分隔条并返回
            Return New PopMenuItem(parentMenu, index)
        End Function
        ''' <summary>
        ''' 添加工具栏
        ''' </summary>
        ''' <param name="menuGroup">工具栏所属的菜单组</param>
        ''' <param name="name">工具栏的显示名称</param>
        ''' <returns>返回添加的工具栏</returns>
        <Extension()>
        Function AddToolbar(ByVal menuGroup As MenuGroup, ByVal name As String) As Toolbar
            Dim tb As Toolbar = Nothing ''声明一个工具栏对象
            ''如果菜单组中没有名称为name的工具栏
            If menuGroup.Toolbars.IsNameFree(name) Then
                ''为工具栏指定显示名称和所属的菜单组
                tb = New Toolbar(name, menuGroup)
                ''设置工具栏为浮动工具栏
                tb.ToolbarOrient = ToolbarOrient.floating
                ''设置工具栏可见
                tb.ToolbarVisible = ToolbarVisible.show
            End If

            Return tb ''返回工具栏对象
        End Function
        ''' <summary>
        ''' 向工具栏添加按钮
        ''' </summary>
        ''' <param name="parent">按钮所属的工具栏</param>
        ''' <param name="index">按钮在工具栏上的位置</param>
        ''' <param name="name">按钮的显示名称</param>
        ''' <param name="macroId">按钮的命令宏的Id</param>
        ''' <returns>返回工具栏按钮对象</returns>
        <Extension()>
        Function AddToolbarButton(ByVal parent As Toolbar, ByVal index As Integer, ByVal name As String, ByVal macroId As String) As ToolbarButton
            ''创建一个工具栏按钮对象,指定其命令宏Id、显示名称、所属的工具栏和位置
            Dim button As ToolbarButton = New ToolbarButton(macroId, name, parent, index)
            Return button ''返回工具栏按钮对象
        End Function
        ''' <summary>
        ''' 向工具栏添加弹出式工具栏
        ''' </summary>
        ''' <param name="parent">工具栏所属的父工具栏</param>
        ''' <param name="index">弹出式工具栏在父工具栏上的位置</param>
        ''' <param name="toolbarRef">弹出式工具栏所引用的工具栏</param>
        <Extension()>
        Sub AttachToolbarToFlyout(ByVal parent As Toolbar, ByVal index As Integer, ByVal toolbarRef As Toolbar)
            ''创建一个弹出式工具栏,指定其所属的工具栏和位置
            Dim flyout As ToolbarFlyout = New ToolbarFlyout(parent, index)
            ''指定弹出式工具栏所引用的工具栏
            flyout.ToolbarReference = toolbarRef.Name
            ''引用的工具栏初始状态不可见
            toolbarRef.ToolbarVisible = ToolbarVisible.hide
        End Sub
    End Module
End Namespace

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值