一位同事多年来一直使用自定义AVI来表示长时间运行的进展情况。它总是很好。
最近他决定从Delphi 7迁移到Delphi 2007,部分原因是为他的应用程序提供主题支持。 (我们终于得到了大多数人,但不是全部,在XP上运行。)动画停止了工作。禁用主题会使其再次发挥作用。
TAnimate是Windows动画控件的包装器,使用InitCommonControlsEx(ICC_ANIMATE_CLASS)创建。 MSDN文档说“如果您使用的是ComCtl32.dll版本6,则不支持该线程,因此请确保您的应用程序不会阻止UI或动画不会发生。”显然,这是预期的行为。
是否有人建议解决此问题或替代此问题?他试图显示进度的处理并不适合产生一个单独的线程,并且由于显而易见的原因,Application.ProcessMessages也不是一个好的解决方案。
编辑:我正在给Rob Kennedy这个问题的正确答案,因为a)他为Raymond Chen关于这个主题的博客文章提供了“缺失的链接”(双关语),以及b)因为当然要把事情转移到一个单独的主题是正确的答案。具有讽刺意味的是:他正在进行的阻止TAnimate的操作是我们使用的数据库引擎(Advantage Database Server或ADS)的索引操作。当他找到问题时,他没有提到他。
ADS支持使用TAdsDataSet.AdsRegisterCallbackFunction和TAdsDataSet.AdsClearCallbackFunction方法进行回调。回调函数既提供当前操作的进度(百分比),也提供通过函数返回值取消操作的方法。所以整个问题都没有实际意义;回调函数可用于更新进度条,向用户指示应用程序未挂起。
答案 0 :(得分:6)
Raymond Chen has written about this.他甚至没有触及我通常认为的线程控制无法正常工作的主要原因,即线程不应该在与不同的窗口关联的窗口上绘制线程。
我鼓励你的同事重新审视那些让他决定不能把任务放到一个单独的线程中的东西。阻止主UI线程并不是一个好主意,无论是否有动画控制来掩盖无响应。
答案 1 :(得分:1)
作为TThreads的替代方案,您可以使用AsyncCalls,从功能角度提供更简单的多线程处理入口点。尽管如此,处理此问题的最佳方法是在后台执行长时间的过程以保持应用程序的响应。