BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Updating a statusbar

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc
View previous topic :: View next topic  
Author Message
Tom de Neef
Guest





PostPosted: Mon Jan 16, 2006 2:15 pm    Post subject: Updating a statusbar Reply with quote



I have never used a TstatusBar before. My first impression is that it is a
bit primitive, with panels that you can refer to only by index. So, I've
introduced properties in the form to update individual panels, like
property updateStatusCount : integer write setStatusCount;

Now, this statuscount can change in a number of places, outside the form.
1) How do I go about it without getting references to the form
(mainForm.updateStatusCount:=n) all over the place?

2) Where to put the update call in a derived class?
Eg:
type
TbaseCalc = class
procedure build; virtual;
end;

TspecialCalc = class(TbaseCalc)
procedure build; override;
end;

procedure TbaseCalc.build;
begin
<initialization>
end;

procedure TspecialCalc.build;
begin
inherited;
<calculate results in N>
mainForm.updateSatusCount:=N
end;

I can put common code that is to be executed _before_ the calculations in
TbaseCalc.build; But where do I put the updateStatusCount call that goes
_after_ the calculations? I do not want it in every derived class of
TbaseCalc since it will be common to all of them.

Tom


Back to top
Maarten Wiltink
Guest





PostPosted: Mon Jan 16, 2006 3:27 pm    Post subject: Re: Updating a statusbar Reply with quote



"Tom de Neef" <tdeneef (AT) qolor (DOT) nl> wrote


Quote:
I have never used a TstatusBar before. My first impression is that
it is a bit primitive, with panels that you can refer to only by
index. So, I've introduced properties in the form to update individual
panels, likeproperty updateStatusCount : integer write setStatusCount;

Now, this statuscount can change in a number of places, outside the
form. 1) How do I go about it without getting references to the form
(mainForm.updateStatusCount:=n) all over the place?

Decouple publisher and subscriber. Have a central unit or object that
allows registrations for both publishing and subscription to named
"slots". Allocate a slot whenever a registration of either type comes
in for it. Save the last published value; if a new subscription comes
in, this is what you want to send it. If a new value is published,
forward it to all registered subscribers.

It's a bit awkward to consider perhaps, because in your case there
are many publishers and only a single subscriber, the statusbar.


Quote:
2) Where to put the update call in a derived class?
Eg:
type
TbaseCalc = class
procedure build; virtual;
end;

TspecialCalc = class(TbaseCalc)
procedure build; override;
end;

procedure TbaseCalc.build;
begin
initialization
end;

procedure TspecialCalc.build;
begin
inherited;
calculate results in N
mainForm.updateSatusCount:=N
end;

I can put common code that is to be executed _before_ the
calculations in TbaseCalc.build; But where do I put the
updateStatusCount call that goes _after_ the calculations?
I do not want it in every derived class of TbaseCalc since
it will be common to all of them.

I'm not sure I understand the problem, but you could introduce an
extra property in TBaseCalc. Write its write accessor like this:

procedure TBaseCalc.SetStatusCount(const Value: Integer);
begin
if (StatusCount<>Value) then begin
FStatusCount:=Value;
MainForm.UpdateStatusCount(StatusCount);
end;
end;

All derived classes would have to store the result of their
calculations in the StatusCount property. I'm not sure if that is
a weaker requirement than that they republish the StatusCount
when they've computed it. It looks mighty similar to me, just the
place of publication is different.

Groetjes,
Maarten Wiltink



Back to top
Tom de Neef
Guest





PostPosted: Mon Jan 16, 2006 11:24 pm    Post subject: Re: Updating a statusbar Reply with quote



"Maarten Wiltink" <maarten (AT) kittensandcats (DOT) net> schreef in bericht
news:43cbbb7e$0$11074$e4fe514c (AT) news (DOT) xs4all.nl...

Quote:
Now, this statuscount can change in a number of places, outside the
form. 1) How do I go about it without getting references to the form
(mainForm.updateStatusCount:=n) all over the place?

Decouple publisher and subscriber. Have a central unit or object that
allows registrations for both publishing and subscription to named
"slots". Allocate a slot whenever a registration of either type comes
in for it. Save the last published value; if a new subscription comes
in, this is what you want to send it. If a new value is published,
forward it to all registered subscribers.

It's a bit awkward to consider perhaps, because in your case there
are many publishers and only a single subscriber, the statusbar.

This approach I use to synchronize lists and graphics on different forms and

I like it for its simplicity. A unit introducing a change is only
responsible for informing the central manager, which dispatches to every
unit that has registered to be informed about such change. There can be any
number of change types and it remains clean.
For the statusbar is seems a bit like an overkill. After all, what is the
difference between informing a central manager and writing to a main form's
property. But thanks anyway.

Quote:

2) Where to put the update call in a derived class?

I'm not sure I understand the problem, but you could introduce an
extra property in TBaseCalc. Write its write accessor like this:

procedure TBaseCalc.SetStatusCount(const Value: Integer);
begin
if (StatusCount<>Value) then begin
FStatusCount:=Value;
MainForm.UpdateStatusCount(StatusCount);
end;
end;

All derived classes would have to store the result of their
calculations in the StatusCount property. I'm not sure if that is
a weaker requirement than that they republish the StatusCount
when they've computed it. It looks mighty similar to me, just the
place of publication is different.


The point I tried to make was that you can use 'inherited' before or after
the code in the derived class. You call inherited before when common code is
to be executed before the subclass code, like in a constructor. You call
inherited near the end if the base class code has to follow the subclass,
like in a destructor. I have introductory code in the base class - so
'inherited' in the subclass goes up front. But I have also common code (eg
updating the statusbar) that you wish to place in the base class - since it
it common to all derived classes - _after_ the execution of subclass code.

procedure Tclass.Amethod;
begin
<prepare calculation, common to all classes>
<calculation, one subclass per type of calculation>
<cleanup and inform others, common to all classes>
end;

I.e. need for 'inherited' as in a constructor as well as in a destructor.
But you can't have both. So you're stuck with common code, either on entry
or before leaving, that needs to be repeated in all derived classes. It
boils down to just a procedure call, but still, it doesn't please me.

Tom



Back to top
Maarten Wiltink
Guest





PostPosted: Tue Jan 17, 2006 10:16 am    Post subject: Re: Updating a statusbar Reply with quote

"Tom de Neef" <tdeneef (AT) qolor (DOT) nl> wrote


[...]
Quote:
procedure Tclass.Amethod;
begin
prepare calculation, common to all classes
calculation, one subclass per type of calculation
cleanup and inform others, common to all classes
end;

I.e. need for 'inherited' [both before and after].
But you can't have both.

Funny you should mention this. I ran into the exact same problem
last night with my filesystem code. Moving a file to another directory
has generic bookkeeping done beforehand (removing the file from the
old directory object's cache), a specialised implementation (moving
the file in the backing store), and more generic bookkeeping afterwards
(adding the file to the new directory object's cache).

procedure TmwFile.SetDirectory(const NewNewValue: TmwDirectory);
begin
if (Self.Directory<>Value) then begin
DoMoving(NewValue); { event dispatcher, virtual }
MoveFile(Self.Directory, NewValue); { worker method, abstract }
DoMoved; { event dispatcher, virtual }
end;
end;

It took me several hours to realise that overriding WrDirectory was
never going to give me what I wanted, and that I needed to make
the MoveFile fragment an overrideable method.

Groetjes,
Maarten Witlnk



Back to top
Tom de Neef
Guest





PostPosted: Tue Jan 17, 2006 12:09 pm    Post subject: Re: Updating a statusbar Reply with quote

"Maarten Wiltink" <maarten (AT) kittensandcats (DOT) net> schreef in bericht
news:43ccc405$0$11079$e4fe514c (AT) news (DOT) xs4all.nl...
Quote:
"Tom de Neef" <tdeneef (AT) qolor (DOT) nl> wrote in message
news:43cc2b2c$0$11066$e4fe514c (AT) news (DOT) xs4all.nl...

[...]
procedure Tclass.Amethod;
begin
prepare calculation, common to all classes
calculation, one subclass per type of calculation
cleanup and inform others, common to all classes
end;

I.e. need for 'inherited' [both before and after].
But you can't have both.

Funny you should mention this. I ran into the exact same problem
last night with my filesystem code. Moving a file to another directory
has generic bookkeeping done beforehand (removing the file from the
old directory object's cache), a specialised implementation (moving
the file in the backing store), and more generic bookkeeping afterwards
(adding the file to the new directory object's cache).

procedure TmwFile.SetDirectory(const NewNewValue: TmwDirectory);
begin
if (Self.Directory<>Value) then begin
DoMoving(NewValue); { event dispatcher, virtual }
MoveFile(Self.Directory, NewValue); { worker method, abstract }
DoMoved; { event dispatcher, virtual }
end;
end;

It took me several hours to realise that overriding WrDirectory was
never going to give me what I wanted, and that I needed to make
the MoveFile fragment an overrideable method.


Yep, as I've said before: once you know the answers, it is all so simple !
Tom



Back to top
alanglloyd@aol.com
Guest





PostPosted: Tue Jan 17, 2006 5:13 pm    Post subject: Re: Updating a statusbar Reply with quote

Quote:
I.e. need for 'inherited' as in a constructor as well as in a destructor.
But you can't have both.

Unless I misunderstand you, there's no reason (is there Maarten ?) why
one cannot call parent methods from the subclass using the inherited
keyword. And the parent's method will know the caller which may be
useful (to do or omit certain actions on that caller).

Alan Lloyd


Back to top
Maarten Wiltink
Guest





PostPosted: Tue Jan 17, 2006 5:50 pm    Post subject: Re: Updating a statusbar Reply with quote

<alanglloyd (AT) aol (DOT) com> wrote


Quote:
I.e. need for 'inherited' as in a constructor as well as in
a destructor. But you can't have both.

Unless I misunderstand you, there's no reason (is there Maarten ?)
why one cannot call parent methods from the subclass using the
inherited keyword.

No, you can do that - call inherited Loaded in
TDerivedForm.IntroducedMethod, by way of example. It's not terribly
good form, of course, but I think I've done it once or twice.

But this was a different problem.


Quote:
And the parent's method will know the caller which may be
useful (to do or omit certain actions on that caller).

It's usually a mistake to vary ancestor class behaviour with the
exact derived classtype. If you have a derived class, place the
overrides there. (As Tom and I both experienced, sometimes it's
not immediately obvious how to organise the code.)

Groetjes,
Maarten Wiltink



Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> comp.lang.pascal.delphi.misc All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.