verpies
asked on
Children of a descendant of TRadioGroup not appearing at run time.
Regarding the scenario described in:
https://www.experts-exchange.com/questions/27489664/Children-of-a-descendant-of-TRadioGroup-disappearing-from-DFM-after-Save.html
Why does a TCheckBox dropped inside the TRadioGroupeEx disappear from the Form Designer's IDEm, after saving, closing and reopening a project containing TCheckBox inside TRadioGroupEx?
https://www.experts-exchange.com/questions/27489664/Children-of-a-descendant-of-TRadioGroup-disappearing-from-DFM-after-Save.html
Why does a TCheckBox dropped inside the TRadioGroupeEx disappear from the Form Designer's IDEm, after saving, closing and reopening a project containing TCheckBox inside TRadioGroupEx?
ASKER
I am interested primarily in Designtime disappearances...
FYI: the checkbox does not appear during runtime too.
FYI: the checkbox does not appear during runtime too.
unit RadioGroupEx;
interface
uses
Classes, Controls, ExtCtrls;
type
TRadioGroupEx = class(TCustomRadioGroup)
public
constructor Create(AOwner: TComponent); override;
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
published
property Align;
property Anchors;
property BiDiMode;
property Caption;
property Color;
property Columns;
property Ctl3D;
property DragCursor;
property DragKind;
property DragMode;
property Enabled;
property Font;
property ItemIndex;
property Items;
property Constraints;
property ParentBiDiMode;
property ParentBackground default True;
property ParentColor;
property ParentCtl3D;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnClick;
property OnContextPopup;
property OnDragDrop;
property OnDragOver;
property OnEndDock;
property OnEndDrag;
property OnEnter;
property OnExit;
property OnStartDock;
property OnStartDrag;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Additional', [TRadioGroupEx]);
end;
constructor TRadioGroupEx.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csAcceptsControls];
end;
procedure TRadioGroupEx.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
I: Integer;
Control: TControl;
begin
for I := 0 to ControlCount - 1 do
begin
Control := Controls[I];
if Control.Owner = Root then Proc(Control);
end;
end;
end.
What are you actually trying to do ?
A Radiogroup has the distinct concept of giving index for a selected radioitem
Why do you want to add checkboxes ???
> You will probably need to create a compound component
if you want a mix of checkbox, radiobutton, etc you need a groupbox
What is the goal you are trying to achieve ?
A Radiogroup has the distinct concept of giving index for a selected radioitem
Why do you want to add checkboxes ???
> You will probably need to create a compound component
if you want a mix of checkbox, radiobutton, etc you need a groupbox
What is the goal you are trying to achieve ?
ASKER
The goal is to increase my knowledge of Delphi's design-time behavior.
So why does the TCheckBox disappear from the Form Designer's IDE if it is present in the DFM?
So why does the TCheckBox disappear from the Form Designer's IDE if it is present in the DFM?
because internally the TRadioGroup keeps track of how many GroupButtons it contains and recreates them
check the vcl source of StdCtrls, Controls and ExtCrtls
check the vcl source of StdCtrls, Controls and ExtCrtls
it only recreates the RadioButtons it knows about
the rest is not recreated
browser problem ... too fast post in earlier msg
the rest is not recreated
browser problem ... too fast post in earlier msg
ASKER
This does not compute.
I don't have to "recreate" children dropped on a component such as TCustomContainerControl, which is a descendant of TCustomControl. See the attached code.
All of TCustomContainerControl's children appear inside it at design time and run time, without problems.
TCustomRadioGroup is also a decendant of TCustomContol, but its children do not appear inside of it at design time and run time.
Why?
I don't have to "recreate" children dropped on a component such as TCustomContainerControl, which is a descendant of TCustomControl. See the attached code.
All of TCustomContainerControl's children appear inside it at design time and run time, without problems.
TCustomRadioGroup is also a decendant of TCustomContol, but its children do not appear inside of it at design time and run time.
Why?
unit CustomContainerControl;
interface
uses
Classes, Controls;
type
TCustomContainerControl = class(TCustomControl)
public
constructor Create(AOwner: TComponent); override;
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
published
property Brush;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Additional', [TCustomContainerControl]);
end;
constructor TCustomContainerControl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csAcceptsControls];
end;
procedure TCustomContainerControl.GetChildren(Proc: TGetChildProc; Root: TComponent);
var
I: Integer;
Control: TControl;
begin
for I := 0 to ControlCount - 1 do
begin
Control := Controls[I];
if Control.Owner = Root then Proc(Control);
end;
end;
end.
because it does some internal changes
> TCustomRadioGroup has an empty override proc of GetChildren and FlipChildren which negates all actions on children, including storing, saving, painting, etc
It creates radiobuttons based upon 2 internal list structures: fButtons and fItems
It only paints radiobuttons via those internal list structures
if you have access to the source code of TCustomRadioGroup in $Delphi\Source\Win32\VCL\E xtCtrls.pa s you can check this yourself
So there is no point in putting other controls within this container
If you want a container, descend from TCustomPanel
> TCustomRadioGroup has an empty override proc of GetChildren and FlipChildren which negates all actions on children, including storing, saving, painting, etc
It creates radiobuttons based upon 2 internal list structures: fButtons and fItems
It only paints radiobuttons via those internal list structures
if you have access to the source code of TCustomRadioGroup in $Delphi\Source\Win32\VCL\E
So there is no point in putting other controls within this container
If you want a container, descend from TCustomPanel
> you changed your question from TCustomRadioGroup to TCustomControl
This is something totally different !
This is something totally different !
ASKER
No I did not change the object of the question.
The question (with a question mark) still pertains to missing children in TCustomRadioGroup.
I mentioned the TCustomContainerControl was only for comparative illustration. Its point was that no additional code is needed to show the children in a container control descended from TCustomControl ,at design time and run time.
The illustration is valid because both TCustomRadioGroup and TCustomContainerControl have the same ancestor which has code that is responsible for showing their children at design time and run time.
You statement about the objects that TCustomRadioGroup creates (radiobuttons based upon 2 internal list structures) does not explain why its other children are not visible.
However your statement about TCustomRadioGroup having an empty override proc of GetChildren and FlipChildren which negates all actions on children, including storing, saving, painting, etc..., does answer my question.
I will verify it and get back to you.
The question (with a question mark) still pertains to missing children in TCustomRadioGroup.
I mentioned the TCustomContainerControl was only for comparative illustration. Its point was that no additional code is needed to show the children in a container control descended from TCustomControl ,at design time and run time.
The illustration is valid because both TCustomRadioGroup and TCustomContainerControl have the same ancestor which has code that is responsible for showing their children at design time and run time.
You statement about the objects that TCustomRadioGroup creates (radiobuttons based upon 2 internal list structures) does not explain why its other children are not visible.
However your statement about TCustomRadioGroup having an empty override proc of GetChildren and FlipChildren which negates all actions on children, including storing, saving, painting, etc..., does answer my question.
I will verify it and get back to you.
ASKER
I have determined that TCustomRadioGroup.FlipChil dren is not responsible for the disappearance of children dropped onto TCustomRadioGroup.
The procedure that is responsible for the disappearing children is the CustomRadioGroup.ArrangeBu ttons , concretely the function DeferWindowPos() inside it. This function is responsible for the disappearances because it creates the TGroupButtons (descendants of TRadioButton) so large that they cover up any siblings lower in the ZORDER. It so happens that the external components dropped on the TRadioGroup are created first and thus are lower in the ZORDER.
The above can be easily seen by considering the following line in CustomRadioGroup.ArrangeBu ttons :
ButtonWidth := (Width - 10) div FColumns;
The above line is responsible for making the TGroupButtons fill up the whole width of the TRadioGroup.
If the external components dropped on TRadioGroup were higher in the ZOrder than the radio buttons (TGroupButton s) then they would be visible.
Also if the size of the TGroupButtons was smaller then the other children would be visible between them.
If you rephrase it nicely I will award you the points so some other poor soul considering this puzzling behavior can jump right into nicely summarized solution.
The procedure that is responsible for the disappearing children is the CustomRadioGroup.ArrangeBu
The above can be easily seen by considering the following line in CustomRadioGroup.ArrangeBu
ButtonWidth := (Width - 10) div FColumns;
The above line is responsible for making the TGroupButtons fill up the whole width of the TRadioGroup.
If the external components dropped on TRadioGroup were higher in the ZOrder than the radio buttons (TGroupButton s) then they would be visible.
Also if the size of the TGroupButtons was smaller then the other children would be visible between them.
If you rephrase it nicely I will award you the points so some other poor soul considering this puzzling behavior can jump right into nicely summarized solution.
rephrase it nicely ?
are you serious ?
are you serious ?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
The overridden TCustomRadioGroup...GetChi ldren is responsible for not saving the children to the DFM file.
The children of TCustomRadioGroup.. are created from the DFM and painted even if the code in TCustomRadioGroup.. does not create and paint them explicitly.
The child components dropped on TCustomRadioGroup.. during design time are invisible during runtime and designtime because the superior Zorder and size of the "radiobuttons" (TGroupButton s) causes them to cover up any children.
Additional Info:
The lack of csAcceptControls attribute is responsible for TCustomRadioGroup not accepting child controls dropped on it during design time.
The children of TCustomRadioGroup.. are created from the DFM and painted even if the code in TCustomRadioGroup.. does not create and paint them explicitly.
The child components dropped on TCustomRadioGroup.. during design time are invisible during runtime and designtime because the superior Zorder and size of the "radiobuttons" (TGroupButton s) causes them to cover up any children.
Additional Info:
The lack of csAcceptControls attribute is responsible for TCustomRadioGroup not accepting child controls dropped on it during design time.
please post your code