EaBIM一直以来积极响应国家“十二五”推进建筑业信息化的号召,对建筑领域的信息技术开展深入技术交流和探讨!致力于打造“BIM-建筑师-生态技术”三位一体综合资源交流共享平台,希望为BIM与可持续设计理念及技术的普及做出微小的贡献!!!

萧闫子 发表于 2014-1-8 14:41:39

[实体对象] .NET版本的OPM(属性管理器)

下面是C#代码:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows.OPM;
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace OPMNetSample
{
#region Our Custom Property
[
    Guid("F60AE3DA-0373-4d24-82D2-B2646517ABCB"),
    ProgId("OPMNetSample.CustomProperty.1"),
    // 这个类不会产生类接口,
    // 没有接口被标识为缺省的。
    // 要求用户通过此对象显式暴露的接口来暴露功能
    // 这也就是说此对象只能暴露我们定义的接口
    ClassInterface(ClassInterfaceType.None),
    // 设置用来自动化的缺省COM接口。
    // 类似于C#、C++和VB之类的语言允许你
    //查询你所感兴趣的接口,但类似于javascript之类的只关心自动化的语言
    //不允许查询接口并且只会产生缺省的接口。
    ComDefaultInterface(typeof(IDynamicProperty2)),
    ComVisible(true)
]
public class CustomProp : IDynamicProperty2
{
    private IDynamicPropertyNotify2 m_pSink = null;
    // 唯一的属性ID
    public void GetGUID(out Guid propGUID)
    {
      propGUID =
      new Guid("F60AE3DA-0373-4d24-82D2-B2646517ABCB");
    }
    // 属性显示的名字
    public void GetDisplayName(out string szName)
    {
      szName = "My integer property";
    }
    // 显示/隐藏OPM中的属性
    public void IsPropertyEnabled(object pUnk, out int bEnabled)
    {
      bEnabled = 1;
    }
    // 属性是否显示为只读
    public void IsPropertyReadOnly(out int bReadonly)
    {
      bReadonly = 0;
    }
    // 获取属性描述字符串
    public void GetDescription(out string szName)
    {
      szName =
      "This property is an integer";
    }
    // OPM通常会把这些显示在一个可编辑框中
    // 可选:表示属性类型名称的元数据,如ACAD_ANGLE
    public void GetCurrentValueName(out string szName)
    {
      throw new System.NotImplementedException();
    }
    // 属性类型What is the property type, ex. VT_R8
    public void GetCurrentValueType(out ushort varType)
    {
      // 对于动态属性,属性管理器支持下列类型的数据:
      // VT_I2, VT_I4, VT_R4, VT_R8,VT_BSTR, VT_BOOL
      // 和 VT_USERDEFINED.
      varType = 3; // VT_I4
    }
    // 获取属性值,输入参数为需要指定属性的对象
    public void GetCurrentValueData(object pUnk, ref object pVarData)
    {
      // 获取值并返回给AutoCAD
      // 因为我们上面说过值的类型是32位整数(VT_I4)
      pVarData = (int)4;
    }
    // 设置属性值,输入参数为需要指定属性的对象
    public void SetCurrentValueData(object pUnk, ref object varData)
    {
      // 保存返回给你值
      //因为我们上面说过值的类型是32位整数(VT_I4)
      int myVal = (int)varData;
    }
    // OPM传递实现自定义属性的IDynamicPropertyNotify接口,
    // 你通知OPM你的属性值改变了
    public void Connect(object pSink)
    {
      m_pSink = (IDynamicPropertyNotify2)pSink;
    }
    public void Disconnect() {
      m_pSink = null;
    }
}
#endregion
#region Application Entry Point
public class MyEntryPoint : IExtensionApplication
{
    protected internal CustomProp custProp = null;
    public void Initialize()
    {
      Assembly.LoadFrom("asdkOPMNetExt.dll");
      // 添加动态属性
      Dictionary classDict = SystemObjects.ClassDictionary;
      RXClass lineDesc = (RXClass)classDict.At("AcDbLine");
      IPropertyManager2 pPropMan =
      (IPropertyManager2)xOPM.xGET_OPMPROPERTY_MANAGER(lineDesc);
      custProp = new CustomProp();
      pPropMan.AddProperty((object)custProp);
    }
    public void Terminate()
    {
      // 移除动态属性
      Dictionary classDict = SystemObjects.ClassDictionary;
      RXClass lineDesc = (RXClass)classDict.At("AcDbLine");
      IPropertyManager2 pPropMan =
      (IPropertyManager2)xOPM.xGET_OPMPROPERTY_MANAGER(lineDesc);
      pPropMan.RemoveProperty((object)custProp);
      custProp = null;
    }
}
#endregion
}
代码中需要说明的一些问题:
代码定义了一个自定义动态属性(CustomProp),因此我们需要一个唯一的GUID,然后实现了不同的回调函数来表示属性的名字、类型、描述和可写性,也定义了获取和设置属性值的函数。对应于本例,我们的属性叫做“My integer property”,那么猜猜看它表示什么?——它是一个整型值,值被硬编码为4。当然我们没有通过这个属性来存储数据,但在初建的应用程序中,你可能会让它存储扩展数据、扩展记录或外部数据库。
在接下来的代码中,我们定义了一些函数,用于在这个模块被装载和AutoCAD退出时被调用。我们使用了Initialize()回调函数来装载我们的C++混合编程的模块(asdkOPMNetExt.dll),然后初始化我们的属性并把它附加到直线对象上去。
编译程序并装载DLL,请确保属性面板是可见的(使用PROPS命令或者双击直线对象),选择一条直线,你会看到下图所示的动态属性。
页: [1]
查看完整版本: [实体对象] .NET版本的OPM(属性管理器)