1. ATL 实现
如果com组件要在IE中进行调用,则必须实现IObjectSafety接口,不然在ie中必须调整activex选项才可以正常运行,
如下是实现IObjectSafety的例子:
#include <atlctl.h>
/
// Cwebpy
class ATL_NO_VTABLE Cwebpy :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<Cwebpy, &CLSID_webpy>,
public IDispatchImpl<Iwebpy, &IID_Iwebpy, &LIBID_ATLSAFTLib>,
public IObjectSafetyImpl<Cwebpy,INTERFACESAFE_FOR_UNTRUSTED_CALLER|INTERFACESAFE_FOR_UNTRUSTED_DATA>
{
public:
Cwebpy()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_WEBPY)
DECLARE_PROTECT_FINAL_CONSTRUCT()
STDMETHODIMP GetInterfaceSafetyOptions( REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions){
ATLTRACE(_T("Cwebpy::GetInterfaceSafetyOptions()\n"));
*pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
*pdwEnabledOptions = *pdwSupportedOptions;
return S_OK;
}
STDMETHODIMP GetInterfaceSafetyOptions( REFIID riid, DWORD *dwOptionSetMask, DWORD dwEnabledOptions){
ATLTRACE(_T("Cwebpy::GetInterfaceSafetyOptions()\n"));
return S_OK;
}
BEGIN_COM_MAP(Cwebpy)
COM_INTERFACE_ENTRY(Iwebpy)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()
// Iwebpy
public:
};
注意包含的文件头atlctl.h
2. mfc active 和SDI Automaion 实现
头文件加入:
BEGIN_INTERFACE_PART(ObjSafe, IObjectSafety)
STDMETHOD_(HRESULT, GetInterfaceSafetyOptions) (
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions
);
STDMETHOD_(HRESULT, SetInterfaceSafetyOptions) (
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions
);
END_INTERFACE_PART(ObjSafe);
注意头文件要包含objsafe.h
实现文件添加:
BEGIN_INTERFACE_MAP(CApm2webDoc, CDocument)
INTERFACE_PART(CApm2webDoc, IID_IApm2web, Dispatch)
INTERFACE_PART(CApm2webDoc, IID_IObjectSafety, ObjSafe) //这儿只添加这一句
END_INTERFACE_MAP()
/ 下面都要添加上
// IObjectSafety member functions
// Delegate AddRef, Release, QueryInterface
ULONG FAR EXPORT CApm2webDoc::XObjSafe::AddRef()
{
METHOD_PROLOGUE(CApm2webDoc, ObjSafe)
return pThis->ExternalAddRef();
}
ULONG FAR EXPORT CApm2webDoc::XObjSafe::Release()
{
METHOD_PROLOGUE(CApm2webDoc, ObjSafe)
return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CApm2webDoc::XObjSafe::QueryInterface(
REFIID iid, void FAR* FAR* ppvObj)
{
METHOD_PROLOGUE(CApm2webDoc, ObjSafe)
return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
}
const DWORD dwSupportedBits =
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
INTERFACESAFE_FOR_UNTRUSTED_DATA;
const DWORD dwNotSupportedBits = ~ dwSupportedBits;
/
// CStopLiteCtrl::XObjSafe::GetInterfaceSafetyOptions
// Allows container to query what interfaces are safe for what. We're
// optimizing significantly by ignoring which interface the caller is
// asking for.
HRESULT STDMETHODCALLTYPE
CApm2webDoc::XObjSafe::GetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
METHOD_PROLOGUE(CApm2webDoc, ObjSafe)
HRESULT retval = ResultFromScode(S_OK);
// does interface exist?
IUnknown FAR* punkInterface;
retval = pThis->ExternalQueryInterface(&riid,
(void * *)&punkInterface);
if (retval != E_NOINTERFACE) { // interface exists
punkInterface->Release(); // release it--just checking!
}
// we support both kinds of safety and have always both set,
// regardless of interface
*pdwSupportedOptions = *pdwEnabledOptions = dwSupportedBits;
return retval; // E_NOINTERFACE if QI failed
}
/
// CStopLiteCtrl::XObjSafe::SetInterfaceSafetyOptions
// Since we're always safe, this is a no-brainer--but we do check to make
// sure the interface requested exists and that the options we're asked to
// set exist and are set on (we don't support unsafe mode).
HRESULT STDMETHODCALLTYPE
CApm2webDoc::XObjSafe::SetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions)
{
METHOD_PROLOGUE(CApm2webDoc, ObjSafe)
// does interface exist?
IUnknown FAR* punkInterface;
pThis->ExternalQueryInterface(&riid, (void * *)&punkInterface);
if (punkInterface) { // interface exists
punkInterface->Release(); // release it--just checking!
}
else { // interface doesn't exist
return ResultFromScode(E_NOINTERFACE);
}
// can't set bits we don't support
if (dwOptionSetMask & dwNotSupportedBits) {
return ResultFromScode(E_FAIL);
}
// can't set bits we do support to zero
dwEnabledOptions &= dwSupportedBits;
// (we already know there are no extra bits in mask )
if ((dwOptionSetMask & dwEnabledOptions) !=
dwOptionSetMask) {
return ResultFromScode(E_FAIL);
}
// don't need to change anything since we're always safe
return ResultFromScode(S_OK);
}
SDI 中添加到doc类中,activex添加到主类实现文件中!