Jump to content
egnew

Access Violation when Enabling TTimer in TComponent

Recommended Posts

I have a component in a Delphi package.  The component contains a TTimer.  When I manually create an instance of the Component, everything works fine.

 

But when I drop the component on my form, everything works until the component tries to activate the timer.  When the component attempts to start the timer with "FTimer.Enabled := True;", the access violation occurs.

 

The following code from Vcl.ExtCtrls is called with Value=True but as soon as "if Value <> FEnabled" executes, the access violation occurs.

 

procedure TTimer.SetEnabled(Value: Boolean);
begin
  if Value <> FEnabled then
  begin
    FEnabled := Value;
    UpdateTimer;
  end;
end

Is this a bug or am I overlooking something?

 

Thanks

 

Share this post


Link to post

Run your application under the debugger and set a break point on the line "FTimer.Enabled := True;". Check FTimer value. It is likely FTimer is nil at that moment.

Show the code in your component source code where you create the TTimer instance.

 

Share this post


Link to post

To tell what is wrong, we need to see your class declaration and implementation - in this case most likely constructor is what matters. Showing TTimer code is not very helpful. So when you ask for help, you should post your code first.

 

However, knowing that your code works when you construct component directly and it does not when you drop it on a form, narrows down potential cause and most likely culprit is that you didn't add override directive to your component constructor. When you call constructor directly specifying its class then your constructor will run and create timer component, but when you drop it on a form original virtual constructor chain from TComponent will run, but it will skip calling your constructor because it is not marked as part of the chain (missing override directive).

 

type
  TMyComponent = class(...
  ...
  public
   constructor Create(AOwner: TComponent); override;
  ens;

 

If that is the case, you would also see warning W1010 Method 'Create' hides virtual method of base type... This warning tells you that something is wrong with your declaration and that you most likely forgot to add override directive (there are other scenarios besides this one, but in your case this is the one that matters)

  • Like 2
  • Thanks 1

Share this post


Link to post

Dalija Prasnikar:  You are the best.

 

I have not built any components in years and forgot to add the override.  That was the issue.

 

Thanks so much.

Share this post


Link to post
On 4/2/2023 at 2:30 AM, Dalija Prasnikar said:

However, knowing that your code works when you construct component directly and it does not when you drop it on a form, narrows down potential cause and most likely culprit is that you didn't add override directive to your component constructor.

It is a shame that the IDE doesn't have an option to validate that issue automatically when a component is first dropped on a Form Designer.  It knows the type being created, it could quickly check the component's RTTI to see if its most-derived constructor is properly overriding the virtual TComponent constructor, and if not then warn the user of that potential bug so they can fix it.  Oh well...

Share this post


Link to post

IIRC, the compiler emits a warning W1010 Method 'Create' hides virtual method of base type 'TComponent' for a construct like this:

type
  TMyCom = class(TComponent)
  public
    constructor Create;
  end;

That seems sufficient to fix the bug before the component is even registered in the IDE.

  • Like 2

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×