关于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的问题的主要内容,如果未能解决你的问题,请参考以下文章