| 将自定义对象或实体添加到对象模型 如果 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)
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1   苏公网安备32011402011833)
GMT+8, 2025-10-31 06:51
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.