開發ActiveX控件調用另外一個ActiveX系列1——開發一個MFC ActiveX控件

 

ActiveX開發的教程有不少,我也從中受益不淺,例如如下這幾篇:javascript

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

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

屬性、方法開發:http://blog.csdn.net/waxgourd0/article/details/7652478c++

 

可是因爲個人目的是開發一個身份證識別儀的ActiveX控件,所以我就要先仿照識別儀ActiveX開發一個ActiveX。c#

 

本文講述如何模仿開發一個ActiveX控件,若是對此不感興趣請閱讀系列後續文章。測試

我用vs2012,win8操做系統。ui

新建MFC ActiveX控件工程

image

image

咱們選擇ActiveX「運行時不可見」,「關於對話框隨」便選不選均可以。項目生成後結構編碼

image

 

 

建屬性和方法

根據身份證識別儀的測試頁面,咱們知道身份證的識別儀ActiveX必須有如下屬性和方法url

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。在「類視圖」中選擇以下路徑,添加方法spa

image

image

對於返回字符串的,咱們選擇BSTR類型,輸入方法名,直接點完成便可。

 

而後須要建Name、Nation、Born等方法,看來都是字符串類型便可。一樣的路徑,選擇「添加屬性」

image

類型仍然選擇字符串BSTR,選擇Get/Set方法,輸入屬性名Name

image

這時在ActiveXTestCtrl.cpp中就會有對應的屬性和方法實現代碼

image

咱們在這裏作一個最簡單的實現,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控件到註冊表

image

警告    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

 

而後右鍵,以管理員身份運行

image

這樣就註冊成功了

image

咱們還能夠進入註冊表regedit.exe,查看HKEY+CLASSES_ROOT\Wow6432Node(不一樣操做系統這裏不同)\CLSID\

{AF7E1FF8-E4DC-47B8-BAC9-F06832ABB5F2}中,看到這個ID已經對應磁盤上對應路徑的ocx文件了。

image

 

運行

若是是VS2010開發,則至此能夠運行測試。可是VS2012開發的項目,仍須要作一些加工——在代碼中實現IObjectSafety接口,參見以下:

用VS2012作MFC ActiveX控件並使用html、c#、c++測試容器:http://blog.csdn.net/zengraoli/article/details/17019513

 

編譯後,打開上面準備好的「測試頁.html」,點擊「讀卡」按鈕後則顯示了Hello World,用一樣的方式實現其餘屬性。

image

 

至此,咱們就實現了一個高仿的身份證識別儀讀取ActiveX控件。

若是要僞造身份證識別儀讀取結果,欺騙業務系統說數據是身份證識別儀讀入的,只須要修改相關GUID。後面再說就太危險了,怕查水錶,就不深刻了。

附代碼:代碼

相關文章
相關標籤/搜索