ACTIVEX控件无法显示的问题

原创 2007年10月09日 17:39:00

最近开发ACTIVEX 用于上传文件

但是遇到一个最严重的问题,在客户机上无法显示

经过大量的资料查阅,终于发现了问题根源!

首先,ACTIVEX要在用户机上正确的安装和注册肯定是需要一个数字签名的,当然,如果手动安装和注册,可以忽略这个,不过要用于INTERNET上使用,最好还是使用数字签名,否则很不方便。

其次,在IE6或更高版本上使用,ACTIVEX控件还需要申明安全接口(IobjectSafety接口) ,这个就是遇到的问题根源。

起初在做好控件后,使用证书进行了签名,但是仍然在用户机器上无法显示,很是奇怪,到处查找资料,控件注册、安装、签名,各个方面都正确操作了,还是不行,最后在一骗关于安全接口申明的文章上找到了答案!

文章内容如下:

 

如何在VB中实现ActiveX控件的IobjectSafety接口

--------------------------------------------------------------------------------

总述
本文叙述了如何在VB中实现控件的IobjectSafety接口,以标志该控件是脚本安全和初始化安全的。VB控件默认的处理方式是在注册表中注册组件类来标识其安全性,但实现IobjectSafety接口是更好的方法。本言语包括了实现过程中所需的所有代码。

请注意,控件只有确确实实是安全的,才能被标识为“安全的”。本文并未论及如何确保控件的安全性,这个问题请参阅Internet Client Software Development Kit (SDK)中的相关文档 "Safe Initialization and Scripting for ActiveX Controls",它在Component Development 栏目中。

 

相关信息:
<此处略去了一段也许无关紧要的警告>

现在开始循序渐进地举例说明怎样创建一个简单的VB控件,以及怎样将它标识为脚本安全和初始化安全。
首先新建一个文件夹来存放在本例中所产生的文件。

从VB CD-ROM取得OLE 自动化类库的制作工具。将VB安装光盘中/Common/Tools/VB/Unsupprt/Typlib/目录下所有内容一并拷贝到前面新建的项目文件夹中。


把下列内容拷贝到“记事本”中,然后保存到上述文件夹,文件名为Objsafe.odl:


      [
          uuid(C67830E0-D11D-11cf-BD80-00AA00575603),
          helpstring("VB IObjectSafety Interface"),
          version(1.0)
      ]
      library IObjectSafetyTLB
      {
          importlib("stdole2.tlb");
          [
              uuid(CB5BDC81-93C1-11cf-8F20-00805F2CD064),
              helpstring("IObjectSafety Interface"),
              odl
          ]
          interface IObjectSafety:IUnknown {
              [helpstring("GetInterfaceSafetyOptions")]
              HRESULT GetInterfaceSafetyOptions(
                        [in]  long  riid,
                        [in]  long *pdwSupportedOptions,
                        [in]  long *pdwEnabledOptions);

              [helpstring("SetInterfaceSafetyOptions")]
              HRESULT SetInterfaceSafetyOptions(
                        [in]  long  riid,
                        [in]  long  dwOptionsSetMask,
                        [in]  long  dwEnabledOptions);
           }
       }
在命令行提示符下切换到项目文件夹,输入下列命令创建一个.tlb 文件:


MKTYPLIB objsafe.odl /tlb objsafe.tlb
在VB中新建一个ActiveX Control 项目。修改属性,把项目命名为IobjSafety,控件命名为DemoCtl。在控件上放置一个按钮,命名为cmdTest,在它的Click事件中加入一句代码 MsgBox "Test" 。


打开菜单“工程->引用”,点“浏览”,找到刚刚建立的Objsafe.tlb,把它加入到引用中。


增加一个新module名为basSafeCtl,并在其中加入下列代码:


      Option Explicit

      Public Const IID_IDispatch = "{00020400-0000-0000-C000-000000000046}"
      Public Const IID_IPersistStorage = _
        "{0000010A-0000-0000-C000-000000000046}"
      Public Const IID_IPersistStream = _
        "{00000109-0000-0000-C000-000000000046}"
      Public Const IID_IPersistPropertyBag = _
        "{37D84F60-42CB-11CE-8135-00AA004BB851}"

      Public Const INTERFACESAFE_FOR_UNTRUSTED_CALLER = &H1
      Public Const INTERFACESAFE_FOR_UNTRUSTED_DATA = &H2
      Public Const E_NOINTERFACE = &H80004002
      Public Const E_FAIL = &H80004005
      Public Const MAX_GUIDLEN = 40

      Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
         (pDest As Any, pSource As Any, ByVal ByteLen As Long)
      Public Declare Function StringFromGUID2 Lib "ole32.dll" (rguid As _
         Any, ByVal lpstrClsId As Long, ByVal cbMax As Integer) As Long

      Public Type udtGUID
          Data1 As Long
          Data2 As Integer
          Data3 As Integer
          Data4(7) As Byte
      End Type

      Public m_fSafeForScripting As Boolean
      Public m_fSafeForInitializing As Boolean

      Sub Main()
          m_fSafeForScripting = True
          m_fSafeForInitializing = True
      End Sub
在工程属性中把启动对象改成Sub Main确保上述代码会被执行。m_fSafeForScripting 和m_fSafeForInitializing两件变量的值分别指定了脚本安全和初始化安全取值。


打开控件代码窗口,在声明部分加入如下代码(如果有Option Explicit语句,当然要保证代码放在其后):


Implements IObjectSafety
把下面两个过程代码拷贝到控件代码中:


      Private Sub IObjectSafety_GetInterfaceSafetyOptions(ByVal riid As _
      Long, pdwSupportedOptions As Long, pdwEnabledOptions As Long)

          Dim Rc      As Long
          Dim rClsId  As udtGUID
          Dim IID     As String
          Dim bIID()  As Byte

          pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER Or _
                                INTERFACESAFE_FOR_UNTRUSTED_DATA

          If (riid <> 0) Then
              CopyMemory rClsId, ByVal riid, Len(rClsId)

              bIID = String$(MAX_GUIDLEN, 0)
              Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)), MAX_GUIDLEN)
              Rc = InStr(1, bIID, vbNullChar) - 1
              IID = Left$(UCase(bIID), Rc)

              Select Case IID
                  Case IID_IDispatch
                      pdwEnabledOptions = IIf(m_fSafeForScripting, _
                    INTERFACESAFE_FOR_UNTRUSTED_CALLER, 0)
                      Exit Sub
                  Case IID_IPersistStorage, IID_IPersistStream, _
                     IID_IPersistPropertyBag
                      pdwEnabledOptions = IIf(m_fSafeForInitializing, _
                    INTERFACESAFE_FOR_UNTRUSTED_DATA, 0)
                      Exit Sub
                  Case Else
                      Err.Raise E_NOINTERFACE
                      Exit Sub
              End Select
          End If
      End Sub

      Private Sub IObjectSafety_SetInterfaceSafetyOptions(ByVal riid As _
      Long, ByVal dwOptionsSetMask As Long, ByVal dwEnabledOptions As Long)
          Dim Rc          As Long
          Dim rClsId      As udtGUID
          Dim IID         As String
          Dim bIID()      As Byte

          If (riid <> 0) Then
              CopyMemory rClsId, ByVal riid, Len(rClsId)

              bIID = String$(MAX_GUIDLEN, 0)
              Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)), MAX_GUIDLEN)
              Rc = InStr(1, bIID, vbNullChar) - 1
              IID = Left$(UCase(bIID), Rc)

              Select Case IID
                  Case IID_IDispatch
                      If ((dwEnabledOptions And dwOptionsSetMask) <> _
                   INTERFACESAFE_FOR_UNTRUSTED_CALLER) Then
                          Err.Raise E_FAIL
                          Exit Sub
                      Else
                          If Not m_fSafeForScripting Then
                              Err.Raise E_FAIL
                          End If
                          Exit Sub
                      End If

                  Case IID_IPersistStorage, IID_IPersistStream, _
                IID_IPersistPropertyBag
                      If ((dwEnabledOptions And dwOptionsSetMask) <> _
                    INTERFACESAFE_FOR_UNTRUSTED_DATA) Then
                          Err.Raise E_FAIL
                          Exit Sub
                      Else
                          If Not m_fSafeForInitializing Then
                              Err.Raise E_FAIL
                          End If
                          Exit Sub
                      End If

                  Case Else
                      Err.Raise E_NOINTERFACE
                      Exit Sub
              End Select
          End If
      End Sub
保存后,把工程编译成OCX文件。现在控件已经实现了IObjectSafety 接口。在.htm中加入这件控件试一试吧。

 

经过以上资料的指导,终于在用户机器上显示了控件。

总结:

要使用户机器正常使用ACTIVEX控件,必须满足以下条件

1、程序代码必须正确(这虽然是废话,但是有时候很多大问题总是出现在很白痴的地方)
2、用户机器必须正确安装和注册控件(最常见的方法当然就是通过自动下载安装,这个需要数字签名,当然手动也可以)
3、控件必须申明安全接口(新手常长忽略掉这个重要部分)
4、IE浏览器设置(前3条做好的话,默认设置即可满足要求)

暂时就这么多了,还有什么问题,以后补充

版权声明:本文为博主原创文章,未经博主允许不得转载. dawngrp.com

ActiveX控件缺失解决方法

在对学生信息管理系统进行
  • u013044000
  • u013044000
  • 2014年07月06日 21:36
  • 1819

基于对话框的ActiveX控件开发以及MFC对话框调用点击无响应问题

基于MFC的ActiveX控件,主要功能是加载图片进行局部放大。 Demo小样:一、放大控件的设计过程1.新建MFC ActiveX项目 2.添加对话框MyDlg类,对话框ID为IDD_MYDLG...
  • u010684134
  • u010684134
  • 2015年12月07日 15:05
  • 1372

vs编写ActiveX控件,无法运行调试配置

在VS中开发MFC ActiveX控件,开发完后,通常使用VS自带的容器ActiveX Control Test Container来运行ActiveX控件。此容器在VS安装后的文件中是找不到的,需要...
  • evil_119
  • evil_119
  • 2015年06月17日 09:18
  • 733

ACTIVEX控件加载上了但没作用

IE加载activex的水很深啊,说不定什么问题就导致加载不了了,今天终于解决了这个头疼的问题,记录一下 现象:一开始的时候activex可以正常加载并使用,可是装了某某activex控件后,我的a...
  • rankun1
  • rankun1
  • 2016年06月22日 15:27
  • 2360

登入系统后加载ActiveX控件已被阻止的解决方法

在登入系统之后,系统会自动加载控件,所以浏览器安全级别太高的话是无法加载的,所以要对浏览器进行设置,下面是在加载控件时经常出现的错误,如图5-1和图5-2。   图5-1 ActiveX控件已被阻止 ...
  • w630636065
  • w630636065
  • 2014年02月12日 08:38
  • 9745

解决“未能实例化ActiveX控件”的三种方法

方法一、 使用Regsvr32.exe程序对ActiveX控件进行注册     对于未注册过的ActiveX控件可使用此软件对其进行注册,外来ActiveX控件要应用到自己的程序中也必须进行注册...
  • dassh
  • dassh
  • 2014年12月07日 23:08
  • 3473

ActiveX控件localhost可以调用,内外网IP不可以的解决办法

开发ActiveX控件过程中遇到这样的问题: 本机上开发完成后,用TstCon测试接口没问题。js写静态页面测试调用没问题。但是给到web端开发,他们使用内网IP或者外网地址时,会报错。如图: 开...
  • passionkk
  • passionkk
  • 2016年06月17日 16:22
  • 1529

无法获取控件的窗口句柄和不支持无窗口的 ActiveX 控件

在win7 下面调用ActiveX  出现如题错误。xp下测试正常。 编译环境: VS2008  编程语言:CSharp  系统版本:Windows7  OCX控件:无窗口的OCX控件 ...
  • start2011
  • start2011
  • 2013年11月25日 15:35
  • 3297

VC ActiveX 控件 开发总结

VC 制作ActiveX 控件(OCX) http://ileson.iteye.com/blog/1002910 1、vc6下建立一下activeX工程     详见http://hi...
  • bcbobo21cn
  • bcbobo21cn
  • 2016年03月27日 12:19
  • 1533

让Firefox支持ActiveX控件

让Firefox支持ActiveX控件   疑难集锦字号   我现在用Firefox作为主力浏览器,Firefox下能否支持ActiveX插件?所为对某些包含ActiveX控件的网站并不兼...
  • wlanye
  • wlanye
  • 2014年11月21日 07:04
  • 5390
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ACTIVEX控件无法显示的问题
举报原因:
原因补充:

(最多只允许输入30个字)