如何持久化对Delphi';s组件?

如何持久化对Delphi';s组件?,delphi,runtime,persistence,Delphi,Runtime,Persistence,每次我向列表框、列表视图或编辑器中的按钮添加文本时,它都会在每次程序启动时显示。问题是为什么当我在运行时添加它们,然后重新启动程序时,这些项(文本或按钮)会消失。我知道文本可以保存在文件中,但有没有其他方法像编辑器中保存的默认文本一样。当您在设计时添加文本时,它会保存在.dfm文件中并编译到程序中。这不会在运行时发生 想象一下,如果是这样的话。它不能以同样的方式运行,因为一旦部署了应用程序,就不能更改可执行文件。您不希望将用户设置存储在可执行文件中。因此,这些设置确实需要位于应用程序外部 要实现

每次我向列表框、列表视图或编辑器中的按钮添加文本时,它都会在每次程序启动时显示。问题是为什么当我在运行时添加它们,然后重新启动程序时,这些项(文本或按钮)会消失。我知道文本可以保存在文件中,但有没有其他方法像编辑器中保存的默认文本一样。

当您在设计时添加文本时,它会保存在.dfm文件中并编译到程序中。这不会在运行时发生

想象一下,如果是这样的话。它不能以同样的方式运行,因为一旦部署了应用程序,就不能更改可执行文件。您不希望将用户设置存储在可执行文件中。因此,这些设置确实需要位于应用程序外部


要实现这一点,您需要实现自己的持久化机制。您需要将运行时添加的内容保存到某个文件中(例如,在用户配置文件下),然后在应用程序启动时重新加载该文件。

是的,我已经做了很多年了。从TForm下降并覆盖创建和销毁。在dtor中,使用Tstream.WriteComponent(),(并调用inherited!)输出整个表单。使用形式classname或某些派生形式来组合文件名

在create中,再次组合文件名,并检查表单是否存在流文件。如果没有,只需调用继承的create(),以便“正常”创建表单。如果文件确实存在,请调用CreateNew(),然后使用Tstream.ReadComponent以流的形式传输

这将有效地保存和恢复所有已发布的属性。表单及其所有组件的大小、位置颜色、字体、文本、标题等都将保持不变。应用程序启动时的外观与关闭时完全相同。标签、列表、备忘录文本、图像等都是在会话中自动保存的,不需要编写任何额外的代码

如果您将新的“TpersistentForm”类放入一个单元中,您可以通过将“persistent”单元添加到表单单元的uses子句,将表单类从“TForm”编辑为“TpersistentForm”,并通过添加一个单元和更改类来重建“即时”持久化应用程序,从而轻松地使现有应用程序成为“持久化”应用程序

我几乎在我所有的Delphi应用程序上都使用它。当应用程序以上次关闭时相同的位置、字体等启动时,它会给用户留下无尽的印象。此外,我不需要任何代码来存储配置数据——TEdits中的文件路径等。只需立即弹出备份即可——我不需要讨厌的复杂INI文件或注册表


如果你尝试这个方法,你会发现它的缺点。一个是设计/开发时间——你测试了你的半成品应用程序,它工作得很好,所以你添加了一些额外的按钮、标签来做新的东西,然后重新运行应用程序——新的组件不在那里!发生这种情况是因为从上一次运行保存的流文件不包含新组件的属性:((

我认为您需要根据算法向列表框添加一些项(所有值都有某种相似性)并使其始终可用。做您要求的事情可能会成为一个相当高级的主题,而且您听起来好像处于一个非常基本的级别。您用于调用创建控件的函数的任何输入都需要持久化(保存到磁盘上的文件或注册表项中)并重新加载。@Martin这将是实现我在第3段中概述的目标的一种方法。不过,您概述的缺点有点严重。我想我希望对我的应用程序加载的.dfm文件保持更严格的控制。@DavidHeffernan好吧,在开发过程中需要时禁用流式处理是相当容易的-一个命令行参数例如,“noStream”或条件编译。还有其他好处-如果将表单流式处理为文本,则可以使用记事本查看属性或通过电子邮件发送给您。这在调试客户安装时偶尔有用。理想情况下,应与写入内存映射的dfm资源结合使用。@user memory mapped files?为什么需要这样做?听起来有些过头了。这显然是给非高级开发人员提供高级建议,因此我认为你应该警告noobs;这是一个可怕的想法,除非你是高级开发人员。@WarrenP-大多数开发人员,无论他们的技能/经验水平如何,都可以知道是否需要处理某些工作B或不是。例如,我已经开发了几十年,但我不喜欢触摸任何东西,除了最简单的SQL。我认为避免编写、测试和维护INI文件和/或注册表代码的痛苦,并通过添加一个单元和编辑类名来代替它是一个坏主意。我认为读/写配置只是GungWorksI。现在要做所有这些在一个嵌入式C++工作,这是一个真正的痛苦,继续管理配置在SD卡的“ini文件”。@ USER 53944--我只是使用普通的旧文件,如David H.建议,实际上,我使用文件夹树和文件。根文件夹命名的应用程序和子文件夹命名为表单和子窗体类名称。这允许多我同意Warren的观点,这个解决方案并不是真正的noob友好型。