2009-11-22 98 views
3

我有一个带有TTimer(timAnimateDataChange)的TFrame(fraDisplay)。计时器用于控制小动画。在含有所述帧的形式我想有做了这样的方法:我该如何等待TTimer完成?

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; 

,因为尽管该方法可以运行:-( 计时器不会闪光)

回答

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时调度的窗口消息。但无论如何这是一个坏主意,因为它使用大量的CPU而不需要它。

+0

听起来像一个很好的建议。不幸的是,我仍然在2007年:-(无论如何,还有几个月的时间) – 2009-11-22 19:19:04

+0

这也适用于没有匿名方法,只需要多一点代码:) – 2009-11-22 19:21:20

1

当计时器自行禁用和设置AnimationRunning变量为False,您可以直接调用下一步应该执行的方法。

+0

我不知道下一个应该调用哪个方法。有几种方法需要暂停并等待动画完成。 – 2009-11-22 19:11:17

0

那么你的计时器正在做什么是很长的,大约几秒?无论如何,这种长时间运行的活动不应该在主GUI循环中执行。也不应该等待这样的:

当你等待动画完成(如果可以的话),你的应用程序的其余部分将表现得像死程序,即它不会以任何方式响应GUI,包括调整大小,重新绘制,使用X等关闭。

解决方法是将您的DoStuff方法分解为两个;一个启动定时器活动,另一个在定时器结束时执行。为了完成后者,该计时器应该在说再见之前调用你的第二种方法。

拉尔斯做了一个很棒的工作,考虑这本书去与他的电影:)

+0

不是非常冗长。一秒左右。这实际上是垄断的一个小实施。动画就像动画模具卷,移动令牌等。没有花哨的图形,只有文字和画布上的彩色矩形,但是一定数量的动画使游戏感觉更好。 我有一个名为TGame的对象,它有一个名为FDisplay的属性,这是我提到的框架。该框架具有诸如AnimateDieRoll和MoveToken的方法。 – 2009-11-22 19:40:13

0

使AnimateResults采取参数的方法被调用时,它完成。

1

斯洛文尼亚的一位斯德哥尔摩的程序员写了你正在寻找的代码 - Active Sleep