Link to home
Start Free TrialLog in
Avatar of verpies
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?
Avatar of Geert G
Geert G
Flag of Belgium image

runtime ? or designtime ?

please post your code
Avatar of verpies
verpies

ASKER

I am interested primarily in Designtime disappearances...
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.

Open in new window

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 ?
Avatar of verpies

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?
because internally the TRadioGroup keeps track of how many GroupButtons it contains and recreates them
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
Avatar of verpies

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?
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.

Open in new window

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\ExtCtrls.pas 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
> you  changed your question from TCustomRadioGroup to TCustomControl

This is something totally different !
Avatar of verpies

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.
Avatar of verpies

ASKER

I have determined that TCustomRadioGroup.FlipChildren is not responsible for the disappearance of children dropped onto TCustomRadioGroup.

The procedure that is responsible for the disappearing children is the CustomRadioGroup.ArrangeButtons , 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.ArrangeButtons :
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 ?

SOLUTION
Avatar of verpies
verpies

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
ASKER CERTIFIED SOLUTION
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
Avatar of verpies

ASKER

The overridden TCustomRadioGroup...GetChildren 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.