4

我在我的 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 错误?

4

6 回答 6

15

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

于 2009-01-27T13:26:33.487 回答
2

好吧,dfm 文件可以是二进制文件或 tekst 文件(因为我在 4.0 版中是正确的)。

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

如果 dfm 文件损坏,您可以尝试通过删除所有可疑行来修复它。确保保持对象 .. 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

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

于 2009-01-27T11:20:50.090 回答
2

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

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

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

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

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

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

于 2009-01-27T11:37:57.903 回答
2

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

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

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

更新:

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

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

于 2009-01-27T13:47:48.233 回答
1

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

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

于 2009-01-27T12:20:28.847 回答
1

试试这个:

  1. 先做好备份
  2. 右键单击设计器中的表单;取消选中“文本 DFM”
  3. 节省
  4. 右键单击设计器中的表单;检查“文本 DFM”
  5. 节省
于 2009-01-27T17:53:11.030 回答