You cannot create the notorious thread-unsafe form of VCL in this way (note - this is not only Delphi - all GUI work that I have seen has this limitation). Either use TThread.Synchronize to signal the main thread to create the form, or use some other signaling mechanism such as the PostMessage () API.
In general, it is best to try to save the contents of the GUI from secondary threads as much as possible. Secondary streams are best used for I / O without using a graphical interface (GUI) and / or CPU (especially if they can be split and executed in parallel).
PostMessage example (there is only one speed on it):
unit mainForm; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons; const CM_OBJECTRX=$8FF0; type EmainThreadCommand=(EmcMakeBlueForm,EmcMakeGreenForm,EmcMakeRedForm); TformMakerThread = class(TThread) protected procedure execute; override; public constructor create; end; TForm1 = class(TForm) SpeedButton1: TSpeedButton; procedure SpeedButton1Click(Sender: TObject); private myThread:TformMakerThread; protected procedure CMOBJECTRX(var message:Tmessage); message CM_OBJECTRX; end; var Form1: TForm1; ThreadPostWindow:Thandle; implementation {$R *.dfm} { TForm1 } procedure TForm1.CMOBJECTRX(var message: Tmessage); var thisCommand:EmainThreadCommand; procedure makeForm(formColor:integer); var newForm:TForm1; begin newForm:=TForm1.Create(self); newForm.Color:=formColor; newForm.Show; end; begin thisCommand:=EmainThreadCommand(message.lparam); case thisCommand of EmcMakeBlueForm:makeForm(clBlue); EmcMakeGreenForm:makeForm(clGreen); EmcMakeRedForm:makeForm(clRed); end; end; function postThreadWndProc(Window: HWND; Mess, wParam, lParam: Longint): Longint; stdcall; begin result:=0; if (Mess=CM_OBJECTRX) then begin try TControl(wparam).Perform(CM_OBJECTRX,0,lParam); result:=-1; except on e:exception do application.messageBox(PChar(e.message),PChar('PostToMainThread perform error'),MB_OK); end; end else Result := DefWindowProc(Window, Mess, wParam, lParam); end; var ThreadPostWindowClass: TWndClass = ( style: 0; lpfnWndProc: @postThreadWndProc; cbClsExtra: 0; cbWndExtra: 0; hInstance: 0; hIcon: 0; hCursor: 0; hbrBackground: 0; lpszMenuName: nil; lpszClassName: 'TpostThreadWindow'); procedure TForm1.SpeedButton1Click(Sender: TObject); begin TformMakerThread.create; end; { TformMakerThread } constructor TformMakerThread.create; begin inherited create(true); freeOnTerminate:=true; resume; end; procedure TformMakerThread.execute; begin while(true) do begin postMessage(ThreadPostWindow,CM_OBJECTRX,integer(Form1),integer(EmcMakeBlueForm)); sleep(1000); postMessage(ThreadPostWindow,CM_OBJECTRX,integer(Form1),integer(EmcMakeGreenForm)); sleep(1000); postMessage(ThreadPostWindow,CM_OBJECTRX,integer(Form1),integer(EmcMakeRedForm)); sleep(1000); end; end; initialization Windows.RegisterClass(ThreadPostWindowClass); ThreadPostWindow:=CreateWindow(ThreadPostWindowClass.lpszClassName, '', 0, 0, 0, 0, 0, 0, 0, HInstance, nil); finalization DestroyWindow(ThreadPostWindow); end.