Windows Delphi XE2将Application.MainForm.Handle分配给DLL中的Application.Handle

Windows Delphi XE2将Application.MainForm.Handle分配给DLL中的Application.Handle,windows,delphi,dll,delphi-xe2,Windows,Delphi,Dll,Delphi Xe2,我对从DLL内部创建的表单有一个小问题 基本上,当dll中的一个窗体(Form1)显示时(我认为它必须保持在顶部),您打开另一个窗体(Form2),它是主应用程序的一部分(即,不在dll中)。如果将光标放在Form2上的控件上以显示提示,Form2将立即转到Form1后面 这仅在MainFormOnTaskBar为true时发生。目前,我们正在将主应用程序的application.Handle传递给DLL,并将其分配给DLL的application.Handle 我通过将Application.

我对从DLL内部创建的表单有一个小问题

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

这仅在MainFormOnTaskBar为true时发生。目前,我们正在将主应用程序的application.Handle传递给DLL,并将其分配给DLL的application.Handle

我通过将Application.MainForm.Handle传递给要分配给DLL中Application.Handle的DLL,成功地解决了这个问题


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

您的解决方案非常合理。我有一个Excel COM外接程序,它的功能非常类似。在该代码中,我将DLL中的Application.Handle设置为Excel主窗口的窗口句柄。这对你正在做的事很有帮助

问题是您需要正确设置窗口所有权。你需要所有权链,才能一直回到你的应用程序的主窗体。DLL中的窗体不知道主窗体是什么,因此必须提供这些知识

请注意,我谈论的是Windows使用的窗口所有者概念,而不是完全不同的VCL所有者概念。在VCL术语中,这称为弹出父窗体,您可以通过显式地将DLL窗体的弹出父窗体设置为主窗体来解决问题。相关属性为PopupMode和PopupParent。对于主应用程序中的窗体,VCL自然会使其弹出父窗体成为主窗体

但是,在谈到显式设置弹出式父项之后,我要强调的是,您当前的解决方案更简单、更方便

这两种解决方案所做的是确保所有辅助表单都属于主表单。这意味着这些表单始终位于主表单的顶部。这意味着如果主窗体最小化,辅助窗体将最小化。在此处阅读有关拥有的windows的信息:


顺便说一句,如果您使用的是运行时包而不是DLL,那么包中的代码将连接到与主窗体相同的VCL。因此,打包的代码将能够看到主窗体并适当地设置窗口所有者。这当然是使用包的一个优点。当然,您需要使用DLL而不是软件包可能有一个很好的理由。

谢谢。我只是想知道是否需要在DLL中包含的应用程序对象上将MainFormOnTaskBar属性设置为true?因为DLL中的应用程序对象没有主窗体,所以我想我们不需要或不应该在应用程序对象上将MainFormOnTaskBar设置为true同意,没有必要这样做,这并不重要,因为我假设Application.MainForm没有被分配,因为您从未调用Application.CreateForm。