Re: Getting component's name from notification parameter?
From: Maarten Wiltink (maarten_at_kittensandcats.net)
Date: 01/30/05
- Next message: Rob Kennedy: "Re: Events in a console application"
- Previous message: Robert: "Events in a console application"
- In reply to: Raptor: "Re: Getting component's name from notification parameter?"
- Next in thread: Raptor: "Re: Getting component's name from notification parameter?"
- Reply: Raptor: "Re: Getting component's name from notification parameter?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Sun, 30 Jan 2005 20:39:43 +0100
"Raptor" <bogus@none.com> wrote in message
news:ctidqo02r7b@news2.newsguy.com...
[...]
> I made no headway on getting the nonwindowed component to post a
> message to itself,
Since non-windowed controls do not have their own message loops, that
was to be expected. I suppose they borrow the message loop of their
Parent or perhaps the Form they're on somehow, but I don't know. So I
stick to what I do know.
> but when I quit butting my head against the wall
> the following test worked with relative ease:
[...]
> procedure TWCMessage.WCMessage(var Msg: TMessage);
> begin
> if assigned(aWCMessage) then aWCMessage.Free;
Does Freeing it also clear the reference? Watch your step.
> dbs(GetComponentCount); <--displays on status bar
> showmessage('WCMessage received... ');
> end;
>
>
> constructor TWCMessage.Create(aOwner: TComponent);
> begin
> inherited Create(aOwner);
> Self.Parent := FormMain;
This introduces lexical dependencies that will bite you when you try
to generalise this component. Is it even necessary? This is not a
_visual_ component, you're just using a windowed control to get a
message loop.
(You may have tried it without a parent and found it didn't work then.
If so, that would be useful to know.)
> end;
>
>
> constructor TTranslate.Create(aOwner: TComponent);
> begin
> inherited Create(aOwner);
> aWCMessage := TWCMessage.Create(aOwner);
> PostMessage(aWCMessage.Handle, TM_WCMESSAGE, 0, 0);
> ...
> end;
It looks like aWCMessage is a field in the TTranslate instance. That
makes me think you should clear the field once you free the object
it references.
You can make the windowed control refer to the translation component
instead of the other way; that would minimise the impact of the
whole scheme on the permanent part. By placing the reference in the
inner component, it automatically goes away once the component has
served its purpose.
> =============
>
> I'd still like to know if there's a way to do this with a nonwindowed
> control. Various posts speak about using Dispatch, but... ahem... no
> code examples.
>
> I don't mind spawning a temporary TWinControl for this purpose, then
> freeing it, if that's an acceptable/best/only way, but I did have
> one problem: I couldn't find a way to assign it a parent except by
> specific reference... thus couldn't come up with a way to genericize
> the code which compiled or worked.
Spoke before my turn, I see.
Well, as I said you may not need to - although I have some faith that
if you ask about it, you already know that you do. It's possible to
check that the Owner is not just a TComponent but a TWinControl, and
use that if it is.
The Owner is passed from the TTranslator instance to the TWCMessage
and _usually_ it will be the form, which then works fine. Of course,
someone someday will instantiate your translator component at runtime
and not pass it an Owner at all.
That may not be a problem because of the unique and very specific
circumstances that created the need for message processing in the
first place - if the application is already up and running, you don't
need it anymore. Of course, when you deem yourself secure in that, the
day will come that someone integrates it into their custom form class
and manages to instantiate TTranslator without an Owner while forms
are still being autocreated.
So scenarios remain possible where you _need_ a Parent for the inner
component, and you just don't have one. You can give the outer
component a Parent property and pass it to the inner component, or
you can have the inner component query the outer component for it.
The outer component can give its own best guess or pass on the
request by firing an event. Let me know if you decide to use any of
those techniques and I'll jot down some example code. But not right
now; dinner's waiting.
> Would that problem disappear somehow if I turned this into a
> Registered drop-on component?
Only if you drop it on a form, because the form will become the Owner
and it's also useable as the Parent. But it remains possible to
create it outside Delphi's designers system, and it should not stop
working then.
> PS to Maarten: Happy to note that the component count when this message
> received is 73, the same count as on app closure, which says that even
> the dynamically-created menu items (called from TFormMain.FormActivate)
> are being included before the message is returned.
>
> You think that's a dependable circumstance?
No. TForm.OnActivate occurs (for the first time) during component
streaming while autocreating forms, but many dynamic schemes are most
active while the application is fully up and running.
TForm.OnActivate is almost always the wrong place to do things, BTW.
Look into TComponent.Loaded instead.
Groetjes,
Maarten Wiltink
- Next message: Rob Kennedy: "Re: Events in a console application"
- Previous message: Robert: "Events in a console application"
- In reply to: Raptor: "Re: Getting component's name from notification parameter?"
- Next in thread: Raptor: "Re: Getting component's name from notification parameter?"
- Reply: Raptor: "Re: Getting component's name from notification parameter?"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]