|
下面是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命令或者双击直线对象),选择一条直线,你会看到下图所示的动态属性。
|
|