delphiaccess-violationdelphi-10.1-berlin

Cannot access a VCL component in a procedure called from FormCreate on a modal form (i.e. directly after opening the form)


Running into a runtime error when I open a modal form (Form2) that, on create, calls another procedure that does somehting with a VCL component. The following program demonstrates the issue.

This is the code on the modal form:

procedure DoLabel;
begin
  form2.Label1.Caption := 'A';
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  DoLabel;
end;

This compiles well. However, the program crashes on opening the modal form. The debugger says: access violation at address xxxx. It is probably a basic error, but what am I doing wrong? And how to solve this?


Solution

  • You are using the global Form2 variable, which has not been assigned yet (or at all) while the TForm2 object is still being constructed.

    You need to change your code to not rely on that variable during construction (and preferably remove it entirely, unless TForm2 is auto-created at startup, which it does not sound like it is).

    For instance, pass the Form's Self pointer, or even its TLabel pointer, as an input parameter to DoLabel(), eg:

    procedure DoLabel(ALabel: TLabel);
    begin
      ALabel.Caption := 'A';
    end;
    
    procedure DoFormStuff(AForm: TForm2);
    begin
      // use AForm as needed...
    end;
    
    procedure TForm2.FormCreate(Sender: TObject);
    begin
      DoLabel(Label1);
      DoFormStuff(Self);
    end;
    

    Though, in this case, it would make more sense to have DoFormStuff(), and possible DoLabel() too, be a member of the TForm2 class instead of free functions:

    procedure TForm2.FormCreate(Sender: TObject);
    begin
      DoLabel;
      DoFormStuff;
    end;
    
    procedure TForm2.DoLabel;
    begin
      Label1.Caption := 'A';
    end;
    
    procedure TForm2.DoFormStuff;
    begin
      // use Self as needed...
    end;