如题,写了几个控件给网页调用,必须要去设置ie的受信任站点中的安全级别,一不小心设置变了的话,页面调用控件就会报错。比如(SCRIPT3: 找不到成员),以前碰到该错误的解决办法只能去将“对未标记为可安全执行脚本的ActiveX控件初始化并执行脚本”这一项设置为启用。
新发现的办法,可在ActiveX工程中添加代码实现控件安全初始化,无需设置浏览器即可正常调用。具体操作:
1.xxxCtrl.h文件中
#include <ObjSafe.h>
class CxxxCtrl : public COleControl
{
DECLARE_DYNCREATE(CxxxCtrl)
/***ActiveX控件安全初始化:实现ISafeObject接口 开始***/
DECLARE_INTERFACE_MAP()
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);
/***ActiveX控件安全初始化:实现ISafeObject接口 结束***/
// 构造函数
public:
CxxxCtrl();
......
}
2. xxxCtrl.cpp中,添加如下内容:
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/***ActiveX控件安全初始化:实现ISafeObject接口 开始***/
// Interface map for IObjectSafety
BEGIN_INTERFACE_MAP( CxxxCtrl, COleControl )
INTERFACE_PART(CxxxCtrl, IID_IObjectSafety, ObjSafe)
END_INTERFACE_MAP()
// IObjectSafety member functions
// Delegate AddRef, Release, QueryInterface
ULONG FAR EXPORT CxxxCtrl::XObjSafe::AddRef()
{
METHOD_PROLOGUE(CxxxCtrl, ObjSafe)
return pThis->ExternalAddRef();
}
ULONG FAR EXPORT CxxxCtrl::XObjSafe::Release()
{
METHOD_PROLOGUE(CxxxCtrl, ObjSafe)
return pThis->ExternalRelease();
}
HRESULT FAR EXPORT CxxxCtrl::XObjSafe::QueryInterface(
REFIID iid, void FAR* FAR* ppvObj)
{
METHOD_PROLOGUE(CxxxCtrl, 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
CxxxCtrl::XObjSafe::GetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
/* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
{
METHOD_PROLOGUE(CxxxCtrl, 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
CxxxCtrl::XObjSafe::SetInterfaceSafetyOptions(
/* [in] */ REFIID riid,
/* [in] */ DWORD dwOptionSetMask,
/* [in] */ DWORD dwEnabledOptions)
{
METHOD_PROLOGUE(CxxxCtrl, 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);
}
/***ActiveX控件安全初始化:实现ISafeObject接口 结束***/
IMPLEMENT_DYNCREATE(CxxxCtrl, COleControl)
本文介绍了一种新的方法,可以在不更改浏览器设置的情况下解决IE中ActiveX控件的安全问题。通过在控件代码中实现ISafeObject接口,可以避免因浏览器安全级别设置不同导致的控件调用失败。
1430

被折叠的 条评论
为什么被折叠?



