📄 dlgnewcard.cpp
字号:
// DlgNewCard.cpp : implementation file
//
#include "stdafx.h"
#include "ShoolCard.h"
#include "DlgNewCard.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "Global.h"
#include "Config.h"
extern CConfig gConfig;
extern CDatabase gDatabase;
/////////////////////////////////////////////////////////////////////////////
// CDlgNewCard dialog
CDlgNewCard::CDlgNewCard(CWnd* pParent /*=NULL*/)
: CDialog(CDlgNewCard::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlgNewCard)
m_Money = 0.0f;
m_StudentId = _T("");
//}}AFX_DATA_INIT
}
void CDlgNewCard::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgNewCard)
DDX_Control(pDX, IDC_BUTTON_NEW_CARD, m_btnNewCard);
DDX_Control(pDX, IDC_LIST1, m_ListBox);
DDX_Text(pDX, IDC_EDIT_MONEY, m_Money);
DDX_Text(pDX, IDC_EDIT_STUDENT_ID, m_StudentId);
DDX_Control(pDX, IDC_MSCOMM1, m_ComPort);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlgNewCard, CDialog)
//{{AFX_MSG_MAP(CDlgNewCard)
ON_WM_CLOSE()
ON_WM_SHOWWINDOW()
ON_BN_CLICKED(IDC_BUTTON_QUERY, OnButtonQuery)
ON_NOTIFY(NM_CLICK, IDC_LIST1, OnClickList1)
ON_BN_CLICKED(IDC_BUTTON_NEW_CARD, OnButtonNewCard)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgNewCard message handlers
void CDlgNewCard::OnClose()
{
// TODO: Add your message handler code here and/or call default
if(m_Card.IsOpen()) m_Card.Close();
if(m_CardUser.IsOpen()) m_Card.Close();
if(m_CardLookupMaxId.IsOpen()) m_Card.Close();
//关闭串口
if(m_ComPort.GetPortOpen()) m_ComPort.SetPortOpen(false);
CDialog::OnClose();
}
//====================私有函数=======================
bool CDlgNewCard::IsCardInWriter()
{
CByteArray mByteAry;
CByteArray mIn;
//构造上位机报文
mByteAry.SetSize(4);
mByteAry.SetAt(0,0x0f);
mByteAry.SetAt(1,0xf0);
mByteAry.SetAt(2,0x01);//读物理卡号
//计算报文的校验位
mByteAry.SetAt(3,CGlobal::CalCheck(&mByteAry,0,2));
//发读物理卡号命令
m_ComPort.SetOutput(COleVariant(mByteAry));
//等待读卡机的应答信息
Sleep(60);
//读串口信息
if (m_ComPort.GetInBufferCount() != 13)
{
return false;
}
//将下位机报文接受到缓冲区
mIn.SetSize(13);
COleVariant olearray = m_ComPort.GetInput();
for(int i=0;i<13;i++)
mIn.SetAt(i,((unsigned char *)olearray.parray->pvData)[i]);
//检查校验位
if(!CGlobal::IsArrayValid(&mIn)) return false;
//从应答的报文中解析卡号
if ((mIn[3] == 0xff) && (mIn[4] == 0xff) && (mIn[5] == 0xff) &&
(mIn[6] == 0xff) && (mIn[7] == 0xff) && (mIn[8] == 0xff) &&
(mIn[9] == 0xff) && (mIn[10] == 0xff))
return true;
return false;
}
short int CDlgNewCard::WriteCard(CString ACardNo)
{
CByteArray mByteAry;
CByteArray mIn;
//构造上位机报文
mByteAry.SetSize(13);
mByteAry.SetAt(0,0x0f);
mByteAry.SetAt(1,0xf0);
mByteAry.SetAt(2,0x03);//写命令
mByteAry.SetAt(3,0x01);//第1区
//卡号数据写入
mByteAry.SetAt(4,ACardNo.GetAt(0));
mByteAry.SetAt(5,ACardNo.GetAt(1));
mByteAry.SetAt(6,ACardNo.GetAt(2));
mByteAry.SetAt(7,ACardNo.GetAt(3));
mByteAry.SetAt(8,ACardNo.GetAt(4));
mByteAry.SetAt(9,0x00);//保留
mByteAry.SetAt(10,0x00);//保留
mByteAry.SetAt(11,0xff);//数据区以FF结尾
//计算报文的校验位
mByteAry.SetAt(12,CGlobal::CalCheck(&mByteAry,0,12));
//发读第一区的命令
m_ComPort.SetOutput(COleVariant(mByteAry));
//等待读卡机的应答信息
Sleep(60);
//读串口信息
if (m_ComPort.GetInBufferCount() != 6)
{
return -2;
}
//将下位机报文接受到缓冲区
mIn.SetSize(13);
COleVariant olearray = m_ComPort.GetInput();
for(int i=0;i<13;i++)
mIn.SetAt(i,((unsigned char *)olearray.parray->pvData)[i]);
//检查校验位
if(!CGlobal::IsArrayValid(&mIn) || (mIn.GetAt(4) != 0x0f))
return -3;
return 1;
}
short int CDlgNewCard::WriteTime(CTime ATime)
{
BYTE year1,year2,month1,month2,day1,day2;
DecodeInt(ATime.GetYear(),year1,year2);
DecodeInt(ATime.GetMonth(),month1,month2);
DecodeInt(ATime.GetDay(),day1,day2);
//======================串口操作==================
CByteArray mByteAry;
CByteArray mIn;
//构造上位机报文
mByteAry.SetSize(13);
mByteAry.SetAt(0,0x0f);
mByteAry.SetAt(1,0xf0);
mByteAry.SetAt(2,0x03);//写命令
mByteAry.SetAt(3,0x01);//第2区
//时间数据写入
mByteAry.SetAt(4,year1);
mByteAry.SetAt(5,year2);
mByteAry.SetAt(6,month1);
mByteAry.SetAt(7,month2);
mByteAry.SetAt(8,day1);
mByteAry.SetAt(9,day2);
mByteAry.SetAt(10,ATime.GetDayOfWeek());
mByteAry.SetAt(11,0xff);//数据区以FF结尾
//计算报文的校验位
mByteAry.SetAt(12,CGlobal::CalCheck(&mByteAry,0,12));
//发读第一区的命令
m_ComPort.SetOutput(COleVariant(mByteAry));
//等待读卡机的应答信息
Sleep(60);
//读串口信息
if (m_ComPort.GetInBufferCount() != 6)
{
return -2;
}
//将下位机报文接受到缓冲区
mIn.SetSize(13);
COleVariant olearray = m_ComPort.GetInput();
for(int i=0;i<13;i++)
mIn.SetAt(i,((unsigned char *)olearray.parray->pvData)[i]);
//检查校验位
if(!CGlobal::IsArrayValid(&mIn) || (mIn.GetAt(4) != 0x0f))
return -3;
return 1;
}
short int CDlgNewCard::WriteMoney(float AMoney)
{
//======================串口操作==================
CByteArray mByteAry;
CByteArray mIn;
//构造上位机报文
mByteAry.SetSize(13);
mByteAry.SetAt(0,0x0f);
mByteAry.SetAt(1,0xf0);
mByteAry.SetAt(2,0x03);//写命令
mByteAry.SetAt(3,0x03);//第3区
char chMoney[6];
//转换为整数
int nMoney = AMoney * 100;
//取出每一位
for(int i=0 ;i<6 ;i++)
{
chMoney[i] = nMoney % 10;
nMoney = nMoney /10;
}
//卡中的金额数据写入
mByteAry.SetAt(4,CGlobal::Encrypt(chMoney[0]));
mByteAry.SetAt(5,CGlobal::Encrypt(chMoney[1]));
mByteAry.SetAt(6,CGlobal::Encrypt(chMoney[2]));
mByteAry.SetAt(7,CGlobal::Encrypt(chMoney[3]));
mByteAry.SetAt(8,CGlobal::Encrypt(chMoney[4]));
mByteAry.SetAt(9,CGlobal::Encrypt(chMoney[5]));
mByteAry.SetAt(10,CGlobal::CalMoneyCheck(&mByteAry,4,9));
mByteAry.SetAt(11,0xff);//数据区以FF结尾
//计算报文的校验位
mByteAry.SetAt(12,CGlobal::CalCheck(&mByteAry,0,12));
//发读第一区的命令
m_ComPort.SetOutput(COleVariant(mByteAry));
//等待读卡机的应答信息
Sleep(60);
//读串口信息
if (m_ComPort.GetInBufferCount() != 6)
{
return -2;
}
//将下位机报文接受到缓冲区
mIn.SetSize(13);
COleVariant olearray = m_ComPort.GetInput();
for(i=0;i<13;i++)
mIn.SetAt(i,((unsigned char *)olearray.parray->pvData)[i]);
//检查校验位
if(!CGlobal::IsArrayValid(&mIn) || (mIn.GetAt(4) != 0x0f))
return -3;
return 1;
}
CString CDlgNewCard::GetNewCardId()
{
if(!m_CardLookupMaxId.IsOpen())
{
m_CardLookupMaxId.m_strSort = "card_id";
m_CardLookupMaxId.Open();
}
else
m_CardLookupMaxId.Requery();
if(m_CardLookupMaxId.IsEOF()&&m_CardLookupMaxId.IsBOF())
return _T("00001");
else
{
m_CardLookupMaxId.MoveLast();
return _IntToStr5(atoi(LPCTSTR(m_CardLookupMaxId.m_card_id))+1);
}
}
void CDlgNewCard::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow, nStatus);
// TODO: Add your message handler code here
//打开串口
if (!m_ComPort.GetPortOpen())
{
try
{
short int nComPort = CGlobal::ComStrToInt(gConfig.Port);
m_ComPort.SetCommPort(nComPort);
CString strSetting = gConfig.Speed + ','
+gConfig.CheckBit.GetAt(0) + ','
+gConfig.DataBit + ','
+gConfig.StopBit;
m_ComPort.SetSettings(strSetting);
m_ComPort.SetPortOpen(true);
}
catch(CException ee)
{
MessageBox("串口不能打开,请检查串口的配置!");
return;
}
}
//不显示任何学生
InitListView();
OnButtonQuery();
}
void CDlgNewCard::DecodeInt(int A, BYTE &B1, BYTE &B2)
{
B1 = A % 10;
B2 = (A / 10) % 10;
}
void CDlgNewCard::OnButtonQuery()
{
UpdateData(CON2VAR);
CString str;
str = "user_id = '" + m_StudentId + "'";
m_CardUser.m_strFilter = str;
if(m_CardUser.IsOpen()) m_CardUser.Close();
if(!m_CardUser.Open())
{
MessageBox("数据表不能打卡,数据库错误!");
return;
}
//利用后台数据更新用户界面
FillListView();
ConfigButtons();
m_CardUser.Close();
}
void CDlgNewCard::FillListView()
{
ASSERT(m_CardUser.IsOpen());
//删除老的显示数据
m_ListBox.DeleteAllItems();
//没有数据需要显示
if(m_CardUser.GetRecordCount() <= 0) return ;
int nRow = 0;
m_CardUser.MoveFirst();
while(!m_CardUser.IsEOF())
{
m_ListBox.InsertItem(nRow,"");
m_ListBox.SetItemText(nRow,0,m_CardUser.m_user_id);
m_ListBox.SetItemText(nRow,1,m_CardUser.m_name);
CString str;
str.Format("%2d",m_CardUser.m_age);
m_ListBox.SetItemText(nRow,2,str);
m_ListBox.SetItemText(nRow,3,m_CardUser.m_address);
nRow++;
m_CardUser.MoveNext();
}
}
void CDlgNewCard::InitListView()
{
m_ListBox.InsertColumn(0,"学号");
m_ListBox.InsertColumn(1,"姓名");
m_ListBox.InsertColumn(2,"年龄");
m_ListBox.InsertColumn(3,"联系地址");
m_ListBox.SetColumnWidth(0,90);
m_ListBox.SetColumnWidth(1,150);
m_ListBox.SetColumnWidth(2,120);
m_ListBox.SetColumnWidth(3,250);
}
void CDlgNewCard::ConfigButtons()
{
int nIndex = m_ListBox.GetNextItem(-1, LVNI_SELECTED);
if(nIndex == -1)
{
m_btnNewCard.EnableWindow(false);
}
else
{
m_btnNewCard.EnableWindow(true);
}
}
void CDlgNewCard::OnClickList1(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
ConfigButtons();
*pResult = 0;
}
void CDlgNewCard::OnButtonNewCard()
{
// TODO: Add your control notification handler code here
double mMoney;
CString mCardId;
CTime mTime;
short int nRet;
//获取界面数据
UpdateData(CON2VAR);
//测试新卡是否放入读卡器
if(IsCardInWriter())
{
MessageBox("系统检查不到银卡,请将一张新卡放入写卡器!");
return;
}
//在数据库中读取可用的新卡号
mCardId = GetNewCardId();
//在数据库中读取可用的新卡号失败
if(mCardId == "#####")
{
MessageBox("数据库中数据错误,请立即和开发方联系!");
::PostQuitMessage(0);
return;
}
//向数据库中写入数据
mTime = CTime::GetCurrentTime();
//设置数据库,开始事务
m_Card.m_pDatabase = &gDatabase;
gDatabase.BeginTrans();
if(!m_Card.IsOpen()) m_Card.Open();
m_Card.AddNew();
m_Card.m_card_id = mCardId;
m_Card.m_user_id = m_StudentId;
m_Card.m_create_date = mTime;
m_Card.m_money = m_Money;
//设置状态为未挂失状态
m_Card.m_state = "0";
//提交
m_Card.Update();
nRet = WriteCard(mCardId);
if(nRet < 0) goto Error;
nRet = WriteTime(mTime);
if(nRet < 0) goto Error;
nRet = WriteMoney(mMoney);
if(nRet < 0) goto Error;
gDatabase.CommitTrans();
m_Card.Close();
MessageBox("新卡办理成功!");
return;
//错误处理
Error:
switch(nRet)
{
case -1: MessageBox("写卡器端口打开异常,请检查系统配着!");break;
case -2: MessageBox("写卡器没有正常应答,请检查写卡器连接是否正确!");break;
case -3: MessageBox("写卡器读写校验错误,请重试!");break;
default: MessageBox("不能确定的读写错误,请重试!");
}
gDatabase.Rollback();
m_Card.Close();
}
void CDlgNewCard::OnDestroy()
{
if(m_Card.IsOpen()) m_Card.Close();
if(m_CardUser.IsOpen()) m_CardUser.Close();
//关闭串口
if(m_ComPort.GetPortOpen()) m_ComPort.SetPortOpen(false);
CDialog::OnDestroy();
// TODO: Add your message handler code here
}
CString CDlgNewCard::_IntToStr5(int AInt)
{
CString strRet;
strRet.Format("%d",AInt);
switch(strRet.GetLength())
{
case 1:strRet = "0000" + strRet;
break;
case 2:strRet = "000" + strRet;
break;
case 3:strRet = "00" + strRet;
break;
case 4:strRet = "0" + strRet;
break;
}
return strRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -