Re: Shapes at Runtime?
- From: "Maarten Wiltink" <maarten@xxxxxxxxxxxxxxxxxx>
- Date: Mon, 1 Aug 2005 22:21:44 +0200
<cybatech@xxxxxxxxxxxxx> wrote in message
news:4shse19vmd2vcsrg01mjod2f5as1qc5enk@xxxxxxxxxx
> I'm sorry I just don't get it (Must be dumb).
No, I can be a very bad teacher. It's this assumption that everybody
knows everything already that I just can't shake. That, and the fact
that I absolutely don't want to make it too easy. So I usually fall
short of the information you'd need to understand things.
My assumptions: you have a form with a number of TShapes and a number
of TLabels on it. You want to be able to transfer the colour of any
label to any shape by clicking a shape (selecting it) and clicking
a label. Clicking the label should copy the clicked label's colour to
the last clicked shape's colour.
If that's not exactly what you want, bear with me. Once you understand
how that works, many other things should have become much easier.
There is a problem right here, which is that TShape has an OnClick
event but it's protected. You can't get at it without tricks. So we'll
use the OnMouseUp event instead. It's not the same, but close enough.
Start by creating a new Delphi project with a single form and
populating it with some shapes and a few labels. I named the form
FColourCopy, the labels lblRed, lblGreen, and lblBlue, and left the
shapes at Shape1, Shape2, and Shape3. Use your own names (but make
them meaningful names if at all possible), but these are the ones
I'll be using.
Now think. I've described above what this program will _do_. Things
will happen when you click a shape, and when you click a label.
That's two event handlers. When a label is clicked, something will
happen to the selected shape. When a shape is clicked, it must be
selected. How will we "select" a shape? I've chosen to change its
appearance mainly because I can, but the important thing is to
remember which shape is selected.
When you click the shape, execution enters the event handler. The
methods runs and returns. At that point, all local variables
vanish. This is crucial. If you don't understand that, go read a
book on Pascal first. Local variables come into existence when a
routine is entered (it starts executing), and disappear when it is
left (executing returns to the place from which it was called).
Note that that applies to the variables. Objects remain in existence
until freed, and variables only point to the actual objects. You can
create a new object by calling TSomething.Create; that is essentially
a function call that returns a reference _to_ the object. It is
customary to store that reference somewhere, perhaps in a local
variable. Once execution leaves the procedure, the variable disappears
and you lose the reference. The object stays, you just don't know
where it is anymore.
Variables of simple types disappear too, but the integer value 5 is
not pointed to. It is simply stored in the variable directly.
Back to what happens when you click on a shape. The event handler
has a parameter that tells you which shape was clicked. As I've said,
parameters are very much like local variables. They too will go away
when execution leaves the procedure but the actual value in Sender is
a _reference_ to the shape and the shape will stay, only the reference
will be lost. We're going to need that reference, or rather a copy of
it (all copies of the same reference are the same), so we need to
store it in a variable that does not go away when the event handler
returns.
That variable will be in the form. All this code executes in the
context of the form object so we can always get at its fields, and
the fields will be there while the form object exists. And they
will keep their values between calls of the event handlers. Yell if
you don't understand that bit but I'll be glossing over it now.
I'll name the field Selection and it will be of type TShape.
In the public section of the form class declaration, add the line
"Selection: TShape;". Proper indentation is two spaces. Now when
the form object is created, there will be a field in it for your
use. It will initially contain the value nil. All fields in an
object will initially contain "zero", and for references to objects,
that means nil: no object. Following a reference to no object is an
error; you'll often have to check for that (sometimes you _know_ a
reference won't be nil, though).
Let's write the first event handler, the shape click (or mouse-up,
really) handler. It will deselect the previous shape if there was one,
store the current shape for later, and make the current shape look
selected.
Select one of the shapes, switch to the Object Inspector, and on the
Events tab, in the OnMouseUp box, type "SelectShape" and press Enter.
Magic happens. Realise that "Shape1MouseUp" is not the only possible
name for an OnMouseUp event handler for a shape.
Deselecting the previous shape, if there was one, needs the old value
of the Selection form field, so we do that first. Selecting the new
shape can use the new value of Selection; doing so saves a cast.
procedure TFColourCopy.ReleaseShape(Sender: TObject; <more parameters>);
begin
{ Deselect }
if Assigned(Selection) then begin
Selection.Pen.Width:=1;
Selection.Pen.Color:=clBlack;
end;
{ Remember }
Selection:=Sender as TShape;
{ Select }
Selection.Pen.Width:=2;
Selection.Pen.Color:=clFuchsia;
end;
Remember, blank lines and comments are free.
Set this same event handler for all the other shapes, too.
Now let's turn to what happens when you click on a label. If there is
a selected shape, it should get the colour of the clicked label. The
selected shape is in Self.Selection. The clicked label is in Sender.
There should be no problem, and there isn't.
procedure TFColourCopy.CopyColour(Sender: TObject);
begin
if Assigned(Selection) then begin
Selection.Brush.Color:=(Sender as TLabel).Font.Color;
end;
end;
Did you follow so far? Then you can press F9 now.
Groetjes,
Maarten Wiltink
.
- Follow-Ups:
- Re: Shapes at Runtime?
- From: cybatech
- Re: Shapes at Runtime?
- References:
- Re: Shapes at Runtime?
- From: cybatech
- Re: Shapes at Runtime?
- From: Maarten Wiltink
- Re: Shapes at Runtime?
- From: cybatech
- Re: Shapes at Runtime?
- From: Maarten Wiltink
- Re: Shapes at Runtime?
- From: cybatech
- Re: Shapes at Runtime?
- Prev by Date: Re: Shapes at Runtime?
- Next by Date: Re: Shapes at Runtime?
- Previous by thread: Re: Shapes at Runtime?
- Next by thread: Re: Shapes at Runtime?
- Index(es):
Relevant Pages
|