有没有一种绝对安全的方法来释放 Delphi 控件?
我有一个 TStringGrid 的子类,我正在其中“嵌入”一个自定义控件以进行原地编辑。当用户通过 Tab 键或箭头键在网格单元格之间导航时,如果单元格可编辑,我需要创建一个动态控件。我已经钩住了所需的事件,并利用我的自定义控件的 OnKeyDown 事件将导航键传回父 TStringGrid。
以前,TStringGrid 子类只会对嵌入的控件调用 FreeAndNil,但在某些情况下,这会导致在 UpdateUIState/GetParentForm 中出现访问冲突。查看调用堆栈,似乎有时在控件被释放后,仍会发生 WM_KEYDOWN (TWinControl.WMKeyDown) 消息。
我已经查看并实施了如何在其事件处理程序中释放控件?中讨论的更改。这似乎解决了问题,但我想知道是否还有其他注意事项。
实际上,这种解决方法只是延迟了控件的销毁,直到 CM_RELEASE 消息发布时队列中的所有现有消息都被处理完毕。
我有一个 TStringGrid 的子类,我正在其中“嵌入”一个自定义控件以进行原地编辑。当用户通过 Tab 键或箭头键在网格单元格之间导航时,如果单元格可编辑,我需要创建一个动态控件。我已经钩住了所需的事件,并利用我的自定义控件的 OnKeyDown 事件将导航键传回父 TStringGrid。
以前,TStringGrid 子类只会对嵌入的控件调用 FreeAndNil,但在某些情况下,这会导致在 UpdateUIState/GetParentForm 中出现访问冲突。查看调用堆栈,似乎有时在控件被释放后,仍会发生 WM_KEYDOWN (TWinControl.WMKeyDown) 消息。
我已经查看并实施了如何在其事件处理程序中释放控件?中讨论的更改。这似乎解决了问题,但我想知道是否还有其他注意事项。
实际上,这种解决方法只是延迟了控件的销毁,直到 CM_RELEASE 消息发布时队列中的所有现有消息都被处理完毕。
我能否在CM_RELEASE被发布后,消息队列中已经有另外的WM_KEY*或类似的消息?
我的当前CM_RELEASE处理程序如下:
procedure TMyCustomControl.HandleRelease(var Msg: TMessage);
begin
Free;
end;
那么,在所有情况下,这是否安全?或者我应该做一些清除队列中其他消息的操作?( SendMessage(Self.Handle,WM_DESTROY,0,0) 很容易想到)