5,388
社区成员
发帖
与我相关
我的任务
分享
//RF卡管理类 提供查询、发牌、注销等功能
unit URFCardMng;
interface
uses
Classes, Controls, SysUtils, Forms, Variants,
Registry, Windows, Dialogs, StrUtils, UGlobalUnit;
Const
DLLPath='RF002Reader.dll';
Type
TPromptMsg = procedure(msg: string) of object;//提示信息 方法指针
TRFCardMng = class(TObject)
private
FCommIsWorking: Boolean; //串口是否已正常工作
FCommPort: integer;
FOnPromptMsg: TPromptMsg; //提示信息事件
reData:array of Variant;
FHandWareVer: string;//硬件版本
FProductDate: string;//出厂日期
FCustomID:Integer;
private
procedure sendPromptMsg(msg: string); //发送事件信息
function setCommPort(commPort: Integer): Integer;//设置串口端口 返回值 0: 成功 -1:失败; 1:串口已打开 ;2;串口端口不存在
procedure openComm();//如果串口没有打开则打开
public
constructor Create;
destructor Destory; overload;
public
{
自动打开串口
返回值:0:成功 其它值:失败
}
function autoOpenComm(): integer;
{
功能:读取手牌号与区域
boxId:取得的手牌号
zone:取得的区域名称
errMsg:错误信息
}
function getBoxIdAndZone(var boxId: string;var ZoneIndex: Integer; var errMsg: string): Integer;
procedure enterLock();
procedure leaveLock();
published
{
事件触发方法
if Assigned(OnPromptMsg) then
OnPromptMsg(Text);
}
property OnPromptMsg: TPromptMsg read FOnPromptMsg write FOnPromptMsg;
property HandWareVer: string read FHandWareVer; //硬件版本
property ProductDate: string read FProductDate; //出厂日期
// property CustomID: Integer read FCustomID ;
end;
implementation
var
FCriticalSection :TRTLCriticalSection;
function OpenReader(COMMNAME:integer):HWND; stdcall; external DLLPath name 'OpenReader';
function CloseReader():HWND; stdcall; external DLLPath name 'CloseReader';
function ReadRFID(Var RFIDData:Byte):DWORD; stdcall; external DLLPath name 'ReadRFID';
function SetCard(Var RFIDData:Byte):DWORD; stdcall; external DLLPath name 'SetCard';
function ClearCard(Var RFIDData:Byte):DWORD; stdcall; external DLLPath name 'ClearCard';
function GetReaderVersion(Var ReaderVersion:Byte):DWORD; stdcall; external DLLPath name 'GetReaderVersion';
function GetHandId(Var HandId:Byte):DWORD; stdcall; external DLLPath name 'GetHandId';
function SetHandId(Var HandId:Byte):DWORD; stdcall; external DLLPath name 'SetHandId';
function GetReaderRTC(var RTC:byte):DWORD; stdcall;external DllPath name 'GetRTC';
function SetReaderRTC(var RTC:byte):DWORD; stdcall;external DllPath name 'SetRTC';
function GetHandType(Var HandType:Byte):DWORD; stdcall; external DLLPath name 'GetHandType';
function SetHandType(Var HandType:Byte):DWORD; stdcall; external DLLPath name 'SetHandType';
{ TRFCardMng }
constructor TRFCardMng.Create;
begin
FCommIsWorking := False;
openComm;
end;
destructor TRFCardMng.Destory;
begin
end;
function TRFCardMng.setCommPort(commPort: Integer): Integer;
var
RetVal:DWORD;
tmpVersion:array [0..9] of byte;
begin
try
if FCommPort = commPort then
begin
Result := 0;
exit;
end;
FCommPort := commPort;
Result := 0;
FCommIsWorking := True;
RetVal:=OpenReader(CommPort); //执行DLL函数,打开读卡器,传入参数为读卡器对应的串口号码
if (RetVal=0) then
begin
FcommPort := 0;
FCommIsWorking :=False;
Result:=-1; //返回打开异常
exit;
end;
RetVal:=GetReaderVersion(tmpVersion[0]); //查询读卡器版本信息
if (RetVal=$00) then //读版本指令返回正常
Begin
FHandWareVer:=chr(tmpVersion[1])+chr(tmpVersion[2])+chr(tmpVersion[3])+chr(tmpVersion[4]);
FProductDate:=IntToHex(tmpVersion[5],2)+IntToHex(tmpVersion[6],2);;
FCustomID:= tmpVersion[7]*256+ tmpVersion[8];
if (FCustomID>$0000) then
begin
sendPromptMsg('[COM' + IntToStr(commPort) + ']'+'联机成功,硬件版本: '+FHandWareVer+' 出厂日期:'+FProductDate+' 客户代码: '+IntToHex(FCustomID,4));
end
else
begin
sendPromptMsg('联机成功,硬件版本: '+FHandWareVer+' 内部专用');
end
end
else
begin
sendPromptMsg('[COM' + IntToStr(commPort) + ']' + '通讯失败!');
FCommIsWorking := False;
Result := -1;
end;
except
on e:exception do
begin
if UpperCase(e.Message) = 'PORT ALREADY OPEN' then
begin
Result := 1;//串口已打开
sendPromptMsg('[COM' + IntToStr(commPort) + ']' + '串口已打开');
end
else if UpperCase(e.Message) = 'INVALID PORT NUMBER' then
begin
Result := 2;//串口端口不存在
sendPromptMsg('[COM' + IntToStr(commPort) + ']' + '串口端口不存在');
end
else
begin
sendPromptMsg('[COM' + IntToStr(commPort) + '] 错误:' + e.Message);
end;
end;
end;
end;
function TRFCardMng.getBoxIdAndZone(var boxId: string;var ZoneIndex: Integer; var errMsg: string): Integer;
var
RetVal:DWORD;
tmpHandId:array [0..5] of byte;
begin
// openComm;
try
enterLock();
if not FCommIsWorking then
begin
Result := 98;//串口未打开
errMsg := '串口未打开';
sendPromptMsg('串口未打开');
exit;
end;
Result := -1;
errMsg := '读卡时:未知错误';
RetVal:=GetHandId(tmpHandId[0]); //调用DLL读手牌码指令
if ((RetVal=0) and ((tmpHandId[0] xor tmpHandId[1] xor tmpHandId[2])=tmpHandId[3])) then
Begin
boxId := IntTohex(tmpHandId[0]*$100+tmpHandId[1],4);
ZoneIndex := tmpHandId[2]; //getZone( (RecData[3]-48) mod 4 ) ;
sendPromptMsg('读手牌与门禁通道码成功');
Result := 0;
end
else
begin
errMsg := '读手牌与区域异常';
sendPromptMsg('读手牌与门禁通道码异常');
Result := 2;
end;
finally
leaveLock();
end;
end;
procedure TRFCardMng.sendPromptMsg(msg: string);
begin
{
try
if Assigned(OnPromptMsg) then
begin
OnPromptMsg(msg);
end;
except
end;
}
end;
function TRFCardMng.autoOpenComm: integer;
var
reg:TRegistry;
ts:TStrings;
commPort: Integer;
i: integer;
begin
try
enterLock();
try
Result := -1;
reg := TRegistry.Create;
reg.RootKey := HKEY_LOCAL_MACHINE;
reg.OpenKey('hardware\devicemap\serialcomm',false);
ts:=TStringList.Create;
commPort := UGlobalUnit.ReadIniFile('RFCard','commport',0);
if commPort <> 0 then
begin
if setCommPort(commPort) = 0 then //设置串口成功
begin
Result := 0;
Exit;
end;
end;
reg.GetValueNames(ts);
if ts.Count = 0 then
begin
sendPromptMsg('未找到串行通讯端口');
end;
for i := 0 to ts.Count-1 do
begin
commPort := StrToInt( Copy(reg.ReadString(ts.Strings[i]),4,MaxInt) );
if setCommPort(commPort) = 0 then //设置串口成功
begin
UGlobalUnit.WriteIniFile('RFCard','commport',commPort);
Result := 0;
Break;
end;
end;
except
on e: Exception do
begin
sendPromptMsg('[COM' + IntToStr(commPort) + ']错误:' + e.Message);
end;
end;
finally
ts.Free;
reg.CloseKey;
reg.free;
leaveLock();
end;
end;
procedure TRFCardMng.openComm;
begin
try
enterLock();
if not FCommIsWorking then
begin
if autoOpenComm <> 0 then
begin
sendPromptMsg('打开串口失败');
end;
end;
finally
leaveLock();
end;
end;
function TRFCardMng.getCustomId: string;
begin
Result := IntToHex(FCustomID,4);
end;
procedure TRFCardMng.enterLock;
begin
EnterCriticalSection(FCriticalSection);
end;
procedure TRFCardMng.leaveLock;
begin
LeaveCriticalSection(FCriticalSection);
end;
initialization
InitializeCriticalSection(FCriticalSection); //初始化
finalization
DeleteCriticalSection(FCriticalSection); //删除
end.