开发者

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, thi开发者_如何转开发s 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 )


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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜