实现定义自定义对象的静态属性的 COM 对象包装器的最简单方法是使用活动模板库 (ATL)。通过 ATL,可以轻松创建支持。最困难的部分是将 ObjectARX 自定义对象代码与 ATL 生成的 ActiveX Server 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; } 在向导创建的存根中,添加相应的代码以设置属性值。下面是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; } 编译并生成应用程序。 测试自定义对象的属性
仅使用内置类别对属性进行分类 您可能不希望所有媒体资源都显示在“常规”类别下。本节演示如何使用内置类别。请注意,类通过接口继承。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() 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; } |
|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-1-8 19:47
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.