3
votes

We have a Delphi 5 application, that is built without runtime packages, dlls or external resources (i.e. a single executable). when we install it on a clients PC we get the following error messages:

Class TListView not found

or

Class TImage not found

We have installed it on dozens of PCs before without incident, but this latest install is problematic.

The target PC is a fresh install of Windows XP (Service pack 3) with no other software installed.

It does not complain about all of the classes however just one or two. for example TPanel/ TForm/ TEdit are all OK.

Can anyone think what is causing this?

EDIT

The exe on the new PC is on 30 or so other PCs that I know of, ranging from windows XP Sp1,2,3, Windows Vista and Windows embedded. both old and new PCs were installed with an old version and then updated with the newest version. The only difference is that the version jump was higher for the latest install.

7
@Re0sless, bear with me while I'm playing the devils advocate but did you actually copied an exe from a working machine to a non-working machine and verified it didn't work? If you did, we can lay that path to rest. Unfortunatly, besides cleaning the uses clause, I am out of suggestions.Lieven Keersmaekers
@Re0sless - do you care to share what the final problem was?Lieven Keersmaekers
I turned out that there was a unit in the uses clause that we didn't use any more, once that was removed from all the units we do use the problem went away, I am still not sure why it didn't show on the other computers.Re0sless

7 Answers

4
votes

Re0sless,

I suggest you open and close every form of your application and do a fresh build after that. If memory serves me well, that was the solution when we encountered similar problems.

You might also take a look at DFM Check to open and close all your dfm's automatically and at CnPack to help you clean your uses clause.

Regards,
Lieven

10
votes

This is typically an error during the streaming of a .DFM. Usually this error occurs with TLabel components because many folks remove the TLabel fields from the form or frame in order to cut down on the clutter and reduce the instance size of the form. The common and confusing mistake they make, however, is that in their over-zealousness, they remove all TLabel references. That is when bad things start to happen. Let me run down how the streaming system locates a component's class.

Remember that the class reference in the .DFM is just a string. The streaming system has to convert this string into a class reference (TComponentClass). There are two mechanisms that the streaming system uses to do this. The first one is very simple and involves a global list of class references. You can call RegisterClass or RegisterClasses to explicitly make the streaming system aware of it. The second is much more subtle and not very well known; in fact it is all part of the "magic" of Delphi :-). When the compiler builds the form, all the fields that represent the components on the form are processed and an internal table is built as part of the RTTI or metadata for the form/frame/datamodule itself. This table contains a list of references to all the individual component types represented by the component fields. So even if a component is not in the global list, it can still be found by scanning through this compiler generated table. That is what the Classes.TReader.GetFieldClass() method does.

Back to my TLabel example, this problem is easily fixed by simply ensuring that at least one of a given component type has a field. So as long as there is at least field of type TLabel, all the other TLabels will load just fine. So in your case, make sure the TListView or TImage fields haven't been deleted.

1
votes

I think Lieven is definitely on the right track: simple base classes not being found during runtime are a Delphi (linker) problem. This exception is not caused by the Operating System.

My experience with similar problems: the linker generates a project with the units wrongly arranged.
Example: a form unit is linked in before the base units. Forcing the project to completely recompile/relink itself should make this exception go away.

A simple [Rebuild All] will probably not suffice. You might try to recompile without optimizations.

I have tried to reproduce this error but I have not been able to. The Delphi compiler/linker is one of the best - speed of compilation/speed of compiled exes - but this bug is definitely a show stopper.

Note: I have only experienced this error in D5. Has anybody else experienced this error with other Delphi versions?

0
votes

I've seen a similar problem due to a file copy error. To make matters more confusing, the fault was on an intermediate media device. The issue was resolved by simply recopying the file from the existing release build.

It is probably impossible to confirm now, but it is quite possible that the problem was 'solved'; not because of the removal of an unnecessay uses clause item, but because it also involved a new copy of the executable.

0
votes

I had the same problem. Class TCheckBox not found. I usually edit large set of components through .DFM of form(for example renaming large amount of component). This error comes when I rename all CheckBox on my form through it .DFM.

I just cut all the checkbox and paste them again(So .DFM file is refreshed). The error disappeared.

0
votes

The solution for all errors of this type "Class XXX not found" is simple. Open DFM file of a form in text editor and manualy remove the definition of the XXX object in it.

0
votes

Change the name of the Form and save the .pas with other name. Change all references to create the new unit name if this is used in other units. Build All. With this the error disappeared.