编写ActiveX控件并封装为.cab文件
需求描述
厂商提供了读卡器的全套工具,包括读卡的测试工具,样例代码,文档等等(一开始的时候没发现这些工具费了很多事),根据提供的dll,封装上面的方法到一个ActiveX控件中,使得插上读卡器的PC设备使用IE浏览器访问网站即可实现读写卡的功能,而无须本地下载读卡工具。简单来说需求就是在ActiveX中引用dll并抛出一些有用的接口。
编写过程
dll调用的过程就不说了,这里一切正常,我写了一个C++类来管理这个dll的调用问题,剩下的就是把写好的类在ActiveX控件中使用即可。
ActiveX控件的创建
1. 本人用的是Visual Studio 2017,新建一个MFC ActiveX项目(没有此选项的应该是没有下载MFC的开发组件,打开下载工具下载即可):
![]()
然后一直下一步,这里需要说明一下:
![]()
如果写的ActiveX控件没有界面(MFC那种对话框之类的),1处选择none即可,2处的关于对话框可以取消选择。我写的控件只需要提供接口即可,不需要界面,界面由前端网页实现,因此选none。
2. 新建好了之后,我们看到VS工具自动给我们生成了这些文件:
![]()
当然这些文件是做什么的我也不知道,不过没关系,我们还是可以直接使用工具来实现我们的功能。这里的关键就是**类视图**了。
3. 点开类视图,点开后缀为Lib的那个东东,发现里面有两个东西:
![]()
这里面就前两个带_下划线前缀的有用,有一个以Events结尾,意思是这里控制着事件响应的方法,不带Events的是普通方法,可以直接被JS调用的方法,右键这里,选择添加栏中的添加方法即可添加想要外部JS调用的方法(接口)了。
4. 点击添加方法之后,弹出一个向导:
![]()
发现这里有许多看不懂的返回值,一般来说用得上的就是字符串类型和数字类型了,字符串在这里面的替代类型是BSTR,原本的int类型我这里就使用LONG替代了。这里我们实现一个add两个整数的方法add()。(这里也有坑,不过我这里就不详细聊了,是字符集和编码的问题)
![]()
点击完成即可。
5. 我们在解决方案那个视图里找到后缀为Ctrl的cpp文件,我们刚在添加好的方法其实在这里,写好后就可以了。
![]()
6. 现在编译这个文件,直接点击F5运行即可,但是会发现有错误:
![]()
原因是打开VS的时候不是以管理员权限打开的,而我们运行的时候VS想直接帮我们把这个ActiveX控件编译好的.ocx控件注册到我们计算机中的注册表中,因为没有权限所以注册失败报了错,我们可以手动注册这个控件:
![]()
打开管理员的命令控制台,进入到工程目录下的Debug目录,使用regsvr32命令注册我们的.ocx控件。注册成功之后,我们就完成了一半了。注册这步其实就是代表之前我们写在ActiveX控件中的代码已经注册到本地,可以直接使用了,当然也可以由IE浏览器直接调用。
7. 现在随便先写一个HTML文件测试我们的控件能不能用:
![]()
重点来了,也是我遇到的一个坑,这里面<OBJECT>标签代表着我们写的ActiveX控件对象,当然这个东西只有IE浏览器能识别,别的浏览器不支持。ID属性一定要写成你写的.ocx的文件名,因为引用的时候是直接根据这个ID的值来引用的,看的教程说这里随便写,然后用一个var a = getElementById(id)就可以引用OBJECT对象了,但是我这里怎么也不好使,后来问了朋友,从MSDN上看到了正确的示例代码,才跑通。**ID值一定是.ocx文件的名字!建议整个标签内容全部大写,因为示例代码就是如此,不这么写也许会不灵!CLASSID**需要重点说明一下,这里指的是工程文件中.idl文件最下方的那个uuid,上面标识着**CMFCActiveXControl1Ctrl 的类信息**,似乎代表着Ctrl这个类。这个文件中别的ID我都试了一遍,只有在这里写上这个才好使!(也许无界面的控件就是这样)。WIDTH和HEIGHT代表这个对象的宽和高,全为0表示就是不显示了。CLASSID的值中不要忘了**CLSID:**这个东西!
在JS中引用,直接使用ID的值,点运算符调用方法即可。
右键打开我们的HTML文件,打开方式选择IE浏览器,允许ActiveX控件,点击按钮就可以看到效果了!
终于成功了!下一步就是把写好的封装成.cab文件,无需本地注册即可使用我们写好的控件,这时候需要的就是签名打包等等步骤了,这里给出一个博客的链接,写的很全,按着他的一步步来就可以成功了,到此为止,我们的流程就结束了:)
封装.cab的教程
http://blog.csdn.net/troylemon/article/details/47975815