Link to home
Start Free TrialLog in
Avatar of Palamedes
PalamedesFlag for United States of America

asked on

Free'ing the sender's parent's parent... hehe

When a user goes through a series of steps in my application a FRAME is dynamically generated to a Scrollbox and assigned a new name.  On that frame there are all kinds of controls.  One of the controls is a speedbutton with a little X in it (like the one at the top right of every window application).  It is designed to do the same thing as the x on all windows apps; remove/close the frame.  If someone clicks that little x, it should FREE the FRAME from the scrollbox.  Now, I have been able to free the speedbutton of course.  

Sender.free;      makes the sender(TspeedButton) go away nicely (and someone comically.  You push the delete button, and sure enough.. the button is deleted.. hehe)

The problem is, I need the whole frame to be free’d.  The frame is dynamically named each time so I will have to use FindComponent I assume?  Not really sure..

So, in short.  When a user clicks TspeedButton on my dynamically generated Frame.  I need that frame to disappear.  

Note, Speedbutton is parented to a panel which is right aligned to another panel, which in turn is TOP aligned to the frame.

-Pal
Avatar of Madshi
Madshi

Have you tried "TSpeedButton(Sender).parent.parent.parent.Free"?

:-)

Regards, Madshi.
or just using a form?

GL
Mike
I haven't used frames before, but it strikes me that the owner of the speedbutton might be the frame itself, so you could go TSpeedButton(Sender).owner.free.

Alternatively you can walk up the parent hierarchy until you find the frame like this:

var
  AObject : TComponent;

  AObject := Sender as TComponent;
  repeat
    AObject := AObject.Parent;
  until not assigned(AObject) or (AObject is TFrame); // Correct name for class?
 
  if Assigned (AObject) then
    AObject.Free;

Cheers,

Raymond.
Avatar of Palamedes

ASKER

Can't use a form.

Madshi, that works but I get an error.  
Control '' has no parent window.
(the first time you try it and the second time you delete one, you get an access violation error)

rwilson, same thing happens with your owner.free snippet.  

Control '' has no parent window.

*shrug* I don't even know what that one means..

    AObject := AObject.Parent;

And for some reason, Delphi 5 says that Parent is an undeclared identifier right here..  I cut and pasted your code direcly in too.. so I know I declared AObject :TComponent and sender as.. *shrug*

-pal
Do I have to set the parenting for each component in the frame?

When the frame is dynamically created, I declare that
NewFrame.parent:=scrollbox;  

but I assume that all the components in the frame, are already parented.. Do I have to specifically say, SpeedButton.parent:=panel
and panel.parent:=frame

etc..?

also, is saying

TSpeedButton(Sender)

the same as saying

with sender as TSpeedbutton

?

Oops, that shoudl be TControl rather than TComponent.

Cheers,

Raymond.
Same error..

Control '' has no parent window.
Argh! I hate the Delphi help sometimes. Try TGraphicControl - that should work!

Cheers,

Raymond.
Is the correct field "parent" or "owner"?
if the speedbutton is on the frame then simpley
                   TFrame(Sender.Parent).Free;

but if the Speedbutton is not on the frame then do the following:

For I := 0 to ScrollBox.ControlCount-1 do begin
  if Controls[I] is TFrame then TFrame(Controls[I]).Free;
end;

Best Regards
Kifah R. Najem
TGraphicControl is a no go.. TWinControl is also no go..

kifah, your answer doesnt work at all.. further more.. please refrain from using the "ANSWER" selection as it keeps others from commenting.  If your comment is the correct answer, I would have given you the points.  Thanks..


Okay everyone.. So what do I do..  I am at a total loss here..

-Pal
I have been playing a bit to see if there is something else I can do to get this to work...

sender.free;  correctly free's the speed button.

If I do;
sender.free;
TSpeedButton(sender).parent.free;

it correctly deletes the speedbutton AND the panel that it is in.

If I try to do a

sender.free;
tSpeedButton(sender).parent.free;
tSpeedButton(sender).parent.parent.free;

I get an access violation error.

if I do just

tspeedbutton(sender).parent.free;

I get the error 'Control '' has no parent window.'  But it does correctly free it.. I mean its gone..

I have NO IDEA whats going on here and really need your help all..

thanks..
as to the first:

sender.free;
tSpeedButton(sender).parent.free;
tSpeedButton(sender).parent.parent.free;

SHOULD result in an access violation error as the tSpeedButton(sender).parent.parent reference would have been destroyed with the tSpeedButton(sender).parent.free; call.

As to the second, well , I'll have to investigate that one :)

GL
Mike

I have made an example program demonstrating my problem.

http://www.palaquest.com/jason/Project1.exe

ASKER CERTIFIED SOLUTION
Avatar of synature
synature

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi,

Just a little question.  Is the TSpeedButton in the TFrame component, or do you drop it on the TFrame component afterwards ?

If you drop it on the TFrame after you dropped the TFrame on the form (or after you created it dynamically), I suggest you try it by putting it directly in the TFrame instead.


Best regards,


Stefaan.
If the first and second line works, but not the third one than the conclusion is...

sender.free;
tSpeedButton(sender).parent.free;
tSpeedButton(sender).parent.parent.free;

.... that the speedbutton's parent property is set alright to its parent panel, but that this panel's parent property is NOT set right. So you should make sure that you set the parent property when creating the controls. Ehm... Do you create them dynamically at runtime?

BTW, Mike, you're half right. The order of the 3 lines is *VERY* wrong. But it need not result in an access violation, because "Free" was called (which doesn't set the object pointer to nil), not "FreeAndNil" (a Delphi 5 function). So the object pointer has it's old value and so the chance for an access violation is perhaps 30 to 70...
I like those odds...

Hee hee,

Tim.

PS:  Wouldn't "Release" be better here than "Free"?
Release is only available for forms, or am I wrong? But I don't know these frames, perhaps they have a release, too...
Yes you're right, though free *should* call destroy which *should* free all mem associated with the object, hence (even if it isn't *always*) one should expect the access violation error.


GL
Mike
Release will not work with frames for whatever reason.  I have tried it errors out.  While a frame is a container similar to a form, it doesnt have all the features that a form has.

Madshi, The SpeedButton is parented to the panel on which it sits.  That panel is parented to the panel on which IT sits, which is parented to the frame.  The frame in turn is parented tothe scrollbox.  I have tried this both declaring and NOT declaring the parenting.  Neither work, both giving the same error.

I then did what synature suggested, and used a BitBtn which worked like a charm!

So... It looks like TSpeedButton isnt a TWinControl descendant..

What a pain in the rear huh..  Boy I have learned alot though..

Thanks to everyone for their help on this .. I do really appreciate it..

-Pal
Thanks!