6

谁在设计时绘制 TTimer?

在使用 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 的设计时间外观。

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

在 StackOverflow 的其他地方,有人问是否可以在运行时加载 .dfm 文件。有人回答:“不,不可能”

但这并不完全正确。我已经编写了一些代码来做到这一点:从磁盘加载“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 的表单设计器中一样可见?

4

1 回答 1

5

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

谁在设计时绘制 TTimer?

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

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

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

于 2014-04-19T19:18:02.953 回答