由于ID卡或者是其它的一些不同类型的卡,它们只是负责模拟键盘的录入,但是,它们在录入的时候没有一个很好的标识位可以让我们知道当前输入的是客户手工录入的字符串还是ID卡读入的字符串,我相信,很多人在做这样的开发时应该都遇到过这种郁闷的事,有些人的做法呢,就是在特定的位置录入字符串就算是ID卡的读取了,我想,这样的方法很多人都不喜欢的了,感觉很不科学。因此,这模块就是应这种要求而设计的,可以让你在任何情况下,应该说,限制很少的情况下,满足了题目的要求。废话不多说,先看看模块代码:
 unit zgw_IDCheckU;
unit zgw_IDCheckU;
 interface
interface uses
uses Windows,Dialogs;
  Windows,Dialogs; type
type TIDCheckOKEvent = procedure (IDCheckResult:string) of object;
  TIDCheckOKEvent = procedure (IDCheckResult:string) of object; TIDCheck=class(TObject)
  TIDCheck=class(TObject) protected
  protected m_INTCheck:array of integer;//结果的检测用
    m_INTCheck:array of integer;//结果的检测用 m_TimeCheck:array of integer;//时间的检测用
    m_TimeCheck:array of integer;//时间的检测用 m_Begin:integer;//检测录入的字符第一个开始时间。
    m_Begin:integer;//检测录入的字符第一个开始时间。 m_MaxTime:Smallint;//超出该时间证明不是ID的录入时间范围
    m_MaxTime:Smallint;//超出该时间证明不是ID的录入时间范围 m_Length:integer;//读取长度
    m_Length:integer;//读取长度 m_LastResult:string;//上一次读取的结果
    m_LastResult:string;//上一次读取的结果 FOnIDCheck: TIDCheckOKEvent;
    FOnIDCheck: TIDCheckOKEvent; FOnIDCheck_SP: TIDCheckOKEvent;
    FOnIDCheck_SP: TIDCheckOKEvent; procedure DoClear;//当检测到符合清空条件的,则还原所有变量
    procedure DoClear;//当检测到符合清空条件的,则还原所有变量 function CheckID:Boolean;
    function CheckID:Boolean; function GetIDResult:string;
    function GetIDResult:string; procedure DoAddKey(var key:integer);//符合条件的进行处理。
    procedure DoAddKey(var key:integer);//符合条件的进行处理。 procedure SetOnIDCheckResult_SP(value:TIDCheckOKEvent);
    procedure SetOnIDCheckResult_SP(value:TIDCheckOKEvent); public
  public function KeyDownCheck(var key:integer):string;
    function KeyDownCheck(var key:integer):string; property IDLength:integer read m_Length;
    property IDLength:integer read m_Length; property IDResult:string read GetIDResult;
    property IDResult:string read GetIDResult; property LastResult:string read m_LastResult;
    property LastResult:string read m_LastResult; constructor Create(MaxTime:integer=50;Length:integer=10);
    constructor Create(MaxTime:integer=50;Length:integer=10); destructor Destroy; override;
    destructor Destroy; override; procedure APPIntercept(var Msg:TMsg;var Handled:Boolean);//截取程序的消息,改为自己的截取过程
    procedure APPIntercept(var Msg:TMsg;var Handled:Boolean);//截取程序的消息,改为自己的截取过程 property OnIDCheckResult: TIDCheckOKEvent read FOnIDCheck write FOnIDCheck;         //默认的事件
    property OnIDCheckResult: TIDCheckOKEvent read FOnIDCheck write FOnIDCheck;         //默认的事件 property OnIDCheckResult_SP: TIDCheckOKEvent read FOnIDCheck_SP write SetOnIDCheckResult_SP;//特殊事件,当特殊事件存在时不会去执行默认事件的。
    property OnIDCheckResult_SP: TIDCheckOKEvent read FOnIDCheck_SP write SetOnIDCheckResult_SP;//特殊事件,当特殊事件存在时不会去执行默认事件的。 end;
  end; 
   var
var IDCheckObj:TIDCheck;
  IDCheckObj:TIDCheck;
 implementation
implementation uses
uses Forms,StdCtrls,Messages;
  Forms,StdCtrls,Messages;
 procedure TIDCheck.APPIntercept(var Msg: TMsg; var Handled: Boolean);
procedure TIDCheck.APPIntercept(var Msg: TMsg; var Handled: Boolean); var
var aStr:string;
  aStr:string; begin
begin
 if Msg.message=WM_KEYDOWN then
  if Msg.message=WM_KEYDOWN then begin
  begin aStr:=KeyDownCheck(Msg.wParam);
    aStr:=KeyDownCheck(Msg.wParam); if length(aStr)>0 then
    if length(aStr)>0 then begin
    begin Msg.wParam:=0;
      Msg.wParam:=0; end
    end else  //没有完整返回ID的检测,下面是一些比较特殊的处理。
    else  //没有完整返回ID的检测,下面是一些比较特殊的处理。 begin
    begin if ((m_TimeCheck[1]>0) and (m_TimeCheck[1]<=m_MaxTime) and not (Screen.ActiveForm.ActiveControl is TCustomEdit)) then
      if ((m_TimeCheck[1]>0) and (m_TimeCheck[1]<=m_MaxTime) and not (Screen.ActiveForm.ActiveControl is TCustomEdit)) then Msg.wParam:=0;
        Msg.wParam:=0; end;
    end; //下面是屏蔽数字的快捷键的,因此数字快捷键必须使用数字键盘
    //下面是屏蔽数字的快捷键的,因此数字快捷键必须使用数字键盘 if ((Msg.wParam>=48) and (Msg.wParam<=57)) then
    if ((Msg.wParam>=48) and (Msg.wParam<=57)) then if not (Screen.ActiveForm.ActiveControl is TCustomEdit) then
    if not (Screen.ActiveForm.ActiveControl is TCustomEdit) then Msg.wParam:=0;
      Msg.wParam:=0; end;
  end;

 end;
end;
 function TIDCheck.CheckID: Boolean;
function TIDCheck.CheckID: Boolean; begin
begin if m_INTCheck[m_Length-1]<0 then
  if m_INTCheck[m_Length-1]<0 then result:=false
    result:=false else
  else result:=true;
    result:=true; end;
end;
 constructor TIDCheck.Create(MaxTime: integer;Length:integer);
constructor TIDCheck.Create(MaxTime: integer;Length:integer); begin
begin m_MaxTime:=MaxTime;
  m_MaxTime:=MaxTime; m_Length:=Length;
  m_Length:=Length; SetLength(m_INTCheck,m_Length);
  SetLength(m_INTCheck,m_Length); SetLength(m_TimeCheck,m_Length);
  SetLength(m_TimeCheck,m_Length); DoClear;
  DoClear; end;
end;
 destructor TIDCheck.Destroy;
destructor TIDCheck.Destroy; begin
begin Finalize(m_INTCheck);
  Finalize(m_INTCheck); Finalize(m_TimeCheck);
  Finalize(m_TimeCheck); inherited;
  inherited; end;
end;
 procedure TIDCheck.DoAddKey(var key: integer);
procedure TIDCheck.DoAddKey(var key: integer); var
var i:Smallint;
  i:Smallint; begin
begin for i:=0 to m_Length-1 do
  for i:=0 to m_Length-1 do if m_INTCheck[i]<0 then
    if m_INTCheck[i]<0 then begin
    begin m_INTCheck[i]:=key;
      m_INTCheck[i]:=key; m_TimeCheck[i]:=GetTickCount-m_Begin;
      m_TimeCheck[i]:=GetTickCount-m_Begin; m_Begin:=GetTickCount;
      m_Begin:=GetTickCount; break;
      break; end;
    end; if i=m_Length then//没有空间记录,把所有数据前移并把新的放在最后一位。
  if i=m_Length then//没有空间记录,把所有数据前移并把新的放在最后一位。 begin
  begin for i:=1 to m_Length-1 do
    for i:=1 to m_Length-1 do begin
    begin m_INTCheck[i-1]:=m_INTCheck[i];
      m_INTCheck[i-1]:=m_INTCheck[i]; m_TimeCheck[i-1]:=m_TimeCheck[i];
      m_TimeCheck[i-1]:=m_TimeCheck[i]; end;
    end; m_INTCheck[m_Length]:=key;
    m_INTCheck[m_Length]:=key; m_TimeCheck[m_Length]:=GetTickCount-m_Begin;
    m_TimeCheck[m_Length]:=GetTickCount-m_Begin; m_Begin:=GetTickCount;
    m_Begin:=GetTickCount; end;
  end; if (m_TimeCheck[i]>=m_MaxTime) and (i>0) then //超出ID卡读取范围则清空
  if (m_TimeCheck[i]>=m_MaxTime) and (i>0) then //超出ID卡读取范围则清空 DoClear;
    DoClear; end;
end;
 procedure TIDCheck.DoClear;
procedure TIDCheck.DoClear; var
var i:integer;
  i:integer; begin
begin for i:=0 to m_Length-1 do
  for i:=0 to m_Length-1 do begin
  begin m_INTCheck[i]:=-1;
    m_INTCheck[i]:=-1; m_TimeCheck[i]:=-1;
    m_TimeCheck[i]:=-1; end;
  end; m_Begin:=0;
  m_Begin:=0; end;
end;
 function TIDCheck.GetIDResult: string;
function TIDCheck.GetIDResult: string; var
var i:Shortint;
  i:Shortint; begin
begin if CheckID then
  if CheckID then begin
  begin for i:=0 to m_Length-1 do
    for i:=0 to m_Length-1 do result:=result+char(m_INTCheck[i]);
      result:=result+char(m_INTCheck[i]); end;
  end; end;
end;
 function TIDCheck.KeyDownCheck(var key:integer):string;
function TIDCheck.KeyDownCheck(var key:integer):string; var
var aStr:string;
  aStr:string; i:integer;
  i:integer; begin
begin result:='';
  result:=''; case key of
  case key of 48..57:DoAddKey(key);
  48..57:DoAddKey(key); 13:begin
      13:begin if checkid then //检测到结果则把结果返回
           if checkid then //检测到结果则把结果返回 begin
           begin result:=GetIDResult;
             result:=GetIDResult; m_LastResult:=result;
             m_LastResult:=result;
 if Screen.ActiveForm.ActiveControl is TCustomEdit then
              if Screen.ActiveForm.ActiveControl is TCustomEdit then begin
              begin aStr:=TCustomEdit(Screen.ActiveForm.ActiveControl).Text;
                aStr:=TCustomEdit(Screen.ActiveForm.ActiveControl).Text; Delete(aStr,length(aStr)-IDLength+1,IDLength);
                Delete(aStr,length(aStr)-IDLength+1,IDLength); i:=TCustomEdit(Screen.ActiveForm.ActiveControl).SelStart;
                i:=TCustomEdit(Screen.ActiveForm.ActiveControl).SelStart; TCustomEdit(Screen.ActiveForm.ActiveControl).Text:=aStr;
                TCustomEdit(Screen.ActiveForm.ActiveControl).Text:=aStr; TCustomEdit(Screen.ActiveForm.ActiveControl).SelStart:=i;
                TCustomEdit(Screen.ActiveForm.ActiveControl).SelStart:=i; end;
              end;
 if assigned(OnIDCheckResult_SP) then
             if assigned(OnIDCheckResult_SP) then OnIDCheckResult_SP(result)
               OnIDCheckResult_SP(result) else
             else begin
             begin if assigned(FOnIDCheck) then
               if assigned(FOnIDCheck) then FOnIDCheck(result);
                 FOnIDCheck(result); end;
             end; DoClear;//清空重新处理。
             DoClear;//清空重新处理。 end
           end else
           else DoClear;//清空重新处理。
             DoClear;//清空重新处理。 end;
         end; else//非数字的要清空并重新处理
  else//非数字的要清空并重新处理 DoClear;
    DoClear; end;
  end; end;
end;
 procedure TIDCheck.SetOnIDCheckResult_SP(value: TIDCheckOKEvent);
procedure TIDCheck.SetOnIDCheckResult_SP(value: TIDCheckOKEvent); begin
begin FOnIDCheck_SP:=value;
  FOnIDCheck_SP:=value; DoClear;
  DoClear; end;
end;
 initialization
initialization IDCheckObj:=TIDCheck.Create;
  IDCheckObj:=TIDCheck.Create; finalization
finalization IDCheckObj.Free;
  IDCheckObj.Free;
 end.
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/