我有一个控件,实现了SAFE FOR SCRIPTING AND SAFE FOR INITIALIZING, 并且实现了IObjectSafe,且在两个方法中都返回S_OK,也就是标记我的控件对初始化和脚本都是安全的,但是当在服务器上测试的时候,如果将客户端的IE安全设置中的对未标记为安全ActiveX控件的初始化和脚本设为提示,则一切正常,如果设为启用的话,则在第一次打开网页(即下载并注册控件时)正常,但如果以后再打开网页,则弹出对话框说意外的调用了方法和属性访问.这是怎么回事,该如何解决.

解决方案 »

  1.   

    在头文件中添加如下代码:
    //*****************************安全接口添加代码***************
        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);
    //*****************************安全接口添加代码***************
    在实现文件中添加如下代码
    //*****************************安全接口添加代码***************
    BEGIN_INTERFACE_MAP( CTestComponent, COleControl )
       INTERFACE_PART(CTestComponent, IID_IObjectSafety, ObjSafe)
    END_INTERFACE_MAP()ULONG FAR EXPORT CTestComponent::XObjSafe::AddRef()
    {
        METHOD_PROLOGUE(CTestComponent, ObjSafe)
        return pThis->ExternalAddRef();
    }ULONG FAR EXPORT CTestComponent::XObjSafe::Release()
    {
        METHOD_PROLOGUE(CTestComponent, ObjSafe)
        return pThis->ExternalRelease();
    }HRESULT FAR EXPORT CTestComponent::XObjSafe::QueryInterface(
        REFIID iid, void FAR* FAR* ppvObj)
    {
        METHOD_PROLOGUE(CTestComponent, ObjSafe)
        return (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
    }const DWORD dwSupportedBits = INTERFACESAFE_FOR_UNTRUSTED_CALLER |
                                  INTERFACESAFE_FOR_UNTRUSTED_DATA;
    const DWORD dwNotSupportedBits = ~ dwSupportedBits;HRESULT STDMETHODCALLTYPE 
       CTestComponent::XObjSafe::GetInterfaceSafetyOptions( 
          /* [in] */ REFIID riid,
            /* [out] */ DWORD __RPC_FAR *pdwSupportedOptions,
            /* [out] */ DWORD __RPC_FAR *pdwEnabledOptions)
    {
       METHOD_PROLOGUE(CTestComponent, ObjSafe)   HRESULT retval = ResultFromScode(S_OK);   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
    }HRESULT STDMETHODCALLTYPE 
       CTestComponent::XObjSafe::SetInterfaceSafetyOptions( 
            /* [in] */ REFIID riid,
            /* [in] */ DWORD dwOptionSetMask,
            /* [in] */ DWORD dwEnabledOptions)
    {
        METHOD_PROLOGUE(CTestComponent, 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);
    }
    //*****************************安全接口添加代码***************注意:把CTestComponent换成你的类名字就可以了
      

  2.   

    你在MSDN上COPY的,我都看了N遍了,不是这个实现的问题,这样只能标记我们的控件是安全的,按理说IE中对没有标记为安全的控件初始化和脚本执行的不同设置是不会影响我们的控件的,但是对没有标记为安全的控件初始化和脚本执行的不同设置却影响了这个控件的执行,所以我很疑惑,也不知道该如何解决.我用MFC和ATL都写过最简单的控件,且我发现默认的实现都没有标记控件是安全的,但IE的不同设置也没有出现这个问题.
      

  3.   

    这是个Windows IE的设置问题!
    这样设置就好了:IE菜单Tools->Internet Options->Security->Custom Level->然后把所有与ActiveX controls and Plug-ins相关的项都设为Enable,就ok了
      

  4.   

    现在的问题是将未标记为安全的ActiveX初始化和脚本执行设为启用就不OK啊,设为提示是OK的,但我的控件是标记为安全的.另外我也试过不标记为安全的,但也是同样的问题,在别的服务器上试也一样.
      

  5.   

    你标记成安全,客户就认为是安全么?那这样3721之流岂不乐疯了~
    把自己置成safe不就行了:)
      

  6.   

    一般来说,当你的控件实现了SAFE FOR SCRIPTING AND SAFE FOR INITIALIZING,只要你的IE安全设置没有问题,就能够正常地下载和安装。根据你的描述,第一次能够被下载和安装,说明你的控件在这方面没有问题,但是如果以后再打开网页,则弹出对话框说意外的调用了方法和属性访问,很有可能是你的控件本身的属性或者内部的数据处理有问题,你最好是查一查控件代码有没有疏漏的地方,而不要一味地在脚本安全和初始化安全上纠缠。最好的测试方法是使用ActiveX控件测试容器工具或者建立一个对话框程序,把你的控件应用在上面,看看控件本身有没有问题。我觉得,十有八九是控件本身的问题。