這段時間做了一個小型貸款軟件,包括客戶管理,交易管理,存折管理和打印,統計分析等模塊,其中要求結合存折讀卡器一起使用,比如添加存折的時候,存折號要求刷完卡后讀出來,刷卡后可以顯示客戶信息等,和銀行的刷卡機差不多。
客戶買的刷卡機器提前沒給我說一聲,商家沒有提供動態庫,接口之類的,所以只能自己寫一個對串口操作的,一般對CoM操作的程序要么用js寫,要么就是寫一個ActiveX組建,因為主要是對本機的串口操作的,所以保證讀卡程序在客戶端執行,這兩個是很好的選擇,這里我用的是后者,用C#寫了一個ActiveX組件,在實現的過程中也遇到了很多問題,剛開始自己寫了一個C/S結構的,可以正常讀取,可是B/S確出了一些問題
我才用了微軟提供的SerialPort類,大概的流程是這樣的:
首先,找到計算機中可用的COM名稱,代碼如下
{
// 獲取可用的串號
{
serialPort1.Close();
}
// 若串口可以打開說明可以用,否則繼續查找可用的串口
if (serialPort1.IsOpen)
{
serialPort1.PortName = com;
break;
}
}
其次,設置串口的參數,包括波特率,協議,數據長度等,代碼如下
serialPort1.BaudRate = 9600;
serialPort1.Parity = 0;
serialPort1.DataBits = 8;
然后,打開串口,發送命令,,這個時候設備的燈會亮,等待你的刷卡
{
serialPort1.Open();
}
byte[] data = new byte[ 2];
data[ 0] = 0x1b;
data[ 1] = 0x5d;
serialPort1.Write(data, 0, 2);
再次,調用SerialPort的DataReceived事件執行刷卡后的動作,比如刷完卡后就讓卡號獨到頁面的文本框中,這里面需要ActiceX去調用頁面的JavaScript
void serialPort1_DataReceived( object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
Thread.Sleep( 50);/
int bytes = serialPort1.BytesToRead;
byte[] buffer = new byte[bytes];
serialPort1.Read(buffer, 0, bytes);
string strbuffer = Encoding.ASCII.GetString(buffer);
string romovestartChar = strbuffer.Substring( 2);
string rightInfo = romovestartChar.Substring( 0, romovestartChar.IndexOf( ' ? '));
temphtml.execScript(functionstr + " (' " + rightInfo + " ') ", " JScript ");
if (serialPort1.IsOpen)
{
serialPort1.Close();
}
}
catch (Exception ex)
{
if (serialPort1.IsOpen)
{
serialPort1.Close();
}
MessageBox.Show(ex.Message);
}
}
其中, temphtml.execScript(functionstr + "('" + rightInfo + "')", "JScript"); 就是調用頁面的js函數的,這里簡答的說一下關於ActiveX是如何調用Js的
首先,我們要加入micsoft.mshtml引用
using mshtml;
private IHTMLWindow2 temphtml = null;
private string functionstr = "";
public void RegJs(object win, string fuc)
{
temphtml = (IHTMLWindow2)win;
if (temphtml != null && !string.IsNullOrEmpty(fuc))
{
functionstr = fuc;
}
else
{
temphtml = null;
functionstr = "";
MessageBox.Show("注冊腳本失敗");
}
}
加載頁面的時候,頁面就調用RegJs完成傳值,把窗體和js函數傳到activeX中
<script type="text/javascript">
window.onload = function () {
document.getElementById("Object1").RegJs(window, "Show"); //將頁面對象,和所需調用的js方法名傳給activex
}
//activex調用的js方法,將卡號轉到頁面的文本框中
function Show(str) {
document.getElementById("text1").value = str;
}
然后在ActiveX就可以調用temphtml.execScript(functionstr + "('" + rightInfo + "')", "JScript");就可以完成調用賦值了
接着上面的說說,自己也用按鈕測試了,當點擊按鈕的時候確實可以把值傳過去,也就是說,只要在ActiveX觸發事件,都可以實現傳值,但是問題就出現在這里了,當我觸發刷卡事件serialPort1.DataReceived的時候(這個事件卻是可以觸發,測試過了),就是傳不過去卡號,而且還報有異常和錯誤:指定的轉化無效,很是郁悶,也咨詢了高手,自己也查了資料,就是不知道是什么原因,在這里,希望知道原因的朋友給予指導,謝謝了
沒辦法,就換了一個方式,完成了
打開頁面的時候,打開串口,初始化串口參數,發送命令,然后開始刷卡,刷卡完成后,本來想放個按鈕獲得卡號的,可是感覺客戶操作起來可能不太方便,就用鍵盤代替,按下回車鍵獲取卡號,按下空格鍵重啟設備,總的來說,這樣也可以,只是沒有立刷立獲數據的效果完美吧,等以后有時間在研究其他的辦法去解決….
代碼下載: