检测ID卡的输入或者是其它卡的输入。

由于ID卡或者是其它的一些不同类型的卡,它们只是负责模拟键盘的录入,但是,它们在录入的时候没有一个很好的标识位可以让我们知道当前输入的是客户手工录入的字符串还是ID卡读入的字符串,我相信,很多人在做这样的开发时应该都遇到过这种郁闷的事,有些人的做法呢,就是在特定的位置录入字符串就算是ID卡的读取了,我想,这样的方法很多人都不喜欢的了,感觉很不科学。因此,这模块就是应这种要求而设计的,可以让你在任何情况下,应该说,限制很少的情况下,满足了题目的要求。废话不多说,先看看模块代码:

unit zgw_IDCheckU;

interface
uses
  Windows,Dialogs;
type
  TIDCheckOKEvent 
= procedure (IDCheckResult:string) of object;
  TIDCheck
=class(TObject)
  protected
    m_INTCheck:array of integer;
//结果的检测用
    m_TimeCheck:array of integer;
//时间的检测用
    m_Begin:integer;
//检测录入的字符第一个开始时间。
    m_MaxTime:Smallint;
//超出该时间证明不是ID的录入时间范围
    m_Length:integer;
//读取长度
    m_LastResult:string;
//上一次读取的结果
    FOnIDCheck: TIDCheckOKEvent;
    FOnIDCheck_SP: TIDCheckOKEvent;
    procedure DoClear;
//当检测到符合清空条件的,则还原所有变量
    function CheckID:Boolean;
    function GetIDResult:string;
    procedure DoAddKey(var key:integer);
//符合条件的进行处理。
    procedure SetOnIDCheckResult_SP(value:TIDCheckOKEvent);
  public
    function KeyDownCheck(var key:integer):string;
    property IDLength:integer read m_Length;
    property IDResult:string read GetIDResult;
    property LastResult:string read m_LastResult;
    constructor Create(MaxTime:integer
=50;Length:integer=10);
    destructor Destroy; override;
    procedure APPIntercept(var Msg:TMsg;var Handled:Boolean);
//截取程序的消息,改为自己的截取过程
    property OnIDCheckResult: TIDCheckOKEvent read FOnIDCheck write FOnIDCheck;         
//默认的事件
    property OnIDCheckResult_SP: TIDCheckOKEvent read FOnIDCheck_SP write SetOnIDCheckResult_SP;
//特殊事件,当特殊事件存在时不会去执行默认事件的。
  end;
  
var
  IDCheckObj:TIDCheck;

implementation
uses
  Forms,StdCtrls,Messages;

procedure TIDCheck.APPIntercept(var Msg: TMsg; var Handled: Boolean);
var
  aStr:string;
begin

  
if Msg.message=WM_KEYDOWN then
  begin
    aStr:
=KeyDownCheck(Msg.wParam);
    
if length(aStr)>0 then
    begin
      Msg.wParam:
=0;
    end
    
else  //没有完整返回ID的检测,下面是一些比较特殊的处理。
    begin
      
if ((m_TimeCheck[1]>0) and (m_TimeCheck[1]<=m_MaxTime) and not (Screen.ActiveForm.ActiveControl is TCustomEdit)) then
        Msg.wParam:
=0;
    end;
    
//下面是屏蔽数字的快捷键的,因此数字快捷键必须使用数字键盘
    
if ((Msg.wParam>=48and (Msg.wParam<=57)) then
    
if not (Screen.ActiveForm.ActiveControl is TCustomEdit) then
      Msg.wParam:
=0;
  end;


end;

function TIDCheck.CheckID: Boolean;
begin
  
if m_INTCheck[m_Length-1]<0 then
    result:
=false
  
else
    result:
=true;
end;

constructor TIDCheck.Create(MaxTime: integer;Length:integer);
begin
  m_MaxTime:
=MaxTime;
  m_Length:
=Length;
  SetLength(m_INTCheck,m_Length);
  SetLength(m_TimeCheck,m_Length);
  DoClear;
end;

destructor TIDCheck.Destroy;
begin
  Finalize(m_INTCheck);
  Finalize(m_TimeCheck);
  inherited;
end;

procedure TIDCheck.DoAddKey(var key: integer);
var
  i:Smallint;
begin
  
for i:=0 to m_Length-1 do
    
if m_INTCheck[i]<0 then
    begin
      m_INTCheck[i]:
=key;
      m_TimeCheck[i]:
=GetTickCount-m_Begin;
      m_Begin:
=GetTickCount;
      
break;
    end;
  
if i=m_Length then//没有空间记录,把所有数据前移并把新的放在最后一位。
  begin
    
for i:=1 to m_Length-1 do
    begin
      m_INTCheck[i
-1]:=m_INTCheck[i];
      m_TimeCheck[i
-1]:=m_TimeCheck[i];
    end;
    m_INTCheck[m_Length]:
=key;
    m_TimeCheck[m_Length]:
=GetTickCount-m_Begin;
    m_Begin:
=GetTickCount;
  end;
  
if (m_TimeCheck[i]>=m_MaxTime) and (i>0) then //超出ID卡读取范围则清空
    DoClear;
end;

procedure TIDCheck.DoClear;
var
  i:integer;
begin
  
for i:=0 to m_Length-1 do
  begin
    m_INTCheck[i]:
=-1;
    m_TimeCheck[i]:
=-1;
  end;
  m_Begin:
=0;
end;

function TIDCheck.GetIDResult: string;
var
  i:Shortint;
begin
  
if CheckID then
  begin
    
for i:=0 to m_Length-1 do
      result:
=result+char(m_INTCheck[i]);
  end;
end;

function TIDCheck.KeyDownCheck(var key:integer):string;
var
  aStr:string;
  i:integer;
begin
  result:
='';
  case key of
  
48..57:DoAddKey(key);
      
13:begin
           
if checkid then //检测到结果则把结果返回
           begin
             result:
=GetIDResult;
             m_LastResult:
=result;

              
if Screen.ActiveForm.ActiveControl is TCustomEdit then
              begin
                aStr:
=TCustomEdit(Screen.ActiveForm.ActiveControl).Text;
                Delete(aStr,length(aStr)
-IDLength+1,IDLength);
                i:
=TCustomEdit(Screen.ActiveForm.ActiveControl).SelStart;
                TCustomEdit(Screen.ActiveForm.ActiveControl).Text:
=aStr;
                TCustomEdit(Screen.ActiveForm.ActiveControl).SelStart:
=i;
              end;

             
if assigned(OnIDCheckResult_SP) then
               OnIDCheckResult_SP(result)
             
else
             begin
               
if assigned(FOnIDCheck) then
                 FOnIDCheck(result);
             end;
             DoClear;
//清空重新处理。
           end
           
else
             DoClear;
//清空重新处理。
         end;
  
else//非数字的要清空并重新处理
    DoClear;
  end;
end;

procedure TIDCheck.SetOnIDCheckResult_SP(value: TIDCheckOKEvent);
begin
  FOnIDCheck_SP:
=value;
  DoClear;
end;

initialization
  IDCheckObj:
=TIDCheck.Create;
finalization
  IDCheckObj.Free;

end.

 下面是它的使用方法:(对象不用创建的,引用了该模块就可以使用,应该它在模块引用的时候就已经创建出来的了。)

    Application.OnMessage:=IDCheckObj.APPIntercept;(首先这里设置截获应用程序的消息。)
    IDCheckObj.OnIDCheckResult:=OnIDCheckReturn;(设置检测到ID卡读取后要执行的事件。)

调用的方法就是这么简单了。

下面的是特殊情况下调用的方法:

IDCheckObj.OnIDCheckResult_SP:=OnIDCheckReturn;(OnIDCheckResult是默认的执行事件,如果你在某个窗体里面要求检测到ID卡读取后执行比较特殊的事件,而不执行默认事件的话,就要设置这个事件了,记得窗体不再激活的时候要把它设置为NULL哦,否者,其它地方会执行OnIDCheckResult_SP这个事件的)

介绍一个这个事件过程是如何定义的:procedure OnIDCheckReturn(IDCheckResult:string);

下面是我的默认事件所执行的过程,可以参考一下:

procedure TMainForm.OnIDCheckReturn(IDCheckResult: string);
var
  frm_IDCardCon:Tfrm_IDCardControl;
begin
  frm_IDCardCon:=Tfrm_IDCardControl.Create(IDCheckResult);
  if frm_IDCardCon.VIP_NO<>'' then
    frm_IDCardCon.ShowModal
  else
    frm_IDCardCon.Free;
end;


IDCheckResult:就是检测到的那串字符串。我这里是检测到就弹出窗体。不知道我这东西是否适合大家使用呢?不管适用与否,我都已经用在客户那里啦,反应挺好的。


原创作品出自努力偷懒,转载请说明文章出处http://blog.csdn.net/kfarvid或 http://www.cnblogs.com/kfarvid/

原文地址:https://www.cnblogs.com/kfarvid/p/2251447.html