123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802 |
- unit frmPartner;
- {$MODE Delphi}
- interface
- uses
- {$IFNDEF FPC}
- Windows,
- {$ELSE}
- LCLIntf, LCLType, LMessages,
- {$ENDIF}
- Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, ComCtrls, Grids, SyncObjs,
- StdCtrls, ExtCtrls,
- Snap7;
- Const
- _Active = true; // <- the underscore to avoid conflicts with the Form property "Active"
- _Passive = false;
- type
- TS7Buffer = packed array[0..$FFFF] of byte;
- TPartnerForm = class;
- TRecvThread = class(TThread)
- private
- FPartnerForm : TPartnerForm;
- public
- constructor Create(PartnerForm : TPartnerForm);
- procedure Execute; override;
- end;
- TPartnerForm = class(TForm)
- PageControl: TPageControl;
- TabBSend: TTabSheet;
- TabBRecv: TTabSheet;
- SB: TStatusBar;
- DataGrid: TStringGrid;
- GR_Remote: TGroupBox;
- Label5: TLabel;
- Label6: TLabel;
- Label7: TLabel;
- EdRemoteIP: TEdit;
- EdRemTsapHI: TEdit;
- EdRemTsapLO: TEdit;
- StartBtn: TButton;
- StopBtn: TButton;
- Label1: TLabel;
- Ed_R_ID: TEdit;
- Label4: TLabel;
- EdAmount: TEdit;
- BsendBtn: TButton;
- AsBsendBtn: TButton;
- lbldump: TLabel;
- RxMemo: TMemo;
- EdR_ID_In: TEdit;
- Label8: TLabel;
- GR_local: TGroupBox;
- Label2: TLabel;
- Label3: TLabel;
- Label9: TLabel;
- EdLocalIP: TEdit;
- EdLocTsapHI: TEdit;
- EdLocTsapLO: TEdit;
- DataLed: TStaticText;
- TLed: TTimer;
- TBsend: TTimer;
- ChkSend: TCheckBox;
- TStat: TTimer;
- TabStat: TTabSheet;
- EdSent: TEdit;
- Label10: TLabel;
- Label11: TLabel;
- EdRecv: TEdit;
- RGMode: TRadioGroup;
- TBRecv: TTimer;
- EdTimeout: TEdit;
- Label13: TLabel;
- BRecvBtn: TButton;
- BRecvLbl: TLabel;
- ARGMode: TRadioGroup;
- procedure DataGridDrawCell(Sender: TObject; ACol, ARow: Integer;
- Rect: TRect; State: TGridDrawState);
- procedure DataGridExit(Sender: TObject);
- procedure DataGridKeyPress(Sender: TObject; var Key: Char);
- procedure FormCreate(Sender: TObject);
- procedure TLedTimer(Sender: TObject);
- procedure StartBtnClick(Sender: TObject);
- procedure StopBtnClick(Sender: TObject);
- procedure TStatTimer(Sender: TObject);
- procedure FormDestroy(Sender: TObject);
- procedure ChkSendClick(Sender: TObject);
- procedure TBsendTimer(Sender: TObject);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- procedure BsendBtnClick(Sender: TObject);
- procedure AsBsendBtnClick(Sender: TObject);
- procedure RGModeClick(Sender: TObject);
- procedure TBRecvTimer(Sender: TObject);
- procedure ARGModeClick(Sender: TObject);
- procedure BRecvBtnClick(Sender: TObject);
- private
- { Private declarations }
- TxBuffer : TS7Buffer;
- FActive : boolean;
- FRunning: boolean;
- RecvThread : TRecvThread;
- Cnt : byte;
- AsSendMode : integer;
- AsRecvMode : integer;
- FLastSendError: integer;
- FLastRecvError: integer;
- FLastStartError: integer;
- procedure ValidateGrid;
- procedure DataToGrid(Amount : integer);
- procedure GridToData(Amount : integer);
- procedure SetFRunning(const Value: boolean);
- procedure PartnerStart;
- procedure PartnerStop;
- procedure DumpData(P : PS7Buffer; Memo : TMemo; Count : integer);
- procedure BSend(Async : boolean; Const Cyclic : boolean = false);
- procedure SetFLastSendError(const Value: integer);
- procedure SetFLastRecvError(const Value: integer);
- procedure SetFLastStartError(const Value: integer);
- procedure WaitBSendCompletion;
- procedure BRecv(WithPolling : boolean);
- function ErrorText(ErrNo : integer) : String;
- public
- { Public declarations }
- Partner : TS7Partner;
- RxBuffer : TS7Buffer;
- RxSize : integer;
- RxR_ID : cardinal;
- RxError : integer;
- RxEvent : TEvent;
- TxEvent : TEvent;
- procedure DataIncoming;
- procedure CreatePartner(Mode : boolean);
- property Running : boolean read FRunning write SetFRunning;
- property LastStartError : integer read FLastStartError write SetFLastStartError;
- property LastSendError : integer read FLastSendError write SetFLastSendError;
- property LastRecvError : integer read FLastRecvError write SetFLastRecvError;
- end;
- implementation
- {$R *.lfm}
- Const
- amPolling = 0;
- amWait = 1;
- amCallBack = 2;
- Var
- CS : TCriticalSection;
- procedure OnRecv(usrPtr : pointer; opResult : integer; R_ID : dword;
- pdata : pointer; size : integer);
- {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
- Var
- PF : TPartnerForm;
- begin
- CS.Enter;
- try
- PF:=TPartnerForm(usrPtr);
- if Assigned(PF) then
- begin
- if opResult=0 then
- begin
- move(pdata^,PF.RxBuffer[0],Size);
- PF.RxSize:=Size;
- PF.RxR_ID:=R_ID;
- end;
- PF.RxError:=opResult;
- PF.RxEvent.SetEvent;
- end;
- finally
- CS.Leave;
- end;
- end;
- procedure OnSend(usrPtr : pointer; opResult : integer); stdcall;
- var
- PF : TPartnerForm;
- begin
- CS.Enter;
- try
- PF:=TPartnerForm(usrPtr);
- if Assigned(PF) then
- PF.TxEvent.SetEvent;
- finally
- CS.Leave;
- end;
- end;
- procedure TPartnerForm.ARGModeClick(Sender: TObject);
- begin
- AsRecvMode:=ARGMode.ItemIndex; // 0 : amPolling
- // 1 : amEvent
- // 2 : amCallBack
- case AsRecvMode of
- amPolling,
- amWait : begin
- Partner.SetRecvCallback(nil,Self); // <-- We don't want callback
- BRecvBtn.Enabled:=true;
- end;
- amCallback: begin
- Partner.SetRecvCallback(@OnRecv,Self);
- BRecvBtn.Enabled:=false; // <-- the recv is full async
- end;
- end;
- BRecvLbl.Enabled :=BRecvBtn.Enabled;
- EdTimeout.Enabled:=BRecvBtn.Enabled;
- end;
- procedure TPartnerForm.AsBsendBtnClick(Sender: TObject);
- begin
- BSend(true,false);
- end;
- procedure TPartnerForm.BRecv(WithPolling: boolean);
- Var
- Timeout : cardinal;
- Result : integer;
- Elapsed : cardinal;
- Done : boolean;
- begin
- Timeout:=StrToIntDef(edTimeout.Text,0);
- edTimeout.Text:=IntToStr(Timeout);
- if WithPolling then
- begin
- Elapsed:=GetTickCount;
- repeat
- Application.ProcessMessages;
- Done:=Partner.CheckAsBRecvCompletion(Result,RxR_ID,@RxBuffer,RxSize);
- until Done or (GetTickCount-Elapsed>Timeout);
- if not Done then
- Result:=errParRecvTimeout;
- end
- else // Wait idle
- Result:=Partner.BRecv(Timeout,RxR_ID,@RxBuffer,RxSize);
- LastRecvError:=Result;
- if Result=0 then
- begin
- DumpData(@RxBuffer,RxMemo,RxSize);
- lbldump.Caption:='Data Dump : '+IntToStr(RxSize)+' bytes';
- EdR_ID_In.Text:='$'+IntToHex(RxR_ID,8);
- end;
- end;
- procedure TPartnerForm.BRecvBtnClick(Sender: TObject);
- begin
- BRecv(ARGMode.ItemIndex=0);
- end;
- procedure TPartnerForm.BSend(Async: boolean; Const Cyclic : boolean = false);
- Var
- Amount : integer;
- R_ID : cardinal;
- c: Integer;
- SendTime,RecvTime : cardinal;
- begin
- // Amount
- Amount:=StrToIntDef(EdAmount.Text,0);
- if Amount>65536 then
- Amount:=65536;
- EdAmount.Text:=IntToStr(Amount);
- // R_ID
- R_ID:=StrToIntDef(Ed_R_ID.Text,0);
- Ed_R_ID.Text:='$'+IntToHex(R_ID,8);
- if Cyclic then
- begin
- TBSend.Enabled:=false;
- inc(Cnt);
- for c := 0 to Amount - 1 do
- TxBuffer[c]:=Cnt;
- DataToGrid(Amount);
- end
- else
- GridToData(Amount);
- if Async then
- FLastSendError:=Partner.AsBSend(R_ID,@TxBuffer,Amount)
- else
- LastSendError:=Partner.BSend(R_ID,@TxBuffer,Amount);
- if FLastSendError=0 then
- begin
- if ASync then
- WaitBSendCompletion;
- end;
- SB.Panels[1].Text:=IntToStr(Partner.SendTime)+' ms';
- if Cyclic then
- TBSend.Enabled:=true;
- end;
- procedure TPartnerForm.BsendBtnClick(Sender: TObject);
- begin
- BSend(false,false);
- end;
- procedure TPartnerForm.ChkSendClick(Sender: TObject);
- begin
- if ChkSend.Checked then
- begin
- BSendBtn.Enabled:=false;
- Ed_R_ID.Enabled:=false;
- EdAmount.Enabled:=false;
- AsBSendBtn.Enabled:=false;
- TBSend.Enabled:=true;
- end
- else begin
- TBSend.Enabled:=false;
- BSendBtn.Enabled:=true;
- AsBSendBtn.Enabled:=true;
- Ed_R_ID.Enabled:=true;
- EdAmount.Enabled:=true;
- end;
- end;
- procedure TPartnerForm.CreatePartner(Mode: boolean);
- begin
- Partner:=TS7Partner.Create(Mode);
- FActive:=Mode;
- if FActive then
- begin
- Caption:='Active Partner';
- GR_Local.Caption:='Local Partner (Active)';
- GR_Remote.Caption:='Remote Partner (Passive)';
- EdLocalIP.Text:='';
- EdLocalIP.Color:=clBtnFace;
- EdLocalIP.Enabled:=false;
- end
- else begin
- Caption:='Passive Partner';
- GR_Local.Caption:='Local Partner (Passive)';
- GR_Remote.Caption:='Remote Partner (Active)';
- end;
- Partner.SetRecvCallback(@OnRecv,Self);
- BRecvBtn.Enabled:=false; // <-- the recv is full async
- BRecvLbl.Enabled:=false;
- EdTimeout.Enabled:=false;
- ARgMode.ItemIndex:=2;
- Running:=false;
- end;
- procedure TPartnerForm.DataGridDrawCell(Sender: TObject; ACol, ARow: Integer;
- Rect: TRect; State: TGridDrawState);
- Var
- aRect : TRect;
- aText : string;
- Style : TTextStyle;
- begin
- with Sender as TStringGrid do
- begin
- ARect:=Rect;
- AText:=Cells[ACol,ARow];
- if (ACol=0) or (ARow=0) then
- Canvas.Brush.Color:=clbtnface
- else
- Canvas.Brush.Color:=clWhite;
- Canvas.FillRect(Rect);
- Style.Alignment:=taCenter;
- Style.Clipping:=true;
- Style.ExpandTabs:=false;
- Style.Layout:=tlCenter;
- Style.ShowPrefix:=false;
- Style.Wordbreak:=false;
- Style.SystemFont:=false;
- Style.RightToLeft:=false;
- Canvas.TextRect(ARect, 0,0, AText,Style);
- if gdfocused in State then
- begin
- Canvas.Brush.Color:=clRed;
- Canvas.FrameRect(ARect);
- end;
- end;
- end;
- procedure TPartnerForm.DataGridExit(Sender: TObject);
- begin
- ValidateGrid;
- end;
- procedure TPartnerForm.DataGridKeyPress(Sender: TObject; var Key: Char);
- begin
- if Key=#13 then
- ValidateGrid;
- end;
- procedure TPartnerForm.DataIncoming;
- begin
- if RxError=0 then
- begin
- DataLed.Color:=clLime;
- DumpData(@RxBuffer,RxMemo,RxSize);
- lbldump.Caption:='Data Dump : '+IntToStr(RxSize)+' bytes';
- EdR_ID_In.Text:='$'+IntToHex(RxR_ID,8);
- TLed.Enabled:=true;
- end;
- LastRecvError:=RxError;
- end;
- procedure TPartnerForm.DataToGrid(Amount: integer);
- Var
- x, c, r : integer;
- begin
- with DataGrid do
- begin
- c:=1;r:=1;
- for x := 0 to Amount - 1 do
- begin
- Cells[c,r]:='$'+IntToHex(TxBuffer[x],2);
- inc(c);
- if c=ColCount then
- begin
- c:=1;
- inc(r);
- end;
- end;
- Row:=1;
- Col:=1;
- if PageControl.ActivePage=TabBSend then
- SetFocus;
- end;
- end;
- procedure TPartnerForm.DumpData(P: PS7Buffer; Memo: TMemo; Count: integer);
- Var
- SHex, SChr : string;
- Ch : AnsiChar;
- c, cnt : integer;
- begin
- Memo.Lines.Clear;
- Memo.Lines.BeginUpdate;
- SHex:='';SChr:='';cnt:=0;
- try
- for c := 0 to Count - 1 do
- begin
- SHex:=SHex+IntToHex(P^[c],2)+' ';
- Ch:=AnsiChar(P^[c]);
- if not (Ch in ['a'..'z','A'..'Z','0'..'9','_','$','-',#32]) then
- Ch:='.';
- SChr:=SChr+String(Ch);
- inc(cnt);
- if cnt=16 then
- begin
- Memo.Lines.Add(SHex+' '+SChr);
- SHex:='';SChr:='';
- cnt:=0;
- end;
- end;
- // Dump remainder
- if cnt>0 then
- begin
- while Length(SHex)<48 do
- SHex:=SHex+' ';
- Memo.Lines.Add(SHex+' '+SChr);
- end;
- finally
- Memo.Lines.EndUpdate;
- end;
- end;
- function TPartnerForm.ErrorText(ErrNo: integer) : string;
- begin
- Result:=String(ParErrorText(ErrNo));
- end;
- procedure TPartnerForm.FormClose(Sender: TObject; var Action: TCloseAction);
- begin
- Action:=caFree;
- end;
- procedure TPartnerForm.FormCreate(Sender: TObject);
- Var
- c : integer;
- begin
- RxEvent:=TEvent.Create(nil,false,false,'');
- TxEvent:=TEvent.Create(nil,false,false,'');
- RecvThread := TRecvThread.Create(Self);
- RecvThread.Start;
- // Init Grid
- with DataGrid do
- begin
- DefaultColWidth:=32;
- ColWidths[0]:=48;
- DefaultRowHeight:=18;
- ColCount:=17;
- RowCount:=4097;
- for c := 1 to ColCount - 1 do
- Cells[c,0]:=inttohex(c-1,2);
- for c := 1 to RowCount - 1 do
- Cells[0,c]:=inttohex((c-1)*16,4);
- end;
- ValidateGrid;
- end;
- procedure TPartnerForm.FormDestroy(Sender: TObject);
- begin
- Partner.Free;
- RecvThread.Terminate;
- RxEvent.SetEvent;
- TxEvent.SetEvent;
- RecvThread.Free;
- RxEvent.Free;;
- TxEvent.Free;
- end;
- procedure TPartnerForm.GridToData(Amount: integer);
- Var
- x, c, r : integer;
- begin
- ValidateGrid;
- with DataGrid do
- begin
- c:=1;r:=1;
- for x := 0 to Amount- 1 do
- begin
- TxBuffer[x]:=StrToIntDef(Cells[c,r],0);
- inc(c);
- if c=ColCount then
- begin
- c:=1;
- inc(r);
- end;
- end;
- end;
- end;
- procedure TPartnerForm.PartnerStart;
- Var
- LocalAddress : AnsiString;
- RemoteAddress: AnsiString;
- LocalTsapHI : integer;
- LocalTsapLO : integer;
- RemoteTsapHI : integer;
- RemoteTsapLO : integer;
- LocalTsap : integer;
- RemoteTsap : integer;
- function GetChar(ED : TEdit) : integer;
- Var
- B : byte;
- begin
- B:=StrToIntDef('$'+Ed.Text,0);
- Ed.Text:=IntToHex(B,2);
- Result:=B;
- end;
- begin
- LocalAddress :=EdLocalIP.Text;
- RemoteAddress:=EdRemoteIP.Text;
- LocalTsapHI :=GetChar(EdLocTsapHI);
- LocalTsapLO :=GetChar(EdLocTsapLO);
- RemoteTsapHI :=GetChar(EdRemTsapHI);
- RemoteTsapLO :=GetChar(EdRemTsapLO);
- LocalTsap :=LocalTsapHI shl 8 + LocalTsapLO;
- RemoteTsap :=RemoteTsapHI shl 8 + RemoteTsapLO;
- LastStartError:=Partner.StartTo(LocalAddress,
- RemoteAddress,
- LocalTsap,
- RemoteTsap);
- Running:=FLastStartError=0;
- end;
- procedure TPartnerForm.PartnerStop;
- begin
- Partner.Stop;
- Running:=false;
- SB.Panels[2].Text:='';
- end;
- procedure TPartnerForm.RGModeClick(Sender: TObject);
- begin
- AsSendMode:=RGMode.ItemIndex; // 0 : amPolling
- // 1 : amEvent
- // 2 : amCallBack
- case AsSendMode of
- amPolling,
- amWait : Partner.SetSendCallback(nil,Self);
- amCallback: Partner.SetSendCallback(@OnSend,Self);
- end;
- end;
- procedure TPartnerForm.SetFLastRecvError(const Value: integer);
- begin
- FLastRecvError := Value;
- if FLastRecvError=0 then
- SB.Panels[2].Text:='Last BRecv OK'
- else
- SB.Panels[2].Text:=ErrorText(FLastRecvError);
- end;
- procedure TPartnerForm.SetFLastSendError(const Value: integer);
- begin
- FLastSendError := Value;
- if FLastSendError=0 then
- SB.Panels[2].Text:='Last BSend OK'
- else
- SB.Panels[2].Text:=ErrorText(FLastSendError);
- end;
- procedure TPartnerForm.SetFLastStartError(const Value: integer);
- begin
- FLastStartError := Value;
- if FLastStartError=0 then
- SB.Panels[2].Text:='Last Start OK'
- else
- SB.Panels[2].Text:=ErrorText(FLastRecvError);
- end;
- procedure TPartnerForm.SetFRunning(const Value: boolean);
- begin
- FRunning := Value;
- if FRunning then
- begin
- EdLocalIP.Enabled:=false;
- EdLocTsapHI.Enabled:=false;
- EdLocTsapLO.Enabled:=false;
- EdRemoteIP.Enabled:=false;
- EdRemTsapHI.Enabled:=false;
- EdRemTsapLO.Enabled:=false;
- StartBtn.Enabled:=false;
- StopBtn.Enabled:=true;
- BSendBtn.Enabled:=true;
- AsBSendBtn.Enabled:=true;
- Ed_R_ID.Enabled:=true;
- EdAmount.Enabled:=true;
- end
- else begin
- EdLocalIP.Enabled:=not FActive;
- EdLocTsapHI.Enabled:=true;
- EdLocTsapLO.Enabled:=true;
- EdRemoteIP.Enabled:=true;
- EdRemTsapHI.Enabled:=true;
- EdRemTsapLO.Enabled:=true;
- StartBtn.Enabled:=true;
- StopBtn.Enabled:=false;
- if FActive then
- EdLocalIP.Text:='';
- ChkSend.Checked:=false;
- BSendBtn.Enabled:=false;
- AsBSendBtn.Enabled:=false;
- Ed_R_ID.Enabled:=false;
- EdAmount.Enabled:=false;
- TBSend.Enabled:=false;
- end;
- end;
- procedure TPartnerForm.StartBtnClick(Sender: TObject);
- begin
- if not FRunning then
- PartnerStart;
- end;
- procedure TPartnerForm.StopBtnClick(Sender: TObject);
- begin
- if FRunning then
- PartnerStop;
- end;
- procedure TPartnerForm.TBRecvTimer(Sender: TObject);
- begin
- //
- // if Partner.AsBRecvCompletion()
- end;
- procedure TPartnerForm.TBsendTimer(Sender: TObject);
- begin
- if not (csDestroying in ComponentState) and Partner.Linked then
- BSend(false,true);
- end;
- procedure TPartnerForm.TLedTimer(Sender: TObject);
- begin
- DataLed.Color:=clBtnFace;
- end;
- procedure TPartnerForm.TStatTimer(Sender: TObject);
- Var
- Status : integer;
- BytesSent : cardinal;
- BytesRecv : cardinal;
- ErrSend : cardinal;
- ErrRecv : cardinal;
- begin
- Status:=Partner.Status;
- case Status of
- par_stopped : SB.Panels[0].Text:='Stopped';
- par_connecting : SB.Panels[0].Text:='Connecting';
- par_waiting : SB.Panels[0].Text:='Waiting';
- par_linked : SB.Panels[0].Text:='Connected';
- par_sending : SB.Panels[0].Text:='Sending';
- par_receiving : SB.Panels[0].Text:='Receiving';
- par_binderror : SB.Panels[0].Text:='Bind Error';
- end;
- BytesSent:=Partner.BytesSent;
- BytesRecv:=Partner.BytesRecv;
- ErrSend :=Partner.SendErrors;
- ErrRecv :=Partner.RecvErrors;
- EdSent.Text:=IntToStr(BytesSent);
- EdRecv.Text:=IntToStr(BytesRecv);
- end;
- procedure TPartnerForm.ValidateGrid;
- Var
- r,c : integer;
- function ValidateHexCell(S : string) : string;
- Var
- V : integer;
- begin
- if S='' then
- S:='0';
- V:=StrToIntDef(S,0);
- if V<0 then V:=0;
- if V>255 then V:=255;
- Result:='$'+IntToHex(V,2);
- end;
- begin
- With DataGrid do
- for r:=1 to RowCount - 1 do
- for c := 1 to ColCount - 1 do
- Cells[c,r]:=ValidateHexCell(Cells[c,r])
- end;
- procedure TPartnerForm.WaitBSendCompletion;
- Var
- Result : integer;
- begin
- Application.ProcessMessages;
- if AsSendMode=amPolling then
- begin
- repeat
- Application.ProcessMessages;
- until Partner.CheckAsBSendCompletion(Result);
- end
- else
- Result:=Partner.WaitAsBSendCompletion(3000);
- LastSendError:=Result;
- end;
- { TRecvThread }
- constructor TRecvThread.Create(PartnerForm: TPartnerForm);
- begin
- inherited Create(true);
- FreeOnTerminate:=false;
- FPartnerForm:=PartnerForm;
- end;
- procedure TRecvThread.Execute;
- begin
- while not Terminated do
- begin
- FPartnerForm.RxEvent.WaitFor(infinite);
- if not Terminated then
- Synchronize(FPartnerForm.DataIncoming);
- end;
- end;
- initialization
- CS:=TCriticalSection.Create;
- finalization
- CS.Free;;
- end.
|