ChickenCoder
2008-07-11 21:12:18 UTC
I have stripped the code to the base essentials to still create the problem.
My intentions are to create instaces of a Scale class that has a listening
client. IT works if I only have one scale set in my database but will not
even get to FormShow if I set it up for two. On FormCreate, I make a
ScaleList (probably not neccesary since I never need to access the scale
object, once created) .
The CreateScale loops throught he databse to make a Scale instance which in
turn, creates a TReadingInfinitiThread instance.
I guess I have the thread instanciation screwed up. Am I even close to
doing this right?
Thanks,
Larry
=======================================================================================
unit uMain;
interface
uses ...
type
TScale = class
private
fScaleID: Integer;
fPortNbr: Integer;
fIPaddr: String;
fActive: Boolean;
fScaleName: String;
public
ReadingInfinitiThread : TReadingInfinitiThread;
Property ScaleName : String read fScaleName;
Property ScaleID : Integer read fScaleID;
Property PortNbr : Integer read fPortNbr;
Property IPaddr : String read fIPaddr;
Property Active : Boolean read fActive;
//constructor
Constructor Create( Const ScaleName : String;
Const ScaleID : Integer;
Const PortNbr : Integer;
Const IPaddr : String;
Const Active : Boolean);
end;
type
TfrmMain = class(TForm)
pnlMid: TPanel;
StatusBar1: TStatusBar;
ToolBar1: TToolBar;
Splitter1: TSplitter;
pnlBottom: TPanel;
Memo1: TMemo;
procedure Memo1DblClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
private
FConnInCritSec: TCriticalSection;
fActiveSetID: Integer;
{ Private declarations }
public
{ Public declarations }
fBroadCast: String;
ScaleList : TObjectList;
Procedure DisplayBroadcast;
procedure MakeCriticalSections;
procedure CreateScale;
Property ActiveSetID : Integer read fActiveSetID write fActiveSetID;
Property ConnInCritSec : TCriticalSection read FConnInCritSec;
end;
var
frmMain: TfrmMain;
implementation
uses uDMmain, raw_ping, ABOUT;
{$R *.dfm}
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ScaleList.Free;
Action := caFree;
end;
procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
FConnInCritSec.Free;
application.Terminate;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
MakeCriticalSections;
ScaleList := TObjectList.Create(True);
CreateScale;
end;
procedure TfrmMain.MakeCriticalSections;
begin
FConnInCritSec := TCriticalSection.Create;
end;
procedure TfrmMain.Memo1DblClick(Sender: TObject);
begin
Memo1.Clear;
end;
procedure TfrmMain.CreateScale;
var
tScaleName : string;
tScaleID : integer;
tPortNbr : integer;
tIPaddr : string;
tActive : Boolean;
begin
Try
dmMain.qrySettings.open;
With dmMain.qrySettings do
Begin
While Not(Eof) do
Begin
tScaleName := FieldByName('ScaleName').AsString;
tScaleID := FieldByName('ScaleID').AsInteger;
tPortNbr := FieldByName('Port').AsInteger;
tIPaddr := FieldByName('IPAddress').AsString;
tActive := FieldByName('Active').AsBoolean;
ScaleList.Add(TScale.Create(tScaleName, tScaleID, tPortNbr, tIPaddr,
tActive));
Next;
End;
End;
Finally
dmMain.qrySettings.close;
End;
end;
procedure TfrmMain.DisplayBroadcast;
begin
Memo1.Lines.Add(fBroadcast);
end;
{ TScale }
constructor TScale.Create(const ScaleName: String; const ScaleID,
PortNbr: Integer; const IPaddr: String; const Active: Boolean);
Begin
fScaleName := ScaleName;
fScaleID := ScaleID;
fPortNbr := PortNbr;
fIPaddr := IPaddr;
fActive := Active;
ReadingInfinitiThread := TReadingInfinitiThread.Create(fPortNbr, fIPaddr,
fScaleID);
end;
end.
========================================================================================
unit ReadInfiniti;
interface
uses
Classes, IdTCPClient, StrUtils, forms, SysUtils, AdoDb, Windows,
IdTCPConnection;
type
TReadingInfinitiThread = class(TThread)
private
{ Private declarations }
FConn: TIdTCPClient;
Buffer : string;
FBroadcast : string;
procedure DisplayData;
protected
procedure Execute; override;
public
procedure AfterConstruction; override;
constructor Create(Port:integer; IPAddr:String; ScaleID : Integer);
reintroduce;
end;
implementation
uses uMain, IdIOHandler, uDM, dialogs;
{ TReadingInfinitiThread }
procedure TReadingInfinitiThread.AfterConstruction;
begin
inherited;
Resume;
FConn.Connect;
If FConn.Connected then
FConn.IOHandler.Write(Byte(22)); //SYN
end;
procedure TReadingInfinitiThread.DisplayData;
begin
frmMain.ConnInCritSec.Enter;
try
frmMain.fBroadCast := FBroadcast;
frmMain.DisplayBroadcast;
finally
frmMain.ConnInCritSec.Leave;
end;
end;
constructor TReadingInfinitiThread.Create(Port:integer; IPAddr:String;
ScaleID : Integer);
begin
inherited Create(True);
beep(1000, 100);
Priority := tpLower;
try
FConn := TIdTCPClient.Create(application);
with FConn do
begin
ConnectTimeout := 0;
Port := 9100;//Port;
Host := IPAddr;
ReadTimeout := -1;
end;
except
on e:exception do
Begin
FBroadcast := e.Message+' for scale '+IntToStr(ScaleID);
DisplayData;
End;
end;
end;
procedure TReadingInfinitiThread.Execute;
begin
while not Terminated do
begin
case FConn.IOHandler.ReadByte of
$02: // STX
begin
Buffer := FConn.IOHandler.ReadLn(Chr(3));
FBroadcast := 'Buffer '+ Buffer;
DisplayData;
end; // to be picked up by a second thread
else
Begin
FBroadcast := 'unknown character';
DisplayData;
End;
end; //case
end;
end;
end.
My intentions are to create instaces of a Scale class that has a listening
client. IT works if I only have one scale set in my database but will not
even get to FormShow if I set it up for two. On FormCreate, I make a
ScaleList (probably not neccesary since I never need to access the scale
object, once created) .
The CreateScale loops throught he databse to make a Scale instance which in
turn, creates a TReadingInfinitiThread instance.
I guess I have the thread instanciation screwed up. Am I even close to
doing this right?
Thanks,
Larry
=======================================================================================
unit uMain;
interface
uses ...
type
TScale = class
private
fScaleID: Integer;
fPortNbr: Integer;
fIPaddr: String;
fActive: Boolean;
fScaleName: String;
public
ReadingInfinitiThread : TReadingInfinitiThread;
Property ScaleName : String read fScaleName;
Property ScaleID : Integer read fScaleID;
Property PortNbr : Integer read fPortNbr;
Property IPaddr : String read fIPaddr;
Property Active : Boolean read fActive;
//constructor
Constructor Create( Const ScaleName : String;
Const ScaleID : Integer;
Const PortNbr : Integer;
Const IPaddr : String;
Const Active : Boolean);
end;
type
TfrmMain = class(TForm)
pnlMid: TPanel;
StatusBar1: TStatusBar;
ToolBar1: TToolBar;
Splitter1: TSplitter;
pnlBottom: TPanel;
Memo1: TMemo;
procedure Memo1DblClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
private
FConnInCritSec: TCriticalSection;
fActiveSetID: Integer;
{ Private declarations }
public
{ Public declarations }
fBroadCast: String;
ScaleList : TObjectList;
Procedure DisplayBroadcast;
procedure MakeCriticalSections;
procedure CreateScale;
Property ActiveSetID : Integer read fActiveSetID write fActiveSetID;
Property ConnInCritSec : TCriticalSection read FConnInCritSec;
end;
var
frmMain: TfrmMain;
implementation
uses uDMmain, raw_ping, ABOUT;
{$R *.dfm}
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ScaleList.Free;
Action := caFree;
end;
procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
FConnInCritSec.Free;
application.Terminate;
end;
procedure TfrmMain.FormCreate(Sender: TObject);
begin
MakeCriticalSections;
ScaleList := TObjectList.Create(True);
CreateScale;
end;
procedure TfrmMain.MakeCriticalSections;
begin
FConnInCritSec := TCriticalSection.Create;
end;
procedure TfrmMain.Memo1DblClick(Sender: TObject);
begin
Memo1.Clear;
end;
procedure TfrmMain.CreateScale;
var
tScaleName : string;
tScaleID : integer;
tPortNbr : integer;
tIPaddr : string;
tActive : Boolean;
begin
Try
dmMain.qrySettings.open;
With dmMain.qrySettings do
Begin
While Not(Eof) do
Begin
tScaleName := FieldByName('ScaleName').AsString;
tScaleID := FieldByName('ScaleID').AsInteger;
tPortNbr := FieldByName('Port').AsInteger;
tIPaddr := FieldByName('IPAddress').AsString;
tActive := FieldByName('Active').AsBoolean;
ScaleList.Add(TScale.Create(tScaleName, tScaleID, tPortNbr, tIPaddr,
tActive));
Next;
End;
End;
Finally
dmMain.qrySettings.close;
End;
end;
procedure TfrmMain.DisplayBroadcast;
begin
Memo1.Lines.Add(fBroadcast);
end;
{ TScale }
constructor TScale.Create(const ScaleName: String; const ScaleID,
PortNbr: Integer; const IPaddr: String; const Active: Boolean);
Begin
fScaleName := ScaleName;
fScaleID := ScaleID;
fPortNbr := PortNbr;
fIPaddr := IPaddr;
fActive := Active;
ReadingInfinitiThread := TReadingInfinitiThread.Create(fPortNbr, fIPaddr,
fScaleID);
end;
end.
========================================================================================
unit ReadInfiniti;
interface
uses
Classes, IdTCPClient, StrUtils, forms, SysUtils, AdoDb, Windows,
IdTCPConnection;
type
TReadingInfinitiThread = class(TThread)
private
{ Private declarations }
FConn: TIdTCPClient;
Buffer : string;
FBroadcast : string;
procedure DisplayData;
protected
procedure Execute; override;
public
procedure AfterConstruction; override;
constructor Create(Port:integer; IPAddr:String; ScaleID : Integer);
reintroduce;
end;
implementation
uses uMain, IdIOHandler, uDM, dialogs;
{ TReadingInfinitiThread }
procedure TReadingInfinitiThread.AfterConstruction;
begin
inherited;
Resume;
FConn.Connect;
If FConn.Connected then
FConn.IOHandler.Write(Byte(22)); //SYN
end;
procedure TReadingInfinitiThread.DisplayData;
begin
frmMain.ConnInCritSec.Enter;
try
frmMain.fBroadCast := FBroadcast;
frmMain.DisplayBroadcast;
finally
frmMain.ConnInCritSec.Leave;
end;
end;
constructor TReadingInfinitiThread.Create(Port:integer; IPAddr:String;
ScaleID : Integer);
begin
inherited Create(True);
beep(1000, 100);
Priority := tpLower;
try
FConn := TIdTCPClient.Create(application);
with FConn do
begin
ConnectTimeout := 0;
Port := 9100;//Port;
Host := IPAddr;
ReadTimeout := -1;
end;
except
on e:exception do
Begin
FBroadcast := e.Message+' for scale '+IntToStr(ScaleID);
DisplayData;
End;
end;
end;
procedure TReadingInfinitiThread.Execute;
begin
while not Terminated do
begin
case FConn.IOHandler.ReadByte of
$02: // STX
begin
Buffer := FConn.IOHandler.ReadLn(Chr(3));
FBroadcast := 'Buffer '+ Buffer;
DisplayData;
end; // to be picked up by a second thread
else
Begin
FBroadcast := 'unknown character';
DisplayData;
End;
end; //case
end;
end;
end.