使用delphi開發OCX插件


在C/S開發主導的時代,delphi無疑是windows開發的佼佼者,號稱 vb killer,隨着 java 和 C#的崛起,互聯網開發時代來到,delphi也就失去了往日的光環,雖然現在絕大部分項目工作都是java web項目,但眾所周知,web應用,要跟硬件打交道,特別是在瀏覽器中,單純的jsp或者html、js,都無法實現,由於企業應用開發少不了要與硬件對接,如考勤機(人臉識別或指紋機)、門禁機、PDA(盤點機)等等,要實現在瀏覽器中對接硬件,其中一個可行方案就是開發IE瀏覽器下的OCX插件,OCX的本質就是一個C/S程序,可以訪問瀏覽器所在電腦的資源,最常見的就是dll,通過dll操作與電腦相連的硬件。因為delphi太久沒用,而ocx插件的開發也不是經常需要,導致每次開發都要翻看 以前的項目或資料重溫技術實現,最近又有一個項目,即使用便攜式指紋機實現硬件控制集團查看薪金權限,薪資管理員除了有系統功能操作權限外,還需要到人事部登記指紋,領取指紋機,在操作工資相關功能前,進行指紋認證,認證通過才能正常操作系統,趁着這次項目,把ocx開發過程記錄下來,以備以后的不時之需,也供其他同行參考。

閑話少說,直入正題,本文提及的項目,使用delphi 7,下面從新建一個ocx項目開始,一步一步指引如何用delph 7開發一個可以在 IE 上運行的OCX插件;

一、插件ACTIVEX工程

1、啟動Delphi,點擊菜單 File->New->Other:

2、選擇【ActiveX】標簽頁,選中Active Form圖標:

注:本案例中的OCX插件有用戶交互界面,所以使用 ActiveX Form。

3、為ActiveX項目和窗體對象命名:

由上圖可見,只需修改ActiveX窗體名稱、窗體實現代碼文件名、項目名即可,其他選項默認。

點擊【ok】按鈕完成項目創建,完成創建后的界面如下圖:

4、保存項目

點擊菜單 File->Save All,在彈出的保存框,選擇一個保存的目錄,然后一直點擊【保存】即可:

 至此已完成一個ActiveX項目的創建,可以點擊菜單 View->Units瀏覽delphi創建的相關代碼文件:

上面三個文件是delphi自動產生的,其概要作用是:

FingerEnrollFormImplOcx的實現類,編寫代碼基本都在這個文件中進行;

OfficeOcx:項目組織文件,一般不需要手工修改,由delphi自動維護;

OfficeOcx_TLBOCX類庫代碼文件,一般也不需要手工修改;

二、設計OCX接口方法

應用程序(本例即瀏覽器中的js代碼)通過OCX提供的接口與OCX進行交互,Delphi會自動為OCX插件創建接口,我們只需跟進實際業務需要,為OCX接口增加相應的方法即可,如本案例需要添加5個接口方法:

InitDevice:鏈接指紋機;

SetUser:設置當前登記指紋的用戶資料;

GetResult:獲取指紋登記結果,0 失敗,1成功;

GetFinger1:獲取已登記的第一枚指紋數據;(每個用戶登記兩枚指紋,此款指紋機可以將采集的指紋信息轉換成字符串,以便存儲在數據庫中)

GetFinger2:獲取已登記的第二枚指紋數據;

下面介紹如何添加接口;

1、點擊菜單 View->Type Libraly:

注:Type Libraly 是Delphi中一個很重要的工具,尤其是開發類庫這一類的項目,必不可少。

2、在彈出的對話框中,右鍵左邊目錄樹中的,然后選擇 New->Method:

3、為新的方法命名為:InitDevice,然后為方法添加參數:

4、完成以上操作后,點擊菜單欄的刷新圖標:

刷新后可查看FingerEnrollFormImpl代碼中是否已包含此方法:

注:如找不到FingerEnrollFormImpl文件,可以點擊菜單 View->Units進行選擇並打開;

5、重復2-4步驟添加其他方法,下面只列出SetUser方法截圖說明,其他方法的創建類似,記得每個方法改名和添加完參數后,要點擊刷新圖標:

5個方法創建后顯示如下:

三、為接口方法添加代碼

這一部分是常規的Delphi開發,跟OCX插件開發技術本身並沒有直接關系,所以如果使用Delphi開發OCX插件,需要有一定的Delphi開發基礎,本案例並不會細談如何使用delphi進行軟件開發,接口方法都是根據實際業務需要進行代碼開的,這里只展示OCX窗體界面最終的效果:

窗體上有一個特殊的控件:,這個控件在安裝了廠家提供的指紋機驅動程序后,可以導入到Delphi中進行使用,所以非常方便,下面順帶介紹一下如何導入操作系統中已安裝的控件:

點擊菜單 Component->Import ActiveX Control...:

在彈出的對話框中:

點擊【Install】后,可以在【ActiveX】中看到這個控件:

已安裝的第三方控件,可以像其他常規控件一下,拖拽到窗體上進行開發,非常方便!

四、編譯OCX插件

編譯之后,在項目代碼保存路徑下可以看到已生成OCX插件:

把這個OCX文件拷貝到web項目下,就可以發布了。

五、發布並訪問OCX插件:

 有了以上的OCX文件,就可以將它拷貝到web項目下,在頁面中引入並使用它;

本案例為java web項目,服務器環境是tomcat 6和jdk 1.6;

1、將 FtnFingerEnrollForm.ocx 文件拷貝到web項目某目錄下,如:

注:WebRoot 為web 項目代碼根目錄;

2、新建一個jsp文件 ocxTest.jsp:

注:jsp文件的存放目錄沒有特別要求,只要tomcat啟動后,能通過IE瀏覽器訪問到即可;

jsp文件代碼如下:

<%@page language="java" contentType="text/html;charset=UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
		+ request.getServerName() + ":" + request.getServerPort()
		+ path;
 %>
<!DOCTYPE html>
<html>
<head>
 <title>OCX插件測試</title>
 <script type="text/javascript">
	
 </script>
</head>
<body>
<object id="fingerEnroll" classid="clsid:061D3A76-B267-465A-9529-F438AADD90B9"
	codebase="<%=basePath%>/frame/ActiveX/FtnFingerEnrollForm.ocx#version=1,0,0,0"
	width="606"	 height="271"
>
</object>
</body>
</html>

 object標簽的 classid 值來自delphi項目的 FtnFingerEnrollForm_TLB.pas:

codebase屬性值為 ocx 文件在 web 項目中的 url,#version=1,0,0,0 為 ocx 控件的版本號,可以在delphi中進行查看:

點擊菜單 Project->Options...:

3、啟動tomcat,在IE中輸入jsp文件的url:

可見OCX插件被成功加載了;

在IE中加載ActiveX插件,需要做一系列的配置,如果發布到外網使用,可能還需要證書和簽名,由於平常的項目都是企業內部的應用系統,所以一般將IE安全級別降低,並將服務器IP設置為信任站點,具體的配置可以百度一下,網上有很多相關資料。

 六、調用OCX接口方法

接下來演示如何在js中調用OCX接口方法,這點很重要,如果js能調用OCX接口方法,就意味着可以在瀏覽器中操作電腦上的所有資源,這在純瀏覽器環境中是做不到的。

1、修改OCX代碼

在修改OCX代碼之前,需要修改OCX項目的一些屬性,由於HTML頁面裝載OCX插件時需要指定文件版本號,瀏覽器第一次加載之后,就算OCX代碼被修改了,但是版本號沒有改,瀏覽器是不會加載新的OCX插件的。

在Delphi中打開OCX項目,點擊菜單 Project->Options...:

參照以上紅框的選項進行設置,點擊【OK】按鈕,以后修改代碼后,點擊 Project->Build FtnFingerEnrollForm時,Delphi會自動為版本號加1,可以右鍵生成的 FtnFingerEnrollForm.ocx文件進行查看:

在Delphi中修改 GetResult 方法,簡單的返回一個數值10,返回到jsp的js腳本調用中,如果js能正確顯示該數值,證明接口調用成功。

下面是 GetResult 方法代碼:

function TFingerEnrollForm.GetResult: SYSINT;
begin
  Result:= 10;
end;

2、重新構建OCX項目,點擊菜單 Project->Build FtnFingerEnrollForm,將新生成的 FtnFingerEnrollForm.ocx 重新拷到web項目發布目錄下,覆蓋原來的文件;

3、修改jsp文件,增加一個按鈕,點擊調用 GetResult 方法,將該方法返回的值 alert 出來:

<%@page language="java" contentType="text/html;charset=UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
		+ request.getServerName() + ":" + request.getServerPort()
		+ path;
 %>
<!DOCTYPE html>
<html>
<head>
 <title>OCX插件測試</title>
 <script type="text/javascript">
	function testGetResult() {
		var ocx = document.getElementById("fingerEnroll");
		if (ocx) {
			var i = ocx.GetResult();
			alert('GetResult返回的值為:' + i);
		} else {
			alert("OCX控件裝載失敗!");
		}
	}
 </script>
</head>
<body>
<object id="fingerEnroll" classid="clsid:061D3A76-B267-465A-9529-F438AADD90B9"
	codebase="<%=basePath%>/frame/ActiveX/FtnFingerEnrollForm.ocx#version=1,0,0,4"
	width="606"	 height="271"
></object>
<br/>
<input type="button" value="test GetResult" onclick="testGetResult();"/>
</body>
</html>

 注意 version=1,0,0,4要跟OCX文件的版本號一致;

4、在IE瀏覽器中驗證結果:

 

七、OCX控件最終效果測試

jsp代碼:

<%@page language="java" contentType="text/html;charset=UTF-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
		+ request.getServerName() + ":" + request.getServerPort()
		+ path;
 %>
<!DOCTYPE html>
<html>
<head>
 <title>OCX插件測試</title>
 <script type="text/javascript">
 	function getOcx() {
 		return document.getElementById("fingerEnroll");
 	}
 	
	function initDevice() {
		var ocx = getOcx();
		var i = ocx.InitDevice();
	}
	
	function setUser() {
		var ocx = getOcx();
		ocx.SetUser(document.getElementById("userCode").value, document.getElementById("userName").value, 
							document.getElementById("deptName").value, document.getElementById("compName").value);
	}
	
	function getFinger() {
		var ocx = getOcx();
		document.getElementById("finger1").value = ocx.getFinger1();
		document.getElementById("finger2").value = ocx.getFinger2();
	}
 </script>
</head>
<body>
<input type="button" value="連接設備" onclick="initDevice();"/>
<br/>
<br/>
工號:<input type="text" value="TX8888" id="userCode"/>
姓名:<input type="text" value="張三" id="userName"/>
部門:<input type="text" value="人事部" id="deptName"/>
公司:<input type="text" value="DMP" id="compName"/>
<input type="button" value="寫入用戶信息" onclick="setUser();"/>
<br/>
<br/>
<object id="fingerEnroll" classid="clsid:061D3A76-B267-465A-9529-F438AADD90B9"
	codebase="<%=basePath%>/frame/ActiveX/FtnFingerEnrollForm.ocx#version=1,0,0,19"
	width="650"	 height="271"
></object>
<br/>
<br/>
<br/>
<input type="button" value="讀取指紋" onclick="getFinger();"/>
<br/>
<br/>
指紋1:
<br/>
<textarea rows="3" cols="100" id="finger1"></textarea>
<br/>
<br/>
指紋2:
<br/>
<textarea rows="3" cols="100" id="finger2"></textarea>
</body>
</html>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM