Palamedes
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
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
or just using a form?
GL
Mike
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.
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.
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
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
ASKER
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..?
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..?
ASKER
also, is saying
TSpeedButton(Sender)
the same as saying
with sender as TSpeedbutton
?
TSpeedButton(Sender)
the same as saying
with sender as TSpeedbutton
?
Oops, that shoudl be TControl rather than TComponent.
Cheers,
Raymond.
Cheers,
Raymond.
ASKER
Same error..
Control '' has no parent window.
Control '' has no parent window.
Argh! I hate the Delphi help sometimes. Try TGraphicControl - that should work!
Cheers,
Raymond.
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
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
ASKER
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
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
ASKER
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).paren t.free;
it correctly deletes the speedbutton AND the panel that it is in.
If I try to do a
sender.free;
tSpeedButton(sender).paren t.free;
tSpeedButton(sender).paren t.parent.f ree;
I get an access violation error.
if I do just
tspeedbutton(sender).paren t.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..
sender.free; correctly free's the speed button.
If I do;
sender.free;
TSpeedButton(sender).paren
it correctly deletes the speedbutton AND the panel that it is in.
If I try to do a
sender.free;
tSpeedButton(sender).paren
tSpeedButton(sender).paren
I get an access violation error.
if I do just
tspeedbutton(sender).paren
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).paren t.free;
tSpeedButton(sender).paren t.parent.f ree;
SHOULD result in an access violation error as the tSpeedButton(sender).paren t.parent reference would have been destroyed with the tSpeedButton(sender).paren t.free; call.
As to the second, well , I'll have to investigate that one :)
GL
Mike
sender.free;
tSpeedButton(sender).paren
tSpeedButton(sender).paren
SHOULD result in an access violation error as the tSpeedButton(sender).paren
As to the second, well , I'll have to investigate that one :)
GL
Mike
ASKER
I have made an example program demonstrating my problem.
http://www.palaquest.com/jason/Project1.exe
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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.
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).paren t.free;
tSpeedButton(sender).paren t.parent.f ree;
.... 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...
sender.free;
tSpeedButton(sender).paren
tSpeedButton(sender).paren
.... 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"?
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
GL
Mike
ASKER
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
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
ASKER
Thanks!
:-)
Regards, Madshi.