//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "TThreadListList.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}

// BeginExample: TThreadList
// Method: Classes.TThreadList.LockList
// Method: Classes.TThreadList.UnlockList
// Method: Classes.TThreadList.Add
// Method: Classes.TThreadList.Remove
// Method: Classes.TThread.Terminate
// Property: Classes.TThread.Terminated

// BeginCode
/*
The following example shows how to use the LockList and
UnlockList methods to access a thread-safe version  of a
TList object:
*/

#include <memory> // for the auto_str

class TMyThread : public TThread
{
__published:	// IDE-managed Components
private:	// User declarations
protected:  // User declarations
	void __fastcall Execute();
public:		// User declarations
	__fastcall TMyThread(bool suspended);
};

__fastcall TMyThread::TMyThread(bool suspended)
	: TThread(suspended)
{
}

class TYouThread : public TThread
{
__published:	// IDE-managed Components
private:	// User declarations
protected:  // User declarations
	void __fastcall Execute();
public:		// User declarations
	__fastcall TYouThread(bool suspended);
};

__fastcall TYouThread::TYouThread(bool suspended)
	: TThread(suspended)
{
}

class TListThread : public TThread
{
__published:	// IDE-managed Components
private:	// User declarations
protected:  // User declarations
	void __fastcall Execute();
public:		// User declarations
	__fastcall TListThread(bool suspended);
};

__fastcall TListThread::TListThread(bool suspended)
	: TThread(suspended)
{
}

TThreadList *threadList1;
bool mythreadRunning, youthreadRunning, listthreadRunning;
int globalCount;
TMyThread *secondProcess;
TYouThread *otherSecondProcess;
TListThread *listProcess; // thread arecustom descendants of TThread

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if (mythreadRunning == FALSE)
  {
	mythreadRunning = TRUE;
	secondProcess = new TMyThread(True); // create suspended – secondprocess does not run yet
	secondProcess->FreeOnTerminate = True; // don't need to cleanup after terminate
	secondProcess->Priority = tpLower;  // set the priority to lower than normal
	secondProcess->Resume(); // now run the thread
  }
  else
	MessageDlg("This thread is still running.  You are going to hurt yourself!",
	  mtInformation, TMsgDlgButtons() << mbOK, 0);
}

void __fastcall TMyThread::Execute()
{
  for (int I = 0; I <= 20; I++)
  {
	if (Terminated) break;
	TRadioButton *myRadio = new TRadioButton(Form1); // The owner (Form1) will clean this up.
	globalCount = globalCount + 1;
	myRadio->Name = "RadioButton" + IntToStr(globalCount);
    threadList1->Add(myRadio);
	Sleep(1000);
  }
  mythreadRunning = FALSE;
}

void __fastcall TForm1::Button3Click(TObject *Sender)
{
  if (youthreadRunning == FALSE)
  {
	youthreadRunning = TRUE;
	otherSecondProcess = new TYouThread(True); // create suspended – other secondprocess does not run yet
	otherSecondProcess->FreeOnTerminate = True; // don't need to cleanup after terminate
	otherSecondProcess->Priority = tpLower;  // set the priority to lower than normal
	otherSecondProcess->Resume(); // now run the thread
  }
  else
	MessageDlg("This thread is still running.  You are going to hurt yourself!",
	  mtInformation, TMsgDlgButtons() << mbOK, 0);
}

void __fastcall TYouThread::Execute()
{
  for (int I = 0; I <= 10; I++)
  {
	if (Terminated) break;
	try
	{
	  TList *list = threadList1->LockList();
	  if (2*I < list->Count)
	  {
		TControl *Temp = reinterpret_cast<TControl *>(list->Items[2*I]);
		threadList1->Remove(Temp);
	  }
	}
	__finally
	{
	  threadList1->UnlockList();
	}
	if (Terminated)
	  MessageDlg("youThread has been asked to terminate, but is still running!",
		mtInformation, TMsgDlgButtons() << mbOK, 0);
    Sleep(3000);
  }
  youthreadRunning = FALSE;
}

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  if (listthreadRunning == FALSE)
  {
	listthreadRunning = TRUE;
	listProcess = new TListThread(True); // create suspended – secondprocess does not run yet
	listProcess->FreeOnTerminate = True; // don't need to cleanup after terminate
	listProcess->Priority = tpLower;  // set the priority to lower than normal
	listProcess->Resume(); // now run the thread
  }
  else
	MessageDlg("This thread is still running.  You are going to hurt yourself!",
	  mtInformation, TMsgDlgButtons() << mbOK, 0);
}

void __fastcall TListThread::Execute()
{
  while(True)
  {
	if (Terminated) break;
	Form1->ListBox1->Clear();
	TList *myList = threadList1->LockList();
	try
	{
	  for (int I = 0; I < myList->Count; I++)
	  {
		TControl *Temp = reinterpret_cast<TControl *>(myList->Items[I]);
		Form1->ListBox1->Items->Add(Temp->Name);
	  }
	}
	__finally
	{
	  threadList1->UnlockList();
	}
    Sleep(1000);
  }
}

void __fastcall TForm1::Button4Click(TObject *Sender)
{
  if (secondProcess != NULL)
	secondProcess->Terminate();
  if (otherSecondProcess != NULL)
	otherSecondProcess->Terminate();
}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
  mythreadRunning = FALSE;
  youthreadRunning = FALSE;
  listthreadRunning = FALSE;
  listProcess = NULL;
  secondProcess = NULL;
  otherSecondProcess = NULL;
  static std::auto_ptr<TThreadList> _threadList1Cleaner(threadList1 = new TThreadList());
  for (int I = 1; I <= 5; I++)
  {
	TRadioButton *RadioButton = new TRadioButton(Form1); // The owner (Form1) will clean this up.
	RadioButton->Name = "RadioButton" + IntToStr(I);
	threadList1->Add(RadioButton);
  }
  globalCount = 5;
}
// EndCode
// EndExample: TThreadList

