将自定义对象或实体添加到对象模型
如果 COM 包装类封装自定义对象或实体,则需要修改 ATL 生成的代码以支持相应的接口。ObjectARX samples\com\AsdkSquareWrapper_dg\square 目录包含作为单独 DLL 编写的自定义实体的包装类示例。 您还必须确保 ObjectARX 组件满足 ActiveX 自动化要求,并且必须扩展包装应用程序以支持 ObjectARX 组件。以下各节提供了演示如何完成此操作的过程:
为自定义对象或实体创建自动化包装器项目
#include "acadi_i.c" 您刚刚创建的项目包含大量生成的代码。必须扩展其中的某些代码才能使用 ObjectARX,如下一过程所示。 调整 ATL 生成的代码以实现 ObjectARX 兼容性
// For a custom object. // public IAcadObjectDispatchImpl<CWrapperClass, &CLSID_WrapperClass,IWrapperClass, &IID_IWrapperClass,&LIBID_LIBRARYLib> // For a custom entity. // public IAcadEntityDispatchImpl<CWrapperClass, &CLSID_WrapperClass,IWrapperClass, &IID_IWrapperClass,&LIBID_LIBRARYLib> 将以下条目添加到:COM_MAP COM_INTERFACE_ENTRY(IAcadBaseObject) COM_INTERFACE_ENTRY(IAcadObject) COM_INTERFACE_ENTRY(IAcadEntity) // For an entity only. COM_INTERFACE_ENTRY(IRetrieveApplication) COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer) // Only // necessary to support events. 必须在 COM 代码中实现一个特殊函数,以公开自定义对象和实体。以下过程演示了如何提供此支持。 添加 ObjectARX 自定义对象和自定义实体支持将以下必需的替代添加到 COM 类的公共声明: // IAcadBaseObjectImpl // virtual HRESULT CreateNewObject( AcDbObjectId& objId, AcDbObjectID& ownerId, TCHAR* keyName); 此抽象函数是类的公共成员。COM 包装类通过 或 继承。 必须重写才能将默认对象添加到数据库中。IAcadBaseObjectImplIAcadBaseObjectImplIAcadObjectDispatchImplIAcadEntityDispatchImplCreateNewObject 实现该函数和任何其他特定于对象或特定于实体的函数。CreateNewObject() 以下示例显示了 from 的实现:CreateNewObject()AsdkSquareWrapper HRESULT CAsdkSquareWrapper::CreateNewObject( AcDbObjectId& objId, AcDbObjectId& ownerId, TCHAR* keyName) { try { AcAxDocLock docLock(ownerId, AcAxDocLock::kNormal); Acad::ErrorStatus es; AcDbObjectPointer<AsdkSquare> pSq; if((es = pSq.create()) != Acad::eOk) throw es; AcDbDatabase* pDb = ownerId.database(); pSq->setDatabaseDefaults(pDb); AcDbBlockTableRecordPointer pBlockTableRecord(ownerId, AcDb::kForWrite); if((es = pBlockTableRecord.openStatus()) != Acad::eOk) throw es; if((es = pBlockTableRecord-> appendAcDbEntity(objId, pSq.object())) != Acad::eOk) throw es; } catch(const Acad::ErrorStatus) { //To become more sophisticated // return Error(L"Failed to create square", IID_IAsdkSquareWrapper, E_FAIL); } return S_OK; } 将所需的 ActiveX 方法和属性添加到包装类中,如通过 ActiveX 公开功能中所述。 为了正确定义对象的自动化接口,必须修改生成的接口定义语言 (IDL) 文件。 调整 IDL 文件以适应 ObjectARX 使用在 IDL 文件中,将 COM 对象的接口派生从自定义对象的 to 更改为自定义实体的接口派生。下面是 AsdkSquareLib.idl 示例文件中的示例:IDispatchIAcadObjectIAcadEntity interface IAsdkSquareWrapper : IAcadEntity 在 和 之后添加以下代码:importlib stdole32.tlbimportlib stdole2.tlb importlib("acax24enu.tlb"); // revise the path to match your
// own AutoCAD installation
请确保替换与AutoCAD安装匹配的路径。 在与包装器 coclass 对应的 IDL 文件部分中,在行后添加以支持事件。[source] interface IAcadObjectEvents;[default] 将 acax24enu.tlb 部分移动到 IDL 文件的顶部,并移动自定义目标代码,使其位于该部分中。 IDL 文件现在类似于以下代码: import "oaidl.idl"; import "ocidl.idl"; [ uuid(800F70A1-6DE9-11D2-A7A6-0060B0872457), version(1.0), helpstring("AsdkSquareLib 1.0 Type Library") ] library ASDKSQUARELIBLib { importlib("stdole32.tlb"); importlib("stdole2.tlb"); importlib("acax23enu.tlb"); [ object, uuid(800F70AD-6DE9-11D2-A7A6-0060B0872457), dual, helpstring("IAsdkSquareWrapper Interface"), pointer_default(unique) ] interface IAsdkSquareWrapper : IAcadEntity { [propget, id(1), helpstring("property Number")] HRESULT Number([out, retval] short *pVal); [propput, id(1), helpstring("property Number")] HRESULT Number([in] short newVal); }; [ uuid(800F70AE-6DE9-11D2-A7A6-0060B0872457), helpstring("AsdkSquareWrapper Class") ] coclass AsdkSquareWrapper { [default] interface IAsdkSquareWrapper; [source] interface IAcadObjectEvents; }; }; 注意:IDL 文件修改将导致编译器发出警告,指出接口不符合。您可以忽略此消息。
接下来,请确保 ObjectARX 组件实现必要的替代以支持 ActiveX 自动化。如果要生成单独的 COM 和 ObjectARX DLL,请切换到 ObjectARX 项目以执行下一个过程。 AutoCAD 特性选项板使用该函数检索自定义图元的类型信息。有关实现属性选项板功能的信息,请参阅属性面板 API。如果不按下述进行覆盖,则“属性”选项板仅显示自定义实体的基类信息。但是,如果重写但未实现自定义实体的 OPM 接口,则“属性”选项板无法显示您自己的类信息或基类数据。有关 的更多信息,请参见获取自定义类的 CLSID。getClassID()getClassID()getClassID()getClassID() 准备 ObjectARX 项目以实现 ActiveX 兼容性在每个正在包装的基于 ObjectARX 的类中,重写该函数:getClassID() Acad::ErrorStatus AcDbMyClass::getClassID(CLSID* pClsid) const { *pClsid = CLSID_WrapperClass; // replace CLSID_WrapperClass with // your COM class CLSID return Acad::eOk; } 在包含 的重写的每个文件中,包括必要的 COM 头文件以及编译器生成的 ID 文件:getClassId() #include <objbase.h> #include <initguid.h> #include "library_i.c" // File containing definitions of the // IIDs and CLSIDs for the COM project. // “library” is replaced by your COM project // name. This file resides in your COM // project directory. 根据生成和注册 COM DLL 中的步骤生成并注册 COM 应用程序。如果要生成单独的 COM 和 ObjectARX 或 ObjectDBX ™ DLL,在生成 COM 应用程序之前生成 ObjectARX 或 ObjectDBX 模块。 父主题: |
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-3-14 06:22
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.