如果 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 包装类通过 bothor 继承,必须重写才能将默认对象添加到数据库中。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; } Add the desired ActiveX methods and properties to your wrapper class as described in To expose functionality through ActiveX. In order for your objects' Automation interfaces to be defined correctly, you must revise the generated Interface Definition Language (IDL) file. To adapt the IDL file for ObjectARX usageIn the IDL file, change the interface derivation for your COM object from to for a custom object, or to for a custom entity. Here is an example from the AsdkSquareLib.idl sample file: IDispatchIAcadObjectIAcadEntity interface IAsdkSquareWrapper : IAcadEntity Add the following code after and : importlib stdole32.tlbimportlib stdole2.tlb importlib("acax24enu.tlb"); // revise the path to match your
// own AutoCAD installation
Make sure you substitute the path that matches your AutoCAD installation. In the section of the IDL file that corresponds to your wrapper coclass, add after the line in order to support events. [source] interface IAcadObjectEvents;[default] Move the acax24enu.tlb section to the top of the IDL file, and move your custom object code so that it is within that section. The IDL file now appears similar to the following code: 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 头文件以及编译器生成的标识文件: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-1-8 19:27
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.