3

我有一个带有 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;

因为在方法运行时计时器不会触发:-()

4

5 回答 5

2

Smasher 的建议可以使用 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 而实际上并不需要它。

于 2009-11-22T19:15:53.333 回答
1

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

于 2009-11-22T19:07:34.407 回答
1

一位斯洛文尼亚 Delphi 程序员编写了您正在寻找的代码 - Active Sleep

于 2009-11-23T08:17:13.510 回答
0

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

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

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

拉斯在整理一个例子方面做得很好。认为这本书与他的电影一起去:)

于 2009-11-22T19:18:32.340 回答
0

使 AnimateResults 接受完成时要调用的方法的参数。

于 2009-11-22T22:23:50.393 回答