{
Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure MWatek.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end;
}

unit UWatek;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls;

const cMAX  = 10;
const cWAIT = 1000;

type

MWatek = class(TThread)
private
	MySemaphore : Cardinal;
	wykonuj     : Boolean;
	cyfra       : Integer;
	Memo        : TMemo;
	Panel       : TPanel;
	numer_watku : Integer;

protected
	procedure Execute(); override;

public
   procedure Counter();
   procedure Display();

	constructor create(CreateSuspended : Boolean;
                      parMemo         : TMemo;
                      parPanel        : TPanel;
                      parNumer_watku  : Integer;
                      parMySemaphore  : Cardinal);

end;

implementation
{------------------------------------------------------------------------------}
constructor MWatek.Create(CreateSuspended : Boolean;
                          parMemo         : TMemo;
                          parPanel        : TPanel;
                          parNumer_watku  : Integer;
                          parMySemaphore  : Cardinal);
begin
	inherited Create(CreateSuspended);

   Memo            := parMemo;
   wykonuj         := true;
   cyfra           := 1;
   numer_watku     := parNumer_watku;
   Panel           := parPanel;

   FreeOnTerminate := true;

   MySemaphore     := parMySemaphore;
end;

procedure MWatek.Counter();
begin
	Inc(cyfra);
end;

procedure MWatek.Display();
begin
   Panel.Caption := IntToStr(cyfra);
   Memo.Lines.Add(IntToStr(numer_watku) + '.' + IntToStr(cyfra));
end;

procedure MWatek.Execute();
begin
	//                                         INFINITE
	if WaitForSingleObject(MySemaphore, 100) = WAIT_OBJECT_0 then
   begin
      while wykonuj do
      begin
         Synchronize(Display);
   	   Synchronize(Counter);

         if (Terminated and (cyfra >= cMAX)) then
         begin
            wykonuj := false;
         end;

         Sleep(cWAIT);
      end;

      Synchronize(Display);

      ReleaseSemaphore(MySemaphore, 1, Nil);
   end;
end;

end.


