Delphi 我如何等待一个TTimer完成?

Delphi 我如何等待一个TTimer完成?,delphi,animation,timer,wait,Delphi,Animation,Timer,Wait,我有一个带有TTimer(TimAnimatedAttachange)的TFrame(fraDisplay)。计时器用于控制小动画。在包含框架的表单中,我希望有一个方法可以执行以下操作: procedure TForm.DoStuff; begin DoSomeLogicStuff; fraDisplay.AnimateResult; WaitForAnimationToFinish; DoSomeOtherLogicStuff; fraDisplay.Animat

我有一个带有TTimer(TimAnimatedAttachange)的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;
由于计时器在方法运行时不会触发:-(
)

当计时器禁用自身并将
AnimationRunning
变量设置为
False
时,您可以调用接下来应该执行的方法。

可以使用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;

顺便说一句:实际上,WaitForAnimationToFinish会让OnTimer触发,因为它使用在调用ProcessMessages时发送的windows消息。但这是一个坏主意,因为它使用了大量CPU,而实际上并不需要它。

所以你的计时器所做的事情很长,大约几秒钟?这种长时间运行的行为无论如何,不应在主GUI循环中执行ivity。也不应等待:

当您等待动画完成时(如果可以的话),应用程序的其余部分将像一个死程序一样运行,即它不会以任何方式响应GUI,包括调整大小、重画、用X关闭等

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


拉尔斯做了一个很好的例子,考虑这本书和他的电影:“< /P> < P>制作动画材料时,采取一个方法的参数,当它完成的时候。”/ P> > P>一位斯洛文尼亚的德尔福程序员编写了你要找的代码。有几种方法需要暂停并等待动画完成。这听起来是个不错的建议。不幸的是,我还是在2007年:((至少还有几个月)这在没有匿名方法的情况下也能工作。只需要多一点代码:)不会太长。一秒钟左右。这实际上是垄断的一个小实现。动画是像动画的骰子滚动,移动代币等东西。没有花哨的图形,只有文本和彩色矩形的画布上,但一定数量的动画使游戏感觉更好。我有一个名为TGame的对象,它有一个名为FDisplay的属性,这就是我提到的帧。帧具有类似AnimateDieRoll和MoveToken的方法。