最近一直在做插件方面的工作,总结一下开发过程中的心得,也分享给大家,主要围绕以下内容展开
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>