实现静态属性接口
实现定义自定义对象静态属性的 COM 对象包装的最简单方法是使用活动模板库 (ATL)。ATL 使创建支持 的 COM 对象变得容易。最困难的部分是将 ObjectARX 自定义对象代码与 ATL 生成的 ActiveX 服务器 DLL 集成。但是,一旦基本对象开始工作,就可以简单地添加将显示在属性检查器中的属性。IDispatch 有关如何为自定义对象创建 COM 包装器的信息,请参阅 COM 和 ActiveX 自动化。有关使用 Microsoft 编译器的接口和向导将 ATL 实现元素添加到接口的说明,请参阅 Microsoft 开发人员文档。 添加属性
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; } 编译和生成应用程序。 测试自定义对象的属性
仅使用内置类别对属性进行分类 您可能不希望所有属性都显示在“常规”类别下。本部分演示如何使用内置类别。请注意,该类通过接口继承。CAsdkSquareWrapperICategorizePropertiesIOPMPropertyExtensionImpl
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; } 父主题: |
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-3-5 15:36
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.