开发ActiveX控件调用另一个ActiveX系列1——开发一个MFC ActiveX控件

ActiveX开发的教程有很多,我也从中受益匪浅,例如以下这几篇:

基本教程:http://www.cnblogs.com/guenli/articles/1629915.html

注意事项:http://jon-lt.iteye.com/blog/1676272

属性、方法开发:http://blog.csdn.net/waxgourd0/article/details/7652478

但是由于我的目的是开发一个身份证识别仪的ActiveX控件,因此我就要先仿照识别仪ActiveX开发一个ActiveX。

本文讲述如何模仿开发一个ActiveX控件,如果对此不感兴趣请阅读系列后续文章。

我用vs2012,win8操作系统。

新建MFC ActiveX控件工程

我们选择ActiveX“运行时不可见”,“关于对话框随”便选不选都可以。项目生成后结构

建属性和方法

根据身份证识别仪的测试页面,我们知道身份证的识别仪ActiveX必须有以下属性和方法

var CVR_IDCard = document.getElementById("CVR_IDCard");
var strReadResult = CVR_IDCard.ReadCard();
if(strReadResult == "0"{
    ClearForm();
    document.all[‘Name‘].value = CVR_IDCard.Name;
    document.all[‘Sex‘].value = CVR_IDCard.Sex;
    document.all[‘Nation‘].value = CVR_IDCard.Nation;
    document.all[‘Born‘].value = CVR_IDCard.Born;
    document.all[‘Address‘].value = CVR_IDCard.Address;
    document.all[‘CardNo‘].value = CVR_IDCard.CardNo;
    document.all[‘IssuedAt‘].value = CVR_IDCard.IssuedAt;
    document.all[‘EffectedDate‘].value = CVR_IDCard.EffectedDate;
    document.all[‘ExpiredDate‘].value = CVR_IDCard.ExpiredDate;
    document.all[‘SAMID‘].value = CVR_IDCard.SAMID;
    document.all[‘pic‘].src = CVR_IDCard.Pic;
    document.all[‘Picture‘].value = CVR_IDCard.Picture;
    document.all[‘PictureLen‘].value = CVR_IDCard.PictureLen
}

我们先建方法ReadCard,从方法上看,输入参数应该为空,返回值应该是个string。在“类视图”中选择如下路径,添加方法

对于返回字符串的,我们选择BSTR类型,输入方法名,直接点完成即可。

然后需要建Name、Nation、Born等方法,看来都是字符串类型即可。同样的路径,选择“添加属性”

类型仍然选择字符串BSTR,选择Get/Set方法,输入属性名Name

这时在ActiveXTestCtrl.cpp中就会有对应的属性和方法实现代码

我们在这里做一个最简单的实现,ReadCard直接返回0,GetName返回“Hello World”

BSTR CActiveXTestCtrl::ReadCard(void)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    CString strResult;
    strResult = "0";
    return strResult.AllocSysString();
}

BSTR CActiveXTestCtrl::GetName(void)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    CString strResult;
    strResult = "Hello World";
    return strResult.AllocSysString();
}

void CActiveXTestCtrl::SetName(LPCTSTR newVal)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());
    SetModifiedFlag();
}

生成测试

打开ActiveXTest.idl文件,这个相当于dll中的def文件那样,会有很多控件的关键信息。包括接口、classid

通过coclass是ActiveXTest,找到对应的classid是“AF7E1FF8-E4DC-47B8-BAC9-F06832ABB5F2”

//  CActiveXTestCtrl 的类信息
    [
        uuid(AF7E1FF8-E4DC-47B8-BAC9-F06832ABB5F2)
    ]
    coclass ActiveXTest
    {
        [default] dispinterface _DActiveXTest;
        [default, source] dispinterface _DActiveXTestEvents;
    };

那么我们可以用原来识别仪驱动中带的测试页面,修改其中的classid为“AF7E1FF8-E4DC-47B8-BAC9-F06832ABB5F2”,就成为我们ActiveX控件的测试页了,代码如下

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0027)http://www.chinaidcard.com/ -->

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>华视电子CVR100B/S测试页</title>
</head>
<body style="text-align: center">
 <form id="form1" runat="server">
    <OBJECT classid="clsid:AF7E1FF8-E4DC-47B8-BAC9-F06832ABB5F2"
      id="CVR_IDCard" name="CVR_IDCard" width="0" height="0" >
</OBJECT>

            <script language="javascript" type ="text/javascript">

function ClearForm() {
                       document.all[‘Name‘].value = "";
                       document.all[‘Sex‘].value = "";
                       document.all[‘Nation‘].value = "";
                       document.all[‘Born‘].value = "";
                       document.all[‘Address‘].value = "";
                       document.all[‘CardNo‘].value = "";
                       document.all[‘IssuedAt‘].value = "";
                       document.all[‘EffectedDate‘].value = "";
                       document.all[‘ExpiredDate‘].value = "";
                       document.all[‘SAMID‘].value = "";
                       document.all[‘pic‘].src = "";
                       document.all[‘Picture‘].value = "";
                       document.all[‘PictureLen‘].value = "";
                       return true;
}
function Button1_onclick() {
                    var CVR_IDCard = document.getElementById("CVR_IDCard");
                    var strReadResult = CVR_IDCard.ReadCard();
                    if(strReadResult == "0")
                    {
                        ClearForm();
                          document.all[‘Name‘].value = CVR_IDCard.Name;
                          document.all[‘Sex‘].value = CVR_IDCard.Sex;
                          document.all[‘Nation‘].value = CVR_IDCard.Nation;
                          document.all[‘Born‘].value = CVR_IDCard.Born;
                          document.all[‘Address‘].value = CVR_IDCard.Address;
                          document.all[‘CardNo‘].value = CVR_IDCard.CardNo;
                          document.all[‘IssuedAt‘].value = CVR_IDCard.IssuedAt;
                          document.all[‘EffectedDate‘].value = CVR_IDCard.EffectedDate;
                          document.all[‘ExpiredDate‘].value = CVR_IDCard.ExpiredDate;
                          document.all[‘SAMID‘].value = CVR_IDCard.SAMID;
                          document.all[‘pic‘].src = CVR_IDCard.Pic;
                          document.all[‘Picture‘].value = CVR_IDCard.Picture;
                          document.all[‘PictureLen‘].value = CVR_IDCard.PictureLen
                      }
                      else
                      {
                        ClearForm();
                        alert(strReadResult);
                      }

}

function Button3_onclick() {
                    var CVR_IDCard = document.getElementById("CVR_IDCard");
                    CVR_IDCard.AboutBox();

}

                    </script>
     &nbsp;华视电子CVR100 B/S 测试程序<table style="width: 638px; height: 273px; border-top-style: groove; border-right-style: groove; border-left-style: groove; background-color: transparent; border-bottom-style: groove;">
         <tr>
             <td style="width: 98px">
                 姓名:</td>
             <td style="text-align: left" colspan="3">
                 <input id="Text1" type="text" style="width: 155px" name="Name" /></td>
             <td style="width: 138px; text-align: left;" rowspan="3">
                 <img  src="" style="width: 91px; height: 108px" name="pic"/></td>
         </tr>
         <tr>
             <td style="width: 98px">
                 性别:</td>
             <td style="width: 80px">
                 <input id="Text2" type="text" name="Sex" style="width: 154px" /></td>
             <td style="width: 58px">
                 民族:</td>
             <td style="width: 59px">
                 <input id="Text3" type="text" name="Nation" style="width: 94px" /></td>
         </tr>
         <tr>
             <td style="width: 98px">
                 出生日期:</td>
             <td style="text-align: left;" colspan="3">
                 <input id="Text4" type="text" style="width: 151px" name="Born" /></td>
         </tr>
         <tr>
             <td style="width: 98px">
                 地址:</td>
             <td colspan="4" style="text-align: left">
                 <input id="Text5" style="width: 505px" type="text" name="Address" /></td>
         </tr>
         <tr>
             <td style="width: 98px">
                 身份号码:</td>
             <td colspan="4" style="text-align: left">
                 <input id="Text6" style="width: 506px" type="text" name="CardNo" /></td>
         </tr>
         <tr>
             <td style="width: 98px">
                 签发机关:</td>
             <td colspan="4" style="text-align: left">
                 <input id="Text7" style="width: 505px" type="text" name="IssuedAt" /></td>
         </tr>
         <tr>
             <td style="width: 98px">
                 有效期限:</td>
             <td colspan="4" style="text-align: left">
                 <input id="Text8" style="width: 163px" type="text" name="EffectedDate" />至<input id="Text10" style="width: 163px" type="text" name="ExpiredDate" /></td>
         </tr>
         <tr>
             <td style="width: 98px; text-align: left;">
                 模块号码:</td>
             <td colspan="4" style="text-align: left">
                 <input id="Text9" style="width: 506px" type="text" name="SAMID" /></td>
         </tr>
         <tr>
             <td style="width: 98px; text-align: left; height: 136px;">
                 照片编码:</td>
             <td colspan="4" style="text-align: left; height: 136px;">
                 <textarea id="TextArea1" name="Picture" style="width: 509px; height: 115px"></textarea></td>
         </tr>
         <tr>
             <td style="width: 98px; text-align: left">
                 编码长度:</td>
             <td colspan="4" style="text-align: left">
                 <input id="Text11" style="width: 508px" type="text" name="PictureLen"/></td>
         </tr>
     </table>

    </form>
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<input id="Button1" type="button" value="读   卡" onclick="return Button1_onclick()" />
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp; &nbsp;<input id="Button3" type="button" value="关   于" onclick="return Button3_onclick()" />
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
    &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;

</body>
</html>

编译项目,如果出现以下错误,别担心,不是代码问题,是因为VS没有权限注册ActiveX控件到注册表

警告    1    warning MSB3075: 命令“regsvr32 /s "f:\ActiveXTest\ActiveXTest\Debug\ActiveXTest.ocx"”已退出,代码为 5。请验证您是否有足够的权限来运行此命令。    C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets    1609    5    ActiveXTest

错误    2    error MSB8011: Failed to register output. Please try enabling Per-user Redirection or register the component from a command prompt with elevated permissions.    C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Microsoft.CppCommon.targets    1621    5    ActiveXTest

我们访问生成目录

新建一个脚本setup.bat

cd /d "%~dp0"
regsvr32.exe ActiveXTest.ocx

然后右键,以管理员身份运行

这样就注册成功了

我们还可以进入注册表regedit.exe,查看HKEY+CLASSES_ROOT\Wow6432Node(不同操作系统这里不一样)\CLSID\

{AF7E1FF8-E4DC-47B8-BAC9-F06832ABB5F2}中,看到这个ID已经对应磁盘上对应路径的ocx文件了。

运行

如果是VS2010开发,则至此可以运行测试。但是VS2012开发的项目,仍需要做一些加工——在代码中实现IObjectSafety接口,参见如下:

用VS2012做MFC ActiveX控件并使用html、c#、c++测试容器:http://blog.csdn.net/zengraoli/article/details/17019513

编译后,打开上面准备好的“测试页.html”,点击“读卡”按钮后则显示了Hello World,用同样的方式实现其他属性。

至此,我们就实现了一个高仿的身份证识别仪读取ActiveX控件。

如果要伪造身份证识别仪读取结果,欺骗业务系统说数据是身份证识别仪读入的,只需要修改相关GUID。后面再说就太危险了,怕查水表,就不深入了。

附代码:代码

时间: 2024-07-31 01:23:47

开发ActiveX控件调用另一个ActiveX系列1——开发一个MFC ActiveX控件的相关文章

VC2005从开发MFC ActiveX ocx控件到发布到.net网站的全部过程

开篇语:最近在弄ocx控件发布到asp.net网站上使用,就是用户在使用过程中,自动下载安装ocx控件.(此文章也是总结了网上好多人写的文章,我只是汇总一下,加上部分自己的东西,在这里感谢所有在网上发表相关内容的朋友们.) ActiveX控件用于Web的过程是将控件嵌入主页中,用户通过浏览器访问该主页时,将主页中的控件下载,并在用户机器上注册,以后就可在用户的浏览器上运行.控件下载一次后就驻留在用户本地机器上,下次再访问相同的主页时,可不再下载该控件,而是直接运行用户本地的控件.这里控件容器就是

[activeX]VC2005开发MFC ActiveX ocx控件全过程[转]

ActiveX控件用于Web的过程是将控件嵌入主页中,用户通过浏览器访问该主页时,将主页中的控件下载,并在用户机器上注册,以后就可在用户的浏览器上运行.控件下载一次后就驻留在用户本地机器上,下次再访问相同的主页时,可不再下载该控件,而是直接运行用户本地的控件.这里控件容器就是浏览器,用户不需要通过浏览器调用控件的属性或方法.因此,开发面向Web的ActiveX控件比开发桌面的控件还要简单些,所复杂的是如何将该控件很好地嵌入主页,使用户能正常浏览.下面介绍这个问题. 一.        创建MFC

VS2010开发MFC ActiveX,摄像头拍照上传Webservice(1)

最近工作项目,BS中需要用到摄像头拍照,需要存储本地,同时上传到服务器,尝试使用vc++做ActiveX来实现. 完全没有使用过vc,上网搜索各种知识,初步完成.在这里记录下有帮助的资料. 第一步:编写一个ActiveX 第二部:使用vfw.h开发摄像头拍照功能 第三步:裁剪,转换图并上传 转载出处:http://blog.csdn.net/longhuahaha/article/details/8556964 1.ActiveX的基本概念 ActiveX控件可以看作是一个极小的服务器应用程序,

C++ 使用VS2010创建MFC ActiveX工程项目

1.ActiveX的基本概念 ActiveX控件可以看作是一个极小的服务器应用程序,它不能独立运行,必须嵌入到某个容器程序中,与该容器一起运行.这个容器包括WEB网页,应用程序窗体等... ActiveX控件的后缀名是OCX或者DLL.一般是以OCX和动态库共存的形式打包成cab或者exe的文件放在服务器上,客户端下载后运行安装cab或exe解压成OCX和动态库共存的文件,然后注册ocx文件. ActiveX控件是基于com标准,使得软件部件在网络环境中进行交互的技术集.它与具体的编程语言无关.

c++ ActiveX基础1:使用VS2010创建MFC ActiveX工程项目

1.ActiveX的基本概念 ActiveX控件可以看作是一个极小的服务器应用程序,它不能独立运行,必须嵌入到某个容器程序中,与该容器一起运行.这个容器包括WEB网页,应用程序窗体等... ActiveX控件的后缀名是OCX或者DLL.一般是以OCX和动态库共存的形式打包成cab或者exe的文件放在服务器上,客户端下载后运行安装cab或exe解压成OCX和动态库共存的文件,然后注册ocx文件. ActiveX控件是基于com标准,使得软件部件在网络环境中进行交互的技术集.它与具体的编程语言无关.

如何将 MFC ActiveX 控件标记为安全,脚本和初始化

MSDN原文.ActiveX控件标记安全(可以不仅仅是MFC ActiveX) 概要 默认情况下,MFC ActiveX 控件未标记为对脚本编写是安全的和对初始化是安全的.控制运行在 Internet Explorer 中使用的安全级别设置为中或高时,这一点很明显.在上述这些模式中,控件的数据是不安全或不可能安全脚本中使用该控件,可能会显示警告. 有两个控件可用于消除这些错误的方法.第一个涉及实现 IObjectSafety 接口的控件,并对于想要更改其行为变得"安全"的互联网浏览器的

学习方法和阶段介绍 、 iOS界面开发引入 、 构造第一个App 、 视图控制器和视图 、 控件与事件 、 InterfaceBuilder

1 创建并运行第一个App 1.1 问题 使用Xcode创建一个App项目,该应用实现功能在界面上显示Hello World标签,在模拟器中的运行结果如图-1所示: 图-1 1.2 方案 分析图-1,首先使用Xcode创建一个Single ViewApplicaton应用,起名为MyFirstApp,如图-2所示: 图-2 然后删除Xcode的导航栏里只保留TRAppDelegate.h文件和TRAppDelageat.m文件,其他代码文件.storyboard文件以及xib文件删除,如图-3所

教你写一个可快速复用定制的小键盘输入控件

引子 在Android项目开发中特别是一些稍大型的项目,面对需求文档的时候你经常会发现很多地方用到了同样的组件,但是又略有不同.比如这个: 右边是一个小键盘输入板,左边当焦点不同的时候分别用右边的小键盘输入板来输入内容,同时发现很多别的地方也用到了这个小键盘输入板. 按照以往的做法,我们可能这样子来做出这么一个控件: 写一个小键盘的布局单独存为一个layout文件 在用到这个小键盘的activity/fragment中的layout布局中include这个小键盘布局文件 在activity/fr

WP8.1学习系列(第十二章)——全景控件Panorama开发指南

2014/6/18 适用于:Windows Phone 8 和 Windows Phone Silverlight 8.1 | Windows Phone OS 7.1 全景体验是本机 Windows Phone 外观的一部分.与旨在适合手机屏幕边界的标准应用不同,全景应用通过使用超出屏幕边界的长水平画布提供了一个查看控件.数据和服务的独特方式.这些固有的动态视图使用分层动画和内容,以便各层以不同的速度流畅地平移,类似于视差效果. 本主题包括以下部分. 全景控件概述 导航支持 全景应用功能 相关