CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

AutoCAD 2023 开发者帮助

实现静态属性接口

2024-5-18 19:01| 发布者: admin| 查看: 91| 评论: 0|原作者: admin|来自: AutoCAD

实现静态属性接口

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

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

添加属性

  1. 使用 Microsoft Visual 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;
}

在向导创建的存根中,添加相应的代码以设置属性值。这是put_* put_SquareSize()function from the AsdkSquareWrapper sample:

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 类的派生更改为 include 和 :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()

将以下两个公共内联函数添加到类中:

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

为以下函数添加公开声明:

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);

在 CPP 源文件中添加函数的实现。这些示例适用于对象: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;
}

父主题:

  1. 实现属性

路过

雷人

握手

鲜花

鸡蛋

最新评论

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

GMT+8, 2025-3-5 15:36

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部