关于delphi中Ttimer的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于delphi中Ttimer的问题相关的知识,希望对你有一定的参考价值。

var Form2: TForm2; len:integer; i:integer=0; implementation $R *.dfm procedure TForm2.Button1Click(Sender: TObject); begin progressbar1.Position:=0; richedit2.Lines.Clear; timer1.Enabled:=true; label1.Caption:='正在拷贝数据,请稍等...' ; label1.Visible:=true; i:=0 end; procedure TForm2.FormCreate(Sender: TObject); begin richedit1.Lines.LoadFromFile('E:\编程\据说是世界编程大赛第一名写的程序.txt'); len:=length(richedit1.Text); end; procedure TForm2.Timer1Timer(Sender: TObject); var part_len:integer; begin part_len:=len div 100; richedit2.Text:=copy(richedit1.Text,i,part_len); i:=i+part_len; progressbar1.Position:=progressbar1.Position+1; if i>len then begin timer1.Enabled:=false; label1.Caption:='数据拷贝完毕'; end; end; end. 我想知道: 1.timer是怎么工作的? 2.i为什么会大于len呢,part_len不是已经除以100了吗?应该永远小于len才对啊?

参考技术A 1:
Timer
有个这个属性,Interval
,
是毫秒数,这个程序估计设计的是等于1000的,就是当
timer1.Enabled:=true;
的时候,每隔1秒就会调用Timer1Timer函数
2:
这个程序设计的思路是把一个文件读入,然后分100份,copy到
richedit2中,在copy过程中做了一个进度条.
每隔一段时间(Timer
的Interval
值)就复制一点,同时进度条前进一步,
,
part_len

总长度len的1/100,
i
初始为0
,每次加上
part_len,也就是说大概
Timer1Timer执行100次的时候,
满足
if
i>len
then
条件,
Timer控件停止.

谁在设计时绘制 TTimer?

【中文标题】谁在设计时绘制 TTimer?【英文标题】:Who paints TTimer at design time? 【发布时间】:2014-06-04 03:32:57 【问题描述】:

在使用 Delphi IDE 的表单设计器时,当您在表单上放置一个 TTimer 时,该组件在设计时可见(当然,在运行时不可见)。

TTimer 类是在单元 ExtCtrls 中定义的,所以我当然确实阅读了该单元中的 TTimer 源代码。

我期待看到这样的东西:

procedure TTimer.Paint;
begin
  if csDesigning in ComponentState then
    with Canvas do
    begin
      // Paint the design-time appearance of TTimer here:

      // ... code ...

    end else begin end; // no painting at runtime.
end;

但我很惊讶没有看到这样的代码!

TTimer 组件有这个私有字段:FWindowHandle: HWND;,但它仅用于接收来自 windows 本身的 WM_Timer 消息。它不用于绘制任何东西,即使在设计时也是如此。也没有画布。

在阅读 TTimer 源代码时,我找不到任何与设计时绘画相关的内容。

所以问题是:在 Delphi IDE 本身的表单设计器中,负责在表单上绘制 TTimer 的设计时外观的代码和位置。

现在,如果有人想知道我为什么要问这个问题,这里有一些相关信息:

在 *** 的其他地方,有人询问是否可以在运行时加载 .dfm 文件。有人回答:"No, it is not possible"。

但这并不完全正确。我已经编写了一些代码来做到这一点:从磁盘加载“someform.dfm”并在运行时创建这样的表单。这是可能的,但麻烦的是你需要编写这样的代码:

procedure RegisterNecessaryClasses;
begin
  RegisterClass(TfrmDynaForm);
  RegisterClass(TPanel);
  RegisterClass(TMemo);
  RegisterClass(TTimer);
  RegisterClass(TListBox);
  RegisterClass(TSplitter);
  RegisterClass(TEdit);
  RegisterClass(TCheckBox);
  RegisterClass(TButton);
  RegisterClass(TLabel);
  RegisterClass(TRadioGroup);
end;

这只是第一个示例,它可以让我加载并呈现一个特定的表单而不会出错。但是,只要其他表单包含,例如:TSpeedbutton,则需要编辑上述程序以添加此行:

  RegisterClass(TSpeedbutton);

跳过那个,你会得到一个“找不到类 Txxx”的异常。

另一个问题是,即使我添加了代码以查找要加载的 dfm 中的任何 TTimer 组件,并且我在该 TTimer 实例的 ComponentState 中手动设置了 csDesigning,TTimer 仍然保持不可见。

那么我需要做什么(其他)才能使 TTimer 像在 Delphi IDE 的表单设计器中一样可见?

【问题讨论】:

直接TComponent后代(非可视组件)不支持绘图。 Delphi IDE 的表单设计器负责处理非可视组件(包括其绘图),如果您想要类似的东西,请制作一个可视组件,该组件将绘制一个带有设计时图标的类似框。 请注意,绘画仅以继承树上的TControl开头。 尽管您做出了解释努力,但我没有看到在运行时加载 DFM 时绘制 TTimer 组件的原因。 【参考方案1】:

非可视组件没有Paint 方法,因此无法自行绘制。

谁在设计时绘制 TTimer?

IDE 绘制非可视组件的表示。

那么我需要做什么(其他)才能使 TTimer 像在 Delphi IDE 的表单设计器中一样可见?

您必须在代码中绘制它。非可视组件不会自己绘制。

【讨论】:

“你必须在你的代码中绘制它。”,这很模糊,听起来有点像你可以创建一个子类并覆盖 Paint 方法(哪个 OP预计会找到)。尝试从非可视组件中进行可视化控制(像表单设计器一样具有焦点和拖放支持)需要的远不止这些。我能想到的最简单的方法是制作一些TNonVisual 视觉控件,它会用图标绘制框,并通过一些链接属性与组件实例绑定。

以上是关于关于delphi中Ttimer的问题的主要内容,如果未能解决你的问题,请参考以下文章

谁在设计时绘制 TTimer?

Delphi实现菜单项上出现提示

TTimer 作为组件属性问题

delphi程序问题

delphi多线程参数传递问题

delphi 窗体移动事件