Reputation: 279
I saw the introduction of the TActivityIndicator in Delphi 10 Seattle and thought cool I could make use of this somewhere. I wanted to use this to show that some dynamically created sections of my form were still loading the data before populating the form. So I thought I'd do this before I start loading my data in FormShow
, where self is the form.
indicator := TActivityIndicator.Create(self);
indicator.IndicatorSize := TActivityIndicatorSize.aisLarge;
Sadly when I try to create them dynamically and set then TActivityIndicator.IndicatorSize
I get an exception ... EInvalidOperation with message 'Control '<name>' has no parent window'
Which stepping through the VCL takes me to Vcl.Controls TWinControl.CreateWnd
specifically
if (WndParent = 0) and (Style and WS_CHILD <> 0) then
if (Owner <> nil) and (csReading in Owner.ComponentState) and
(Owner is TWinControl) then
WndParent := TWinControl(Owner).Handle
else
raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);
I've checked Owner
is the form which is of course a TWinControl but (csReading in Owner.ComponentState)
returns false. Stepping through Owner.ComponentState = [] on FormCreate and [csFreeNotification] on FormShow.
I've found that if you try to change the IndicatorSize
of a TActivityIndicator that was created at design time then it works perfectly. So what am I missing here or is it not possible to create TActivityIndicators
at runtime?
Upvotes: 1
Views: 703
Reputation: 125749
The error message is pretty clear. You need to assign a Parent
on which the activity indicator will draw itself. The Owner
is the component responsible for freeing the control when the Owner is destroyed; the Parent
is the control on which the control will be drawn (parented) for display.
The solution is to assign that parent in code:
Indicator := TActivityIndicator.Create(Self);
Indicator.Parent := Self; // <-- here
// Set any other properties here
The same issue is common on all visual controls (such as TEdit
, TLabel
, TMemo
, and so forth), which all need to have a Parent
assigned in order to have a place to paint themselves. And in some cases, a Parent
is required in order for various properties in the child control to function correctly when they depend on the child having an HWND
window, which requires a Parent
window, and so on.
If I understand your intent, I think you're going to be disappointed, however. TActivityIndicator
is pretty static; it's not threaded, which means it will cease updating if your form is busy and doesn't process timer messages (which it uses internally).
Upvotes: 4