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 https://blog.csdn.net/banmuhuangci/article/details/1817227

消息映射表

  消息映射表  1。对不同的消息,MFC用不同的宏实现消息映射  2。消息映射表处理这个类所定义的消息映射和这个类不处理而定义的消息而传递给其父类处理的消息映射  3。在BEGIN_...和END_...
  • lumg
  • lumg
  • 2001-08-03 20:54:00
  • 1619

ActiveX控件缺失解决方法

在对学生信息管理系统进行
  • u013044000
  • u013044000
  • 2014-07-06 21:36:12
  • 2054

Active X不能例示

用vc6.0打开一个网上下载的MFC程序,结果提示: 百度了一下,到网上下载了MSDATGRD.OCX和MSADODC.OCX两个文件,注册一下就好了,具体步骤如下: 先下载这两个文件,下载地...
  • lp310018931
  • lp310018931
  • 2015-05-27 01:56:03
  • 2670

Active X控件不能例示的解决方法 很简单

  • 2014年08月10日 14:49
  • 7KB
  • 下载

解决:无法打开系统服务 提示“一个或多个Activex控件无法显示”

问题: 电脑打开系统的服务时,出现“一个或多个Activex 控件无法显示”的提示,开始以为与IE设置有关,试着在Internet 选项->安全,勾选了“允许ActiveX 控件”, 但是依然无效。 ...
  • CC_JustDoIt
  • CC_JustDoIt
  • 2011-06-28 12:09:00
  • 7304

QTP录制后弹出框一个或多个ActiveX控件无法显示的解决方法

录制一段脚本代码,在专家视图窗口中编辑录制的脚本代码时,会碰到弹出一个对话窗口,提示为“当前安全设置禁止运行该页中的ActiveX 控件,因此,该页可能无法正常显示”类似的东西,而在人工操作时却没有这...
  • KerryRuan
  • KerryRuan
  • 2014-03-17 14:10:06
  • 1684

ACTIVEX控件无法显示的问题

最近开发ACTIVEX 用于上传文件但是遇到一个最严重的问题,在客户机上无法显示经过大量的资料查阅,终于发现了问题根源!首先,ACTIVEX要在用户机上正确的安装和注册肯定是需要一个数字签名的,当然,...
  • banmuhuangci
  • banmuhuangci
  • 2007-10-09 17:39:00
  • 3213

手把手教你用VB制作ActiveX控件

随着控件在可视化编程中地位地位提高,控件也成了编程中最重要的一部分。许多VB编程者也许苦于没有好看的控件,今天登高望远来教大家如何制作ActiveX控件。 一、新建工程       1.选择Acti...
  • qq_33582668
  • qq_33582668
  • 2016-06-11 19:41:00
  • 5014

VB6.0 ActiveX 控件开发详解 [第一章:创建工程]

前言         在CSDN的VB论坛上,我总是能够看见有人这样问“有没有这样的控件,一个列表框,每一个项前面有一个按钮”(这是例子),又或者见到这样:“怎么样做一个ActiveX控件?”,诸如此...
  • JiLuoXingRen
  • JiLuoXingRen
  • 2011-08-03 18:19:50
  • 26381

web页面调用ActiveX

原文地址:http://www.cnblogs.com/qguohog/archive/2013/01/25/2876828.html 简单总结一下前几篇文章的内容,《浏览器插件之A...
  • NRlovestudy
  • NRlovestudy
  • 2015-07-24 14:08:23
  • 425
收藏助手
不良信息举报
您举报文章:ACTIVEX控件无法显示的问题
举报原因:
原因补充:

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