Question

There's a container control, a TScrollBox, that parents multiple item controls.

Every item control, being compound itself, contains (parents & owns) a delete button. Pressing the button initiates the deleting of the item control.

The deleting involves freeing the component and so the actual operation should be extrinsic with regard to the item. The question is, what would be the best way to do it?

I actually know of a couple of options:

  • a timer with a small interval (which is started with the button click);
  • a hidden outside button (to which the mouse down & up messages are posted);
  • the form's custom message handler.

While I could confidently implement any of those methods, as I flatter myself, I'm not sure which one would be best. Besides, the timer option seems childish, the hidden button one hackish, and the custom message one a bit overkill. In short, all three seem equally half-acceptable, more or less.

I may simply be prejudiced and don't mind being convinced to the contrary. Still most of all I would like to know what is a common method to use in such cases (maybe something I've been missing all the time).

Was it helpful?

Solution

The normal approach is to post a message to the control that is to be freed. See how TForm.Release is implemented for example. In fact I see no reason why you can't even re-use the CM_RELEASE message.

The point about posting the message is that is goes to the back of the queue and only gets processed once any synchronous messages (i.e. those delivered by SendMessage) have completed processing. This avoids calling methods on an object after it has been freed which is obviously an error that you are clearly well aware of.

OTHER TIPS

First, I would suggest that you write a custom control that inherits from TScrollBox, and that you provide the sub-control instantiation and removal as a feature inside that scroll box, and not something done "out there in the open" in your form. This code would go in its own unit, and only the public elements of it will be visible outside. That's just object oriented basics.

Secondly, if you are removing (deleting) controls from a scroll box, a Timer is just a source of chaos. It is possible that if you have also subclassed every control you put into that container, that you could use the mechanism used by TForm.Release(it sends them CM_RELEASE messages), and implement CM_RELEASE in a way that controls delete themselves when sent this message, however I find this ugly, except in the case of Edit controls that are destroyed when they lose focus.

I would directly delete these methods, without recourse to a timer, by subclassing both the TScrolLBox class, and any other classes that I want to put into it, and then having the removal of a control be handled by the parent object (TScrollBox), rather than by outside manipulation of any kind.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top