2014-09-11 67 views
1

我在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

问题的核心是你有一个完整的阻塞主线程的进程(表单构造),因此ypu应用程序不能处理正常的Windows消息。这就是为什么当你移动你的应用程序时,它不会推动它的接口。现在基于你的描述,你已经将这个表单构造过程分成多个步骤,所以你可以在它们之间调用Application.ProcessMessages。这将迫使你的应用程序更新其UI部分。您也可以考虑在开始时显示启动画面而不是一半的内置窗体。 – SilverWarior 2014-09-11 10:11:29

+0

感谢您解决我的问题=) – Guillaume 2014-09-11 10:24:35

+0

@SilverWarior您可能想要发表该评论作为答案。 – 2014-09-11 12:55:36

回答

2

你问题的核心是你有一个完整的阻塞主线程的进程(表单构造),因此ypu应用程序不能处理正常的Windows消息。这就是为什么当你移动你的应用程序时,它不会推动它的接口。

现在根据你的描述,你已经把这个表单构造过程分成多个步骤,所以你可以在它们之间调用Application.ProcessMessages。

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

但要小心调用Application.ProcessMessages通常可能会损害您的应用程序的性能。为什么?它通常是一个简单的过程,因为它会迫使你的应用程序处理所有处于其队列中的消息。
通常,并不是所有这些消息都会在到达时处理得如此糟糕。 Windows通过它们的优先级列表在消息队列中对它们进行分组,确保像WM_PAINT这样的高优先级消息尽快得到处理,而其他一些低优先级的消息如应用程序的demmand以响应操作系统,以便操作系统可以查看应用程序是否仍然大多数情况下,处理应用程序的时候或者处于某个特定时间的情况下都会进行处理。因此,这就是为什么Application.ProcessMessages可以如此缓慢,因为它会强制您的应用程序处理所有消息的优先级。

还要记住,在某些情况下使用Application.ProcessMessages实际上会变得有点危险。
让我给你举个例子:
可以说,点击一个按钮可以让一个长时间工作完成。现在为了让表单得到更新,可以在特定的时间间隔内调用Application.ProcessMessages。到目前为止,这一切都很好。但是,如果用户点击该按钮,会发生什么?
由于您调用的Application.ProcessMessages强制您的应用程序处理所有消息,并且由于单击按钮会创建一个MouseClick消息,然后触发按钮OnCLick事件,然后执行最后分配给按钮OnCLick事件的OnCLick方法这将导致再次执行第一个按钮ckick上执行的相同方法。
所以现在你有这个方法部分地完成从第一次按钮点击和相同的方法executng agin第二次鼠标点击。现在,从第二次点击执行的方法将首先完成,然后从第一次按钮单击开始,但与处理第二次按钮单击的Application.ProcessMessages中断的方法将继续执行到最后。
这一切都可能导致难以追踪的奇怪错误,因为作为程序员,您通常不会预测您的最终用户可能已经点击了两次按钮。

因此,为了避免这种情况,我强烈建议您实施一些保护机制,以通过暂时停止按钮来防止此类情况。
但是最好的解决方案总是向用户显示你的应用程序正在工作,在大多数情况下它会阻止他们再次点击按钮,但不幸的是并不总是如此。

在动态构建表单以启用控件时,只有在所有控件已经成功构建后,您才应该小心。如果没有这样做,用户可能会点击你的某个控件,并且控件可能试图访问当时尚未创建的其他控件。难以追踪导致访问冲突的错误。

你也可以考虑在开始时显示启动画面而不是一半的内置窗体。为什么?
有一次,它更好看,它让你的用户等待一下。对于第二个隐藏的主窗体,它完全创建,以确保用户不会过早地进行任何操作。

+0

谢谢你的好解释。我已经解决了这个问题。 如何禁用表单移动?我在搜索这个问题的开始时没有找到... 我会按照您的劝告来提醒用户不耐烦。 再次感谢=) – Guillaume 2014-09-12 07:16:31

相关问题