1. using Autodesk.AutoCAD.ApplicationServices;
    2. using Autodesk.AutoCAD.Customization;
    3. using System.Collections.Specialized;
    4. using System.IO;
    5. namespace CadPluginPlatform
    6. {
    7. /// <summary>
    8. /// 操作Cuix的类
    9. /// </summary>
    10. /// todo:
    11. /// 1. 只写一次,自动生成其他,初步是只写一次ribbon,然后自动根据ribbon生成菜单和工具条
    12. /// 2. 根据cuix的内容生成侧边栏的数据
    13. /// 3. 是否采用xml文件存储历史菜单数据
    14. ///
    15. public static class Cuix
    16. {
    17. /// <summary>
    18. /// 获取并打开主CUIX文件
    19. /// </summary>
    20. /// <param name="doc">AutoCAD文档对象</param>
    21. /// <returns>返回主CUIX文件</returns>
    22. public static CustomizationSection GetMainCustomizationSection(this Document doc)
    23. {
    24. //获得主Cuix文件所在的位置
    25. string mainCuiFile = Application.GetSystemVariable("MENUNAME") + ".cuix";
    26. //打开主Cuix文件
    27. return new CustomizationSection(mainCuiFile);
    28. }
    29. /// <summary>
    30. /// 创建局部Cuix文件
    31. /// </summary>
    32. /// <param name="doc">AutoCAD文档对象</param>
    33. /// <param name="cuiFile">Cuix文件名</param>
    34. /// <param name="menuGroupName">菜单组的名称</param>
    35. /// <returns>返回创建的Cuix文件</returns>
    36. public static CustomizationSection AddCuix(this Document doc, string cuiFile, string menuGroupName)
    37. {
    38. CustomizationSection cs;//声明Cuix文件对象
    39. if (!File.Exists(cuiFile))//如果要创建的文件不存在
    40. {
    41. cs = new CustomizationSection
    42. {
    43. MenuGroupName = menuGroupName//指定菜单组名称
    44. };//创建Cuix文件对象
    45. cs.SaveAs(cuiFile);//保存Cuix文件
    46. }
    47. //如果已经存在指定的Cuix文件,则打开该文件
    48. else cs = new CustomizationSection(cuiFile);
    49. return cs;//返回Cuix文件对象
    50. }
    51. /// <summary>
    52. /// 装载指定的局部Cuix文件
    53. /// </summary>
    54. /// <param name="cs">Cuix文件</param>
    55. public static void LoadCuix(this CustomizationSection cs)
    56. {
    57. if (cs.IsModified) cs.Save();//如果Cuix文件被修改,则保存
    58. //获取当前活动文档
    59. Document doc = Application.DocumentManager.MdiActiveDocument;
    60. //获取主Cuix文件
    61. var maincui = doc.GetMainCustomizationSection();
    62. //如果已存在局部Cuix文件,则先卸载
    63. if (maincui.PartialCuiFiles.Contains(cs.CUIFileName))
    64. {
    65. Application.UnloadPartialMenu(cs.CUIFileName);
    66. }
    67. Application.LoadPartialMenu(cs.CUIFileName);
    68. //Application.ReloadAllMenus();
    69. }
    70. /// <summary>
    71. /// 添加菜单项所要执行的宏,宏id默认为ID_Marco_command
    72. /// </summary>
    73. /// <param name="source">Cuix文件</param>
    74. /// <param name="command">宏的具体命令</param>
    75. /// <param name="helpString">宏的状态栏提示信息</param>
    76. /// <param name="imagePath">宏的图标</param>
    77. /// <returns>返回创建的宏</returns>
    78. public static MenuMacro AddMacro(this CustomizationSection source, string command, string helpString, string imagePath)
    79. {
    80. var commandMacro = "^C^C_" + command;
    81. var commandId = "ID_Marco_" + command;
    82. var macroName = "Name_" + command;
    83. var labelId = "lbl" + command;
    84. MenuGroup menuGroup = source.MenuGroup;//获取Cuix文件中的菜单组
    85. //判断菜单组中是否已经定义与菜单组名相同的宏集合
    86. MacroGroup mg = menuGroup.FindMacroGroup(menuGroup.Name);
    87. if (mg == null)//如果宏集合没有定义,则创建一个与菜单组名相同的宏集合
    88. mg = new MacroGroup(menuGroup.Name, menuGroup);
    89. //如果已经宏已经被定义,则返回
    90. foreach (MenuMacro macro in mg.MenuMacros)
    91. if (macro.ElementID == commandId) return macro;
    92. //在宏集合中创建一个命令宏
    93. var menuMacro = mg.CreateMenuMacro(macroName,
    94. commandMacro,
    95. commandId,
    96. helpString,
    97. MacroType.Any,
    98. imagePath,
    99. imagePath,
    100. labelId);
    101. menuMacro.macro.CLICommand = command;
    102. return menuMacro;//返回命令宏
    103. }
    104. /// <summary>
    105. /// 添加下拉菜单,别名默认为空,id默认为ID_Menu_name
    106. /// </summary>
    107. /// <param name="menuGroup">包含菜单的菜单组</param>
    108. /// <param name="name">菜单名</param>
    109. /// <returns>返回下拉菜单对象</returns>
    110. public static PopMenu AddPopMenu(this MenuGroup menuGroup, string name)
    111. {
    112. var tag = $"ID_Menu_{name}";
    113. var alias = new StringCollection
    114. {
    115. "POP15",
    116. tag
    117. };
    118. //如果菜单组中没有名称为name的下拉菜单
    119. if (menuGroup.PopMenus.IsNameFree(name))
    120. {
    121. //为下拉菜单指定显示名称、别名、标识符和所属的菜单组
    122. return new PopMenu(name, alias, tag, menuGroup);
    123. }
    124. return menuGroup.PopMenus.FindPopWithName(name);
    125. //返回下拉菜单对象
    126. }
    127. /// <summary>
    128. /// 为菜单添加菜单项
    129. /// </summary>
    130. /// <param name="parentMenu">菜单项所属的菜单</param>
    131. /// <param name="index">菜单项的位置</param>
    132. /// <param name="name">菜单项的显示名称</param>
    133. /// <param name="macro">菜单项的命令宏</param>
    134. /// <returns>返回添加的菜单项</returns>
    135. public static PopMenuItem AddMenuItem(this PopMenu parentMenu, int index, string name, MenuMacro macro)
    136. {
    137. var id = $"ID_MenuItem_{name}";
    138. //如果存在名为name的菜单项,则返回
    139. foreach (var item in parentMenu.PopMenuItems)
    140. {
    141. if (item is PopMenuItem popMenuItem && popMenuItem.Name == name)
    142. {
    143. return null;
    144. }
    145. }
    146. //定义一个菜单项对象,指定所属的菜单及位置
    147. var newPmi = new PopMenuItem(parentMenu, index);
    148. ////如果name不为空,则指定菜单项的显示名为name,否则会使用命令宏的名称
    149. if (name != null) newPmi.Name = name;
    150. newPmi.MacroID = macro.ElementID;//菜单项的命令宏的ID
    151. newPmi.ElementID = id;
    152. return newPmi;//返回菜单项对象
    153. }
    154. /// <summary>
    155. /// 为下拉菜单添加子菜单
    156. /// </summary>
    157. /// <param name="parentMenu">下拉菜单</param>
    158. /// <param name="index">子菜单的位置</param>
    159. /// <param name="name">子菜单的显示名称</param>
    160. /// <param name="tag">子菜单的标识字符串</param>
    161. /// <returns>返回添加的子菜单</returns>
    162. public static PopMenu AddSubMenu(this PopMenu parentMenu, int index, string name)
    163. {
    164. var id = $"ID_SubMenu_{name}";
    165. PopMenu pm = null;//声明子菜单对象(属于下拉菜单类)
    166. //如果菜单组中没有名称为name的下拉菜单
    167. if (parentMenu.CustomizationSection.MenuGroup.PopMenus.IsNameFree(name))
    168. {
    169. //为子菜单指定显示名称、标识符和所属的菜单组,别名设为null
    170. pm = new PopMenu(name, null, id, parentMenu.CustomizationSection.MenuGroup);
    171. //为子菜单指定其所属的菜单
    172. _ = new PopMenuRef(pm, parentMenu, index);
    173. }
    174. pm = parentMenu.CustomizationSection.MenuGroup.PopMenus.FindPopWithName(name);
    175. return pm;//返回子菜单对象
    176. }
    177. /// <summary>
    178. /// 为菜单添加分隔条
    179. /// </summary>
    180. /// <param name="parentMenu">下拉菜单</param>
    181. /// <param name="index">分隔条的位置</param>
    182. /// <returns>返回添加的分隔条</returns>
    183. public static PopMenuItem AddSeparator(this PopMenu parentMenu, int index)
    184. {
    185. //定义一个分隔条并返回
    186. return new PopMenuItem(parentMenu, index);
    187. }
    188. #region toolbar
    189. /// <summary>
    190. /// 添加工具栏
    191. /// </summary>
    192. /// <param name="menuGroup">工具栏所属的菜单组</param>
    193. /// <param name="name">工具栏的显示名称</param>
    194. /// <returns>返回添加的工具栏</returns>
    195. public static Toolbar AddToolbar(this MenuGroup menuGroup, string name)
    196. {
    197. Toolbar tb = null;//声明一个工具栏对象
    198. //如果菜单组中没有名称为name的工具栏
    199. if (menuGroup.Toolbars.IsNameFree(name))
    200. {
    201. //为工具栏指定显示名称和所属的菜单组
    202. tb = new Toolbar(name, menuGroup)
    203. {
    204. //设置工具栏为浮动工具栏
    205. ToolbarOrient = ToolbarOrient.floating,
    206. //设置工具栏可见
    207. ToolbarVisible = ToolbarVisible.show
    208. };
    209. }
    210. return tb;//返回工具栏对象
    211. }
    212. /// <summary>
    213. /// 向工具栏添加按钮
    214. /// </summary>
    215. /// <param name="parent">按钮所属的工具栏</param>
    216. /// <param name="index">按钮在工具栏上的位置</param>
    217. /// <param name="name">按钮的显示名称</param>
    218. /// <param name="macroId">按钮的命令宏的Id</param>
    219. /// <returns>返回工具栏按钮对象</returns>
    220. public static ToolbarButton AddToolbarButton(this Toolbar parent, int index, string name, string macroId)
    221. {
    222. //创建一个工具栏按钮对象,指定其命令宏Id、显示名称、所属的工具栏和位置
    223. ToolbarButton button = new ToolbarButton(macroId, name, parent, index);
    224. return button;//返回工具栏按钮对象
    225. }
    226. /// <summary>
    227. /// 向工具栏添加弹出式工具栏
    228. /// </summary>
    229. /// <param name="parent">工具栏所属的父工具栏</param>
    230. /// <param name="index">弹出式工具栏在父工具栏上的位置</param>
    231. /// <param name="toolbarRef">弹出式工具栏所引用的工具栏</param>
    232. public static void AttachToolbarToFlyout(this Toolbar parent, int index, Toolbar toolbarRef)
    233. {
    234. //创建一个弹出式工具栏,指定其所属的工具栏和位置
    235. _ = new ToolbarFlyout(parent, index)
    236. {
    237. //指定弹出式工具栏所引用的工具栏
    238. ToolbarReference = toolbarRef.Name
    239. };
    240. //引用的工具栏初始状态不可见
    241. toolbarRef.ToolbarVisible = ToolbarVisible.hide;
    242. }
    243. #endregion
    244. #region ribbon
    245. /// <summary>
    246. /// 添加新标签页
    247. /// </summary>
    248. /// <param name="instance">cui文件对象</param>
    249. /// <param name="name">标签页名字</param>
    250. /// <param name="text">标签页名字</param>
    251. /// <returns>ribbon 标签对象资源集合</returns>
    252. public static RibbonTabSource AddTab(
    253. this CustomizationSection instance, string name)
    254. {
    255. var ribbonRoot = instance.MenuGroup.RibbonRoot;
    256. var id = $"ID_RibbonTabSource_{name}";
    257. if (ribbonRoot.RibbonTabSources.Contains(id))
    258. {
    259. return ribbonRoot.RibbonTabSources[id];
    260. }
    261. var ribbonTabSource = new RibbonTabSource(ribbonRoot)
    262. {
    263. Name = name,
    264. Text = name,
    265. Id = id,
    266. ElementID = id
    267. };
    268. ribbonRoot.RibbonTabSources.Add(ribbonTabSource);
    269. return ribbonTabSource;
    270. }
    271. /// <summary>
    272. /// 添加新面板
    273. /// </summary>
    274. /// <param name="instance">cui文件对象</param>
    275. /// <param name="name">面板名字</param>
    276. /// <returns>ribbon 面板对象资源集合</returns>
    277. public static RibbonPanelSource AddPanel(
    278. this RibbonTabSource instance, string name)
    279. {
    280. var ribbonRoot = instance.CustomizationSection.MenuGroup.RibbonRoot;
    281. var panels = ribbonRoot.RibbonPanelSources;
    282. var id = $"ID_RibbonPanelSource_{instance.ElementID.Split('_')[2]}_{name}";
    283. if (ribbonRoot.RibbonPanelSources.Contains(id))
    284. {
    285. return ribbonRoot.RibbonPanelSources[id];
    286. }
    287. var ribbonPanelSource = new RibbonPanelSource(ribbonRoot)
    288. {
    289. Name = name,
    290. Text = name,
    291. Id = id,
    292. ElementID = id
    293. };
    294. panels.Add(ribbonPanelSource);
    295. var ribbonPanelSourceReference = new RibbonPanelSourceReference(instance)
    296. {
    297. PanelId = ribbonPanelSource.ElementID
    298. };
    299. instance.Items.Add(ribbonPanelSourceReference);
    300. return ribbonPanelSource;
    301. }
    302. /// <summary>
    303. /// 添加ribbon 行
    304. /// </summary>
    305. /// <param name="instance">ribbon 面板对象资源集合</param>
    306. /// <returns>ribbon 行</returns>
    307. public static RibbonRow AddRibbonRow(this RibbonPanelSource instance, string name)
    308. {
    309. var id = $"ID_PanelSource_{instance.ElementID.Split('_')[3]}_{name}";
    310. if (instance.Items.Contains(id))
    311. {
    312. return instance.Items[id] as RibbonRow;
    313. }
    314. var row = new RibbonRow(instance)
    315. {
    316. ElementID = id,
    317. Text = name
    318. };
    319. instance.Items.Add(row);
    320. return row;
    321. }
    322. /// <summary>
    323. /// 添加ribbon 行
    324. /// </summary>
    325. /// <param name="instance">ribbon 行面板</param>
    326. /// <returns>ribbon 行</returns>
    327. public static RibbonRow AddRibbonRow(this RibbonRowPanel instance, string name)
    328. {
    329. var id = $"ID_RowPanel_{instance.ElementID.Split('_')[3]}_{name}";
    330. if (instance.Items.Contains(id))
    331. {
    332. return instance.Items[id] as RibbonRow;
    333. }
    334. var row = new RibbonRow(instance)
    335. {
    336. ElementID = id,
    337. Text = name
    338. };
    339. instance.Items.Add(row);
    340. return row;
    341. }
    342. /// <summary>
    343. /// 添加行面板
    344. /// </summary>
    345. /// <param name="instance">ribbon 行</param>
    346. /// <returns>行面板</returns>
    347. public static RibbonRowPanel AddRowPanel(this RibbonRow instance, string name)
    348. {
    349. var id = $"ID_Row_{instance.ElementID.Split('_')[3]}_{name}";
    350. if (instance.Items.Contains(id))
    351. {
    352. return instance.Items[id] as RibbonRowPanel;
    353. }
    354. var row = new RibbonRowPanel(instance)
    355. {
    356. ElementID = id,
    357. Text = name
    358. };
    359. instance.Items.Add(row);
    360. return row;
    361. }
    362. /// <summary>
    363. /// 添加命令按钮
    364. /// </summary>
    365. /// <param name="instanse">ribbon 行</param>
    366. /// <param name="text">按钮名</param>
    367. /// <param name="macro">命令宏</param>
    368. /// <param name="style">按钮风格</param>
    369. /// <returns></returns>
    370. public static RibbonCommandButton AddButton(this RibbonRow instance, string text, MenuMacro macro, RibbonButtonStyle style)
    371. {
    372. var id = $"ID_RowButton_{instance.ElementID.Split('_')[3]}_{text}";
    373. if (instance.Items.Contains(id))
    374. {
    375. return instance.Items[id] as RibbonCommandButton;
    376. }
    377. var button = new RibbonCommandButton(instance)
    378. {
    379. Text = text,
    380. MacroID = macro.ElementID,
    381. ButtonStyle = style,
    382. ElementID = id
    383. };
    384. instance.Items.Add(button);
    385. return button;
    386. }
    387. /// <summary>
    388. /// 添加命令按钮
    389. /// </summary>
    390. /// <param name="instanse">下拉按钮</param>
    391. /// <param name="text">按钮名</param>
    392. /// <param name="macro">命令宏</param>
    393. /// <param name="style">按钮风格</param>
    394. /// <returns></returns>
    395. public static RibbonCommandButton AddButton(this RibbonSplitButton instance, string text, MenuMacro macro, RibbonButtonStyle style)
    396. {
    397. var id = $"ID_SplitButton_{instance.ElementID.Split('_')[3]}_{text}";
    398. if (instance.Items.Contains(id))
    399. {
    400. return instance.Items[id] as RibbonCommandButton;
    401. }
    402. var button = new RibbonCommandButton(instance)
    403. {
    404. Text = text,
    405. MacroID = macro.ElementID,
    406. ButtonStyle = style,
    407. ElementID = id
    408. };
    409. instance.Items.Add(button);
    410. return button;
    411. }
    412. /// <summary>
    413. /// 添加新的下拉按钮
    414. /// </summary>
    415. /// <param name="instance">ribbon 行</param>
    416. /// <param name="text">下拉按钮名</param>
    417. /// <param name="behavior">按钮行为</param>
    418. /// <param name="listStyle">按钮列表风格</param>
    419. /// <param name="style">按钮风格</param>
    420. /// <returns></returns>
    421. public static RibbonSplitButton AddSplitButton(
    422. this RibbonRow instance,
    423. string text,
    424. RibbonSplitButtonBehavior behavior,
    425. RibbonSplitButtonListStyle listStyle,
    426. RibbonButtonStyle style)
    427. {
    428. var id = $"ID_Split_{instance.ElementID.Split('_')[3]}_{text}";
    429. if (instance.Items.Contains(id))
    430. {
    431. return instance.Items[id] as RibbonSplitButton;
    432. }
    433. var button = new RibbonSplitButton(instance)
    434. {
    435. Text = text,
    436. Behavior = behavior,
    437. ListStyle = listStyle,
    438. ButtonStyle = style,
    439. ElementID = id
    440. };
    441. instance.Items.Add(button);
    442. return button;
    443. }
    444. /// <summary>
    445. /// 添加分隔符
    446. /// </summary>
    447. /// <param name="instance">ribbon 行</param>
    448. /// <param name="style">分隔符风格</param>
    449. /// <returns></returns>
    450. public static RibbonSeparator AddRibbonSeparator(
    451. this RibbonRow instance,
    452. RibbonSeparatorStyle style = RibbonSeparatorStyle.Line)
    453. {
    454. var separator = new RibbonSeparator(instance);
    455. separator.SeparatorStyle = style;
    456. instance.Items.Add(separator);
    457. return separator;
    458. }
    459. /// <summary>
    460. /// 添加分隔符
    461. /// </summary>
    462. /// <param name="instance">下拉按钮</param>
    463. /// <param name="style">分隔符风格</param>
    464. /// <returns></returns>
    465. public static RibbonSeparator AddRibbonSeparator(
    466. this RibbonSplitButton instance,
    467. RibbonSeparatorStyle style = RibbonSeparatorStyle.Line)
    468. {
    469. var separator = new RibbonSeparator(instance);
    470. separator.SeparatorStyle = style;
    471. instance.Items.Add(separator);
    472. return separator;
    473. }
    474. #endregion ribbon
    475. }
    476. }