Solved

Control the dinamicly generated, task

Posted on 2004-04-08
22
361 Views
Last Modified: 2010-04-16
Dear Sir

   I am creating multi threaded application, a new form with threade should be created at the run time as on clicking the tree node:

procedure TForm1.CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
Begin
  TForm(Sender).Destroy;
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
  NewForm : TForm;
  thread  : Tthread;
begin
  NewForm := TForm.create(self);
  with NewForm do
  begin
    Left := 250;
    Top := 200;
    Width := 200;
    Height := 300;
    Caption := TreeView1.Selected.Text;
    Name   := 'Form'+TreeView1.Selected.Text;
    OnClose := CustomFormOnClose;
    Show;
  end;
  with Thread do
  begin
    Name   := 'Thread'+TreeView1.Selected.Text;
  end;
end;

I could handle the form events - Like OnClose -
my problem is i dont know how to and where to Control the dinamicly generated, task named 'Thread'+TreeView1.Selected.Text;
I mean Start, stop and the procedure execute

Thank you

Eng: Omar Fayyad
0
Comment
Question by:omarmf
  • 11
  • 6
  • 5
22 Comments
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
You first need to create a Decendent from the thread and override its Execute method. It is in that method(Execute) that you place the code you want the thread to perform.


 MyThread = class(TThread)
 protected
  Procedure Execute;override;
 public
 constructor create;
 end;


constructor TMyThread.create;
begin
  inherited create(true);
 //intialize any internal variable here
end;

end;

procedure TMyThread.Execute;
begin
 // your code here
 // if using the VCL, then you need to wrap your code in a Syncronize();
end;



Then spawn your in your main code

 MyThread:= TThread.Create;

Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
If you want to write initialization code for your new thread class, you must override the Create method. Add a new constructor to the declaration of your thread class and write the initialization code as its implementation. This is where you can assign a default priority for your thread and indicate whether it should be freed automatically when it finishes executing.

MyThread = class(TThread)
 protected
  Procedure Execute;override;
 public
 constructor Create(CreateSuspended: Boolean);
 end;


constructor TMyThread.Create(CreateSuspended: Boolean);
begin
  inherited Create(CreateSuspended);
  //Priority := tpIdle; {you can also set the priority)
end;


MyThread:= TMyThread.Create(True); { create suspended }
MyThread.Priority := tpLower;
MyThread.Resume; { now run the thread }


Shane
0
 
LVL 7

Expert Comment

by:sftweng
Comment Utility
You should read the Delphi help for TThread very carefully. The following code shows a sample of a statically-created TThread (using File -> New -> Other -> Thread Object).

Please note very carefulkly that ANY access to GUI (VCL) structures requires the use of Synchronize.

code:
--------------------
unit Unit2;

interface

uses
  Classes;

type
  MyThread = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  end;

implementation

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

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

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

{ MyThread }

procedure MyThread.Execute;
begin
  { Place thread code here }
end;

end.
------------

The Create, Destroy, Execute, Terminate, ... etc. methods are what you will need to use.

There is an example application in the Delphi demos/threads folder that could give you some help.
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility

Also, you might want to pass to your constructor, the TreeNode Item, so you have it when your thread is started.


MyThread = class(TThread)
private
  fNode: TTreeNode;
 protected
  Procedure Execute;override;
 public
 constructor Create(CreateSuspended: Boolean; Node: TTreeNode);reintriduced;
 end;


constructor TMyThread.Create(CreateSuspended: Boolean; Node: TTreeNode);
begin
  inherited create(true);
 //intialize any internal variable here
 fNode:= Node;
end;

end;

procedure TMyThread.Execute;
begin
 Syncronize(DoSomething);
end;


procedure TMyThread.DoSomething
begin
 // do something with FNode
end;
0
 

Author Comment

by:omarmf
Comment Utility
Ok I dont know put the normal thread is not what i want.

I can create New thread

please see my code

//////////////////////////////

unit nismsn;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls, Buttons, RVStyle, RVScroll, RichView,
  ImgList;

type
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Timer: TTimer;
    senderm: TEdit;
    ListBox1: TListBox;
    Label1: TLabel;
    BitBtn1: TBitBtn;
    Button1: TButton;
    R_ID: TEdit;
    S_ID: TEdit;
    recieverm: TRichView;
    RVStyle1: TRVStyle;
    ImageList1: TImageList;
    FontDialog1: TFontDialog;
    Button2: TButton;
    procedure TimerTimer(Sender: TObject);
    procedure sendermKeyPress(Sender: TObject; var Key: Char);
    procedure FormCreate(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
    procedure FontDialog1Close(Sender: TObject);
    procedure TreeView1DblClick(Sender: TObject);
    procedure CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  protected
  public
      MsgL: TStringList;
  end;

var
  Form1: TForm1;

implementation

uses thread;

{$R *.dfm}

procedure TForm1.CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
Begin
  TForm(Sender).Destroy;
end;

procedure TForm1.TimerTimer(Sender: TObject);
begin
  // Running all the generated threads //
end;


procedure TForm1.sendermKeyPress(Sender: TObject; var Key: Char);
begin
If Key = #13 Then
 begin
  if(senderm.Text<>'') Then
  MsgL.Add(senderm.Text);
  ListBox1.Items:= MsgL;
  senderm.Text:= '';
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  TreeNodeM1, TreeNodeM2,TreeNodeS: TTreeNode;
begin
  MsgL:= TStringList.Create;
  TreeNodeM1 := TreeView1.Items.Add(nil, 'Online');
  TreeNodeM2 := TreeView1.Items.Add(nil, 'Offline');
  TreeNodeS := TreeView1.Items.AddChild(TreeNodeM2, 'Omar');
  TreeNodeS := TreeView1.Items.AddChild(TreeNodeM1, 'Abdu');
  TreeNodeS := TreeView1.Items.AddChild(TreeNodeM1, 'Modar');
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  if(senderm.Text<>'') Then
    Begin
      MsgL.Add(senderm.Text);
      ListBox1.Items:= MsgL;
      senderm.Text:= '';
    End;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  MySQLServer.Connected:= True;
  MySQLReciever.Active:= True;
  Timer.Enabled:= True;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  MySQLServer.Connected:= False;
  MySQLReciever.Active:= False;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  FontDialog1.Execute;
end;

procedure TForm1.FontDialog1Close(Sender: TObject);
begin
  RVStyle1.TextStyles[0].FontName:= FontDialog1.Font.Name;
  RVStyle1.TextStyles[0].Color:= FontDialog1.Font.Color;
  RVStyle1.TextStyles[0].Size:= FontDialog1.Font.Size;
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
  NewForm : TForm;
  RichView: TRichView;
  Thread  : TThread;
begin
  NewForm := TForm.create(self);
  with NewForm do
  begin
    Left := 250;
    Top := 200;
    Width := 200;
    Height := 300;
    Caption := TreeView1.Selected.Text;
    Name   := 'Form'+TreeView1.Selected.Text;
    OnClose := CustomFormOnClose;
    Show;
  end;
  RichView:= TRichView.Create(Self);
  with RichView do
  begin
    Left := 5;
    Top := 5;
    Width := 180;
    Height := 250;
    Name   := 'RichView'+TreeView1.Selected.Text;
    Style  := RVStyle1;
    Add(TreeView1.Selected.Text, 1);
    Format;
    Refresh;
    parent := NewForm;
  end;
  with Thread do
  begin
    Name   := 'Thread'+TreeView1.Selected.Text;
  end;
end;

end.

/////

when i click the node a new form with: ('Form'+TreeView1.Selected.Text) name will be generated then new RichView with ('RichView'+TreeView1.Selected.Text) will be generated what i need is to generate a new thread with: 'Thread'+TreeView1.Selected.Text; name;
then i need to start and stop all the threads in the generated forms from a timer in the main form (Timer), this thred could be writing to the dinamicly generated TreeView; as

this is what i need, creating one thread from delphi i can do.

I will increase the point ... please be Patient and try to help me

Eng. Omar Fayyad
0
 
LVL 7

Expert Comment

by:sftweng
Comment Utility
What is it that you would like each thread to do? That code will reside in the TThread.Execute procedure or (if you use the code listed above by shaneholmes, which is good code except for a misspelling of "reintroduced"), in the TMyThread.DoSomething procedure.
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility

You will have to add a private variable  - fName to your thread class, so you will have some kind of ID.

constructor TMyThread.Create(CreateSuspended: Boolean; Node: TTreeNode);
begin
  inherited create(true);
  fNode:= Node;
  fName:= 'Thread ' + Node.Text;
end;


 You will most likely also have to keep a TThread list (You could use a TList, a TObjectList, etc) to keep track of your threads.

  I would recommend using a TObjectList, that way, they are destroyed (set TObjectLists   OwnsObjects = True) when your   main form is destroyed.

 This will also allow you to iterate through and find the Thread you are looking for ny the fName variable described


UNLESS of course you will be tracking it by ThreadId property.

If you want to email me your code (Im using Delphi 7) and you dont use anything special for components, I will take a look


Shane  (homesshane AT charter DOT net)
 
0
 

Author Comment

by:omarmf
Comment Utility
Ok the last answer seems to be the nearest solution

constructor TMyThread.Create(CreateSuspended: Boolean; Node: TTreeNode);
begin
  inherited create(true);
  fNode:= Node;
  fName:= 'Thread ' + Node.Text;
end;

i beleave that the second parometer should be the task name, it is giving error, unknown fName, fNode .... i tryied to declarify fNode as TTreeNode, it is ok put what about fName and how it will pass the thread name ???

one more thing is the execute prucedure for the tasks generated ????
Dont know what to do ....
Omar Fayyad
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Did you et my email? WIth the code

SHane
0
 
LVL 7

Expert Comment

by:sftweng
Comment Utility
If you don't know what to do in the thread, why are you creating one in the first place? Threads are only useful if the executed code would otherwise block further processing if done in a single thread.

If the only reason is to allow editing and manipulation of the created forms, then a thread is useless because you'd have to "Synchronize" back to the main therad anyway for GUI access.
0
 
LVL 7

Expert Comment

by:sftweng
Comment Utility
Reading back, I see references to a SQL server. Is the intention that each thread communicates as a sort of "middleware" to a client attached over some communication channel and then passes SQL queries back and forth?

If so then the thread Execute procedure should just be a repeating transaction handler, querying the end user for input, possibly parsing it and creating an SQL query, passing the query to the SQL server (perhaps under control of a mutex - a mutual exclusion sempahore), sending the results back to the user over the communications channel and possibly indicating status information on the created form(s) via a Synchronize procedure. The Execute procedure should also wath for termination requests.

If this is what you're trying to accomplish, there are proably better ways using some of the built-in Delphi database support.
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:omarmf
Comment Utility
Yes mr Shane

I got it. and it has what i need.

  I will try to finish what i need and check it again then i will close the
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Let me know if you need anymore help
0
 

Author Comment

by:omarmf
Comment Utility
Dear Mr.sftweng

  you got the point, each of these forms is connected to the DB put with diffirent parometers. i cant accept all of them in one form because they are for supportin diffirent emloeeys.  each connection in the form is quiring a special records, the records are in a remote area so it will take more then 3 sec to be completed this will blok the form.

i tryed to recive all the records then disriputing them to form. it is unpossible. thats whay i had to crete task for each.   the task are 6 maximum so i think it will work will   Mr. Shane did a grate thing for me the part of creating task with the same name as the node.

i will be trying now with prossing each creted connection with the different tasks from the task list.  i need some time to try this and i will use the experts for help.

thank you for your recomindations we can gain a lot from the experts

it is med night now, i wil continu tomorro.

thanks again

regard
Omar Fayyad
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
I am posting the unit I had Omar email me so i could look. I have made a few changes to his code for creating a Thread based on his needs.

Shane

unit nismsn;

interface

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

type

  TXThread = class(TThread)
  private
    { Private declarations }
   fNode: TTreeNode;
   fName: String;
  protected
    procedure Execute; override;
  public
   property Name: String read fName write fName;
   property Node: TTreeNode read fNode write fNode;
   constructor Create(CreateSuspended: Boolean; Node: TTreeNode);
 end;

  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Timer: TTimer;
    senderm: TEdit;
    ListBox1: TListBox;
    Label1: TLabel;
    BitBtn1: TBitBtn;
    Button1: TButton;
    R_ID: TEdit;
    S_ID: TEdit;
    ImageList1: TImageList;
    FontDialog1: TFontDialog;
    recieverm: TRichEdit;
    procedure sendermKeyPress(Sender: TObject; var Key: Char);
    procedure FormCreate(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure TreeView1DblClick(Sender: TObject);
    procedure CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
      MsgL: TStringList;
      ThreadList: TObjectList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TXThread.Execute;
begin
 // your code here
 // if using the VCL, then you need to wrap your code in a Syncronize();
end;

constructor TXThread.Create(CreateSuspended: Boolean; Node: TTreeNode);
begin
 inherited Create(CreateSuspended);
 fNode:= Node;
end;

procedure TForm1.CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
Begin
  TForm(Sender).Destroy;
end;

procedure TForm1.sendermKeyPress(Sender: TObject; var Key: Char);
begin
If Key = #13 Then
 begin
  if(senderm.Text<>'') Then
  MsgL.Add(senderm.Text);
  ListBox1.Items:= MsgL;
  senderm.Text:= '';
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  TreeNodeM1, TreeNodeM2: TTreeNode;
begin
  MsgL:= TStringList.Create;
  ThreadList:= TObjectList.Create;
  ThreadList.OwnsObjects:= True;
  TreeNodeM1 := TreeView1.Items.Add(nil, 'Online');
  TreeNodeM2 := TreeView1.Items.Add(nil, 'Offline');
  TreeView1.Items.AddChild(TreeNodeM2, 'Omar');
  TreeView1.Items.AddChild(TreeNodeM1, 'Abdu');
  TreeView1.Items.AddChild(TreeNodeM1, 'Modar');
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  if(senderm.Text<>'') Then
    Begin
      MsgL.Add(senderm.Text);
      ListBox1.Items:= MsgL;
      senderm.Text:= '';
    End;
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
  NewForm : TForm;
  RichEdit: TRichEdit;
  AThread  : TXThread;
begin
  NewForm := TForm.create(self);
  with NewForm do
  begin
    Left := 250;
    Top := 200;
    Width := 200;
    Height := 300;
    Caption := TreeView1.Selected.Text;
    Name   := 'Form'+TreeView1.Selected.Text;
    OnClose := CustomFormOnClose;
    Show;
  end;
  RichEdit:= TRichEdit.Create(Self);
  with RichEdit do
  begin
    Left := 5;
    Top := 5;
    Width := 180;
    Height := 250;
    Name   := 'RichEdit'+TreeView1.Selected.Text;
    parent := NewForm;
  end;
  AThread:= TXThread.Create(True, TreeView1.Selected);
  AThread.Name:= 'Thread'+ AThread.Node.Text;
  ThreadList.Add(AThread);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 ThreadList.Free;
end;

end.
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Oops, I posted th wrong unit, here is the correct one.


 TXThread = class(TThread)
  private
    { Private declarations }
   fNode: TTreeNode;
   fName: String;
  protected
    procedure Execute; override;
  public
   property Name: String read fName write fName;
   property Node: TTreeNode read fNode write fNode;
   constructor Create(Node: TTreeNode);reintroduce;
 end;

  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Timer: TTimer;
    senderm: TEdit;
    ListBox1: TListBox;
    Label1: TLabel;
    BitBtn1: TBitBtn;
    Button1: TButton;
    R_ID: TEdit;
    S_ID: TEdit;
    ImageList1: TImageList;
    FontDialog1: TFontDialog;
    recieverm: TRichEdit;
    procedure sendermKeyPress(Sender: TObject; var Key: Char);
    procedure FormCreate(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure TreeView1DblClick(Sender: TObject);
    procedure CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
      MsgL: TStringList;
      ThreadList: TObjectList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TXThread.Execute;
begin
 ShowMessage(Self.Name);
end;

constructor TXThread.Create(Node: TTreeNode);
begin
inherited Create(False);
 fNode:= Node;
end;

procedure TForm1.CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
Begin
  TForm(Sender).Destroy;
end;

procedure TForm1.sendermKeyPress(Sender: TObject; var Key: Char);
begin
If Key = #13 Then
 begin
  if(senderm.Text<>'') Then
  MsgL.Add(senderm.Text);
  ListBox1.Items:= MsgL;
  senderm.Text:= '';
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  TreeNodeM1, TreeNodeM2: TTreeNode;
begin
  MsgL:= TStringList.Create;
  ThreadList:= TObjectList.Create;
  ThreadList.OwnsObjects:= True;
  TreeNodeM1 := TreeView1.Items.Add(nil, 'Online');
  TreeNodeM2 := TreeView1.Items.Add(nil, 'Offline');
  TreeView1.Items.AddChild(TreeNodeM2, 'Omar');
  TreeView1.Items.AddChild(TreeNodeM1, 'Abdu');
  TreeView1.Items.AddChild(TreeNodeM1, 'Modar');
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  if(senderm.Text<>'') Then
    Begin
      MsgL.Add(senderm.Text);
      ListBox1.Items:= MsgL;
      senderm.Text:= '';
    End;
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
  NewForm : TForm;
  RichEdit: TRichEdit;
  AThread  : TXThread;
begin
  NewForm := TForm.create(self);
  with NewForm do
  begin
    Left := 250;
    Top := 200;
    Width := 200;
    Height := 300;
    Caption := TreeView1.Selected.Text;
    Name   := 'Form'+TreeView1.Selected.Text;
    OnClose := CustomFormOnClose;
    Show;
  end;
  RichEdit:= TRichEdit.Create(Self);
  with RichEdit do
  begin
    Left := 5;
    Top := 5;
    Width := 180;
    Height := 250;
    Name   := 'RichEdit'+TreeView1.Selected.Text;
    parent := NewForm;
  end;
  AThread:= TXThread.Create(TreeView1.Selected);
  AThread.Name:= 'Thread'+ AThread.Node.Text;
  ThreadList.Add(AThread);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 ThreadList.Free;
end;

end.
0
 

Author Comment

by:omarmf
Comment Utility
Again I fail

The thing i need now is to make the label in each generated form run a counter from 1 to 10000 in the new created thread On Clicking the button in the same generated form.

I trayed to get the generated components names in the new generated form put i could only have the name of the event component ( Button in My case )
and the parent (The form name)

Please Try to Help me.


unit nismsn;

interface

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

type

TXThread = class(TThread)
  private
    { Private declarations }
   fNode: TTreeNode;
   fName: String;
  protected
    procedure Execute; override;
  public
   property Name: String read fName write fName;
   property Node: TTreeNode read fNode write fNode;
   constructor Create(Node: TTreeNode);reintroduce;
 end;

  TForm1 = class(TForm)
    TreeView1: TTreeView;
    recieverm: TRichEdit;
    procedure FormCreate(Sender: TObject);
    procedure TreeView1DblClick(Sender: TObject);
    procedure CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BtnClickEv(Sender: TObject);
  private
    { Private declarations }
  public
      MsgL: TStringList;
      ThreadList: TObjectList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.BtnClickEv(Sender: TObject);
begin
  ShowMessage(IntToStr(TForm(TBitBtn(Sender).Parent.Name).ComponentCount));
  ShowMessage(TBitBtn(Sender).Name);
  ShowMessage(TBitBtn(Sender).Parent.Name);
  //ShowMessage(TForm(TBitBtn(Sender).Parent.Name).Components[4].Name);
end;

procedure TXThread.Execute;
begin
  form1.recieverm.Lines.Add('Thread: '+self.Name+' Is Running');
end;

constructor TXThread.Create(Node: TTreeNode);
begin
inherited Create(False);
 fNode:= Node;
end;

procedure TForm1.CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
Begin
  TForm(Sender).Destroy;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  TreeNodeM1, TreeNodeM2: TTreeNode;
begin
  MsgL:= TStringList.Create;
  ThreadList:= TObjectList.Create;
  ThreadList.OwnsObjects:= True;
  TreeNodeM1 := TreeView1.Items.Add(nil, 'Online');
  TreeNodeM2 := TreeView1.Items.Add(nil, 'Offline');
  TreeView1.Items.AddChild(TreeNodeM2, 'Omar');
  TreeView1.Items.AddChild(TreeNodeM1, 'Abdu');
  TreeView1.Items.AddChild(TreeNodeM1, 'Modar');
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
  NewForm : TForm;
  RichEdit: TRichEdit;
    Edit  : TEdit;
    BitBtn: TBitBtn;
  NewLabel: TLabel;
  AThread : TXThread;
begin
  NewForm := TForm.create(self);
  with NewForm do
  begin
    Left := 100;
    Top := 200;
    Width := 250;
    Height := 350;
    Caption := TreeView1.Selected.Text;
    Name   := 'Form'+TreeView1.Selected.Text;
    OnClose := CustomFormOnClose;
    Show;
  end;
  RichEdit:= TRichEdit.Create(Self);
  with RichEdit do
  begin
    Left := 5;
    Top := 5;
    Width := 180;
    Height := NewForm.Height - 60;
    text:= '';
    Name   := 'RichEdit'+TreeView1.Selected.Text;
    parent := NewForm;
  end;
  Edit:= TEdit.Create(Self);
  with Edit do
  begin
    Left := RichEdit.Left;
    Width := RichEdit.Width;
    Height := 300;
    Top := RichEdit.Height+10;
    Name   := 'Edit'+TreeView1.Selected.Text;
    text := '';
    parent := NewForm;
  end;
  BitBtn:= TBitBtn.Create(Self);
  with BitBtn do
  begin
    Left := edit.width + 10;
    Width := 50;
    Height := Edit.Height;
    Top := Edit.Top;
    Name   := 'BitBtn'+TreeView1.Selected.Text;
    Caption:= 'Send';
    OnClick:= BtnClickEv;
    parent := NewForm;
  end;
  NewLabel:= TLabel.Create(Self);
  with NewLabel do
  begin
    Left := edit.width + 30;
    Width := 50;
    Height := Edit.Height;
    Top := 30;
    Name   := 'Caption'+TreeView1.Selected.Text;
    Caption:= '0';
    parent := NewForm;
  end;
  AThread:= TXThread.Create(TreeView1.Selected);
  AThread.Name:= 'Thread'+ AThread.Node.Text;
  ThreadList.Add(AThread);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 ThreadList.Free;
end;

end.


Thank You

Omar Fayyad

0
 
LVL 7

Expert Comment

by:sftweng
Comment Utility
In TXThread.Execute you are using form1 directly. I have tried to emphasize it but I'll say it again - you MUST use Synchronize.
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Omarmf,

I have made the changes below. I am emailing you the code as well.

Shane


unit nismsn;

interface

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

type

  TXThread = class(TThread)
  private
    { Private declarations }
   fNode: TTreeNode;
   fName: String;
   fForm: TForm;
   fLabel: TLabel;
   fButton: TButton;
  protected
    procedure DoCount;
    procedure Execute; override;
  public
   property Name: String read fName write fName;
   property ThreadNode: TTreeNode read fNode write fNode;
   property ThreadForm: TForm read fFOrm write fForm;
   property FormLabel: TLabel read fLabel write fLabel;
   property FormButton: TButton read fButton write fButton;
   constructor Create(ANode: TTreeNode; AForm: TForm; ALabel:
                      TLabel; AButton: TButton);reintroduce;
 end;

  TForm1 = class(TForm)
    TreeView1: TTreeView;
    Timer: TTimer;
    senderm: TEdit;
    ListBox1: TListBox;
    Label1: TLabel;
    BitBtn1: TBitBtn;
    Button1: TButton;
    R_ID: TEdit;
    S_ID: TEdit;
    ImageList1: TImageList;
    FontDialog1: TFontDialog;
    recieverm: TRichEdit;
    procedure sendermKeyPress(Sender: TObject; var Key: Char);
    procedure FormCreate(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure TreeView1DblClick(Sender: TObject);
    procedure CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BtnClickEv(Sender: TObject);
  private
    { Private declarations }
  public
      MsgL: TStringList;
      ThreadList: TObjectList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TXThread.DoCount;
var
 I: Integer;
begin
 for I:= 0 to 10000 do
 FormLabel.Caption:= inttostr(I);
end;

procedure TXThread.Execute;
begin
 Synchronize(DoCount);
end;

constructor TXThread.Create(ANode: TTreeNode; AForm: TForm;
                            ALabel: TLabel; AButton: TButton);
begin
inherited Create(False);
 fNode:= ANode;
 fForm:= AForm;
 fLabel:= ALabel;
 fButton:= AButton;
end;

procedure TForm1.CustomFormOnClose(Sender: TObject; var Action: TCloseAction);
Begin
  TForm(Sender).Destroy;
end;

procedure TForm1.sendermKeyPress(Sender: TObject; var Key: Char);
begin
If Key = #13 Then
 begin
  if(senderm.Text<>'') Then
  MsgL.Add(senderm.Text);
  ListBox1.Items:= MsgL;
  senderm.Text:= '';
 end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  TreeNodeM1, TreeNodeM2: TTreeNode;
begin
  MsgL:= TStringList.Create;
  ThreadList:= TObjectList.Create;
  ThreadList.OwnsObjects:= True;
  TreeNodeM1 := TreeView1.Items.Add(nil, 'Online');
  TreeNodeM2 := TreeView1.Items.Add(nil, 'Offline');
  TreeView1.Items.AddChild(TreeNodeM2, 'Omar');
  TreeView1.Items.AddChild(TreeNodeM1, 'Abdu');
  TreeView1.Items.AddChild(TreeNodeM1, 'Modar');
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  if(senderm.Text<>'') Then
    Begin
      MsgL.Add(senderm.Text);
      ListBox1.Items:= MsgL;
      senderm.Text:= '';
    End;
end;

procedure TForm1.BtnClickEv(Sender: TObject);
begin
  ShowMessage(IntToStr(TForm(TBitBtn(Sender).Parent.Name).ComponentCount));
  ShowMessage(TBitBtn(Sender).Name);
  ShowMessage(TBitBtn(Sender).Parent.Name);
  //ShowMessage(TForm(TBitBtn(Sender).Parent.Name).Components[4].Name);
end;

procedure TForm1.TreeView1DblClick(Sender: TObject);
var
  NewForm : TForm;
  RichEdit: TRichEdit;
    Edit  : TEdit;
  NewButton: TBitBtn;
  NewLabel: TLabel;
  AThread : TXThread;
begin
  NewForm := TForm.create(self);
  with NewForm do
  begin
    Left := 100;
    Top := 200;
    Width := 250;
    Height := 350;
    Caption := TreeView1.Selected.Text;
    Name   := 'Form'+TreeView1.Selected.Text;
    OnClose := CustomFormOnClose;
    Show;
  end;
  RichEdit:= TRichEdit.Create(Self);
  with RichEdit do
  begin
    Left := 5;
    Top := 5;
    Width := 180;
    Height := NewForm.Height - 60;
    text:= '';
    Name   := 'RichEdit'+TreeView1.Selected.Text;
    parent := NewForm;
  end;
  Edit:= TEdit.Create(Self);
  with Edit do
  begin
    Left := RichEdit.Left;
    Width := RichEdit.Width;
    Height := 300;
    Top := RichEdit.Height+10;
    Name   := 'Edit'+TreeView1.Selected.Text;
    text := '';
    parent := NewForm;
  end;
  NewButton:= TBitBtn.Create(Self);
  with NewButton do
  begin
    Left := edit.width + 10;
    Width := 50;
    Height := Edit.Height;
    Top := Edit.Top;
    Name   := 'BitBtn'+TreeView1.Selected.Text;
    Caption:= 'Send';
    OnClick:= BtnClickEv;
    parent := NewForm;
  end;
  NewLabel:= TLabel.Create(Self);
  with NewLabel do
  begin
    Left := edit.width + 30;
    Width := 50;
    Height := Edit.Height;
    Top := 30;
    Name   := 'Caption'+TreeView1.Selected.Text;
    Caption:= '0';
    parent := NewForm;
  end;
  AThread:= TXThread.Create(TreeView1.Selected, NewForm, NewLabel, NewButton);
  AThread.Name:= 'Thread'+ AThread.ThreadNode.Text;
  ThreadList.Add(AThread);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 ThreadList.Free;
end;

end.
0
 
LVL 11

Accepted Solution

by:
shaneholmes earned 250 total points
Comment Utility
OMar,

I dont know what exactly you are doing here

 NewLabel:= TLabel.Create(Self);
  with NewLabel do
  begin
    Left := edit.width + 30;
    Width := 50;
    Height := Edit.Height;
    Top := 30;
    Name   := 'Caption'+TreeView1.Selected.Text;
    Caption:= '0';
    parent := NewForm;
  end;

 I think you meant this:

    Caption:= '0';
    Name   := Caption + TreeView1.Selected.Text;

but anyway, its still doesn't seem right to me, are you sure this is what you want.


Each forms label will start with a zero, followed by the Node.Text



Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
also Omar,

if you add a  Application.ProcessMessages; to the DoCount method, you will actually see the update to the label (instead of waiting until the loop is finished)

Shane

procedure TXThread.DoCount;
var
 I: Integer;
begin
 for I:= 0 to 10000 do
 begin
  FormLabel.Caption:= inttostr(I);
  Application.ProcessMessages;
 end;
end;
0
 

Author Comment

by:omarmf
Comment Utility
Yes Mr Shane

  You are more carfull then the one who is doing actually the program

NewLabel:= TLabel.Create(Self);
  with NewLabel do
  begin
    Left := edit.width + 30;
    Width := 50;
    Height := Edit.Height;
    Top := 30;
    Name   := 'Caption'+TreeView1.Selected.Text;
    Caption:= '0';
    parent := NewForm;
  end;

put this will generate a new label called CaptionOmar as instance

I will make it

Name   := 'Label'+TreeView1.Selected.Text;

Put it is no problem

Thank you a lot
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now