Delphi: release dynamic control at runtime

Is there a safe way to release a Delphi control?

I have a descendant of TStringGrid, which I "embed" in it a custom control for the inplace editor. When the user moves inside the grid cells using the tab key or the arrow keys, I need to create a dynamic control if the cell is editable. I hooked up the necessary events and use the OnKeyDown event of my custom control to pass the navigation keys back to the parent TStringGrid.

Previously, a descendant of TStringGrid simply called FreeAndNil in the built-in control, but in some circumstances this can lead to access violations inside UpdateUIState / GetParentForm. Looking at the call stack, it seems that sometimes after the control was free, the WM_KEYDOWN message (TWinControl.WMKeyDown) still occurred.

I have reviewed and implemented the changes described in How to release control inside my event handler? . This seems to have solved the problem, but I wonder if there is any other strip for this approach.

In fact, this workaround simply delays the destruction of the control until all existing messages in the queue are sent when the CM_RELEASE message is sent.

Wouldn't it be possible that after the publication of CM_RELEASE, another WM_KEY * message or a similar message was sent to the message queue?

My current CM_RELEASE handler looks like this:

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

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

+3
source share
2 answers

In general, you should not destroy a control in the event handler of that control.

But since your function is a simple non-virtual message handler that is never called from the internal code in this control, you should be fine. I don’t like too much in terms of style, but I think this is normal for your use case.

But a custom post may be cleaner.

Wouldn't it be possible that after the publication of CM_RELEASE, another WM_KEY * message or a similar message was sent to the message queue?

If the messages in the queue cause big problems, you can never safely destroy the control, as messages can be sent from other threads and applications. Just make sure that the correct functioning of your application does not depend on what messages are processed in each case.

0
source

SendMessage sends a message and waits for it to return, so you cannot use it safely in the event handler of the control that you release.

PostMessage, on the other hand, will send a message and will be processed after the event is issued (if there is no more code in the event).

0
source

Source: https://habr.com/ru/post/1412671/


All Articles