2011-04-27 62 views
2

将具有完整功能的窗体放入dll中是不错的主意。 主应用程序将调用返回表单对象的dll函数。dll中的Delphi窗体

回答

7

Delphi中接受的方法是使用包而不是DLL。

包本质上是DLL,但具有Delphi特定功能,允许VCL对象跨包边界使用。

试图用DLL来做到这一点将导致软件包处理的各种问题。软件包的一个缺点是所有模块必须使用相同版本的Delphi进行编译。但是,如果你想跨模块边界共享对象,那么如果你使用DLL,你将面临同样的限制。

德尔福的文档有packages的广泛报道。尽管如此,我还是补充说,如果你可以把所有的代码放到一个单独的模块(.exe或.dll)中,那么它确实使生活变得简单得多。

+0

我宁愿说Delphi文档没有关于包的有用信息。 – kludg 2011-04-27 14:29:40

+3

我对软件包的看法是:这是一个很酷的想法,因为它可以消除许多通过DLL共享代码所涉及的典型内存管理问题。然而,在实施过程中,发现所有“好东西”都要求包和应用程序之间的耦合过于紧密。例如。有时将新功能转换为包需要重新组合应用程序。我相信太多的钱都被倒入了包装洞中,没有人想承认这是一个坏主意。 – 2011-04-28 17:43:20

+0

PS:我完全同意单模块方法,除非有重要的需要另外填写。 – 2011-04-28 17:47:19

2

David Heffernan所说的一切+1。

从战略上讲,如果您正在实施插件系统,您实际上只需要需要来实现外部文件中的表单(或其他功能)。

如果你打算允许用任何语言编写插件,那么DLL是唯一的选择。

如果你的插件系统将被限制在具有相同版本的Delphi的开发者(同一个团队或许?),那么就去BPL吧。从我的角度来看,Delphi软件包的另一个缺点是需要在应用程序中部署VCL BPL,而这些应用程序总是比单个编译模块更高。

另一方面,如果您要编写模块化系统,您仍然可以通过在代码中实现松散耦合&“插件”技术并仍编译为单个模块来实现此目的。

5

添加到回答了有关使用包:

  • 包只能如果同时使用,主要的应用程序和所有的DLL(插件)是用Delphi编写的使用Delphi的相同版本的书面
  • 的DLL可以写,可以创建它们,并且可以通过任何程序,无论编程语言

所以可以使用任何编程语言,使用的DLL,而不是包有一定道理。

关于实际问题:是的,可以将表单放入dll中并且它们通常工作正常。只要确保你不会传递它们,因为它们只是dll上下文中的有效对象。你会遇到表单失去焦点或出现在其他表单后面的奇怪问题。这通常可以通过将窗口句柄从主可执行文件传递给dll来解决,然后将dll作为表单的父项。

另请注意:您的dll的TObject与您的应用程序的TObject不同。这同样适用于其他常用的类和变量,例如(Forms。)应用程序。

我已经做到了,腰背疼痛,但并非不可能。主程序用Visual Basic 6编写,一些模块用Delphi 6编写,其他用Delphi 7和Delphi 2007编写。

结论:如果您确定自己的应用程序永远不会使用与Delphi不同的东西,对于你的DLL(插件),并且在切换Delphi版本时总是重新编译所有东西,你应该使用包。否则,使用常规dll可能会更好。 (你确定你将永远是唯一一个写这些DLL的人吗?也许有时候会有一个第三方开发人员为其中一个不需要Delphi版本的dll开发。)

2

IMO this is有时候是一个非常好的主意,也是唯一的出路 - 由于其他人提到的原因,我不喜欢软件包,并且对DLL很熟悉。目前,我正在使用Delphi XE为使用Delphi 5编写的应用程序添加功能 - 它使用DLL或在D5中编写 - 当然,我选择了前者:D5应用程序调用XE编写的DLL,其中包含所有最新和最强大的功能。 (我在Delphi中完成的第一个项目是通过旧的Borland Paradox - Paradox应用程序调用DLL编写的Delphi 1!)

但是,我不会将表单或模块从DLL发送回主应用程序 - 我只是发送DLL模块一个结构,其中包含了它需要知道的工作,当它完成并且DLL的表单关闭时,它会清理并返回一个数字代码或结构返回给调用者,指示成功,失败等老式但非常有效)。

将表单实例从DLL传递回您的主应用程序跨越DLL门限可能会有问题 - 请注意@dummzeuch上面的出色答案,以及如何协商某些问题的一些好的提示,如果您认为这是您唯一的解决方案。

0

如果你在正常的dll中放置一个表单,表单将不能截取TAB或箭头键。我被告知这是由于OnKeyDown无法通过。