Delphi: Freeing a dynamic control at runtime

Is there a failsafe way of freeing a Delphi control?

I have a TStringGrid descendent which I am "embedding" a custom control in it for an inplace editor. When the user navigates within the cells of the grid via the tab key or arrow keys, I need to create a dynamic control if the cell is editable. I have hooked the needed events and am utilizing the OnKeyDown event of my custom control to pass the navigation keys back to the parent TStringGrid.

Previously, the TStringGrid descendent would simply call FreeAndNil on the embedded control, but under some circumstances this would cause access violations inside of UpdateUIState/GetParentForm. Looking at the call stack, it appears that sometimes after the control was free'd, a WM_KEYDOWN (TWinControl.WMKeyDown) message was still happening.

I've all ready looked at and implemented the changes discussed in How to free control inside its event handler?. This appears to have resolved the issue, but I am wondering if there are any other cavet's to this approach.

In effect, this workaround has simply delayed the destruction of the control until after all the existing messages on the queue at the time the CM_RELEASE message was posted.

Would it not be possible that after the CM_RELEASE was posted, another WM_KEY* or similar message could all ready have been posted to the message queue?

My current CM_RELEASE handler looks like:

procedure TMyCustomControl.HandleRelease(var Msg: TMessage);
begin
  Free;
end;

So, will this be safe in all instances or should I do something to clear any other messages from the queue? ( SendMessage(Self.Handle, WM_DESTROY, 0, 0) comes to mind )

Answers


In general you should not destroy a control in an event-handler of that control.

But since your function is a plain non virtual message handler which is never called from internal code in that control you should be ok. I don't like too too much from a style point of view, but I think it's ok for your use-case.

But a custom message might be cleaner.

Would it not be possible that after the CM_RELEASE was posted, another WM_KEY* or similar message could all ready have been posted to the message queue?

If messages in queue would cause big problems you could never safely destroy a control since messages can be posted from other threads and applications. Just make sure the correct functioning of your application doesn't depends on those messages being handles in every case.


SendMessage sends the message and wait for it to return, that's why you can not use it safely in the event handler of the control you are freeing.

PostMessage in the other hand, will send the message and will be processed after the event exits (if there are no more code in the event).


Need Your Help

Java database driver not found, even though it's in the jar file

java sql-server maven intellij-idea jar

I have a Java application that connects to a SQLServer database, and it is intended to run at the commandline. In the maven dependencies I have added the following:

extract line from javascript

javascript jquery

I need to extract this line of code from a script i am retrieving via ajax..

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.