unit UDetectCard;interface uses windows,Classes,SysUtils,Face_public,variable,forms,Dialogs; type TDetectCardThread = class(TThread) private { Private declarations } protected procedure Execute; override; public IsWorking: Boolean; Trantype: Integer; LogFlag: Integer; RetCode: Integer; constructor Create; end; function CreateDetectCardThread: Boolean; function ResumeDetectCardThread: Boolean; function FreeDetectCardThread: Boolean; function DetectCard:Boolean; // function GetMagTrack(TrackData:PChar;Track2:PChar;Track3:PChar):Boolean; var DetectCardThread:TDetectCardThread; implementation uses processMain,udll;function CreateDetectCardThread: Boolean; begin ShowMessage('线程开启'); Result := False; if ( DetectCardThread = nil ) then begin DetectCardThread := TDetectCardThread.Create; DetectCardThread.Execute; Result := True; end; end;function ResumeDetectCardThread: Boolean; begin Result := False; if ( DetectCardThread = nil ) then Exit; DetectCardThread.Resume; DetectCardThread.IsWorking := true; Result := True; end;function FreeDetectCardThread: Boolean; begin Result := False; if ( DetectCardThread = nil ) then Exit; DetectCardThread.Terminate; while not DetectCardThread.Terminated do Application.ProcessMessages; try if ( DetectCardThread <> nil ) then begin DetectCardThread.Free; DetectCardThread := nil; end; Result := True; except DetectCardThread := nil; end; end;constructor TDetectCardThread.Create; begin IsWorking := false; inherited Create(true); //don‘t execute end;procedure TDetectCardThread.Execute; var i:Integer; begin i := 0; while i = 0 do begin DetectCard; end;end;function DetectCard:Boolean; var i,Track2Pos,Track3Pos,len,ErrCount:integer; bReadMode,bReadTrack:BYTE; szTrackData:array [0..160] of char; szTrack2,szTrack3:string; PHasCard,PAllowCardIn:array [0..1] of char;begin ErrCount := 0; Result := FALSE; if gComHandle = 0 then ErrLog(gErrLogPath,'磁条卡串口未被初始化', 5); // ShowMessage('磁条卡串口未被初始化'); PAllowCardIn[0] := char($0); i := CRT386_GetStatus(gComHandle,PHasCard, PAllowCardIn); if i = 0 then begin // ShowMessage('读取是否有卡成功'); if gCardState = 0 then begin if PHasCard[0] = char($1) then begin // ShowMessage('读卡器插卡'); gCardState := 1; i := 0; i := CRT_IC_CardOpen(gComHandle); if i = 0 then ErrLog(gErrLogPath,'上电成功', 5); // ShowMessage('上电成功'); i := 0; i := AT88SC102_Reset(gComHandle); if i = 0 then begin ShowMessage('复位成功'); ErrLog(gErrLogPath,'IC卡复位成功,判断为煤气卡', 5); if(PostMessage(Controlfrm.handle,WM_MQCARD_IN,0,0)) then ShowMessage('发送煤气卡消息成功'); end else begin i := 0; bReadMode := $30; bReadTrack := $35; i := MC_ReadTrack(gComHandle,bReadMode,bReadTrack,szTrackData); if i = 0 then begin Len := sizeof(szTrackData); i := 5; for i:= 5 to Len-1 do begin if szTrackData[i] = char($1F) then begin Track3Pos := i; break; end; end; Track2Pos := 5; if szTrackData[4] = char($59) then begin szTrack2 := copy(String(szTrackData),6,(Track3Pos-Track2Pos)); end else begin ErrLog(gErrLogPath,'无二磁信息或读取失败', 5); Inc(ErrCount); // ShowMessage('无二磁信息或读取失败'); end; if szTrackData[Track3Pos+1] = char($59) then begin szTrack3 := copy(String(szTrackData),Track3Pos+3,104); end else begin ErrLog(gErrLogPath,'无三磁信息或读取失败', 5); Inc(ErrCount); // ShowMessage('无三磁信息或读取失败'); end; if ErrCount>= 2 then begin PostMessage(Controlfrm.handle,WM_ReadCardFail,0,0); // ShowMessage('发送失败消息'); end else begin ShowMessage('发送成功消息'); if(PostMessage(Controlfrm.handle,WM_ReadCardSuccess,WPARAM(szTrack2),LPARAM(szTrack3))) then // ShowMessage('消息发送成功'); end; sleep(500); // ShowMessage(szTrack2); // ShowMessage(szTrack3); end else begin ErrLog(gErrLogPath,'读取磁条卡失败', 5); // ShowMessage('读取磁条卡失败'); end; end; end;// else // ShowMessage('无动作1'); end else begin if PHasCard[0] = char($1) then // ShowMessage('无动作1'); else begin gCardState := 0; // ShowMessage('读卡器退卡'); end; end; end;end; end. 这个是我线程的代码,窗口的代码以前别人写的,比较大,先不发了.我在程序一开始的时候就调用CreateDetectCardThread.或者在一个按钮里面开启这个线程,都会使窗口没响应了,鼠标点不到上面的按钮
uses
windows,Classes,SysUtils,Face_public,variable,forms,Dialogs;
type
TDetectCardThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
public
IsWorking: Boolean;
Trantype: Integer;
LogFlag: Integer;
RetCode: Integer;
constructor Create;
end; function CreateDetectCardThread: Boolean;
function ResumeDetectCardThread: Boolean;
function FreeDetectCardThread: Boolean;
function DetectCard:Boolean;
// function GetMagTrack(TrackData:PChar;Track2:PChar;Track3:PChar):Boolean;
var
DetectCardThread:TDetectCardThread;
implementation
uses
processMain,udll;function CreateDetectCardThread: Boolean;
begin
ShowMessage('线程开启');
Result := False;
if ( DetectCardThread = nil ) then
begin
DetectCardThread := TDetectCardThread.Create;
DetectCardThread.Execute;
Result := True;
end;
end;function ResumeDetectCardThread: Boolean;
begin
Result := False;
if ( DetectCardThread = nil ) then
Exit; DetectCardThread.Resume;
DetectCardThread.IsWorking := true; Result := True;
end;function FreeDetectCardThread: Boolean;
begin
Result := False;
if ( DetectCardThread = nil ) then
Exit; DetectCardThread.Terminate;
while not DetectCardThread.Terminated do
Application.ProcessMessages; try
if ( DetectCardThread <> nil ) then
begin
DetectCardThread.Free;
DetectCardThread := nil;
end; Result := True;
except
DetectCardThread := nil;
end;
end;constructor TDetectCardThread.Create;
begin
IsWorking := false; inherited Create(true); //don‘t execute
end;procedure TDetectCardThread.Execute;
var
i:Integer;
begin
i := 0;
while i = 0 do
begin
DetectCard;
end;end;function DetectCard:Boolean;
var
i,Track2Pos,Track3Pos,len,ErrCount:integer;
bReadMode,bReadTrack:BYTE;
szTrackData:array [0..160] of char;
szTrack2,szTrack3:string;
PHasCard,PAllowCardIn:array [0..1] of char;begin
ErrCount := 0;
Result := FALSE;
if gComHandle = 0 then
ErrLog(gErrLogPath,'磁条卡串口未被初始化', 5);
// ShowMessage('磁条卡串口未被初始化');
PAllowCardIn[0] := char($0);
i := CRT386_GetStatus(gComHandle,PHasCard, PAllowCardIn);
if i = 0 then
begin
// ShowMessage('读取是否有卡成功');
if gCardState = 0 then
begin
if PHasCard[0] = char($1) then
begin
// ShowMessage('读卡器插卡');
gCardState := 1;
i := 0;
i := CRT_IC_CardOpen(gComHandle);
if i = 0 then
ErrLog(gErrLogPath,'上电成功', 5);
// ShowMessage('上电成功');
i := 0;
i := AT88SC102_Reset(gComHandle);
if i = 0 then
begin
ShowMessage('复位成功');
ErrLog(gErrLogPath,'IC卡复位成功,判断为煤气卡', 5);
if(PostMessage(Controlfrm.handle,WM_MQCARD_IN,0,0)) then
ShowMessage('发送煤气卡消息成功');
end
else
begin i := 0;
bReadMode := $30;
bReadTrack := $35;
i := MC_ReadTrack(gComHandle,bReadMode,bReadTrack,szTrackData);
if i = 0 then
begin
Len := sizeof(szTrackData);
i := 5;
for i:= 5 to Len-1 do
begin
if szTrackData[i] = char($1F) then
begin
Track3Pos := i;
break;
end;
end; Track2Pos := 5;
if szTrackData[4] = char($59) then
begin
szTrack2 := copy(String(szTrackData),6,(Track3Pos-Track2Pos));
end else
begin
ErrLog(gErrLogPath,'无二磁信息或读取失败', 5);
Inc(ErrCount);
// ShowMessage('无二磁信息或读取失败');
end;
if szTrackData[Track3Pos+1] = char($59) then
begin
szTrack3 := copy(String(szTrackData),Track3Pos+3,104);
end else
begin
ErrLog(gErrLogPath,'无三磁信息或读取失败', 5);
Inc(ErrCount);
// ShowMessage('无三磁信息或读取失败');
end;
if ErrCount>= 2 then
begin
PostMessage(Controlfrm.handle,WM_ReadCardFail,0,0);
// ShowMessage('发送失败消息');
end
else begin
ShowMessage('发送成功消息');
if(PostMessage(Controlfrm.handle,WM_ReadCardSuccess,WPARAM(szTrack2),LPARAM(szTrack3))) then
// ShowMessage('消息发送成功');
end;
sleep(500);
// ShowMessage(szTrack2);
// ShowMessage(szTrack3);
end
else begin
ErrLog(gErrLogPath,'读取磁条卡失败', 5);
// ShowMessage('读取磁条卡失败');
end;
end;
end;// else
// ShowMessage('无动作1');
end else
begin
if PHasCard[0] = char($1) then
// ShowMessage('无动作1');
else begin
gCardState := 0;
// ShowMessage('读卡器退卡');
end;
end;
end;end;
end.
这个是我线程的代码,窗口的代码以前别人写的,比较大,先不发了.我在程序一开始的时候就调用CreateDetectCardThread.或者在一个按钮里面开启这个线程,都会使窗口没响应了,鼠标点不到上面的按钮
线程中,最好也不要用Application.ProcessMessages.
begin
while not Terminated do begin
DetectCard;
sleep(50);
end;
end;
那你这就失去线程的意义了,你这是单线程的。
PostMessage(Controlfrm.handle,WM_ReadCardFail,0,0);
ErrLog(gErrLogPath,'读取卡片磁条信息失败', 5);
ShowMessage('读取失败');
如果我把ShowMessage这句注释掉的话,PostMessage发出的消息,ControlFrm就收不到这个消息,如果ShowMessage没注释掉,ControlFrm就能收到该消息