2012-03-01 49 views
6

我从DLL内部创建的表单有一个小问题。Delphi XE2将Application.MainForm.Handle分配给DLL中的Application.Handle

基本上,当一个dll的窗体(Form1)显示时(我认为它必须保持在最前面),并且打开另一个窗体(Form2),它是主应用程序的一部分(即不生活在dll里面)。如果将光标放在Form2上的控件上以便显示提示,Form2将立即放在Form1后面。

这只发生在MainFormOnTaskBar是真的。目前,我们将主应用程序的Application.Handle传递给DLL并将其分配给DLL的Application.Handle。

我已设法通过将Application.MainForm.Handle传递给要分配给DLL中的Application.Handle的DLL来解决此问题。

这是安全吗?有没有人知道解决这个问题的正确方法?

回答

5

您的解决方案非常合理。我有一个Excel COM加载项,它的功能非常类似。在该代码中,我将DLL中的Application.Handle设置为Excel主窗口的窗口句柄。这与你正在做的事情是一致的。

问题是您需要正确设置窗口所有权。您需要拥有所有权链条以回到应用程序的主窗体。 DLL中的表单不知道主表单是什么,所以你必须提供这些知识。

请注意,我正在讨论Windows所使用的窗口所有者的概念,而不是所有者的VCL概念,它完全不同。在VCL术语中,这被称为弹出父项,并且可以通过将DLL窗体的弹出父项明确设置为主窗体来解决您的问题。相关的属性是PopupMode和PopupParent。对于生活在主应用程序中的表单,VCL自然会使其弹出式父级成为主要形式。

但是,在谈到明确设置弹出父级时,我会强调您当前的解决方案更简单,更方便。

这两种解决方案所做的是确保所有辅助表单都归主窗体所有。这意味着这些形式总是在主要形式之上。这意味着如果主表格被最小化,辅助表格将被最小化。在这里阅读有关拥有的窗口:Window Features。顺便说一下,如果您使用的是运行时软件包而不是DLL,那么软件包中的代码将连接到与主窗体相同的VCL。因此,打包的代码将能够看到主窗体并适当地设置窗口所有者。这当然是使用包的一个优点。当然,为什么你需要使用DLL而不是软件包,这可能是一个很好的理由。

+0

谢谢你。我只是想知道是否需要将MainFormOnTaskBar属性设置为包含在DLL中的应用程序对象的真? – 2012-03-05 20:58:10

+0

既然DLL中的应用程序对象没有主窗体,那么我想我们不需要也不应该将MainFormOnTaskBar设置为true,就应用程序对象 – 2012-03-06 01:06:43

+0

达成一致,不需要这样做,并不是说它实际上很重要因为我认为Application.MainForm没有被分配,因为你永远不会调用Application.CreateForm。 – 2012-03-06 05:54:39