代码之家  ›  专栏  ›  技术社区  ›  Jamo

Delphi“EClassNotFound”错误,以及损坏的DFM可能性

  •  4
  • Jamo  · 技术社区  · 16 年前

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

    我终于在文本编辑器中破解了DFM文件,在我看来它可能已经损坏了(表单元素名称中有很多非ASCII字符,与我在DFM文件中看到的相比,看起来非常“非结构化”)。(我会在这里发布同样的内容,但不确定是否可以,带非aSCII,所以会推迟)。

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

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

    如果DFM文件是问题所在,并且已损坏,那么回滚将必须是一种回滚方式,这将是昂贵的。鉴于IDE仍然可以加载它,是否有任何实用程序可以清理文件?

    或者,我完全偏离了基地,DFM是主要嫌疑人吗?

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

    但仍然存在EClassError问题。re:缺少属性值,或引用不存在的属性等,还有一个问题:错误所针对的类(目前是TnxSqlUpdateObject,但如果迄今为止的经验一致,可能还有更多等待)通常/总是实际的“罪魁祸首”类/对象吗?

    例如,现在我的主窗体有四个对TnxSqlUpdateObject的引用,这些引用实际上已经放在窗体上了。如果我在初始化部分中放入RegisterClass(TnxSqlUpdate Object),它会很好地处理EClassNotFound错误,但会继续处理下一个错误(在本例中为TStringField)。

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

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

    6 回复  |  直到 9 年前
        1
  •  15
  •   mj2008    16 年前

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

        2
  •  2
  •   Toon Krijthe    16 年前

    嗯,dfm文件可以是二进制或tekst(从4.0版本开始,我是对的)。

    您可以通过右键单击表单并选中文本DFM标志来检查这一点。

    如果dfm文件损坏,tou可以尝试通过删除所有可疑行来修复它。 一定要离开这个物体。.end设置保持不变,您可能只会丢失一些属性值。

    顺便说一句,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
    

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

        3
  •  2
  •   Vegar    16 年前

    如果你有一个最近编译的exe可以运行,你可以使用资源编辑器,比如 PE Explorer ,以获得dfm定义。然后,您可以将exe中的一个与您现在拥有的一个进行比较。

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

    如果Delphi IDE显示表单正常,没有错误,我不敢相信有损坏错误。可能是包裹有问题吗?你使用运行时包吗?

    更新:

    你试过Eurekalog或madExcept或类似的东西,以获得更详细的错误消息,包括callstack和memorydumt吗?也许这会给你一些关于这个问题的线索。

    但一般来说,我认为这个错误来自缺少运行时包,或者uses子句中缺少单元。如果您认为您知道witch组件导致了错误,请在源代码中搜索对RegisterClass()的调用,并查看该单元是否以某种方式包含在projcets uses子句中。如果没有,请添加并重试。

        4
  •  2
  •   Community CDub    8 年前

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

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

    Gamecat 指出您可以使用表单弹出菜单中的命令切换DFM存储格式。将其保留为Delphi 5+的文本,使用SVN时效果更好。

    至于运行时问题的原因,我不知道。..

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

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

        5
  •  1
  •   Drejc    16 年前

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

    尝试手动从DFM中删除零件,以便您可以确定是哪个组件导致了问题。

        6
  •  1
  •   dmajkic    16 年前

    试试这个:

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