谁在设计时绘制 TTimer?
Posted
技术标签:
【中文标题】谁在设计时绘制 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
视觉控件,它会用图标绘制框,并通过一些链接属性与组件实例绑定。以上是关于谁在设计时绘制 TTimer?的主要内容,如果未能解决你的问题,请参考以下文章