Delphi_developer
asked on
Issue with custom class
Hi
I have a custom class defined:
tTelemetryPanel = class(Panel)
public
Parent:TWinControl
Constructor Create(AOwner: TComponent); Override;
private
property fParent: TWinControl read Parent write Parent;
Published
Procedure CreateTelemetryPanel;
end;
...
and
Procedure tTelemetryPanel.CreateTele metryPanel ;
Begin
TTelemetryPanel(Self).OnRe size := myPanelResize;
TTelemetryPanel(Self).Bord erStyle := bsNone;
vImage := Timage.Create(Nil);
vImage.Parent := Self;
vImage.Align := alLeft;
end;
this is defined in new unit.
In Form1 on button click I have this:
procedure TForm1.Button1Click(Sender : TObject);
var vA,vB:TTelemetryPanel;
begin
vA:=TTelemetryPanel.Create (Self);
vA.Parent:=Form1.SCPanel14 7;
vA.CreateTelemetryPanel;
vB:=TTelemetryPanel.Create (nil);
vA.Parent:=Form1.SCPanel14 4;
vB.CreateTelemetryPanel;
end;
So, I would like to have two TelemetryPanels on SCPanel147 and 144.
I have a couple of questions:
1. I had to set public 'Parent' otherwise this code failed:
vA.Parent:=Form1.SCPanel14 7;
Why does it work like that? Shouldn't Parent property work as a basic property?
2. Now it fails on
vImage.Parent := Self;
when I try to create vImage on this TelemetryPanel. Why it doesn't work? I also tried
vImage.Parent := TTelemetryPanel(Self);
also didn't work.
3) I would like to have new telemetry panels's width and height as it's parent! How can I do this, can I do this in Create constructor or do I need to have separate code to assign these values?
Thank you
I have a custom class defined:
tTelemetryPanel = class(Panel)
public
Parent:TWinControl
Constructor Create(AOwner: TComponent); Override;
private
property fParent: TWinControl read Parent write Parent;
Published
Procedure CreateTelemetryPanel;
end;
...
and
Procedure tTelemetryPanel.CreateTele
Begin
TTelemetryPanel(Self).OnRe
TTelemetryPanel(Self).Bord
vImage := Timage.Create(Nil);
vImage.Parent := Self;
vImage.Align := alLeft;
end;
this is defined in new unit.
In Form1 on button click I have this:
procedure TForm1.Button1Click(Sender
var vA,vB:TTelemetryPanel;
begin
vA:=TTelemetryPanel.Create
vA.Parent:=Form1.SCPanel14
vA.CreateTelemetryPanel;
vB:=TTelemetryPanel.Create
vA.Parent:=Form1.SCPanel14
vB.CreateTelemetryPanel;
end;
So, I would like to have two TelemetryPanels on SCPanel147 and 144.
I have a couple of questions:
1. I had to set public 'Parent' otherwise this code failed:
vA.Parent:=Form1.SCPanel14
Why does it work like that? Shouldn't Parent property work as a basic property?
2. Now it fails on
vImage.Parent := Self;
when I try to create vImage on this TelemetryPanel. Why it doesn't work? I also tried
vImage.Parent := TTelemetryPanel(Self);
also didn't work.
3) I would like to have new telemetry panels's width and height as it's parent! How can I do this, can I do this in Create constructor or do I need to have separate code to assign these values?
Thank you
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
1. I had to set public 'Parent' otherwise this code failed:
>>You descended from Panel, not TPanel
didn't this give a compiler error ?
2. Now it fails on
>>Probably because it doesn't know which parent as it is declared in TPanel allready
3) I would like to have new telemetry panels's width and height as it's parent! How can I do this, can I do this in Create constructor or do I need to have separate code to assign these values?
>>set Align to alClient
it would be better to describe what you want with an image ...
>>You descended from Panel, not TPanel
didn't this give a compiler error ?
2. Now it fails on
>>Probably because it doesn't know which parent as it is declared in TPanel allready
3) I would like to have new telemetry panels's width and height as it's parent! How can I do this, can I do this in Create constructor or do I need to have separate code to assign these values?
>>set Align to alClient
it would be better to describe what you want with an image ...
if this is for your telemetry component
i'll give you a rough estimate so you know what the workload will be (this is not to put you off)
for me (it would take me roughly 3 months to get this working)
this is for just the basic things (drawing the graphs and interaction)
the real testing in a production environment would probably add a month for testing and tweaking
this is normal workdays
i would need to up my skills for painting of graphs
and probably some math would be involved too
this is so you know what you are getting into
you'll need to read some books to get this component working
Sam's teach yourself Delphi is the start
Mastering Delphi (very good for component creation)
Tomes of Delphi good too
if your a beginner at delphi, it will probably take 6 to 12 months
i'll give you a rough estimate so you know what the workload will be (this is not to put you off)
for me (it would take me roughly 3 months to get this working)
this is for just the basic things (drawing the graphs and interaction)
the real testing in a production environment would probably add a month for testing and tweaking
this is normal workdays
i would need to up my skills for painting of graphs
and probably some math would be involved too
this is so you know what you are getting into
you'll need to read some books to get this component working
Sam's teach yourself Delphi is the start
Mastering Delphi (very good for component creation)
Tomes of Delphi good too
if your a beginner at delphi, it will probably take 6 to 12 months
ASKER
Geert, thank you, but here is the situation:
I already have the telemetry panel done. It is a very simple panel, which consist of scrollbox and 2 images - create a graph. The 'interactive mode' - to mark points on the graph (image) on MouseOver and some other very simple, but useful actions. So, it works very well, for a prototype... I still need to polish small issues, like antialiasing lines and some discrepancies in scaling.
Now it works as a simple program where all objects are created in code and it all works well... but I need 2 or more of them, so I just wanted to have one class, called twice and create all objects on two separate normal panels. (I was sure component is called when you install new VCL object - component; I didn't know a new class type is already regarded as a component... ).
I got this very basic, but almost suitable/usable, in a few days. I'm a total beginner in components, classes, but not really in Delphi.
The other way to make this work, is to have one unit for each telemetry panel, this would work, but clearly is not a good solution.
I will try you suggestions now. I'll let you know how it goes.
I already have the telemetry panel done. It is a very simple panel, which consist of scrollbox and 2 images - create a graph. The 'interactive mode' - to mark points on the graph (image) on MouseOver and some other very simple, but useful actions. So, it works very well, for a prototype... I still need to polish small issues, like antialiasing lines and some discrepancies in scaling.
Now it works as a simple program where all objects are created in code and it all works well... but I need 2 or more of them, so I just wanted to have one class, called twice and create all objects on two separate normal panels. (I was sure component is called when you install new VCL object - component; I didn't know a new class type is already regarded as a component... ).
I got this very basic, but almost suitable/usable, in a few days. I'm a total beginner in components, classes, but not really in Delphi.
The other way to make this work, is to have one unit for each telemetry panel, this would work, but clearly is not a good solution.
I will try you suggestions now. I'll let you know how it goes.
a component is something that functions on it's own (or allmost)
maybe you need to go in the direction of Frames ?
you can create frames like forms, then right click on it to add to Component palette
and then drop them on a form (multiple times too) from the component palette
maybe you need to go in the direction of Frames ?
you can create frames like forms, then right click on it to add to Component palette
and then drop them on a form (multiple times too) from the component palette
ASKER
I would like to make this work, if possible...
It seems I'm getting somewhere. Now I have a procedure 'DrawGraphTemplate', which draws graph's grid, but it fails on this code:
from Form1.Button1clisk I call 'DrawTelemetry' which calls 'DrawGVraphTemplate', which has:
ImageGraph.Picture.Bitmap. Height := ImageGraph.Height;
ImageGraph.Picture.Bitmap. Width := ImageGraph.Width; // FAILS HERE: The parameter is incorrect
ImageGraph.Canvas.Brush.Co lor := clWhite;
Any suggestions?
I have:
private
fImageLeft: TImage;
fImageGraph: TImage;
fSB: TScrollBox;
procedure SetImageLeft(const Value: TImage);
procedure SetImageGraph(const Value: TImage);
procedure SetSB(const Value: TScrollBox);
Published
property ImageLeft: TImage read fImageLeft write SetImageLeft;
property ImageGraph: TImage read fImageGraph write SetImageGraph;
property SB: TScrollBox read fSB write SetSB;
And also a follow up question... what is the difference if I use 'fImageLeft' or 'ImageLeft', in the code of tTelemetryPanel own's procedures?
Thanx
It seems I'm getting somewhere. Now I have a procedure 'DrawGraphTemplate', which draws graph's grid, but it fails on this code:
from Form1.Button1clisk I call 'DrawTelemetry' which calls 'DrawGVraphTemplate', which has:
ImageGraph.Picture.Bitmap.
ImageGraph.Picture.Bitmap.
ImageGraph.Canvas.Brush.Co
Any suggestions?
I have:
private
fImageLeft: TImage;
fImageGraph: TImage;
fSB: TScrollBox;
procedure SetImageLeft(const Value: TImage);
procedure SetImageGraph(const Value: TImage);
procedure SetSB(const Value: TScrollBox);
Published
property ImageLeft: TImage read fImageLeft write SetImageLeft;
property ImageGraph: TImage read fImageGraph write SetImageGraph;
property SB: TScrollBox read fSB write SetSB;
And also a follow up question... what is the difference if I use 'fImageLeft' or 'ImageLeft', in the code of tTelemetryPanel own's procedures?
Thanx
good for you to have this working allready
ImageLeft is a property
fImageLeft is a private variable (in this case)
a property is like using a in between person to do things (like a waiter)
you tell the waiter (property) to set a certain value
you ask the waiter (property) to get something (a value)
where this waiter gets or sets the value is component specific
the component itself doesn't need to use the waiter, it can go directly in private methods (procedures and functions)
as from protected methods it is supposed to use the property
Have you checked if Picture and Picture.Bitmap <> nil ?
if not Assigned(ImageGraph.Pictur e.Graphic) or ImageGrap.Picture.Graphic. Empty then
ImageGraph.Picture.Graphic := TBitmap.Create;
ImageGraph.Picture.Bitmap. Height := ImageGraph.Height;
ImageGraph.Picture.Bitmap. Width := ImageGraph.Width; // FAILS HERE: The parameter is incorrect
ImageGraph.Canvas.Brush.Co lor := clWhite;
Same for ImageLeft
if these lines are in a private method then use fImageGraph
how did you define "DrawTelemetry"
type
TTelemetryPanel = class(TPanel)
private
protected
public
procedure DrawTelemetry; virtual;
end;
can you call DrawTelemetry directly ?
or is DrawTelemetry called from the method Paint ?
ImageLeft is a property
fImageLeft is a private variable (in this case)
a property is like using a in between person to do things (like a waiter)
you tell the waiter (property) to set a certain value
you ask the waiter (property) to get something (a value)
where this waiter gets or sets the value is component specific
the component itself doesn't need to use the waiter, it can go directly in private methods (procedures and functions)
as from protected methods it is supposed to use the property
Have you checked if Picture and Picture.Bitmap <> nil ?
if not Assigned(ImageGraph.Pictur
ImageGraph.Picture.Graphic
ImageGraph.Picture.Bitmap.
ImageGraph.Picture.Bitmap.
ImageGraph.Canvas.Brush.Co
Same for ImageLeft
if these lines are in a private method then use fImageGraph
how did you define "DrawTelemetry"
type
TTelemetryPanel = class(TPanel)
private
protected
public
procedure DrawTelemetry; virtual;
end;
can you call DrawTelemetry directly ?
or is DrawTelemetry called from the method Paint ?
Here you have the help entry for it:
Call SetSubComponent to indicate that this component is or is not a subcomponent. A subcomponent is a component whose Owner is a component other than the form or data module in which it resides. Unless such a component calls SetSubComponent with IsSubComponent set to true, its published properties will not be saved to the form file.
IsSubComponent indicates whether the component is a subcomponent (true) or not (false).
SetSubComponent is called at design time either
From the constructor of a component that always acts as a subcomponent. In this case, the component calls its own SetSubComponent method from the constructor with IsSubComponent set to true.
Immediately after constructing an instance of the subcomponent. In this case, the Owner calls the SetSubComponent method of a component it has just instantiated, with IsSubComponent set to true.