說起微調其實就是對 上一篇文章 今天意外和身份證結緣 中提到的代碼碼放和調用一些巧妙的用法(至少小鬼覺得很有意思很巧妙)。
為什么有必要在寫一篇 寫的理由千千萬;不寫的理由萬萬千。對於小鬼來說就是:我吃飽了,撐着了,該找點事做了。於是神情恍惚,目光呆滯的敲着鍵盤,陶醉的望着跳動的光標,嘴角上揚。

#region Using
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
#endregion
/// <summary>
/// 用於獲取二代身份證的基本信息(包括圖片)
/// 調用時確保 由廠商提供的API的動態鏈接庫等及lic文件
/// 設備 精倫電子公司的iDR200 或 iDR210 型號測試通過
/// 獲取的頭像圖片在應用程序目錄下“photo.bmp”文件
/// </summary>
public class IDCardReader
{
#region DllImport
[DllImport("sdtapi.dll")]
private static extern int InitComm(int iPort);//初始化
[DllImport("sdtapi.dll")]
private static extern int CloseComm();//關閉端口
[DllImport("sdtapi.dll")]
private static extern int Authenticate();//卡認證
[DllImport("sdtapi.dll")]//讀取數據,推薦使用
private static extern int ReadBaseInfos(
StringBuilder Name,
StringBuilder Gender,
StringBuilder Folk,
StringBuilder BirthDay,
StringBuilder Code,
StringBuilder Address,
StringBuilder Agency,
StringBuilder ExpireStart,
StringBuilder ExpireEnd);
[DllImport("kernel32.dll")]
private static extern int Beep(int dwFreq, int dwDuration);//用來大吼一聲
#endregion
public event Action<ReadCardCompletedEventArgs> ReadCardCompleted;
public event Action<string> OnError;
/// <summary>
/// 獲取身份證信息.
/// 如果成功就促發ReadCardCompleted事件,事件參數包含相關信息;
/// 否則促發OnError事件.
/// </summary>
public void ReadCard()
{
StringBuilder Name = new StringBuilder(31);
StringBuilder Gender = new StringBuilder(3);
StringBuilder Folk = new StringBuilder(10);
StringBuilder BirthDay = new StringBuilder(9);
StringBuilder Code = new StringBuilder(19);
StringBuilder Address = new StringBuilder(71);
StringBuilder Agency = new StringBuilder(31);
StringBuilder ExpireStart = new StringBuilder(9);
StringBuilder ExpireEnd = new StringBuilder(9);
//打開端口
int intOpenRet = 0;
for (int i = 1001; i < 1004; i++)
{
intOpenRet = InitComm(i);
if (intOpenRet == 1)
break;
}
if (intOpenRet != 1)
{
if (OnError != null) OnError("閱讀機具未連接");
return;
}
//卡認證
int intReadRet = Authenticate();
if (intReadRet != 1)
{
if (OnError != null) OnError("卡認證失敗");
CloseComm();
return;
}
//ReadBaseInfos(推薦使用)
int intReadBaseInfosRet = ReadBaseInfos(
Name, Gender, Folk, BirthDay,
Code, Address, Agency,
ExpireStart, ExpireEnd);
if (intReadBaseInfosRet == 0)
{
if (OnError != null) OnError("讀卡錯誤");
CloseComm();
return;
}
Beep(2047, 200);
ReadCardCompletedEventArgs args = new ReadCardCompletedEventArgs();
args.Code = Code.ToString().Trim();
args.Name = Name.ToString().Trim();
args.Gender = Gender.ToString().Trim();
args.Folk = Folk.ToString().Trim();
args.BirthDay = BirthDay.ToString().Trim();
args.Address = Address.ToString().Trim();
args.Agency = Agency.ToString().Trim();
args.ExpireStart = ExpireStart.ToString().Trim();
args.ExpireEnd = ExpireEnd.ToString().Trim();
args.PhotoPath = Directory.GetCurrentDirectory() + "\\photo.bmp";
CloseComm();
if (ReadCardCompleted != null)
{
this.ReadCardCompleted(args);
}
}
}
/// <summary>
/// ReadCardCompleted事件參數類
/// 包含身份證基本信息和圖片
/// </summary>
public class ReadCardCompletedEventArgs : EventArgs
{
public String Name { get; set; }
/// <summary>
/// 性別
/// </summary>
public String Gender { get; set; }
/// <summary>
/// 民族
/// </summary>
public String Folk { get; set; }
public String BirthDay { get; set; }
/// <summary>
/// 身份證號
/// </summary>
public String Code { get; set; }
public String Address { get; set; }
/// <summary>
/// 發證機關
/// </summary>
public String Agency { get; set; }
public String ExpireStart { get; set; }
public String ExpireEnd { get; set; }
public String PhotoPath { get; set; }
}
代碼沒有什么改動 就換了一下名字 讓編程生活體驗更好一點。
當時為什么這樣寫? 這個問題是問這么寫有什么好處。現階段我只能說習慣這樣寫。
對了,模模糊糊感覺為了好異步處理這個類的實例。
為什么要處理 異步處理這個類的實例? 因為外部設備運行有一個響應時間,這個響應時間有長有短,不易控制,還容易界面無法響應。
這樣界面就感覺卡卡的,用戶體驗也不好。這樣的軟件還容易被淘汰掉。得妥善解決這一問題!
異步調用是關鍵。
reader.Value.ReadCardCompleted += (args) =>
{
this.txtAddress.Text = args.Address;
this.txtAgency.Text = args.Agency;
this.txtBirthDay.Text = args.BirthDay;
this.txtCode.Text = args.Code;
this.txtExpireEnd.Text = args.ExpireEnd;
this.txtExpireStart.Text = args.ExpireStart;
this.txtFolk.Text = args.Folk;
this.txtGender.Text = args.Gender;
this.txtName.Text = args.Name;
this.picboxSignle.LoadAsync(args.PhotoPath);
};
//reader.Value.ReadCard();
Action delegateReader = () => reader.Value.ReadCard();
delegateReader.BeginInvoke(null, null);
這里用到了委托的異步調用, 明顯改善了程序的性能和用戶體驗。
這里只是寫了一種情況 當然其他具體情況 請看官們斟酌了。
namespace ReadCard
{
#region Using
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
#endregion
/// <summary>
/// 用於獲取二代身份證的基本信息(包括圖片)
/// 調用時確保 由廠商提供的API的動態鏈接庫等及lic文件
/// 設備 精倫電子公司的iDR200 或 iDR210 型號測試通過
/// 獲取的頭像圖片在應用程序目錄下“photo.bmp”文件
/// </summary>
public class IDCardReader
{
#region DllImport
[DllImport("sdtapi.dll")]
private static extern int InitComm(int iPort);//初始化
[DllImport("sdtapi.dll")]
private static extern int CloseComm();//關閉端口
[DllImport("sdtapi.dll")]
private static extern int Authenticate();//卡認證
[DllImport("sdtapi.dll")]//讀取數據,推薦使用
private static extern int ReadBaseInfos(
StringBuilder Name,
StringBuilder Gender,
StringBuilder Folk,
StringBuilder BirthDay,
StringBuilder Code,
StringBuilder Address,
StringBuilder Agency,
StringBuilder ExpireStart,
StringBuilder ExpireEnd);
[DllImport("kernel32.dll")]
private static extern int Beep(int dwFreq, int dwDuration);//用來大吼一聲
#endregion
public event Action<ReadCardCompletedEventArgs> ReadCardCompleted;
public event Action<string> OnError;
#region 參考代碼
//enum ERetReadBaseInfos
//{
// 正確 = 1,
// 讀卡錯誤 = 0,
// 沒有最新住址信息 = 2,
// 相片解碼錯誤 = -1,
// wlt文件后綴錯誤 = -2,
// wlt文件打開錯誤 = -3,
// wlt文件格式錯誤 = -4,
// 軟件未授權 = -5,
// 無效參數 = -11,
//}
#endregion
/// <summary>
/// 獲取身份證信息.
/// 如果成功就促發ReadCardCompleted事件,事件參數包含相關信息;
/// 否則促發OnError事件.
/// </summary>
public void ReadCard()
{
StringBuilder Name = new StringBuilder(31);
StringBuilder Gender = new StringBuilder(3);
StringBuilder Folk = new StringBuilder(10);
StringBuilder BirthDay = new StringBuilder(9);
StringBuilder Code = new StringBuilder(19);
StringBuilder Address = new StringBuilder(71);
StringBuilder Agency = new StringBuilder(31);
StringBuilder ExpireStart = new StringBuilder(9);
StringBuilder ExpireEnd = new StringBuilder(9);
//打開端口
int intOpenRet = 0;
for (int i = 1001; i < 1004; i++)
{
intOpenRet = InitComm(i);
if (intOpenRet == 1)
break;
}
if (intOpenRet != 1)
{
if (OnError != null) OnError("閱讀機具未連接");
return;
}
//卡認證
int intReadRet = Authenticate();
if (intReadRet != 1)
{
if (OnError != null) OnError("卡認證失敗");
CloseComm();
return;
}
//ReadBaseInfos(推薦使用)
int intReadBaseInfosRet = ReadBaseInfos(
Name, Gender, Folk, BirthDay,
Code, Address, Agency,
ExpireStart, ExpireEnd);
if (intReadBaseInfosRet == 0)
{
if (OnError != null) OnError("讀卡錯誤");
CloseComm();
return;
}
Beep(2047, 200);
ReadCardCompletedEventArgs args = new ReadCardCompletedEventArgs();
args.Code = Code.ToString().Trim();
args.Name = Name.ToString().Trim();
args.Gender = Gender.ToString().Trim();
args.Folk = Folk.ToString().Trim();
args.BirthDay = BirthDay.ToString().Trim();
args.Address = Address.ToString().Trim();
args.Agency = Agency.ToString().Trim();
args.ExpireStart = ExpireStart.ToString().Trim();
args.ExpireEnd = ExpireEnd.ToString().Trim();
args.PhotoPath = Directory.GetCurrentDirectory() + "\\photo.bmp";
CloseComm();
if (ReadCardCompleted != null)
{
this.ReadCardCompleted(args);
}
}
}
/// <summary>
/// ReadCardCompleted事件參數類
/// 包含身份證基本信息和圖片
/// </summary>
public class ReadCardCompletedEventArgs : EventArgs
{
public String Name { get; set; }
/// <summary>
/// 性別
/// </summary>
public String Gender { get; set; }
/// <summary>
/// 民族
/// </summary>
public String Folk { get; set; }
public String BirthDay { get; set; }
/// <summary>
/// 身份證號
/// </summary>
public String Code { get; set; }
public String Address { get; set; }
/// <summary>
/// 發證機關
/// </summary>
public String Agency { get; set; }
public String ExpireStart { get; set; }
public String ExpireEnd { get; set; }
public String PhotoPath { get; set; }
}
}