views:

1276

answers:

6

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?

As always, TIA.

======= UPDATE ==========

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?

This has stopped me dead in my tracks for 2 days now, so I really appreciate the help all are offering. Thank you!

+2  A: 

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.

Gamecat
+2  A: 

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.

mghie
Totally agree on the SVN (any version control) part. Binary source are terrible for version control.
Gamecat
+1  A: 

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.

Drejc
+4  A: 

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.

mj2008
And if you place a 'public'-keyword before all the component declarations, delphi wont find the entries either...
Vegar
+2  A: 

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.

Vegar
+1  A: 

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
dmajkic