摘要:IC卡也稱智能卡,是一種便攜式的數據存儲媒介,因其便攜性、抗干擾、壽命長等優勢,在銀行卡、借書卡、公交卡等領域廣泛使用,IC卡考勤系統對于單位人員管理具有重要意義,基于Visual C++實現的IC卡考勤系統,具有成本低、可移植、通用性好等優勢。
關鍵詞:IC卡;VC;考勤系統
中圖分類號:TP391文獻標識碼:A文章編號:1009-3044(2008)15-21111-03
The Design and VC Implement of Roll System Based on IC Card
ZHANG Hai-bo,BI Li-qun, DUAN Jiang-chun,CHENG Lin
(Unit 69046,URUMQI 830002,China)
Abstract: IC Card is named Intelligent Card and a kind of media of data storage.It is used widely on bank Card, reading room Card,Bus Card for its portable capability and so on.The Roll system based on Visual C++ has the virtue of vile cost, all-purpose capability and transplantation.
Key words: IC Card; Visual C++; Roll System
1 前言
基于Visual C++實現的IC卡考勤系統,包括卡片管理、人員管理、考勤管理三個模塊,涵蓋人員管理的主要要素,該系統功能擴充簡便、成本低,稍加改造可以應用于其他較多領域。
2 系統結構
基于Visual C++實現的IC卡考勤系統,包括卡片管理、人員管理、考勤管理三個模塊,涵蓋人員管理的主要要素。其結構圖如圖1所示。

IC卡管理模塊主要調用IC卡寫入程序,實現IC卡的參數寫入;考勤管理模塊主要調用IC卡讀取程序,實現人員身份認證;人員管理模塊主要調用數據庫讀取、寫入程序,實現人員管理,為考勤管理提供人員管理信息。數據庫讀取、寫入,IC卡寫入、讀取程序采用類成員函數設計,考勤管理采用定時器定時檢測IC卡狀態、讀取IC卡信息,并通過管理界面顯示,通過數據庫存儲,供管理人員查詢調閱。
3 軟件設計
本系統采用深圳明華讀卡器,西門子SLE4442型IC卡,通過API調用驅動程序中Mwic_32.dll文件函數,對IC卡進行訪問,軟件設計主要包括三部分:IC卡寫入程序、IC卡讀取程序、考勤管理系統。人員管理的數據庫編程等其他編程內容已經有成熟應用實例,本文不再贅述。
3.1 IC卡寫入、讀取程序常用函數簡介
IC卡初始密碼是“ffffff”,Visual C++編程包含Mwic_32.h文件,常用函數簡介如下:
int auto_init(int port,unsigned long baud)函數:初始化讀卡器。port為端口號,0表示COM1,1表示COM2,baud表示波特率。
int setsc_md(int icdev,int mode)函數:設置密碼模式。icdev是設備句柄,即auto_init函數的返回值;mode為密碼模式,0表示密碼有效,1表示密碼無效。
int get_status(int icdev,int *state)函數:獲取設備當前狀態。icdev為設備句柄,state為設備狀態返回值,0為無卡,1為有卡。
csc_4442(int icdev,int len,unsigned char* p_string)函數:核對IC卡密碼。icdev設備句柄,len為密碼長度,p_string為密碼字符串。
int swr_4442(int icdev,int offset,int len,unsigned char* w_string)函數:向IC卡寫入數據。icdev為設備句柄,offset為地址偏移量,len字符串長度,w_string寫入的字符串。
int srd_4442(int icdev,int offset,int len,int char* r_string)函數:從IC卡讀取數據。icdev設備句柄,offset地址偏移量,len字符串長度,r_string讀取的字符串。
int ic_exit(int icdev)函數:關閉設備端口。Icdev設備句柄。
int dv_beep(int icdev,int time)函數:使讀卡器鳴叫。icdev設備句柄,time鳴叫時間。
3.2 考勤管理程序設計
(1)在主對話框的OnInitDialog()函數中,實現初始化。
icdev= auto_init(0,9600);//初始化端口 COM1 9600
if (icdev<0)
MessageBox(\"端口初始化失敗,請檢查接口線是否連接正確.\");
setsc_md(icdev,1); //設置密碼模式,使設備密碼無效
__int16 rpass= setsc_md(icdev,1);
(2)IC卡寫入函數
IC卡寫入數據的同時,向數據庫寫入條目。部分代碼如下所示。
void CCartSet::OnWrite()
{CString str;
if (str.GetLength()>224)
{MessageBox(\"寫入數據不能超過224個字符\",\"提示\",64);return;}
__int16 result;m_pCon->BeginTrans();CString sql;
sql.Format(\"insert into ICID values ('%s')\",str);
try
{m_pCon->Execute((_bstr_t)sql,NULL,-1);//向數據庫中插入數據
result =swr_4442(m_icdev,33,str.GetLength(),(unsigned char*)str.GetBuffer(0));
//在IC卡的應用區中寫入數據
if (result==0)
{……}
}
……
}

(3)定時器實現的主要功能
該系統主體部分使用定時器實現,定時器內程序流程為:判斷是否插卡;讀取卡信息;查詢數據庫查找該用戶;向考勤數據庫寫入用戶考勤記錄;更新顯示界面。程序主體部分代碼如下所示:
void CReFreshCard::OnTimer(UINT nIDEvent)
{result =get_status(m_icdev,status);//獲取IC卡狀態
setsc_md(m_icdev,1);
if (result<0)
{return;}
else if ((result==0)(status==0))
{m_IsCard = FALSE;m_HINT.SetWindowText(\"請插入IC卡\");return;}
if (m_IsCard )
return;
unsigned char data[224];
result = srd_4442(m_icdev,33,223,data);//讀取卡中的數據
dv_beep(m_icdev,20); //蜂鳴
if (result==0)
{int i =0;
for (i= 0; i<224;i++)
{if (data[i]==255)
break;}
unsigned char* pArray = new unsigned char[i+1];
memset(pArray,0,i+1);memcpy(pArray,data,i);pArray[i]= 0;
CString sql;
sql.Format(\"select * from worker where icid = '%s'\",pArray);
delete pArray;
CString c_workerid,c_name,c_sex,c_duty,c_id;
m_pRecord = m_pCon->Execute((_bstr_t)sql,NULL,-1);
try
{c_workerid = (char* )(_bstr_t)m_pRecord->GetFields()->GetItem(\"ID\")->Value;
c_name = (char* )(_bstr_t)m_pRecord->GetFields()->GetItem(\"Name\")->Value;
c_sex = (char* )(_bstr_t)m_pRecord->GetFields()->GetItem(\"Sex\")->Value;
c_duty = (char* )(_bstr_t)m_pRecord->GetFields()->GetItem(\"Duty\")->Value;
c_id = (char* )(_bstr_t)m_pRecord->GetFields()->GetItem(\"ICID\")->Value;
m_WorkID.SetWindowText(c_workerid);
m_Name.SetWindowText(c_name);
if (c_sex==\"男\")
m_Sex.SetCurSel(0);
else
m_Sex.SetCurSel(1);
m_Duty.SetWindowText(c_duty);
m_ID.SetWindowText(c_id);
m_IsCard = TRUE;
sql.Format(\"insert into record values ('%s','%s')\",c_id,CTime::GetCurrentTime()
.Format(\"%Y-%m-%d %H:%M:%S\"));
try
{m_pCon->Execute((_bstr_t)sql,NULL,-1);
m_HINT.SetWindowText(\"刷卡成功\");}
catch(...)
{m_HINT.SetWindowText(\"數據記錄失敗,請重新插入IC卡\");}
}
catch(...)
{m_WorkID.SetWindowText(\"\");
m_Name.SetWindowText(\"\");
m_Sex.SetWindowText(\"\");
m_Duty.SetWindowText(\"\");
m_ID.SetWindowText(\"\");
m_HINT.SetWindowText(\"不存在該用戶\");
dv_beep(m_icdev,10);
dv_beep(m_icdev,10);
m_IsCard =TRUE;
}
}
CDialog::OnTimer(nIDEvent);
}

4 結果與結論
隨著IC卡應用技術的日益成熟,其應用范圍將更加廣泛,通過Visual C++編程,實現IC卡考勤系統,具有成本低、移植修改簡便、通用性強等優勢,稍加改造可以應用于公交卡系統、借書卡等領域。具有較為廣泛的應用前景。
參考文獻:
[1] 明日科技。Visual C++程序開發范例寶典[M].人民郵電出版社,2007。
[2] 胡志坤,秦業,鄢鋒,等.Visual C++通信編程工程實例精解[M].機械工業出版社,2007.
[3] 高守傳,聶云銘,鄭靜,等.Visual C++6.0開發指南[M].人民郵電出版社,2007.
[4] 求是科技.Visual C++6.0信息管理系統開發實例導航[M].人民郵電出版社,2005.