Yes, you should null out any references you have to the dead Frame object (this is especially imporrtant if you target ARC platforms). In which case, I would probably do something more like this instead:

[bccaarm Error] UnitDibocca.cpp(38): no member named 'ForceQueue' in 'System::Classes::TThread'[bccaarm Error] UnitDibocca.cpp(38): 'Frame1' cannot be captured because it does not have automatic storage duration UnitFrameMessage.h(31): 'Frame1' declared here

Lena wrote:[bccaarm Error] UnitDibocca.cpp(38): 'Frame1' cannot be captured because it does not have automatic storage duration

Hmm... I'm not sure what to make about that one. My lambda kung-fu is not so good.

Frame1 is an object pointer, so a lambda should be able to capture it by value. On the other hand, object pointers in Android are ARC-enabled, so that is probably interfering with the capture. Or, it could just be the fact that Frame1 is not a local variable to FrameButtonClicked() to begin with, so it doesn't need to be captured at all.

Lena wrote:Problem still exists: I see my Frame. When I press Button1Click on my Frame nothing happens. The frame does not disappear. Were my mistake?

Well, did you verify that the code is even TRYING to do something? Did you verify that Button1Click() is being called, and thus FrameButtonClicked() is being called? That TThread::Queue() is calling DisposeOf()? This is basic debugging stuff.

Lena wrote:1. Why we use TThread for delete Frame?

You need to free the TFrame object in a delayed manner after its Button1Click() handler has exited first. To ensure that no code is still trying to access the TFrame object when/after it is destroyed. Since you are using a version of C++Builder that doesn't support TThread::ForceQueue(), we have a TThread::Queue() alternative, except that TThread::Queue() is not delayed when called in the main UI thread, so we call it in a worker thread instead. TThread::ForceQueue() would have avoided the need for that worker thread.

Lena wrote:2. Do we need FreeOnTerminate = true?

TThread::CreateAnonymousThread() creates a TThread object that has FreeOnTerminate=true set.

Lena wrote:3. Frame1->DisposeOf() I read what could be better Frame1->Release()???

Oh yeah, I keep forgetting that all TFmxObject-derived objects (like TFrame) have a Release() method in FMX (whereas only TForm has it in VCL). Well, in that case:

On the other hand, TFmxObject::Release() has been officially deprecated in 10.2 Tokyo, with no official word on what it should be replaced with. So, best to just design your code to account for that now, in case you decide to ever upgrade to Tokyo+ later. Of course, if you did upgrade, then you would have access to TThread::ForceQueue() and wouldn't have to worry about this threading issue anymore.

Frame1 = new TFrame1(this); Frame1->Parent = this; Frame1->Label1->Text = L"Sorry, there is no connection to the server."; Frame1->OnButtonClick = &(Form1->FrameButtonClicked); //&FrameButtonClicked; //ShowMessage(L"Sorry, there is no connection to the server."); }

Lena wrote:I use Indy. Can I creation TFrame in an event ThreadTerminated?

The TThread::OnTerminate event is synchronized with the main UI thread by default. So yes, you can do whatever you want with your UI (you are already doing it with Button2 and AniIndicator1). That has nothing to do with Indy.

On the other hand, your OnTerminate handler is Close()'ing the same Form that you are setting as the Parent for your TFrame, so the user won't get a chance to see your error message. Maybe you meant to use Form1 as the Parent instead?

Because it is not safe to immediately 'delete' an object while you are inside an event handler that is owned by that same object. The RTL still needs access to the object after the event handler exits. So the 'delete' needs to be deferred to a later time when the object is not being accessed anymore.

If you read the discussion more carefully, you will see that 1) calling Release() is one of the proposed solutions, since Release() is a deferred 'delete', and 2) Release() is deprecated in 10.2 Tokyo.

ingalime wrote:Or should I must use always TNotifyEvent OnButtonClick for delete TFrame in FMX?

If you read the discussion more carefully, you will see that the OnButtonClick event was being used because the Frame1 object pointer is owned by another object (the MainForm), so while the TFrame1 object *could* Release() itself, the reference to the released TFrame1 object still needs to be nulled out. Letting the MainForm decide how to manage its TFrame1 object pointer is a better choice from a design perspective.

ingalime wrote:Another question. Do I need to do extra checks when delete TFrame?

Not in the example in this discussion, since OnButtonClick is fired by the TFrame1 object, so the MainForm's Frame1 object pointer should never be null when the OnButtonClick event is fired. And you don't need to set the Parent to null before calling Release().