Delphi“EClassNotFound” 错误和 DFM 损坏的可能性

发布于 2024-07-12 23:23:38 字数 1121 浏览 5 评论 0原文

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

I am getting a cascading set of "EClassNotFound" errors in in my Delphi 2007 project. Doesn't seem to be caused by the missing Name property value as often is the case, and though adding RegisterClass(XXX) in the initialization section(s) fixes the EClassNotFound error at hand, another one follows it seemingly indefinitely.

I finally cracked open the DFM file in text editor, and it looks likely corrupted to me (lots of non-ASCII characters amidst form element names, and very "unstructured" looking when compared to what I'm used to seeing in a DFM file). (I'd post a same here but not sure that's OK, w/the non-aSCII, so will hold off).

The form loads fine, and seems to compile / syntax check OK too, but once I run it, trouble.

Going back to early versions of it in SVN, it looks like it's been in this state for some time, which makes me think that either A) the DFM file isn't my problem, or B) the Delphi form-streaming is quite fault-tolerant/robust (Bonus Question: Which is it?).

If the DFM file is the problem, and is corrupted, rolling back will have to be a roll-back WAY back, and that's gonna be expensive. Given that the IDE can still load it, is there any utility that can clean up the file?

Or, am I totally off base w/the DFM as primary suspect?

Thanks folks for the input. Forgot about the binary/text options w/DFM files, so that was helpful. It looks like the DFM itself is not corrupted.

Still having the EClassError issue though. re: It being missing property values, or referencing non-existing properties, etc., a further question: Is the class the error is given for (currently TnxSqlUpdateObject, but probably more waiting in the wings if experience thus far is consistent) usually/always the actual "culprit" class/object?

For instance, right now my main form has four references to TnxSqlUpdateObject, w/those actually dropped on the form. If I put RegisterClass(TnxSqlUpdateObject) in the initialization section, it runs fine for that EClassNotFound error but then goes on to the next one (in this case, TStringField).

I have reinstalled the NexusDB components in this case, and also built a new project using some of the components I thought might be the problem. It compiles and runs fine, UNTIL I add this other form from my real project (which, in turn, unfortunately references quite a few others).

SO, it sounds like my real issue is how to methodically diagnose and fix any and all EClassNotFound errors?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

殤城〤 2024-07-19 23:23:38

如果组件位于表单上,但源文件中的表单定义中也没有条目,我会收到此错误。 最常见的是当我从其他表单复制并粘贴时。 最简单的解决方案是选择组件,剪切它,然后将其粘贴回来。 当你保存时,组件的单位将被添加到源中,当你再次运行它时,一切都会好起来的。

I get this error if a component is on the form, but doesn't have an entry in the form definition in the source file too. Most often when I've copied and pasted from another form. Simplest solution is to select the component, cut it, then paste it back. When you save, the component's unit will be added to the source, and when you run it again it will all be okay.

[旋木] 2024-07-19 23:23:38

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

您可以通过右键单击表单并检查文本 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

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

Well, a dfm file could be binary or tekst (as I'm correct from version 4.0).

You can check this by right click on the form and check the Text DFM flag.

If a dfm file is corrupt, tou can try to fix it by removing all suspicious lines.
Be sure to leave the object .. end sets intact and you probably only loose some property values.

By the way, the dfm file should look like this (to get an idea of the general structure):

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

If it does not look like that you are probably editing the binary file.

掐死时间 2024-07-19 23:23:38

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

我相信也有工具可以将二进制 dfm 文件转换为文本文件。 这将使您更好地查看文件,并帮助您确定文件是否确实已损坏。 我看到 Felix 有一些有关该主题的内容

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

更新:

您是否尝试过 Eurekalog 或 madExcept 或类似的方法来使用 callstack 和 memorydumt 获取更详细的错误消息? 也许这会给你一些关于这个问题的线索。

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

If you have a recent compiled exe that works, you can use a resource-editor, like PE Explorer, to get the dfm-definition. Then you can compare the one from the exe with the one that you now have.

I believe there is tools to convert binary dfm-files to text-files too. This will give you a better view on the file, and help you decide if it's really corrupted or not. I see Felix has something on the topic.

If the Delphi IDE shows the form ok without errors, I can't believe there is a corruption-error. Could there be a package problem? Do you use runtime-packages?

Update:

Hvae you tried Eurekalog or madExcept or something similar to get a more detailed error message with callstack and memorydumt? Maybe that will give you some clue about the problem.

But generally i think this error comes from missing runtime package, or a missing unit in the uses-clause. If you think you know witch component causes the error, search the source for the call to RegisterClass( ), and see if that unit somehow is included in the projcets uses-clause. If not, add it and try again.

吻安 2024-07-19 23:23:38

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

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

正如 Gamecat 指出的,您可以使用以下形式的命令弹出菜单可切换 DFM 存储格式。 将其保留为 Delphi 5+ 的文本,这样与 SVN 配合使用效果更好。

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

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

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

If you can load the form in the Delphi IDE the DFM resource is not corrupted. Delphi uses the same code to load the DFM as the final executable will use, so I think that won't be the reason.

You can open the DFM in the Delphi IDE directly (if the corresponding pas file is not open), or you can use Alt+F12 to switch between form view and text view of the DFM. In this view the structure should be sane, with correct indentation and so on.

As Gamecat pointed out you can use the command in the form popup menu to toggle the DFM storage format. Leave it as text for Delphi 5+, it works better this way with SVN.

As for the cause of your runtime problem - I have no idea...

Edit: After your ruling out the DFM as the source of the problem I can only assume that an important unit in the uses list is missing, which can only happen if not all the components on your form have a corresponding member field. You should check that all the components referenced in the DFM are also in the form, even when you do not access them in your code. This will in turn cause Delphi to add any missing units to the uses clause when the file is saved. Manually registering components should not be necessary if the form class has references to all the components in the DFM.

For a quick check you could create a test form, drop all of the components that your "problem" form has onto it (one instance is enough), and check whether this works.

忆离笙 2024-07-19 23:23:38

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

尝试从 DFM 中手动删除零件,以便查明哪个组件导致了问题。

This can happen in case you have changed one of your custom components and removed a property from it. The property is stil in the DFM and Delphi tries to initialize it.

Try to remove manually parts from your DFM so you can pinpoint which component is causing the problem.

春夜浅 2024-07-19 23:23:38

试试这个:

  1. 首先进行备份
  2. 右键单击设计器中的表单; 取消选中“文本 DFM”
  3. 保存
  4. 右键单击设计器中的表单; 勾选“文本DFM”
  5. 保存

Try this:

  1. Make backup first
  2. Right click on form in designer; uncheck "Text DFM"
  3. Save
  4. Right click on form in designer; check "Text DFM"
  5. Save
旧话新听 2024-07-19 23:23:38

有一次,我用“另存为...”复制了一个单元(具有关联的表格)。 然后我忘了重命名表格。 因此,单元文件具有不同的名称,但在内部,表单具有相同的名称(TFrmResults)。 这是通过警告巧妙地表明的,类似于“文件 x 中的重复资源 (dfm) 已被丢弃,但保留在文件 y 中”。

更改其中一种表格的名称就足够了。

Once, I made a copy of a unit (that had an associated form) with 'Save as...'. Then I forgot to rename the form. So the unit files had different names but inside, the forms had the same name (TFrmResults). This was subtly indicated by a warning, something like "Duplicate resource (dfm) in file x discarded, but kept in file y".

It was enough to change the name of one of the forms.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文