[实体对象] .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]