最近一直在做插件方面的工作,总结一下开发过程中的心得,也分享给大家,主要围绕以下内容展开
1.ActiveX插件开发
2.JS调用ActiveX
3.ActiveX实现安全接口
本文主要是讲vb6制作插件,由于.net环境开发下的插件客户端必须安装.netFramework相关系列版本,无疑对用户来说不太方便,故采用vb来开发插件
本例中开发的插件主要目的是让JS调用其方法,与此同时实现插件的安全接口(这样安装一次之后浏览器就不会阻止了,简单的就可以这么理解)
一. 建立ActiveX
1.打开VB6.o,新建ActiveX控件工程,保存工程名为Project,可默认使用当前的UserControl1用户控件,在UserControl1用户控件中编写如下代码,并保存工程和控件
MsgBox " 您好: " & str & " 插件测试成功! " End
Function
2.实现安全接口,这样更加安全
从VB CD-ROM取得OLE 自动化类库的制作工具。将VB安装光盘中\Common\Tools\VB\Unsupprt\Typlib\目录下所有内容一并拷贝到Project项目文件夹中,然后将下列内容拷贝到记事本中,将记事本命名为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);
}
}
3创建tlb文件,打开命令提示符并切换至Project项目文件夹下,运行下面的命令
MKTYPLIB objsafe.odl /tlb objsafe.tlb
4添加引用
打开菜单“工程->引用”,点“浏览”,找到刚刚建立的Objsafe.tlb,把它加入到引用中
注意:只有VB IObjectSafety Interface打上勾才算引用成功
5.选择启动项,工程->属性->启动对象,选择Sub Main,不然会引起“automation服务器不能创建对象”的错误
6.右键项目,"添加"->"添加模块",新添加一个模块并命名为basSafeCtl,在该模块中填入以下代码
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
7.向UserControl1用户控件中追加如下代码,实现安全接口
首先在用户控件代码区顶部加入
Implements IObjectSafety
之后在代码底部添加如下代码
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
8.运行工程,出现的插件网页中查看网页源代码,得到如下html代码
</ OBJECT ></ BODY ></ HTML >
9.生成OCX
vb6.0中"文件"->"生成Project.ocx",生成ocx之后运行命令提示符注册该插件,打开命令提示符并切换至Project.ocx所在目录,运行如下命令
二. JS调用ActiveX方法
新建如下网页测试,其中有两种调用ActiveX方法的方法
< head runat ="server" >
< title > 无标题页 </ title >
< script type ="text/javascript" >
function showMsgByActiveXobject(){
var ocx = new ActiveXObject( ' Project.UserControl1 ' );
ocx.msg( " zhang " );
}
function showMsgByObject(){
var abc = document.getElementById( " activeX " );
abc.msg( " Li " );
}
</ script >
< object id ="activeX" classid ="clsid:E4596214-B87A-4238-B19A-318767FBD9A5" >
</ object >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< input type ="button" value ="测试1" onclick ="showMsgByActiveXobject()" />
< input type ="button" value ="测试2" onclick ="showMsgByObject()" />
</ div >
</ form >
</ body >
</ html >