实现静态属性接口
实现定义自定义对象静态属性的 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-11-1 10:07
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.