参考王磊老师编写的 AutoCAD Civil 3D .NET二次开发,基本实现了功能区。
完成后效果:
今天的代码比较坎坷,主要有以下几个坑:
- 需要创建图标,并添加到资源中:
- RibbonButton存在多个引用,不知道选用哪个,通过测试,选用了using Autodesk.Windows;
- Orientation.Vertical需要引用Assembly:PresentationFramework.dll,刚开始一直没发现,后再在MSDN上找到了:
代码如下
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Autodesk.AutoCAD.ApplicationServices.Core;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.Windows;
using Civil3DTools.Properties;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
namespace Civil3DTools
{
internal class RibbonDemo
{
private const int large = 32;
private const int small = 16;
private static Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
/// <summary>
/// 创建标准按钮
/// </summary>
/// <param name="bmp"></param>
/// <param name="text"></param>
/// <param name="toolTip"></param>
/// <param name="command"></param>
/// <returns></returns>
private static RibbonButton CreateStdBtn(Bitmap bmp, string text, string toolTip, string command)
{
var rb = new RibbonButton(); //创建新按钮
rb.Image = Images.getBitmap(bmp, small); //设置标准图标
rb.Text = text; //设置文本
rb.ToolTip = toolTip; //设置提示
rb.CommandParameter = command; //设置命令名称
rb.ShowText = true; //显示文本
rb.CommandHandler = new RibbonbtnCmdHandle(); //设置命令处理程序
return rb;
}
/// <summary>
/// 创建大图标按钮
/// </summary>
/// <param name="bmp"></param>
/// <param name="text"></param>
/// <param name="toolTip"></param>
/// <param name="command"></param>
/// <returns></returns>
private static RibbonButton CreateLargeBtn(Bitmap bmp, string text, string toolTip, string command)
{
var rb = CreateStdBtn(bmp, text, toolTip, command);
rb.LargeImage = Images.getBitmap(bmp, large); //设置大图标
rb.Size = RibbonItemSize.Large; //设置图标尺寸
rb.Orientation = Orientation.Vertical;
return rb;
}
/// <summary>
/// 在附加模块选项卡中添加面板
/// </summary>
public static void AddAddinTab()
{
var rc = ComponentManager.Ribbon;
RibbonTab rt = null;
foreach (var tab in rc.Tabs) //查找附加模块选项卡
if (tab.AutomationName == "附加模块") //根据名称查找
{
rt = tab;
break;
}
if (rt == null) //没找到的话新建一个
{
rt = new RibbonTab();
rt.Title = "附加模块";
rt.Id = "CIVIL.ID_CIVIL 3DAddins"; //设置标题
rc.Tabs.Add(rt); //设置ID
}
var rps = new RibbonPanelSource(); //面板资源
rps.Title = "BJUCD"; //面板标题
var rp = new RibbonPanel(); //新建面板
rp.Source = rps; //设置面板资源
rt.Panels.Insert(0, rp); //将面板插入到选项卡中
var rb = CreateLargeBtn( //创建大图标按钮
Resources.TableOut, //图标
"输出\nCivil 3D表格", //标题文本
"将Civil 3D表格输出为.csv格式文件", //提示信息
" .CTTC "); //命令名称,主要保留空格
rps.Items.Add(rb); //将大图标按钮添加到面板资源中
var rrp = new RibbonRowPanel(); //新建“行面板”
rrp.MinWidth = 150;
rps.Items.Add(new RibbonSeparator()); //插入分隔符
rps.Items.Add(rrp); //将“行面板”添加到面板资源中
var rb1 = CreateStdBtn( //创建标准大小图标按钮
Resources.table, //图标
"逐桩坐标表", //标题文本
"创建逐桩坐标表", //提示信息
" .StationTable "); //命令名称
var rb2 = CreateStdBtn( //创建标准大小图标按钮
Resources.Label, //图标
"路线偏移标签", //标题文本
"创建路线偏移标签", //提示信息
" .OffsetLabel "); //命令名称
rrp.Items.Add(rb1); //将按钮添加到“行面板”
rrp.Items.Add(new RibbonRowBreak()); //添加“换行符”
rrp.Items.Add(rb2); //将按钮添加到“行面板”
}
}
/// <summary>
/// 根据按钮的命令参数执行相应的命令
/// </summary>
internal class RibbonbtnCmdHandle : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object patameter)
{
if (patameter is RibbonButton)
{
var rb = patameter as RibbonButton;
Application.DocumentManager.MdiActiveDocument.SendStringToExecute((string) rb.CommandParameter, true,
false, false);
}
}
}
/// <summary>
/// 将图片转换为ImageSource
/// </summary>
internal class Images
{
public static double m_DpiScale = 1.0;
public static BitmapImage getBitmap(Bitmap image, int l)
{
var stream = new MemoryStream();
image.Save(stream, ImageFormat.Png);
var bmp = new BitmapImage();
bmp.BeginInit();
bmp.StreamSource = stream;
bmp.DecodePixelHeight = (int) (l * m_DpiScale);
bmp.DecodePixelWidth = (int) (l * m_DpiScale);
bmp.EndInit();
return bmp;
}
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr ptr);
[DllImport("user32.dll", EntryPoint = "ReleaseDC")]
private static extern IntPtr ReleaseDC(IntPtr pre, IntPtr hDc);
[DllImport("gdi32.dll")]
private static extern int GetDeviceCaps(IntPtr hDc, int nIndex);
[DllImport("user32.dll")]
internal static extern bool SetProcessDPIAware();
public static void GetDpiScale() //根据DPI对图标进行缩放
{
try
{
SetProcessDPIAware();
var screenDC = GetDC(IntPtr.Zero);
var dpi = GetDeviceCaps(screenDC, 90);
m_DpiScale = dpi / 96.0;
ReleaseDC(IntPtr.Zero, screenDC);
}
catch (Exception ex)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.Message);
}
}
}
/// <summary>
/// 在程序加载时自动创建面板,每次运行都会创建一个面板,先将其注释掉
/// </summary>
//public class MyPlugin : IExtensionApplication
//{
// public void Initialize()
// {
// Images.GetDpiScale();
// Application.Idle += LoadMyRibbon;
// }
// public void Terminate()
// {
// }
// private void LoadMyRibbon(object sender, EventArgs e)
// {
// RibbonDemo.AddAddinTab();
// Application.Idle -= LoadMyRibbon;
// }
//}
}
今天有些匆忙,没有好好写注释,代码理解也不深入,晚上要加班了。