为什么表格移动效果不是第一次发生?

时间:2010-12-12 10:21:56

标签: delphi pascal

我正在使用此代码显示带有类似信使的弹出窗口的表单:

  TimeSleep := 5;

  for i := 1 to FormHeight do
  begin
    Form.Top := Form.Top - 1;

    Sleep(TimeSleep);
  end

它工作顺利,但仅限第二次。我的意思是我的表单上有一个按钮来调用循环,第一次单击表单突然显示没有滑动效果。如果我再次点击,效果会起作用。

我怎样才能让它第一次起作用?

感谢。

2 个答案:

答案 0 :(得分:2)

尝试添加“Application.ProcessMessages;”睡觉前。

答案 1 :(得分:2)

您没有发布足够的代码以确定它,但我认为您的表单在第一次单击按钮之前不可见或甚至没有窗口句柄,因此表单的移动不是不可见。如果你插入

Form.Show;
Form.Update;
循环之前的事情也应该是第一次。请注意对Update()的调用,需要真正显示在上一行中显示的表单。

类似地,你应该在更改到循环内的Update()属性后插入对Top的调用 - 它执行对Application.ProcessMessages()的调用也是如此,而不是这样的大锤。只要有更好的方法,尝试不使用Application.ProcessMessages(),请搜索Stack Overflow进行讨论。

关于你的循环的另外两条建议:

  • 如果有任何原因导致您的Sleep()超过您请求的5毫秒,则移动将不会平滑 - 计算表单顶部坐标的减少量与自此后经过的时间相比要好得多最后的动作。

  • 任何人都无法看到你的表格以1个像素的增量移动 - 人眼和大脑的速度不够快,无法以这个速度收集和处理信息,甚至你房间的猫和昆虫也只会请参阅显示器每秒60次更新。因此,Sleep()的参数为20或甚至50比5更明智。相应地调整表格移动。

修改

以下是一些示例代码,即使有不同的延迟,也会创建表单的持续移动:

uses
  MMSystem;

procedure TForm1.Button1Click(Sender: TObject);
var
  Frm: TForm;
  TicksStart, TicksNow: Longword;
  Progress: Single;
begin
  Frm := TForm.CreateNew(Self);
  try
    // slide a form of 600 by 500 pixel into view over a period of 100 millis
    Frm.SetBounds((Screen.Width - 600) div 2, -500, 600, 500);
    Frm.Show;

    TicksStart := timeGetTime;
    while True do begin
      Sleep(15);
      TicksNow := timeGetTime;
      if TicksNow - TicksStart >= 1000 then
        break;
      Progress := (TicksNow - TicksStart) / 1000;
      Frm.Top := - Round((1.0 - Progress) * 500);
    end;
    Frm.Top := 0;

    Sleep(500);
  finally
    Frm.Free;
  end;
end;