在Delphi中单击任务栏按钮时,将表单置于其他人之上

时间:2009-07-20 10:25:03

标签: windows delphi vcl lost-focus

基本问题:TStatusBar flickers when calling Update procedure. Ways to painlessly fix this

执行的代码在问题首先发布第一部分(你可以看到浅灰色分隔线)......

但问题是,在执行此代码时,表单不会自动激活并专注于所有其他应用程序的顶部。

我读过这些文章:

http://www.installationexcellence.com/articles/VistaWithDelphi/Original/Index.html
http://delphi.about.com/od/formsdialogs/l/aa073101b.htm

但据他们说,无论如何都应该有效。我用Show尝试了所有TApplicationEvents和TForm事件;可见:重绘;刷新; BringToFront; ......什么都行不通。

所以 - 我想我有两个选择 - 多线程或捕获WM_SYSCOMMAND消息,而在SC_ACTIVE事件中只需重新绘制表单。这种情况会成功吗?

1 个答案:

答案 0 :(得分:4)

您所链接的文章都没有解决您遇到的问题。您看到的是不处理Windows消息的程序的行为,因此它不会重绘无效的部分,也不会对键盘或鼠标输入作出反应(例如,使用鼠标移动或调整大小,或者激活应用程序使用任务栏按钮)。

在您的代码中,您调用了StatusBar1.Update,因此至少会重新绘制状态栏文本,但除了进入前台之外,您的应用程序可能还会忽略移动或调整请求大小。

您需要及时处理Windows消息,因此任何超过200或300毫秒的执行路径都需要确保处理消息,否则应用程序将显示无响应或挂起。

您基本上有三种选择:

  • 保留长时间运行的代码,并插入Application.ProcessMessages的调用 - 这将允许处理Windows消息。确保不再输入代码,例如禁用用于启动操作的所有控件。

  • 以一种显示为一系列步骤的方式重新编写代码,每个步骤不超过10毫秒。在Timer事件处理程序中调用代码,或者从Application.OnIdle处理程序调用它。

  • 在工作线程中调用您的代码,并将消息发布到主GUI线程以更新您的UI。

所有这些选项都有各自的优点和缺点,对于多线程,尤其是SO上已经有很多问题和答案。当你从事的不仅仅是玩具项目时,这是最困难但最好的选择。