动态Delphi表单创建 - 确保正确的鼠标消息处理

Bri*_*ost 2 delphi message-queue tform

我的应用程序布局基于左侧的treeView和右侧的面板.该面板托管一个不同的TForm类,具体取决于所选的树节点(一种'形式浏览器').一次只显示一个表单,该表单公开存储在别处的基础数据,并在每个新的树节点点击时创建和销毁表单实例.

除了以下场景外,这一切都正常.单击表单上的一个按钮,该按钮启动需要一秒左右的操作.在此操作期间,可能会调用Application.ProcessMessages.现在,在此操作实际完成之前,用户单击一个新的树节点.处理此wmMousedown消息,导致表单立即释放.然后,操作代码返回到表单代码,以查找自己已更改并导致AV.

我的问题是,在我允许表单被释放之前,有没有办法知道表单的消息已经全部处理完毕?单击关闭按钮时,模态窗体似乎会执行此操作,因为如果忙,它们会在关闭之前暂停...

谢谢Brian

Del*_*ics 7

不惜一切代价避免使用Application.ProcessMessages!

我看到的最常见的不恰当用法是允许重新绘制GUI,例如在更新标签标题之后.确保更新GUI的最安全方法是使用Update方法显式重绘任何受影响的控件(绕过绘制消息并使控件直接重绘).或者它可能是刷新方法 - 或者它可能是其中之一或两者!可悲的是,我永远无法忘记我的头脑!

Application.ProcessMessages会导致您发现的"重入"问题,在您的代码中有效地创建潜在的新的,短暂的"主要消息循环",这可能导致难以诊断并且难以重现问题.

在这种情况下,我会检查Application.ProcessMessages的使用,看看是否有一种替代方法无法从代码中消除它的使用,而不是试图修补许多其他代码只是为了解决应用程序的问题.ProcessMessages原因.

注意:该规则的一个例外是,使用Application.ProcessMessages维护"progress"消息/对话框中"Cancel"按钮的响应性是相对安全的,只要该进度消息/对话框是模态的,其余的应用程序被禁止,同时提出该对话框,让说"取消"按钮可以可以对任何消息做出响应