0

I have problem when run a thread in subform.

main form

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Unit2;

procedure TForm1.Button1Click(Sender: TObject);
begin
TForm2.create(form1).ShowModal;
end;

SUBform

type
TMthread=class(Tthread)
protected
procedure execute; override;
end;
type
TForm2 = class(TForm)
    Label1: TLabel;
    procedure FormShow(Sender: TObject);
  private
  public
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

uses Unit1;

procedure TMthread.Execute;
begin
  synchronize( procedure 
               begin 
                 sleep(200);
                 freeonterminate:=true;
                 sleep(200);
                 form2.label1.Caption:='beep';
                 form1.button1.Caption:='beep'; 
               end);
end;

procedure TForm2.FormShow(Sender: TObject);
var Loadcombo2: TMthread;
begin
  Loadcombo2:=TMthread.Create(False);
end;

Program

program Project1;

uses
  Vcl.Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

I got error in Execute Procedure when trying to access Form2.Label1.caption.

my test:

When I add the subform(Form2) in the Initialize section(last code) the the application runs without error, but doesn't change Label1.caption on the Form2.(Button1.caption on the main form is changed)

When I put exactly the same thread in main form it works without issues.

2
  • 1
    Do not rely on global variables for forms like Form1, Form2. These are normally used by auto-created forms, that means if Application.CreateForm is called. But what do you do if two instances of the forms exits? Or none is auto-created like in your code? Commented Nov 16, 2017 at 12:25
  • 2
    You say twice error, but not once do you tell us what error you got. It's on the screen right in front of you; unfortunately, we can't see your screen from where we're sitting. Yes, it's clear to us from looking at the code, but it won't be to someone who is searching for a solution to a problem in the future. Please include the error information in your question (and while you're making the edit to do so, you can also actually ask a question - your current post does not). Commented Nov 16, 2017 at 13:44

1 Answer 1

2

The variable Form2 is never assigned. Because it is a global variable, its value is nil. Thus you encounter an error when you attempt to reference members of Form2.

You create an instance of Form2 like this:

TForm2.Create(Form1).ShowModal;

I suspect that instead you mean to write something like this:

Form2 := TForm2.Create(Form1);
Try
  Form2.ShowModal;
Finally
  Form2.Free;
End;
Sign up to request clarification or add additional context in comments.

2 Comments

A better solution is to have TForm2.FormShow() pass its Self pointer to the thread's constructor and save it in a variable that Execute() can then use. Then you are not relying on the global Form2 variable anymore, and can have multiple TForm2 instances running in parallel, if desired
@Remy Fair. There are so many other issues with the code here that I couldn't face covering them all this time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.