当我的用户界面冻结时,为什么我的表单会出现在屏幕顶部?

时间:2014-09-11 09:30:12

标签: forms delphi freeze

我对delphy XE2应用程序中的表单有一点问题:

这是一个关于这个应用程序的老问题,我已经开始研究它了一段时间。

当用户选择使用按钮事件启动流程时,我的应用程序会启动与OPCServer,SQLServer的连接并构建表单,以便在两个服务器上获取良好的数据。

我的表单的构造涉及界面的阻塞(大约15秒),因为制作它所需的大量数据。

当它冻结时,如果用户想要拖动表单,她会走远,并且通常使用TMainMenu离开屏幕。在那之后,我们无法使用该应用程序,因为我们无法拖动,我们需要关闭并重新打开。

在旧版本中,表单已经在连接之前构建。因此,对动态表单的修改不会与此问题相关联。

我的活动:

    -Open connexion with OPC Server  
    -Open SQL Connexion  
    -Send SQL Command Text  
    -FieldByName('') for update my UI (Button.Caption// TPage.TStaticText.Caption // TPage.Label1.Caption)  
    -FieldByName('') for update an array of record  
    -Close SQL Connexion
    -Open SQL Connexion
    -Send SQL CommandText
    -FieldByName('') for update an other array of record  
    -Panel.Visible(false)  
    -TPage.Panel.Show;  
    -TPage.Panel.BringToFront;

所以我没有修改过MainForm会改变它的位置。

我是一名年轻的开发人员,所以我不知道为什么要搬家以及我可以为修理做些什么......

如果你想要一部分代码,问我什么,我编辑它,它很长,我不想要垃圾回答。

感谢阅读。

1 个答案:

答案 0 :(得分:2)

您的问题的核心是您有一个冗长的进程(表单构造),它完全阻止主线程,因此您的应用程序无法同时处理正常的Windows消息。这就是为什么当您移动应用程序时,它无法正确更新其界面。

现在根据您的描述,您已将此表单构建过程拆分为多个步骤,以便您可以在它们之间调用Application.ProcessMessages

这将强制您的应用程序更新其UI部分。

但要注意,调用Application.ProcessMessages通常会对应用程序性能造成很大影响。为什么?它通常是一个漫长的过程,因为它会强制您的应用程序处理其队列中的所有消息 通常情况下,并非所有这些消息一到达就会得到处理。 Windows按优先级列表将它们分组到消息队列中,确保尽快处理像WM_PAINT这样的高优先级消息,同时确保一些其他低优先级消息,例如要求应用程序响应OS,以便操作系统可以查看是否应用程序仍在工作时,大多数是在应用程序空闲或排队等待一段时间时处理的 这就是为什么Application.ProcessMessages可能会如此缓慢,因为它会强制您的应用程序处理所有消息而不管其优先级如何。

另外请记住,在某些情况下使用Application.ProcessMessages实际上会变得有点危险 我举个例子:
让我们说点击一个按钮开始一个漫长的工作,这可能需要一些时间才能完成。现在,为了让您的表单更新,请在特定时间间隔内致电Application.ProcessMessages。到目前为止一切都很好。但是,如果用户再次点击该按钮会发生什么? 由于您正在调用Application.ProcessMessages,强制您的应用程序处理所有消息,因此单击按钮会创建一条MouseClick消息,然后触发按钮OnClick事件,然后执行已OnClick方法最后分配给按钮OnClick事件,这将导致在第一次按钮点击时执行的相同方法再次执行。

所以现在你可以通过第一次按钮点击完成此方法,并且再次执行相同的方法以进行第二次鼠标点击。现在,从第二次单击执行的方法将首先完成,然后从第一次按钮单击开始但被Application.ProcessMessages中断的方法处理第二次按钮单击将继续执行到最后。
这一切都可能导致难以跟踪的奇怪错误,因为您作为程序员通常不会预测您的最终用户可能已经两次点击该按钮。

为避免这种情况,我强烈建议您实施一些安全措施,以通过暂时禁用按钮来防止出现这种情况。
但最好的解决方案始终是向用户显示您的应用程序正在运行,这在大多数情况下会阻止他们再次点击按钮,但遗憾的是并非总是如此。

在动态构建表单时,您还应该特别小心,只有在成功构建了所有控件之后才能启用控件。如果不这样做,用户可能会点击您的某个控件,该控件可能会尝试访问当时尚未创建的其他控件。结果很难跟踪导致访问冲突的错误。

您可能还会考虑在开始时显示启动画面而不是半打造的表单。为什么呢?
一旦它看起来好得多,它会告诉用户稍等一下。第二个主要形式隐藏,直到它完全创建,确保用户不会过早地点击它。