明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 360|回复: 10

[资源] VB.NET [源码] AutoCAD下拉菜单和折叠菜单

  [复制链接]
发表于 昨天 14:44 | 显示全部楼层 |阅读模式
本帖最后由 pmq 于 2025-4-20 14:50 编辑

VB.NET写的 AutoCAD下拉菜单和折叠菜单
可自定义配置文件

编译好的DLL


折叠菜单

  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports Autodesk.AutoCAD.Windows
  3. Imports System.IO
  4. Imports System.Windows.Forms

  5. Public Class CADCollapsibleMenuWithAutoCollapse

  6.     ' 定义命令和宏的配置类
  7.     Public Class CommandConfig
  8.         Public Property Title As String  ' 菜单标题
  9.         Public Property Macro As String  ' 对应的AutoCAD宏命令
  10.         Public Property IconPath As String ' 图标路径(可选)
  11.         Public Property SubCommands As List(Of CommandConfig) ' 子菜单列表
  12.     End Class

  13.     ' PaletteSet 对象(侧边栏菜单)
  14.     Private Shared paletteSet As PaletteSet

  15.     ' 用于记录当前展开的子菜单容器
  16.     Private Shared currentExpandedMenu As FlowLayoutPanel

  17.     ' 主方法:创建折叠式侧边栏菜单
  18.     <CommandMethod("ZDCD")>
  19.     Public Sub CreateCollapsibleMenuWithTriangles()
  20.         ' 如果 PaletteSet 已经存在,则直接显示
  21.         If paletteSet IsNot Nothing AndAlso paletteSet.Visible Then
  22.             paletteSet.Visible = True
  23.             Return
  24.         End If

  25.         ' 配置文件路径
  26.         Dim filePath As String = "C:\Asur\MenuRes\commandICO.txt"
  27.         Dim commands As List(Of CommandConfig) = LoadCommandsFromTextFile(filePath)

  28.         If commands Is Nothing OrElse commands.Count = 0 Then
  29.             MsgBox("未在配置文件中找到有效命令。")
  30.             Exit Sub
  31.         End If

  32.         ' 创建 PaletteSet(可停靠窗口)
  33.         paletteSet = New PaletteSet("Collapsible Menu") With {
  34.             .Style = PaletteSetStyles.ShowPropertiesMenu Or PaletteSetStyles.ShowAutoHideButton,
  35.             .MinimumSize = New Drawing.Size(180, 500) ' 设置最小尺寸
  36.         }

  37.         ' 创建一个主 Panel 容器
  38.         Dim mainPanel As New FlowLayoutPanel() With {
  39.             .Dock = DockStyle.Fill,
  40.             .AutoScroll = True, ' 支持滚动
  41.             .FlowDirection = FlowDirection.TopDown, ' 主菜单按钮竖向排列
  42.             .Padding = New Padding(0),
  43.             .Margin = New Padding(0)
  44.         }

  45.         ' 遍历命令列表,生成主菜单和子菜单
  46.         For Each command In commands
  47.             ' 主菜单按钮
  48.             Dim mainButton As New Button() With {
  49.                 .Text = "&#9654; " & command.Title,
  50.                 .Width = 180,
  51.                 .Height = 25,
  52.                 .Margin = New Padding(0),
  53.                 .Padding = New Padding(0),
  54.                 .BackColor = Drawing.Color.LightGray,
  55.                 .TextAlign = Drawing.ContentAlignment.MiddleLeft
  56.             }

  57.             ' 子菜单 Panel
  58.             Dim subMenuPanel As New FlowLayoutPanel() With {
  59.                 .Dock = DockStyle.Top,
  60.                 .AutoSize = True,
  61.                 .Visible = False, ' 默认隐藏子菜单
  62.                 .FlowDirection = FlowDirection.TopDown,
  63.                 .Padding = New Padding(0),
  64.                 .Margin = New Padding(0)
  65.             }

  66.             ' 添加子菜单按钮
  67.             If command.SubCommands IsNot Nothing AndAlso command.SubCommands.Count > 0 Then
  68.                 For Each subCommand In command.SubCommands
  69.                     Dim subButton As New Button() With {
  70.                         .Text = subCommand.Title,
  71.                         .Width = 180,
  72.                         .Height = 25,
  73.                         .Margin = New Padding(0),
  74.                         .Padding = New Padding(0),
  75.                         .BackColor = Drawing.Color.White,
  76.                         .TextAlign = Drawing.ContentAlignment.MiddleLeft
  77.                     }

  78.                     ' 子菜单按钮点击事件
  79.                     AddHandler subButton.Click,
  80.                         Sub(sender, e)
  81.                             Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute(subCommand.Macro & vbCr, True, False, False)
  82.                         End Sub

  83.                     subMenuPanel.Controls.Add(subButton)
  84.                 Next
  85.             End If

  86.             ' 主菜单按钮点击事件
  87.             AddHandler mainButton.Click,
  88.                 Sub(sender, e)
  89.                     ' 收起当前展开的子菜单
  90.                     If currentExpandedMenu IsNot Nothing AndAlso currentExpandedMenu IsNot subMenuPanel Then
  91.                         currentExpandedMenu.Visible = False
  92.                         Dim parentButton = CType(mainPanel.Controls(mainPanel.Controls.IndexOf(currentExpandedMenu) - 1), Button)
  93.                         parentButton.Text = "&#9654; " & parentButton.Text.Substring(2)
  94.                     End If

  95.                     ' 切换当前子菜单的可见性
  96.                     subMenuPanel.Visible = Not subMenuPanel.Visible
  97.                     mainButton.Text = If(subMenuPanel.Visible, "▼ " & command.Title, "&#9654; " & command.Title)

  98.                     ' 更新当前展开的子菜单
  99.                     If subMenuPanel.Visible Then
  100.                         currentExpandedMenu = subMenuPanel
  101.                     Else
  102.                         currentExpandedMenu = Nothing
  103.                     End If
  104.                 End Sub

  105.             ' 添加主菜单和子菜单到主 Panel
  106.             mainPanel.Controls.Add(mainButton)
  107.             mainPanel.Controls.Add(subMenuPanel)
  108.         Next

  109.         ' 将主 Panel 添加到 PaletteSet
  110.         paletteSet.Add("折叠菜单", mainPanel)
  111.         paletteSet.Visible = True
  112.         paletteSet.Size = New Drawing.Size(150, 500)
  113.         paletteSet.Dock = DockSides.Left
  114.     End Sub

  115.     ' 从文本文件加载命令配置
  116.     Private Function LoadCommandsFromTextFile(filePath As String) As List(Of CommandConfig)
  117.         Dim commands As New List(Of CommandConfig)
  118.         Dim currentParent As CommandConfig = Nothing

  119.         Try
  120.             If File.Exists(filePath) Then
  121.                 Dim lines = File.ReadAllLines(filePath)

  122.                 For Each line In lines
  123.                     If String.IsNullOrWhiteSpace(line) OrElse line.StartsWith("#") Then Continue For

  124.                     If line.StartsWith("    ") Then
  125.                         Dim match = System.Text.RegularExpressions.Regex.Match(line.Trim(), "^\[(.*?)(?:,(.*?))?\](.*?)$")
  126.                         If match.Success AndAlso currentParent IsNot Nothing Then
  127.                             currentParent.SubCommands.Add(New CommandConfig() With {
  128.                                 .Title = match.Groups(1).Value.Trim(),
  129.                                 .Macro = match.Groups(3).Value.Trim(),
  130.                                 .IconPath = If(match.Groups(2).Success, match.Groups(2).Value.Trim(), Nothing)
  131.                             })
  132.                         End If
  133.                     Else
  134.                         Dim match = System.Text.RegularExpressions.Regex.Match(line.Trim(), "^\[(.*)\]$")
  135.                         If match.Success Then
  136.                             Dim parentCommand As New CommandConfig() With {
  137.                                 .Title = match.Groups(1).Value.Trim(),
  138.                                 .Macro = String.Empty,
  139.                                 .SubCommands = New List(Of CommandConfig)()
  140.                             }
  141.                             commands.Add(parentCommand)
  142.                             currentParent = parentCommand
  143.                         End If
  144.                     End If
  145.                 Next
  146.             Else
  147.                 MsgBox("未找到配置文件:" & filePath)
  148.             End If
  149.         Catch ex As Exception
  150.             MsgBox("读取配置文件时出错:" & ex.Message)
  151.         End Try

  152.         Return commands
  153.     End Function

  154. End Class



下拉菜单
  1. Imports Autodesk.AutoCAD.Runtime
  2. Imports Autodesk.AutoCAD.Windows
  3. Imports System.IO
  4. Imports System.Windows.Forms
  5. Imports System.Drawing ' 用于加载图标
  6. Imports System.Text.RegularExpressions

  7. Public Class DynamicToolbarMenu

  8.     ' 定义命令和宏的配置类
  9.     Public Class CommandConfig
  10.         Public Property Title As String ' 菜单标题
  11.         Public Property Macro As String ' 对应的AutoCAD宏命令
  12.         Public Property IconPath As String ' 图标路径
  13.         Public Property SubCommands As List(Of CommandConfig) ' 子菜单
  14.     End Class

  15.     ' 主方法:创建嵌套菜单形式的 PaletteSet
  16.     <CommandMethod("XLCD")>
  17.     Public Sub CreateDynamicToolbarMenu()
  18.         Dim filePath As String = "C:\Asur\MenuRes\commandICO.txt"
  19.         Dim ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
  20.         Dim commands As List(Of CommandConfig) = LoadCommandsFromTextFile(filePath)

  21.         If commands Is Nothing OrElse commands.Count = 0 Then
  22.             MsgBox("未在配置文件中找到有效命令。")
  23.             Exit Sub
  24.         End If

  25.         ' 创建 PaletteSet(可停靠窗口)
  26.         Dim paletteSet As New PaletteSet("Dynamic Toolbar") With {
  27.             .Style = PaletteSetStyles.ShowPropertiesMenu Or PaletteSetStyles.ShowAutoHideButton,
  28.             .MinimumSize = New Drawing.Size(400, 50)
  29.         }

  30.         ' 创建一个 Panel 来容纳工具
  31.         Dim panel As New Panel() With {
  32.             .Dock = DockStyle.Fill
  33.         }

  34.         ' 创建工具条
  35.         Dim toolStrip As New ToolStrip() With {
  36.             .Dock = DockStyle.Top
  37.         }

  38.         ' 遍历命令列表,添加到工具条
  39.         For Each command In commands
  40.             ed.WriteMessage("生成主菜单: " & command.Title & vbCrLf)
  41.             Dim dropDownButton As New ToolStripDropDownButton() With {
  42.                 .Text = command.Title
  43.             }

  44.             If command.SubCommands IsNot Nothing AndAlso command.SubCommands.Count > 0 Then
  45.                 For Each subCommand In command.SubCommands
  46.                     ed.WriteMessage("  添加子菜单: " & subCommand.Title & vbCrLf)
  47.                     Dim subButton As New ToolStripMenuItem() With {
  48.                         .Text = subCommand.Title
  49.                     }

  50.                     ' 仅在图标路径存在时加载图标
  51.                     If Not String.IsNullOrEmpty(subCommand.IconPath) Then
  52.                         Dim icon = LoadIcon(subCommand.IconPath)
  53.                         If icon IsNot Nothing Then
  54.                             subButton.Image = icon
  55.                         End If
  56.                     End If

  57.                     AddHandler subButton.Click, Sub(sender, e)
  58.                                                     Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.SendStringToExecute(subCommand.Macro & vbCr, True, False, False)
  59.                                                 End Sub
  60.                     dropDownButton.DropDownItems.Add(subButton)
  61.                 Next
  62.             End If

  63.             toolStrip.Items.Add(dropDownButton)
  64.         Next

  65.         ' 将工具条添加到 Panel
  66.         panel.Controls.Add(toolStrip)

  67.         ' 将 Panel 添加到 PaletteSet
  68.         paletteSet.Add("Toolbar", panel)
  69.         paletteSet.Size = New Drawing.Size(400, 25)
  70.         paletteSet.Dock = DockSides.Top
  71.         paletteSet.Visible = True
  72.     End Sub

  73.     ' 从文本文件加载命令配置,包括主菜单和子菜单
  74.     Private Function LoadCommandsFromTextFile(filePath As String) As List(Of CommandConfig)
  75.         Dim ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
  76.         Dim commands As New List(Of CommandConfig)
  77.         Dim currentParent As CommandConfig = Nothing

  78.         Try
  79.             If File.Exists(filePath) Then
  80.                 Dim lines = File.ReadAllLines(filePath)
  81.                 ed.WriteMessage("读取配置文件成功,文件路径: " & filePath & vbCrLf)

  82.                 For Each line In lines
  83.                     ' 跳过空行和注释
  84.                     If String.IsNullOrWhiteSpace(line) OrElse line.StartsWith("'") Then Continue For
  85.                     ed.WriteMessage("读取行: " & line & vbCrLf)

  86.                     ' 判断是否是主菜单
  87.                     If Not line.StartsWith("    ") AndAlso line.StartsWith("[") Then
  88.                         ' 主菜单解析
  89.                         Dim title = line.Trim().Trim("["c, "]"c)
  90.                         Dim parentCommand As New CommandConfig() With {
  91.                             .Title = title,
  92.                             .Macro = "",
  93.                             .IconPath = Nothing,
  94.                             .SubCommands = New List(Of CommandConfig)()
  95.                         }
  96.                         ed.WriteMessage("解析主菜单: " & parentCommand.Title & vbCrLf)
  97.                         commands.Add(parentCommand)
  98.                         currentParent = parentCommand
  99.                     ElseIf line.StartsWith("    ") Then
  100.                         ' 子菜单解析
  101.                         Dim match = Regex.Match(line.Trim(), "^\[(.*?)(?:,(.*?))?\](.*?)$")
  102.                         If match.Success AndAlso currentParent IsNot Nothing Then
  103.                             Dim subCommand As New CommandConfig() With {
  104.                                 .Title = match.Groups(1).Value.Trim(), ' 提取标题
  105.                                 .Macro = match.Groups(3).Value.Trim(), ' 提取宏命令
  106.                                 .IconPath = If(match.Groups(2).Success, match.Groups(2).Value.Trim(), Nothing) ' 提取图标路径(如果存在)
  107.                             }
  108.                             ed.WriteMessage("解析子菜单: 标题=" & subCommand.Title & ", 宏=" & subCommand.Macro & ", 图标路径=" & If(subCommand.IconPath, "无") & vbCrLf)
  109.                             currentParent.SubCommands.Add(subCommand)
  110.                         End If
  111.                     End If
  112.                 Next
  113.             Else
  114.                 MsgBox("未找到配置文件:" & filePath)
  115.             End If
  116.         Catch ex As Exception
  117.             MsgBox("读取配置文件时出错:" & ex.Message)
  118.         End Try

  119.         Return commands
  120.     End Function

  121.     Private Function LoadIcon(iconPath As String) As Image
  122.         Dim ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor
  123.         If Not String.IsNullOrEmpty(iconPath) Then
  124.             Dim resolvedPath = Path.Combine("C:\Asur\MenuRes", iconPath)
  125.             If File.Exists(resolvedPath) Then
  126.                 Try
  127.                     ed.WriteMessage("加载图标: " & resolvedPath & vbCrLf)
  128.                     Return Image.FromFile(resolvedPath)
  129.                 Catch ex As Exception
  130.                     ed.WriteMessage("图标加载失败: " & resolvedPath & " 错误: " & ex.Message & vbCrLf)
  131.                 End Try
  132.             Else
  133.                 ed.WriteMessage("图标文件不存在: " & resolvedPath & vbCrLf)
  134.             End If
  135.         Else
  136.             ed.WriteMessage("图标路径为空" & vbCrLf)
  137.         End If
  138.         Return Nothing
  139.     End Function

  140. End Class
配置文件格式:
  1. [剖面]
  2.      [绘制图框,P38tk.bmp]_TK
  3.      [绘剖面线,P39pmx.bmp]_Hhatch
  4.      [剖面计算,P40js.bmp]_PmJs
  5.      [剖面绘制]_HuiPMT
  6.      [面积计算,P40js.bmp]_MjJs
  7.      [计算体积]_jsTj
  8.      [方量计算,P41CLin.bmp]_jsFl
  9.      [横剖面计算]_flph
  10.      [数据传输]_CeData
  11.      [坐标修改]_XYxg
  12.      [坐标排序]_Js6
  13.      [高程检查]_GcJc
  14.      [剖面处理]_Pmcj
  15.      [多段线剖面]_flph
  16.      [三维线转剖面]_flph
  17.      [交点计算,P68djs.BMP]_JDJS
  18.      [交点坐标,p69xyh.BMP]_XYZ
  19.      [绘制交点]_XZZ
  20.      [高程Z轴归零]_GZreo
  21.      [剖面分离还原]_Pmfl
  22.      [提取剖面数据]_PmSj
  23.      [恢复高程注记,P71ZJGC.bmp]
  24.      [坐标转剖面]
  25.      [创边界,P70cbj.BMP]_Cbj
  26.      [生成三维坐标,pspmx.BMP]_XYHtq
  27.      
  28. ***POP5
  29. [绘制]
  30.      [展碎部点,P37Pzan.bmp]_ZD
  31.      [绘控制点]_ZKzd
  32.      [展高程点]_ZGCD
  33.      [线的中点]_PX
  34.      [绘延长点]_PY
  35.      [绘偏移点]_PP
  36.      [绘垂直点]_PV
  37.      [两点中点]_PZ
  38.      [绘铁路]_Rail
  39.      [三点房屋]_HFW
  40.      [自动编号]_AutoBH
  41.      [简码识别]_JMSB
  42.      [测屏坐标输点]_Surs
  43.      [点到直线距离]
  44.      [展Cass高程点]_Cass
复制代码



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 4明经币 +4 收起 理由
Bao_lai + 1 赞一个!
不一样地设计 + 1 神马都是浮云
统一网名 + 1 很给力!
gaolei_gaolei + 1 很给力!

查看全部评分

回复

使用道具 举报

发表于 昨天 14:58 | 显示全部楼层
只支持cad2026?有其他的吗
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 16:34 | 显示全部楼层
fxlt619 发表于 2025-4-20 14:58
只支持cad2026?有其他的吗

ACeL2026.DLL文件支持CAD2021-2026
源码自己编译成其它版本。
只是引用对应的CAD的三个运行库
accoremgd、acdbmgd、acmgd
回复 支持 反对

使用道具 举报

发表于 昨天 16:43 | 显示全部楼层
效果不错,不过为什么出来的是乱码呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 昨天 18:58 | 显示全部楼层
liuyj 发表于 2025-4-20 16:43
效果不错,不过为什么出来的是乱码呢?

配置文件可能是以 GBK 或 GB2312(常见于中文环境)编码保存的,而代码默认使用 UTF-8 读取文件

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复 支持 反对

使用道具 举报

发表于 昨天 19:16 | 显示全部楼层
感谢分享,侧边菜单栏现在是百花齐放了
回复 支持 反对

使用道具 举报

发表于 7 小时前 | 显示全部楼层
怎么自定义配置文件?加载你提供的配置打不开二级菜单

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 5 小时前 | 显示全部楼层
本帖最后由 pmq 于 2025-4-21 12:36 编辑
zilong136 发表于 2025-4-21 10:35
怎么自定义配置文件?加载你提供的配置打不开二级菜单

这是一个完整的插件,实用于AutoCAD2021-2026
配置文件在C:\Asur\MenuRes\commandICO.txt
默认二级菜单 [ 前有5个空格
你这个全部是一级菜单,没有二级菜单
最好是解压到C:根目录


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复 支持 反对

使用道具 举报

发表于 2 小时前 | 显示全部楼层
点赞点赞
卷起来了,各种边栏产品,百花齐放了。
回复 支持 反对

使用道具 举报

发表于 1 小时前 | 显示全部楼层
这个可以111111
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-4-21 17:57 , Processed in 0.193472 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表