【问题标题】:Delphi: 'Property ClientHeight does Not Exist'Delphi:'属性 ClientHeight 不存在'
【发布时间】:2014-04-06 12:50:45
【问题描述】:

我的 Delphi 程序可以正常构建和编译,但是一旦在调试模式下运行,我就会收到以下错误;

属性 ClientHeight 不存在

查看所有 .DFM 文件源后,每种形式的代码都在那里;

客户端高度 = 111

我不明白我哪里出错了?

【问题讨论】:

标签: delphi properties height client dfm


【解决方案1】:

您的表单将使用较新版本的 Delphi 保存。不幸的是,您需要在 IDE 中打开每个表单并再次保存以清除较新的属性。有一个可以帮助您的工具称为 DFMCheck (http://andy.jgknet.de/blog/ide-tools/dfmcheck/)。这是一个附加组件,它将遍历您的所有表单,并告诉您仅在运行时显示的表单的任何问题。

您看到问题的原因是这样的。 Delphi 保存具有所有属性的表单。它使用流在运行时加载表单。当它尝试加载具有不存在属性的表单时,您将收到类似这样的错误,因为流系统试图在属性不存在时在组件上设置属性。

【讨论】:

  • 非常感谢您的帮助!我将不得不在星期四再次使用开发机器时尝试一下。
  • 如果您定期使用不同的 Delphi 版本并且其中一个保存 ClientHeight 和 ClientWidth 您可能会考虑使用 DDevExtensions(来自与 DFMCheck 相同的站点),您可以在 dfm 中禁用保存这些属性与旧版本兼容。
  • @Graymatter 我尝试再次保存表单,甚至使用 DFMCheck,但我仍然收到错误消息。这是我正在为一个名为 UCWin/Road 6 的程序开发的插件。当我在 Delphi 中调试时,由于插件没有消息,ucwinroad 崩溃了。但是,如果我构建插件然后将其导入 ucwinroad,我会收到一条错误消息,指出 TCPServerPlugin.ClientHeight: Property ClientHeight 不存在。我不知道该怎么做。
  • @Danny 你有哪个版本的 Delphi?
【解决方案2】:

我知道这是旧线程,但希望这将有助于其他有此问题的人。

在这种情况下,您的类继承自其他类并且您知道属性存在,只需重新发布它们。添加已发布部分并再次添加它们,例如:

published
property ClientWidth;
property ClientHeight;

然后强制编译器为父类可能具有前向声明的部分编译这些类型信息,从而解决您的问题。 希望它对某人有所帮助,我花了 3 天的时间才最终找到解决方案。

【讨论】:

    【解决方案3】:

    FMX 帧的现代 Delphi(例如 Rio 10.3)中也会发生同样的错误。经过一番调查,发现它是由调整 TFrame 继承引起的。示例如下:

    type
      // Declaration of custom type
      TFrameEx = class(TFrame) .. {here I override a couple of methods} end;
    
    // Causes a bug (described below)
    TMyFrame = class(TFrameEx)
    
    // Works fine
    TMyFrame = class(TFrame)
    

    说明:
    由于类型改变,Delphi 无法在 FMX 和 VCL 之间正确选择 TMyFrame 类型。因此,当在 IDE 中打开 TMyFrame 时,它​​会要求去除 FMX 属性(在 VCL 中不存在,例如 Size.Width)并添加 VCL 属性(例如 ClientWidth)。保存后,这会使 TMyFrame 出错 - 它会在初始化时在运行时显示“Property ClientHeight 不存在”错误。

    【讨论】:

    • 谢谢。除了不从 TFrame 子类型派生之外,还有其他解决方法吗?
    • @DavidU 我没有找到。这看起来像 IDE 错误,所以可能会在下一个版本中修复。谁知道呢。
    • 有趣的是,我在使用 C++Builder 2010 时遇到了同样的错误(使用派生的 Frame 类),我认为它早于 FMX。
    【解决方案4】:

    有类似的错误。首先,您的框架需要一个 dfm 文件。 继承框架时,dfm 文件必须以“inherited MyFrame: TFRameEx”而不是“object MyFrame: TFrameEx”开头。没有继承,当我这样做时,它正在添加 TForm 属性,并且在编辑器中框架有 TForm 事件,在 Delphi 10.3 中。所以delphi真的需要dfm来找到正确的类型。如果您使用 ide 菜单,它将自动完成。 New->Others->inheritables 它将使用继承的行创建 dfm,在其中创建一个包含 {$R *.dfm} 的文件,并在项目源中创建一行“unitname in '......pas' {我的框架 TFrame};"或者你可以手工完成。 至于在同一个单元中有多个帧的可能性,我自己还没有测试过,但是由于该行是 {$R *.dfm} 它可能是可行的。

    希望它是对克罗姆斯特解决方案的评论,但显然无法评论。

    【讨论】:

      【解决方案5】:

      在我的例子中,我继承了保存在 Delphi 7 中的 TFrame,我更改了 .dfm 来解析。

      第一行:"object" frmMain: TfrmMain

      我改成“继承”,像这样:inherited frmMain: TfrmMain

      【讨论】:

        猜你喜欢
        • 2021-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-21
        • 1970-01-01
        • 2021-01-17
        • 2019-05-04
        • 1970-01-01
        相关资源
        最近更新 更多