【问题标题】:Delphi "EClassNotFound" errors, and corrupted DFM possibilityDelphi "EClassNotFound" 错误和损坏的 DFM 可能性
【发布时间】:2010-10-03 17:43:40
【问题描述】:

我在我的 Delphi 2007 项目中遇到了一系列级联的“EClassNotFound”错误。似乎不是由缺少 Name 属性值引起的,因为通常情况下,虽然在初始化部分添加 RegisterClass(XXX) 修复了手头的 EClassNotFound 错误,但另一个似乎无限期地跟随它。

我终于在文本编辑器中打开了 DFM 文件,它看起来很可能已损坏(表单元素名称中有很多非 ASCII 字符,与我以前在DFM 文件)。 (我会在这里发布相同的内容,但不确定是否可以,使用非 aSCII,所以会推迟)。

表单加载正常,并且似乎编译/语法检查也可以,但是一旦我运行它,就麻烦了。

回到 SVN 中的早期版本,它看起来已经处于这种状态一段时间了,这让我认为要么 A)DFM 文件不是我的问题,要么 B)Delphi 表单流非常容错/健壮(奖励问题:它是哪个?)。

如果 DFM 文件是问题所在并且已损坏,则回滚将必须是回滚方式,而且成本会很高。鉴于IDE仍然可以加载它,是否有任何实用程序可以清理文件?

或者,在 DFM 作为主要嫌疑人的情况下,我是否完全脱离了基地?

感谢大家的意见。忘记了带有 DFM 文件的二进制/文本选项,所以这很有帮助。看起来 DFM 本身没有损坏。

仍然有 EClassError 问题。回复:它缺少属性值,或引用不存在的属性等,还有一个问题:错误的类是给出的(当前是 TnxSqlUpdateObject,但如果到目前为止的经验是一致的,可能更多的等待时间)通常/总是真正的“罪魁祸首”类/对象?

例如,现在我的主窗体有四个对 TnxSqlUpdateObject 的引用,而这些引用实际上被丢弃在窗体上。如果我将 RegisterClass(TnxSqlUpdateObject) 放在初始化部分,它对于 EClassNotFound 错误运行良好,但随后会继续到下一个错误(在本例中为 TStringField)。

在这种情况下,我已经重新安装了 NexusDB 组件,并且还使用我认为可能存在问题的一些组件构建了一个新项目。它编译并运行良好,直到我从我的真实项目中添加了这个另一种形式(不幸的是,它又引用了很多其他形式)。

所以,听起来我真正的问题是如何有条不紊地诊断和修复任何和所有 EClassNotFound 错误?

【问题讨论】:

  • 您是否使用包设置检查了您的构建?使用 filemon 并检查被引用的外部文件。

标签: delphi dfm eclassnotfound


【解决方案1】:

嗯,一个 dfm 文件可以是二进制文件或 tekst 文件(从 4.0 版开始我是正确的)。

您可以通过右键单击表单并检查 Text DFM 标志来检查。

如果 dfm 文件损坏,您可以尝试通过删除所有可疑行来修复它。 请务必保持对象 .. 结束集完好无损,您可能只会丢失一些属性值。

顺便说一下,dfm 文件应该如下所示(以了解一般结构):

object Form5: TForm5
  Left = 0
  DesignSize = (
    426
    652)
  object Button1: TButton
    Left = 343
  end
  object Memo2: TMemo
    Anchors = [akLeft, akTop, akRight, akBottom]
  end
end

如果看起来不是这样,您可能正在编辑二进制文件。

【讨论】:

    【解决方案2】:

    如果您可以在 Delphi IDE 中加载表单,则 DFM 资源不会损坏。 Delphi 使用与最终可执行文件相同的代码来加载 DFM,所以我认为这不是原因。

    可以直接在Delphi IDE中打开DFM(如果对应的pas文件没有打开),也可以使用Alt+F12在DFM的表单视图和文本视图之间切换。在这个视图中,结构应该是健全的,具有正确的缩进等等。

    正如Gamecat 所指出的,您可以使用表单弹出菜单中的命令来切换 DFM 存储格式。将其保留为 Delphi 5+ 的文本,这种方式与 SVN 一起使用效果更好。

    至于你的运行时问题的原因 - 我不知道......

    编辑:在您排除了 DFM 作为问题的根源之后,我只能假设使用列表中的一个重要单元丢失了,这只有在您的所有组件都没有的情况下才会发生表单有相应的成员字段。您应该检查 DFM 中引用的所有组件是否也在表单中,即使您没有在代码中访问它们。这反过来会导致 Delphi 在保存文件时将任何缺少的单元添加到使用子句中。如果表单类引用了 DFM 中的所有组件,则无需手动注册组件。

    为了快速检查,您可以创建一个测试表单,将“问题”表单具有的所有组件放到它上面(一个实例就足够了),然后检查它是否有效。

    【讨论】:

    • 完全同意 SVN(任何版本控制)部分。二进制源对版本控制来说很糟糕。
    【解决方案3】:

    如果您更改了其中一个自定义组件并从中删除了属性,则可能会发生这种情况。该属性仍在 DFM 中,Delphi 尝试对其进行初始化。

    尝试从您的 DFM 中手动移除部件,这样您就可以查明是哪个组件导致了问题。

    【讨论】:

      【解决方案4】:

      如果组件在表单上,​​但在源文件的表单定义中也没有条目,我会收到此错误。最常见的是当我从另一个表单复制和粘贴时。最简单的解决方案是选择组件,剪切它,然后将其粘贴回去。保存时,组件的单元会添加到源中,再次运行时一切正常。

      【讨论】:

      • 如果你在所有组件声明之前放置一个'public'关键字,delphi也不会找到条目......
      【解决方案5】:

      如果你有一个最近编译的可执行文件,你可以使用资源编辑器,比如PE Explorer,来获取dfm-definition。然后,您可以将 exe 中的那个与您现在拥有的那个进行比较。

      我相信也有将二进制 dfm 文件转换为文本文件的工具。这将使您更好地查看文件,并帮助您确定它是否真的已损坏。我看到菲利克斯有东西on the topic

      如果 Delphi IDE 显示表单没有错误,我无法相信存在损坏错误。会不会是包的问题?你使用运行时包吗?

      更新:

      你尝试过 Eurekalog 或 madExcept 或类似的东西来获得更详细的调用堆栈和 memorydumt 错误消息吗?也许这会给你一些关于这个问题的线索。

      但通常我认为此错误来自缺少运行时包,或使用子句中缺少单元。如果您认为您知道 wwitch 组件会导致错误,请搜索对 RegisterClass( ) 的调用的来源,并查看该单元是否以某种方式包含在项目使用子句中。如果没有,请添加并重试。

      【讨论】:

        【解决方案6】:

        试试这个:

        1. 先备份
        2. 在设计器中右键单击表单;取消选中“文本 DFM”
        3. 保存
        4. 在设计器中右键单击表单;检查“文本 DFM”
        5. 保存

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-20
          • 2013-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多