frmPartner.pas 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. unit frmPartner;
  2. {$MODE Delphi}
  3. interface
  4. uses
  5. {$IFNDEF FPC}
  6. Windows,
  7. {$ELSE}
  8. LCLIntf, LCLType, LMessages,
  9. {$ENDIF}
  10. Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  11. Dialogs, ComCtrls, Grids, SyncObjs,
  12. StdCtrls, ExtCtrls,
  13. Snap7;
  14. Const
  15. _Active = true; // <- the underscore to avoid conflicts with the Form property "Active"
  16. _Passive = false;
  17. type
  18. TS7Buffer = packed array[0..$FFFF] of byte;
  19. TPartnerForm = class;
  20. TRecvThread = class(TThread)
  21. private
  22. FPartnerForm : TPartnerForm;
  23. public
  24. constructor Create(PartnerForm : TPartnerForm);
  25. procedure Execute; override;
  26. end;
  27. TPartnerForm = class(TForm)
  28. PageControl: TPageControl;
  29. TabBSend: TTabSheet;
  30. TabBRecv: TTabSheet;
  31. SB: TStatusBar;
  32. DataGrid: TStringGrid;
  33. GR_Remote: TGroupBox;
  34. Label5: TLabel;
  35. Label6: TLabel;
  36. Label7: TLabel;
  37. EdRemoteIP: TEdit;
  38. EdRemTsapHI: TEdit;
  39. EdRemTsapLO: TEdit;
  40. StartBtn: TButton;
  41. StopBtn: TButton;
  42. Label1: TLabel;
  43. Ed_R_ID: TEdit;
  44. Label4: TLabel;
  45. EdAmount: TEdit;
  46. BsendBtn: TButton;
  47. AsBsendBtn: TButton;
  48. lbldump: TLabel;
  49. RxMemo: TMemo;
  50. EdR_ID_In: TEdit;
  51. Label8: TLabel;
  52. GR_local: TGroupBox;
  53. Label2: TLabel;
  54. Label3: TLabel;
  55. Label9: TLabel;
  56. EdLocalIP: TEdit;
  57. EdLocTsapHI: TEdit;
  58. EdLocTsapLO: TEdit;
  59. DataLed: TStaticText;
  60. TLed: TTimer;
  61. TBsend: TTimer;
  62. ChkSend: TCheckBox;
  63. TStat: TTimer;
  64. TabStat: TTabSheet;
  65. EdSent: TEdit;
  66. Label10: TLabel;
  67. Label11: TLabel;
  68. EdRecv: TEdit;
  69. RGMode: TRadioGroup;
  70. TBRecv: TTimer;
  71. EdTimeout: TEdit;
  72. Label13: TLabel;
  73. BRecvBtn: TButton;
  74. BRecvLbl: TLabel;
  75. ARGMode: TRadioGroup;
  76. procedure DataGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  77. Rect: TRect; State: TGridDrawState);
  78. procedure DataGridExit(Sender: TObject);
  79. procedure DataGridKeyPress(Sender: TObject; var Key: Char);
  80. procedure FormCreate(Sender: TObject);
  81. procedure TLedTimer(Sender: TObject);
  82. procedure StartBtnClick(Sender: TObject);
  83. procedure StopBtnClick(Sender: TObject);
  84. procedure TStatTimer(Sender: TObject);
  85. procedure FormDestroy(Sender: TObject);
  86. procedure ChkSendClick(Sender: TObject);
  87. procedure TBsendTimer(Sender: TObject);
  88. procedure FormClose(Sender: TObject; var Action: TCloseAction);
  89. procedure BsendBtnClick(Sender: TObject);
  90. procedure AsBsendBtnClick(Sender: TObject);
  91. procedure RGModeClick(Sender: TObject);
  92. procedure TBRecvTimer(Sender: TObject);
  93. procedure ARGModeClick(Sender: TObject);
  94. procedure BRecvBtnClick(Sender: TObject);
  95. private
  96. { Private declarations }
  97. TxBuffer : TS7Buffer;
  98. FActive : boolean;
  99. FRunning: boolean;
  100. RecvThread : TRecvThread;
  101. Cnt : byte;
  102. AsSendMode : integer;
  103. AsRecvMode : integer;
  104. FLastSendError: integer;
  105. FLastRecvError: integer;
  106. FLastStartError: integer;
  107. procedure ValidateGrid;
  108. procedure DataToGrid(Amount : integer);
  109. procedure GridToData(Amount : integer);
  110. procedure SetFRunning(const Value: boolean);
  111. procedure PartnerStart;
  112. procedure PartnerStop;
  113. procedure DumpData(P : PS7Buffer; Memo : TMemo; Count : integer);
  114. procedure BSend(Async : boolean; Const Cyclic : boolean = false);
  115. procedure SetFLastSendError(const Value: integer);
  116. procedure SetFLastRecvError(const Value: integer);
  117. procedure SetFLastStartError(const Value: integer);
  118. procedure WaitBSendCompletion;
  119. procedure BRecv(WithPolling : boolean);
  120. function ErrorText(ErrNo : integer) : String;
  121. public
  122. { Public declarations }
  123. Partner : TS7Partner;
  124. RxBuffer : TS7Buffer;
  125. RxSize : integer;
  126. RxR_ID : cardinal;
  127. RxError : integer;
  128. RxEvent : TEvent;
  129. TxEvent : TEvent;
  130. procedure DataIncoming;
  131. procedure CreatePartner(Mode : boolean);
  132. property Running : boolean read FRunning write SetFRunning;
  133. property LastStartError : integer read FLastStartError write SetFLastStartError;
  134. property LastSendError : integer read FLastSendError write SetFLastSendError;
  135. property LastRecvError : integer read FLastRecvError write SetFLastRecvError;
  136. end;
  137. implementation
  138. {$R *.lfm}
  139. Const
  140. amPolling = 0;
  141. amWait = 1;
  142. amCallBack = 2;
  143. Var
  144. CS : TCriticalSection;
  145. procedure OnRecv(usrPtr : pointer; opResult : integer; R_ID : dword;
  146. pdata : pointer; size : integer);
  147. {$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  148. Var
  149. PF : TPartnerForm;
  150. begin
  151. CS.Enter;
  152. try
  153. PF:=TPartnerForm(usrPtr);
  154. if Assigned(PF) then
  155. begin
  156. if opResult=0 then
  157. begin
  158. move(pdata^,PF.RxBuffer[0],Size);
  159. PF.RxSize:=Size;
  160. PF.RxR_ID:=R_ID;
  161. end;
  162. PF.RxError:=opResult;
  163. PF.RxEvent.SetEvent;
  164. end;
  165. finally
  166. CS.Leave;
  167. end;
  168. end;
  169. procedure OnSend(usrPtr : pointer; opResult : integer); stdcall;
  170. var
  171. PF : TPartnerForm;
  172. begin
  173. CS.Enter;
  174. try
  175. PF:=TPartnerForm(usrPtr);
  176. if Assigned(PF) then
  177. PF.TxEvent.SetEvent;
  178. finally
  179. CS.Leave;
  180. end;
  181. end;
  182. procedure TPartnerForm.ARGModeClick(Sender: TObject);
  183. begin
  184. AsRecvMode:=ARGMode.ItemIndex; // 0 : amPolling
  185. // 1 : amEvent
  186. // 2 : amCallBack
  187. case AsRecvMode of
  188. amPolling,
  189. amWait : begin
  190. Partner.SetRecvCallback(nil,Self); // <-- We don't want callback
  191. BRecvBtn.Enabled:=true;
  192. end;
  193. amCallback: begin
  194. Partner.SetRecvCallback(@OnRecv,Self);
  195. BRecvBtn.Enabled:=false; // <-- the recv is full async
  196. end;
  197. end;
  198. BRecvLbl.Enabled :=BRecvBtn.Enabled;
  199. EdTimeout.Enabled:=BRecvBtn.Enabled;
  200. end;
  201. procedure TPartnerForm.AsBsendBtnClick(Sender: TObject);
  202. begin
  203. BSend(true,false);
  204. end;
  205. procedure TPartnerForm.BRecv(WithPolling: boolean);
  206. Var
  207. Timeout : cardinal;
  208. Result : integer;
  209. Elapsed : cardinal;
  210. Done : boolean;
  211. begin
  212. Timeout:=StrToIntDef(edTimeout.Text,0);
  213. edTimeout.Text:=IntToStr(Timeout);
  214. if WithPolling then
  215. begin
  216. Elapsed:=GetTickCount;
  217. repeat
  218. Application.ProcessMessages;
  219. Done:=Partner.CheckAsBRecvCompletion(Result,RxR_ID,@RxBuffer,RxSize);
  220. until Done or (GetTickCount-Elapsed>Timeout);
  221. if not Done then
  222. Result:=errParRecvTimeout;
  223. end
  224. else // Wait idle
  225. Result:=Partner.BRecv(Timeout,RxR_ID,@RxBuffer,RxSize);
  226. LastRecvError:=Result;
  227. if Result=0 then
  228. begin
  229. DumpData(@RxBuffer,RxMemo,RxSize);
  230. lbldump.Caption:='Data Dump : '+IntToStr(RxSize)+' bytes';
  231. EdR_ID_In.Text:='$'+IntToHex(RxR_ID,8);
  232. end;
  233. end;
  234. procedure TPartnerForm.BRecvBtnClick(Sender: TObject);
  235. begin
  236. BRecv(ARGMode.ItemIndex=0);
  237. end;
  238. procedure TPartnerForm.BSend(Async: boolean; Const Cyclic : boolean = false);
  239. Var
  240. Amount : integer;
  241. R_ID : cardinal;
  242. c: Integer;
  243. SendTime,RecvTime : cardinal;
  244. begin
  245. // Amount
  246. Amount:=StrToIntDef(EdAmount.Text,0);
  247. if Amount>65536 then
  248. Amount:=65536;
  249. EdAmount.Text:=IntToStr(Amount);
  250. // R_ID
  251. R_ID:=StrToIntDef(Ed_R_ID.Text,0);
  252. Ed_R_ID.Text:='$'+IntToHex(R_ID,8);
  253. if Cyclic then
  254. begin
  255. TBSend.Enabled:=false;
  256. inc(Cnt);
  257. for c := 0 to Amount - 1 do
  258. TxBuffer[c]:=Cnt;
  259. DataToGrid(Amount);
  260. end
  261. else
  262. GridToData(Amount);
  263. if Async then
  264. FLastSendError:=Partner.AsBSend(R_ID,@TxBuffer,Amount)
  265. else
  266. LastSendError:=Partner.BSend(R_ID,@TxBuffer,Amount);
  267. if FLastSendError=0 then
  268. begin
  269. if ASync then
  270. WaitBSendCompletion;
  271. end;
  272. SB.Panels[1].Text:=IntToStr(Partner.SendTime)+' ms';
  273. if Cyclic then
  274. TBSend.Enabled:=true;
  275. end;
  276. procedure TPartnerForm.BsendBtnClick(Sender: TObject);
  277. begin
  278. BSend(false,false);
  279. end;
  280. procedure TPartnerForm.ChkSendClick(Sender: TObject);
  281. begin
  282. if ChkSend.Checked then
  283. begin
  284. BSendBtn.Enabled:=false;
  285. Ed_R_ID.Enabled:=false;
  286. EdAmount.Enabled:=false;
  287. AsBSendBtn.Enabled:=false;
  288. TBSend.Enabled:=true;
  289. end
  290. else begin
  291. TBSend.Enabled:=false;
  292. BSendBtn.Enabled:=true;
  293. AsBSendBtn.Enabled:=true;
  294. Ed_R_ID.Enabled:=true;
  295. EdAmount.Enabled:=true;
  296. end;
  297. end;
  298. procedure TPartnerForm.CreatePartner(Mode: boolean);
  299. begin
  300. Partner:=TS7Partner.Create(Mode);
  301. FActive:=Mode;
  302. if FActive then
  303. begin
  304. Caption:='Active Partner';
  305. GR_Local.Caption:='Local Partner (Active)';
  306. GR_Remote.Caption:='Remote Partner (Passive)';
  307. EdLocalIP.Text:='';
  308. EdLocalIP.Color:=clBtnFace;
  309. EdLocalIP.Enabled:=false;
  310. end
  311. else begin
  312. Caption:='Passive Partner';
  313. GR_Local.Caption:='Local Partner (Passive)';
  314. GR_Remote.Caption:='Remote Partner (Active)';
  315. end;
  316. Partner.SetRecvCallback(@OnRecv,Self);
  317. BRecvBtn.Enabled:=false; // <-- the recv is full async
  318. BRecvLbl.Enabled:=false;
  319. EdTimeout.Enabled:=false;
  320. ARgMode.ItemIndex:=2;
  321. Running:=false;
  322. end;
  323. procedure TPartnerForm.DataGridDrawCell(Sender: TObject; ACol, ARow: Integer;
  324. Rect: TRect; State: TGridDrawState);
  325. Var
  326. aRect : TRect;
  327. aText : string;
  328. Style : TTextStyle;
  329. begin
  330. with Sender as TStringGrid do
  331. begin
  332. ARect:=Rect;
  333. AText:=Cells[ACol,ARow];
  334. if (ACol=0) or (ARow=0) then
  335. Canvas.Brush.Color:=clbtnface
  336. else
  337. Canvas.Brush.Color:=clWhite;
  338. Canvas.FillRect(Rect);
  339. Style.Alignment:=taCenter;
  340. Style.Clipping:=true;
  341. Style.ExpandTabs:=false;
  342. Style.Layout:=tlCenter;
  343. Style.ShowPrefix:=false;
  344. Style.Wordbreak:=false;
  345. Style.SystemFont:=false;
  346. Style.RightToLeft:=false;
  347. Canvas.TextRect(ARect, 0,0, AText,Style);
  348. if gdfocused in State then
  349. begin
  350. Canvas.Brush.Color:=clRed;
  351. Canvas.FrameRect(ARect);
  352. end;
  353. end;
  354. end;
  355. procedure TPartnerForm.DataGridExit(Sender: TObject);
  356. begin
  357. ValidateGrid;
  358. end;
  359. procedure TPartnerForm.DataGridKeyPress(Sender: TObject; var Key: Char);
  360. begin
  361. if Key=#13 then
  362. ValidateGrid;
  363. end;
  364. procedure TPartnerForm.DataIncoming;
  365. begin
  366. if RxError=0 then
  367. begin
  368. DataLed.Color:=clLime;
  369. DumpData(@RxBuffer,RxMemo,RxSize);
  370. lbldump.Caption:='Data Dump : '+IntToStr(RxSize)+' bytes';
  371. EdR_ID_In.Text:='$'+IntToHex(RxR_ID,8);
  372. TLed.Enabled:=true;
  373. end;
  374. LastRecvError:=RxError;
  375. end;
  376. procedure TPartnerForm.DataToGrid(Amount: integer);
  377. Var
  378. x, c, r : integer;
  379. begin
  380. with DataGrid do
  381. begin
  382. c:=1;r:=1;
  383. for x := 0 to Amount - 1 do
  384. begin
  385. Cells[c,r]:='$'+IntToHex(TxBuffer[x],2);
  386. inc(c);
  387. if c=ColCount then
  388. begin
  389. c:=1;
  390. inc(r);
  391. end;
  392. end;
  393. Row:=1;
  394. Col:=1;
  395. if PageControl.ActivePage=TabBSend then
  396. SetFocus;
  397. end;
  398. end;
  399. procedure TPartnerForm.DumpData(P: PS7Buffer; Memo: TMemo; Count: integer);
  400. Var
  401. SHex, SChr : string;
  402. Ch : AnsiChar;
  403. c, cnt : integer;
  404. begin
  405. Memo.Lines.Clear;
  406. Memo.Lines.BeginUpdate;
  407. SHex:='';SChr:='';cnt:=0;
  408. try
  409. for c := 0 to Count - 1 do
  410. begin
  411. SHex:=SHex+IntToHex(P^[c],2)+' ';
  412. Ch:=AnsiChar(P^[c]);
  413. if not (Ch in ['a'..'z','A'..'Z','0'..'9','_','$','-',#32]) then
  414. Ch:='.';
  415. SChr:=SChr+String(Ch);
  416. inc(cnt);
  417. if cnt=16 then
  418. begin
  419. Memo.Lines.Add(SHex+' '+SChr);
  420. SHex:='';SChr:='';
  421. cnt:=0;
  422. end;
  423. end;
  424. // Dump remainder
  425. if cnt>0 then
  426. begin
  427. while Length(SHex)<48 do
  428. SHex:=SHex+' ';
  429. Memo.Lines.Add(SHex+' '+SChr);
  430. end;
  431. finally
  432. Memo.Lines.EndUpdate;
  433. end;
  434. end;
  435. function TPartnerForm.ErrorText(ErrNo: integer) : string;
  436. begin
  437. Result:=String(ParErrorText(ErrNo));
  438. end;
  439. procedure TPartnerForm.FormClose(Sender: TObject; var Action: TCloseAction);
  440. begin
  441. Action:=caFree;
  442. end;
  443. procedure TPartnerForm.FormCreate(Sender: TObject);
  444. Var
  445. c : integer;
  446. begin
  447. RxEvent:=TEvent.Create(nil,false,false,'');
  448. TxEvent:=TEvent.Create(nil,false,false,'');
  449. RecvThread := TRecvThread.Create(Self);
  450. RecvThread.Start;
  451. // Init Grid
  452. with DataGrid do
  453. begin
  454. DefaultColWidth:=32;
  455. ColWidths[0]:=48;
  456. DefaultRowHeight:=18;
  457. ColCount:=17;
  458. RowCount:=4097;
  459. for c := 1 to ColCount - 1 do
  460. Cells[c,0]:=inttohex(c-1,2);
  461. for c := 1 to RowCount - 1 do
  462. Cells[0,c]:=inttohex((c-1)*16,4);
  463. end;
  464. ValidateGrid;
  465. end;
  466. procedure TPartnerForm.FormDestroy(Sender: TObject);
  467. begin
  468. Partner.Free;
  469. RecvThread.Terminate;
  470. RxEvent.SetEvent;
  471. TxEvent.SetEvent;
  472. RecvThread.Free;
  473. RxEvent.Free;;
  474. TxEvent.Free;
  475. end;
  476. procedure TPartnerForm.GridToData(Amount: integer);
  477. Var
  478. x, c, r : integer;
  479. begin
  480. ValidateGrid;
  481. with DataGrid do
  482. begin
  483. c:=1;r:=1;
  484. for x := 0 to Amount- 1 do
  485. begin
  486. TxBuffer[x]:=StrToIntDef(Cells[c,r],0);
  487. inc(c);
  488. if c=ColCount then
  489. begin
  490. c:=1;
  491. inc(r);
  492. end;
  493. end;
  494. end;
  495. end;
  496. procedure TPartnerForm.PartnerStart;
  497. Var
  498. LocalAddress : AnsiString;
  499. RemoteAddress: AnsiString;
  500. LocalTsapHI : integer;
  501. LocalTsapLO : integer;
  502. RemoteTsapHI : integer;
  503. RemoteTsapLO : integer;
  504. LocalTsap : integer;
  505. RemoteTsap : integer;
  506. function GetChar(ED : TEdit) : integer;
  507. Var
  508. B : byte;
  509. begin
  510. B:=StrToIntDef('$'+Ed.Text,0);
  511. Ed.Text:=IntToHex(B,2);
  512. Result:=B;
  513. end;
  514. begin
  515. LocalAddress :=EdLocalIP.Text;
  516. RemoteAddress:=EdRemoteIP.Text;
  517. LocalTsapHI :=GetChar(EdLocTsapHI);
  518. LocalTsapLO :=GetChar(EdLocTsapLO);
  519. RemoteTsapHI :=GetChar(EdRemTsapHI);
  520. RemoteTsapLO :=GetChar(EdRemTsapLO);
  521. LocalTsap :=LocalTsapHI shl 8 + LocalTsapLO;
  522. RemoteTsap :=RemoteTsapHI shl 8 + RemoteTsapLO;
  523. LastStartError:=Partner.StartTo(LocalAddress,
  524. RemoteAddress,
  525. LocalTsap,
  526. RemoteTsap);
  527. Running:=FLastStartError=0;
  528. end;
  529. procedure TPartnerForm.PartnerStop;
  530. begin
  531. Partner.Stop;
  532. Running:=false;
  533. SB.Panels[2].Text:='';
  534. end;
  535. procedure TPartnerForm.RGModeClick(Sender: TObject);
  536. begin
  537. AsSendMode:=RGMode.ItemIndex; // 0 : amPolling
  538. // 1 : amEvent
  539. // 2 : amCallBack
  540. case AsSendMode of
  541. amPolling,
  542. amWait : Partner.SetSendCallback(nil,Self);
  543. amCallback: Partner.SetSendCallback(@OnSend,Self);
  544. end;
  545. end;
  546. procedure TPartnerForm.SetFLastRecvError(const Value: integer);
  547. begin
  548. FLastRecvError := Value;
  549. if FLastRecvError=0 then
  550. SB.Panels[2].Text:='Last BRecv OK'
  551. else
  552. SB.Panels[2].Text:=ErrorText(FLastRecvError);
  553. end;
  554. procedure TPartnerForm.SetFLastSendError(const Value: integer);
  555. begin
  556. FLastSendError := Value;
  557. if FLastSendError=0 then
  558. SB.Panels[2].Text:='Last BSend OK'
  559. else
  560. SB.Panels[2].Text:=ErrorText(FLastSendError);
  561. end;
  562. procedure TPartnerForm.SetFLastStartError(const Value: integer);
  563. begin
  564. FLastStartError := Value;
  565. if FLastStartError=0 then
  566. SB.Panels[2].Text:='Last Start OK'
  567. else
  568. SB.Panels[2].Text:=ErrorText(FLastRecvError);
  569. end;
  570. procedure TPartnerForm.SetFRunning(const Value: boolean);
  571. begin
  572. FRunning := Value;
  573. if FRunning then
  574. begin
  575. EdLocalIP.Enabled:=false;
  576. EdLocTsapHI.Enabled:=false;
  577. EdLocTsapLO.Enabled:=false;
  578. EdRemoteIP.Enabled:=false;
  579. EdRemTsapHI.Enabled:=false;
  580. EdRemTsapLO.Enabled:=false;
  581. StartBtn.Enabled:=false;
  582. StopBtn.Enabled:=true;
  583. BSendBtn.Enabled:=true;
  584. AsBSendBtn.Enabled:=true;
  585. Ed_R_ID.Enabled:=true;
  586. EdAmount.Enabled:=true;
  587. end
  588. else begin
  589. EdLocalIP.Enabled:=not FActive;
  590. EdLocTsapHI.Enabled:=true;
  591. EdLocTsapLO.Enabled:=true;
  592. EdRemoteIP.Enabled:=true;
  593. EdRemTsapHI.Enabled:=true;
  594. EdRemTsapLO.Enabled:=true;
  595. StartBtn.Enabled:=true;
  596. StopBtn.Enabled:=false;
  597. if FActive then
  598. EdLocalIP.Text:='';
  599. ChkSend.Checked:=false;
  600. BSendBtn.Enabled:=false;
  601. AsBSendBtn.Enabled:=false;
  602. Ed_R_ID.Enabled:=false;
  603. EdAmount.Enabled:=false;
  604. TBSend.Enabled:=false;
  605. end;
  606. end;
  607. procedure TPartnerForm.StartBtnClick(Sender: TObject);
  608. begin
  609. if not FRunning then
  610. PartnerStart;
  611. end;
  612. procedure TPartnerForm.StopBtnClick(Sender: TObject);
  613. begin
  614. if FRunning then
  615. PartnerStop;
  616. end;
  617. procedure TPartnerForm.TBRecvTimer(Sender: TObject);
  618. begin
  619. //
  620. // if Partner.AsBRecvCompletion()
  621. end;
  622. procedure TPartnerForm.TBsendTimer(Sender: TObject);
  623. begin
  624. if not (csDestroying in ComponentState) and Partner.Linked then
  625. BSend(false,true);
  626. end;
  627. procedure TPartnerForm.TLedTimer(Sender: TObject);
  628. begin
  629. DataLed.Color:=clBtnFace;
  630. end;
  631. procedure TPartnerForm.TStatTimer(Sender: TObject);
  632. Var
  633. Status : integer;
  634. BytesSent : cardinal;
  635. BytesRecv : cardinal;
  636. ErrSend : cardinal;
  637. ErrRecv : cardinal;
  638. begin
  639. Status:=Partner.Status;
  640. case Status of
  641. par_stopped : SB.Panels[0].Text:='Stopped';
  642. par_connecting : SB.Panels[0].Text:='Connecting';
  643. par_waiting : SB.Panels[0].Text:='Waiting';
  644. par_linked : SB.Panels[0].Text:='Connected';
  645. par_sending : SB.Panels[0].Text:='Sending';
  646. par_receiving : SB.Panels[0].Text:='Receiving';
  647. par_binderror : SB.Panels[0].Text:='Bind Error';
  648. end;
  649. BytesSent:=Partner.BytesSent;
  650. BytesRecv:=Partner.BytesRecv;
  651. ErrSend :=Partner.SendErrors;
  652. ErrRecv :=Partner.RecvErrors;
  653. EdSent.Text:=IntToStr(BytesSent);
  654. EdRecv.Text:=IntToStr(BytesRecv);
  655. end;
  656. procedure TPartnerForm.ValidateGrid;
  657. Var
  658. r,c : integer;
  659. function ValidateHexCell(S : string) : string;
  660. Var
  661. V : integer;
  662. begin
  663. if S='' then
  664. S:='0';
  665. V:=StrToIntDef(S,0);
  666. if V<0 then V:=0;
  667. if V>255 then V:=255;
  668. Result:='$'+IntToHex(V,2);
  669. end;
  670. begin
  671. With DataGrid do
  672. for r:=1 to RowCount - 1 do
  673. for c := 1 to ColCount - 1 do
  674. Cells[c,r]:=ValidateHexCell(Cells[c,r])
  675. end;
  676. procedure TPartnerForm.WaitBSendCompletion;
  677. Var
  678. Result : integer;
  679. begin
  680. Application.ProcessMessages;
  681. if AsSendMode=amPolling then
  682. begin
  683. repeat
  684. Application.ProcessMessages;
  685. until Partner.CheckAsBSendCompletion(Result);
  686. end
  687. else
  688. Result:=Partner.WaitAsBSendCompletion(3000);
  689. LastSendError:=Result;
  690. end;
  691. { TRecvThread }
  692. constructor TRecvThread.Create(PartnerForm: TPartnerForm);
  693. begin
  694. inherited Create(true);
  695. FreeOnTerminate:=false;
  696. FPartnerForm:=PartnerForm;
  697. end;
  698. procedure TRecvThread.Execute;
  699. begin
  700. while not Terminated do
  701. begin
  702. FPartnerForm.RxEvent.WaitFor(infinite);
  703. if not Terminated then
  704. Synchronize(FPartnerForm.DataIncoming);
  705. end;
  706. end;
  707. initialization
  708. CS:=TCriticalSection.Create;
  709. finalization
  710. CS.Free;;
  711. end.