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
LVL 4
PalamedesAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

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

:-)

Regards, Madshi.
0
edeyCommented:
or just using a form?

GL
Mike
0
rwilson032697Commented:
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.
0
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

PalamedesAuthor Commented:
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
0
PalamedesAuthor Commented:
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..?

0
PalamedesAuthor Commented:
also, is saying

TSpeedButton(Sender)

the same as saying

with sender as TSpeedbutton

?

0
rwilson032697Commented:
Oops, that shoudl be TControl rather than TComponent.

Cheers,

Raymond.
0
PalamedesAuthor Commented:
Same error..

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

Cheers,

Raymond.
0
dejohn99Commented:
Is the correct field "parent" or "owner"?
0
kifahCommented:
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
0
PalamedesAuthor Commented:
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
0
PalamedesAuthor Commented:
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..
0
edeyCommented:
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
0
PalamedesAuthor Commented:

I have made an example program demonstrating my problem.

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

0
synatureCommented:
I suspect your problem may be that tSpeedButton is not a TwinControl descendent, and thus does not, normally, have a windows handle.  Thus the parenting of a tspeedbutton is handled differntly than the other controls.  

What I'd suggest is to see if you can get the desired behavior using a tBitBtn, which is a TwinControl descendent.  If you can get your frame to free itself with the bit button's parent, then the problem is the tspeedbutton.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
StefaanCommented:
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.
0
MadshiCommented:
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...
0
AttarSoftwareCommented:
I like those odds...

Hee hee,

Tim.

PS:  Wouldn't "Release" be better here than "Free"?
0
MadshiCommented:
Release is only available for forms, or am I wrong? But I don't know these frames, perhaps they have a release, too...
0
edeyCommented:
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
0
PalamedesAuthor Commented:
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
0
PalamedesAuthor Commented:
Thanks!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.