CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

实现静态属性接口

2022-12-31 11:30| 发布者: admin| 查看: 802| 评论: 0|来自: AutoCAD

实现定义自定义对象的静态属性的 COM 对象包装器的最简单方法是使用活动模板库 (ATL)。通过 ATL,可以轻松创建支持。最困难的部分是将 ObjectARX 自定义对象代码与 ATL 生成的 ActiveX Server DLL 集成。但是,一旦基对象正常工作,就可以轻松地添加将显示在属性检查器中的属性。IDispatch

有关如何为自定义对象创建 COM 包装器的信息,请参阅COM 和 ActiveX 自动化。有关使用 Microsoft 编译器的接口和向导将 ATL 实现元素添加到接口的说明,请参阅 Microsoft 开发人员文档。

添加属性

  1. 使用 MicrosoftVisual Studio 工具,将新的 ATL 属性添加到您的界面。例如,在AsdkSquareWrapper_DG示例项目中,将属性添加到定义中。 ® IAsdkSquareWrapper
  2. 将属性的类型设置为。double
  3. 为属性指定一个名称,例如。将参数列表留空。SquareSize
  4. 完成后,在代码编辑器中打开 COM 对象的实现文件。IAsdkSquareWrapper

    如果在步骤 1-3 中使用了向导,则应在实现文件中为定义的每个读/写属性查找函数存根。get_*put_*

  5. 在属性的函数存根中,添加相应的代码以返回属性值。例如,下面是AsdkSquareWrapper_DG示例中的函数:get_*get_SquareSize()
STDMETHODIMP CAsdkSquareWrapper::get_SquareSize(double *pVal){
AcAxObjectRefPtr<AsdkSquare> pSq(&m_objRef,
AcDb::kForRead);
if (pSq.openStatus() != Acad::eOk)
return E_ACCESSDENIED;			
double size;
pSq->squareSideLength(size);
*pVal = size;
return S_OK;
}

在向导创建的存根中,添加相应的代码以设置属性值。下面是AsdkSquareWrapper示例中的 () 函数:put_* put_SquareSize

STDMETHODIMP CAsdkSquareWrapper::put_SquareSize(double newVal)
{
AcAxDocLock docLock(m_objRef.objectId(), AcAxDocLock::kNormal);
if(docLock.lockStatus() != Acad::eOk && docLock.lockStatus() !=
    Acad::eNoDatabase)
    return E_ACCESSDENIED;
AcAxObjectRefPtr<AsdkSquare> pSq(&m_objRef, AcDb::kForWrite);
if (pSq.openStatus() != Acad::eOk)
    return E_ACCESSDENIED;			
pSq->setSquareSideLength(newVal);
Fire_Notification(DISPID_SQUARESIZE);
return S_OK;
}

编译并生成应用程序。

测试自定义对象的属性

  1. 在 AutoCAD 中,加载应用程序并执行命令以创建自定义实体。确保您的 COM 包装器 DLL 已注册。
  2. 通过在命令行中输入特性来确保加载“特性”选项板。
  3. 选择您的自定义对象。您应该能够在“特性”选项板界面中看到并能够更改实体通用特性和边长。如果您使用的是AsdkSquareWrapper示例,请注意 SquareSize 属性显示在“常规”类别下。

仅使用内置类别对属性进行分类

    您可能不希望所有媒体资源都显示在“常规”类别下。本节演示如何使用内置类别。请注意,类通过接口继承。CAsdkSquareWrapperICategorizePropertiesIOPMPropertyExtensionImpl

  1. 按照添加属性过程添加方形中心和 ID 号的属性。
  2. 在 COM 类头文件中,将 COM 类的派生更改为包含和:IOPMPropertyExtensionImplIOPMPropertyExpander
public IOPMPropertyExtensionImpl<CAsdkSquareWrapper>,
public IOPMPropertyExpander

将以下接口添加到 COM 接口映射的末尾:

COM_INTERFACE_ENTRY(IOPMPropertyExtension)
COM_INTERFACE_ENTRY(ICategorizeProperties)
COM_INTERFACE_ENTRY(IPerPropertyBrowsing)
COM_INTERFACE_ENTRY(IOPMPropertyExpander)

将 OPM 属性映射的声明添加到 COM 类的公共声明中:

// IOPMPropertyExtension
//
BEGIN_OPMPROP_MAP()
    OPMPROP_ENTRY(0, 0x00000001, PROPCAT_Data, \
        0, 0, 0, "", 0, 1, IID_NULL, IID_NULL, "")
    OPMPROP_ENTRY(0, 0x00000003, PROPCAT_Geometry, \
        0, 0, 0, "", 0, 1, IID_NULL, IID_NULL, "")
END_OPMPROP_MAP()

Add the following two public inline functions to the class:

STDMETHOD(GetCategoryName)(
    THIS_
    /* [in]  */ PROPCAT propcat, 
    /* [in]  */ LCID lcid,
    /* [out] */ BSTR* pbstrName) 
    {return S_FALSE;}
virtual HINSTANCE GetResourceInstance()
{
    return _Module.GetResourceInstance();
}

Add public declarations for the following functions:

STDMETHOD(GetElementValue)(
    /* [in] */ DISPID dispID,
    /* [in] */ DWORD dwCookie,
    /* [out] */ VARIANT * pVarOut) ;
// Used for property expansion (currently variant types)
//
STDMETHOD(SetElementValue)(
    /* [in] */ DISPID dispID,
    /* [in] */ DWORD dwCookie,
    /* [in] */ VARIANT VarIn) ;       
// Used for property expansion (currently variant types)
//
STDMETHOD(GetElementStrings)( 
    /* [in] */ DISPID dispID,
    /* [out] */ OPMLPOLESTR __RPC_FAR *pCaStringsOut,
    /* [out] */ OPMDWORD __RPC_FAR *pCaCookiesOut) ;
//Used for property expansion (currently variant types)
//
STDMETHOD(GetElementGrouping)(
    /* [in] */ DISPID dispID,
    /* [out] */ short *groupingNumber) ;
// Used for property expansion (currently variant types)
//
STDMETHOD(GetGroupCount)(
    /* [in] */ DISPID dispID,
    /* [out] */ long *nGroupCnt) ;
STDMETHOD(GetPredefinedStrings)(
    /* [in] */ DISPID dispID,
    /* [out] */ CALPOLESTR *pCaStringsOut,
    /* [out] */ CADWORD *pCaCookiesOut);
STDMETHOD(GetPredefinedValue)(
    /* [in] */ DISPID dispID, 
    /* [out] */ DWORD dwCookie, 
    /* [out] */ VARIANT *pVarOut);

Add the implementation for the function in the CPP source file. These examples are for the object: AsdkSquare

STDMETHODIMP CAsdkSquareWrapper::GetElementValue(
    /* [in] */ DISPID dispID,
    /* [in] */ DWORD dwCookie,
    /* [out] */ VARIANT * pVarOut)
{
    if (pVarOut == NULL)
        return E_POINTER;
    AcAxObjectRefPtr<AsdkSquare> pSq(&m_objRef, AcDb::kForRead);
    if (pSq.openStatus() != Acad::eOk)
        return E_ACCESSDENIED;			
    if (dispID == DISPID_CENTERPOINT) {
        AcGePoint3d acgePt;
         pSq->squareCenter(acgePt);
         AcAxPoint3d acaxPt(acgePt);
         ::VariantCopy(pVarOut,&CComVariant(acaxPt[dwCookie]));
     }
     return S_OK;
 }
 
 STDMETHODIMP CAsdkSquareWrapper::SetElementValue(
   /* [in] */ DISPID dispID,
   /* [in] */ DWORD dwCookie,
   /* [in] */ VARIANT VarIn)
 {
AcAxDocLock docLock(m_objRef.objectId(),     AcAxDocLock::kNormal);
if(docLock.lockStatus() != Acad::eOk && docLock.lockStatus() !=
     Acad::eNoDatabase)
    return E_ACCESSDENIED;
AcAxObjectRefPtr<AsdkSquare> pSq(&m_objRef, AcDb::kForRead);
    if (pSq.openStatus() != Acad::eOk)
        return E_ACCESSDENIED;			
    if (dispID == DISPID_CENTERPOINT) {
        AcGePoint3d acgePt;
        pSq->squareCenter(acgePt);
        AcAxPoint3d acaxPt(acgePt);
 
        acaxPt[dwCookie] = V_R8(&VarIn);
        pSq->upgradeOpen();
        pSq->setSquareCenter(acaxPt);
   Fire_Notification(DISPID_CENTERPOINT);
    }
    return S_OK;
 }
 
 STDMETHODIMP CAsdkSquareWrapper::GetElementStrings( 
   /* [in] */ DISPID dispID,
   /* [out] */ OPMLPOLESTR __RPC_FAR *pCaStringsOut,
   /* [out] */ OPMDWORD __RPC_FAR *pCaCookiesOut)
 {
   if (dispID == DISPID_CENTERPOINT)
   {
        long size;
        size = 3;
        pCaStringsOut->pElems = 
            (LPOLESTR *)::CoTaskMemAlloc(sizeof(LPOLESTR) * size);
        pCaCookiesOut->pElems = 
            (DWORD *)::CoTaskMemAlloc(sizeof(DWORD) * size);
        for (long i=0;i<size;i++)
            pCaCookiesOut->pElems[i] = i;
        pCaStringsOut->cElems = size;
        pCaCookiesOut->cElems = size;
        pCaStringsOut->pElems[0] = ::SysAllocString(L"Center X");
        pCaStringsOut->pElems[1] = ::SysAllocString(L"Center Y");
        pCaStringsOut->pElems[2] = ::SysAllocString(L"Center Z");
    }
    return S_OK;
}
STDMETHODIMP CAsdkSquareWrapper::GetElementGrouping(
    /* [in] */ DISPID dispID,
    /* [out] */ short *groupingNumber)
{
    return E_NOTIMPL;
}
STDMETHODIMP CAsdkSquareWrapper::GetGroupCount(
    /* [in] */ DISPID dispID,
    /* [out] */ long *nGroupCnt)
{
    return E_NOTIMPL;
}
STDMETHODIMP CAsdkSquareWrapper::GetPredefinedStrings(
    DISPID dispID, CALPOLESTR *pCaStringsOut, 
    CADWORD *pCaCookiesOut)
{
    return E_NOTIMPL;
}
STDMETHODIMP CAsdkSquareWrapper::GetPredefinedValue(
    DISPID dispID, DWORD dwCookie, VARIANT *pVarOut)
{
    return E_NOTIMPL;
}

路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 13:09

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部