我有一个带有TTimer(timAnimateDataChange)的TFrame(fraDisplay)。计时器用于控制小动画。在包含框架的表单中,我希望有一个方法可以执行以下操作:
procedure TForm.DoStuff;
begin
DoSomeLogicStuff;
fraDisplay.AnimateResult;
WaitForAnimationToFinish;
DoSomeOtherLogicStuff;
fraDisplay.AnimateEndResult;
WaitForAnimationToFinish;
fraDisplay.Finalize;
end;
动画基本上是由TImage32重绘,由计时器计时。完成后,计时器将自动禁用它,并且帧具有一个名为AnimationRunning的布尔属性,当动画结束时,该属性将设置为false。
没有任何线索或任何类似的东西可以使事情变得复杂或有帮助。
问题是,如何实现WaitForAnimationToFinish方法?
(顺便说一下,这不是一个好的解决方案:
procedure TForm.WaitForAnimationToFinish;
begin
repeat
Application.ProcessMessages;
until not fraDisplay.AnimationRunning;
end;
因为在方法运行时计时器不会触发:-( )
答案 0 :(得分:2)
Smasher's suggestion可以使用Delphi 2009的匿名方法实现。
procedure TForm.DoStuff;
begin
DoSomeLogicStuff;
fraDisplay.AnimateResult.OnFinished :=
procedure (Sender: TObject)
begin
DoSomeOtherLogicStuff;
fraDisplay.AnimateEndResult.OnFinished :=
procedure (Sender: TObject)
begin
fraDisplay.Finalize;
end;
fraDisplay.AnimateEndResult;
end;
fraDisplay.AnimateResult;
end;
BTW:实际上,WaitForAnimationToFinish会让OnTimer激活,因为它使用在调用ProcessMessages时调度的Windows消息。但无论如何它都是一个坏主意,因为它使用了大量的CPU而实际上并不需要它。
答案 1 :(得分:1)
当计时器自行禁用并将AnimationRunning
变量设置为False
时,您可以调用下一步应该执行的方法。
答案 2 :(得分:1)
一位斯洛文尼亚德尔菲同事程序员只写了你要找的代码 - Active Sleep。
答案 3 :(得分:0)
那么你的计时器正在做什么是漫长的,大约几秒钟?无论如何,不应该在主GUI循环中执行那种长时间运行的活动。也不应该等待:
当你等待动画完成时(如果可以的话),你的应用程序的其余部分将表现得像死程序,即它不会以任何方式响应GUI,包括调整大小,重绘,关闭 X 等
解决方案是将DoStuff方法分解为两个;一个启动计时器活动,另一个启动计时器完成。要完成后者,那个计时器应该在说再见之前调用你的第二种方法。
拉斯在组织榜样方面做得很好;考虑这本书与他的电影一起去:)答案 4 :(得分:0)
Make AnimateResults在完成后调用要调用的方法的参数。