Delphi - 找不到 TListView 类

3
我们有一个Delphi 5应用程序,没有运行时包、dll或外部资源(即单个可执行文件)。当我们将其安装在客户端PC上时,会出现以下错误消息:
“Class TListView not found” 或 “Class TImage not found”。
我们之前已经在数十台PC上安装过它,但是最近的安装出了问题。
目标PC是全新安装的Windows XP(Service pack 3),没有安装其他软件。
它并不会对所有类都抱怨,只有其中一两个。例如TPanel/TForm/TEdit都没问题。
有人能想到是什么原因吗?
编辑
新PC上的exe也被安装在我所知道的其他30多台PC上,包括Windows XP Sp1、2、3、Windows Vista和Windows嵌入式系统。新旧PC都安装了旧版本,然后升级到最新版本。唯一的区别是最新安装的版本跳跃更高。

@Re0sless,在我充当恶魔的代言人时请耐心等待,但你是否真的将一个可用机器上的exe文件复制到一个不可用的机器上并验证它无法工作?如果是这样,我们可以放弃这条路。不幸的是,除了清理uses子句之外,我已经没有其他建议了。 - Lieven Keersmaekers
@Re0sless - 你介意分享最终问题是什么吗? - Lieven Keersmaekers
事实证明,在 uses 子句中有一个单元我们不再使用,一旦从所有我们使用的单元中移除它,问题就解决了。我仍然不确定为什么它在其他计算机上没有显示出来。 - Re0sless
7个回答

10

通常,这是在.DFM流式传输过程中的错误。通常,此错误会出现在TLabel组件上,因为许多人会从表单或框架中移除TLabel字段,以便减少混乱并降低表单的实例大小。然而,他们犯的普遍且令人困惑的错误是,在他们的过度热情中,他们移除了所有的TLabel引用。那时候就会发生不好的事情。接下来我将介绍一下流式传输系统如何定位组件类。

请记住,.DFM中的类引用只是一个字符串。流式传输系统必须将此字符串转换为类引用(TComponentClass)。流式传输系统使用的有两个机制。第一个机制非常简单,涉及一个全局类引用列表。您可以调用RegisterClass或RegisterClasses来显式地使流式传输系统知道它。第二个机制要微妙得多,不是很出名;事实上,它都是Delphi的“魔力”:-)。当编译器构建表单时,处理表示表单上的组件的所有字段,并构建内部表作为表单/框架/数据模块本身的RTTI或元数据的一部分。该表包含对由组件字段表示的所有单个组件类型的引用列表。因此,即使组件不在全局列表中,仍然可以通过扫描此编译器生成的表来找到它。这就是Classes.TReader.GetFieldClass()方法的作用。

回到我的TLabel示例,这个问题很容易解决,只需确保至少有一个给定类型的字段。因此,只要有至少一个TLabel类型的字段,所有其他TLabel都会加载得很好。因此,在您的情况下,请确保未删除TListView或TImage字段。


5

Re0sless,

我建议你打开并关闭应用程序的每个表单,然后进行全新构建。如果我的记忆没有出错的话,当我们遇到类似问题时,这就是解决方案。

你还可以查看DFM Check以自动打开和关闭所有dfm文件,并使用CnPack来帮助你清理uses子句。

祝好,
Lieven


我刚刚尝试了“DFM检查”,它返回OK,所以我将尝试打开每个窗体来解决它,如果这是VCL/DFM问题,为什么其他PC上没有出现错误? - Re0sless
@Re0sless。我的第一步将是使用CnPack清理所有的uses子句,并验证我没有错误地使用运行时包。我会使用procmon并过滤*.bpl,以检查应用程序是否尝试加载bpl。希望对你有所帮助,Lieven - Lieven Keersmaekers
另外,您是否比较了要在新机器上安装的可执行文件与已安装在旧机器上的文件?您是否尝试将来自“旧”机器的可执行文件复制到新机器上? - Lieven Keersmaekers

1
我遇到了同样的问题。找不到TCheckBox类。我通常通过表单的.DFM来编辑大量组件(例如重命名大量组件)。当我通过它的.DFM重命名所有复选框时,就会出现这个错误。
我只是剪切了所有的复选框,然后重新粘贴它们(因此.DFM文件得到了刷新)。错误消失了。

有人知道,IDE 存储 DFM 缓存的位置吗?在重新打开 IDE 中的表单之前,在创建表单期间会出现错误。重新打开后什么都没有改变,但是错误不再存在。 - Dżyszla

1

我认为Lieven肯定在正确的轨道上:在运行时找不到简单的基类是Delphi(链接器)的问题。这个异常不是由操作系统引起的。

我对类似问题的经验:链接器将单位错误排列的项目生成。
例如:一个窗体单位在基础单位之前链接。强制项目完全重新编译/重新链接应该可以消除此异常。

仅做[全部重建]可能不足够。您可以尝试重新编译而不进行优化。

我已尝试复制此错误,但未能成功。Delphi编译器/链接器是最好的之一-编译速度/编译后exe的速度-但这个错误肯定会停滞。

注意:我只在D5中遇到过这个错误。其他Delphi版本有没有人遇到过这个错误?


0

我曾经遇到过类似的问题,是由于文件复制错误导致的。更加令人困惑的是,故障出现在中间媒体设备上。问题通过从现有发布版本重新复制文件来解决。

现在可能无法确认,但很可能问题被“解决”了;不是因为删除了一个不必要的uses子句项,而是因为它还涉及到可执行文件的新副本。


0
所有关于“Class XXX not found”的错误解决方案都很简单。用文本编辑器打开表单的DFM文件,手动删除其中XXX对象的定义即可。

0

更改表单的名称并将.pas文件另存为其他名称。如果其他单元中使用了新的单元名称,则更改所有引用以创建新的单元名称。进行全部构建。 这样错误就消失了。


在我的情况下,对象不在表单中,因此Ivan Z的解决方案是不可能的。 - Horacio Cornaggia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接