我对从DLL内部创建的表单有一个小问题。
基本上会发生什么情况是来自dll的表单(Form1)显示(我认为它必须保持在顶部)并且您打开另一个表单(Form2),它是主要应用程序的一部分(即不在内部dll)。如果将光标放在Form2上的控件上以便显示提示,则Form2将立即位于Form1后面。
仅当MainFormOnTaskBar为true时才会发生这种情况。目前我们将主应用程序的Application.Handle传递给DLL并将其分配给DLL的Application.Handle。
我设法解决了这个问题,而是将Application.MainForm.Handle传递给DLL,将其分配给DLL中的Application.Handle。
这样安全吗?有谁知道解决这个问题的正确方法?
答案 0 :(得分:5)
您的解决方案非常合理。我有一个Excel COM加载项,它做了非常相似的事情。在该代码中,我将DLL中的Application.Handle设置为Excel主窗口的窗口句柄。这与你正在做的事情相似。
问题是您需要正确设置窗口所有权。您需要所有权链才能一直回到应用程序的主要表单。 DLL中的表单不知道主要表单是什么,因此您必须提供该知识。
请注意,我说的是Windows使用的窗口所有者的概念,而不是VCL的所有者概念,这是完全不同的。在VCL术语中,这称为弹出父级,您可以通过将DLL表单的弹出父级显式设置为主窗体来解决您的问题。相关属性是PopupMode和PopupParent。对于生活在主应用程序中的表单,VCL自然会使其弹出父表单成为主要表单。
然而,在谈到明确设置弹出式父级时,我会强调您当前的解决方案更简单,更方便。
这两个解决方案的作用是确保所有辅助表单都归主表单所有。这意味着这些表单始终位于主窗体之上。这意味着如果主窗体最小化,辅助窗体将被最小化。在此处阅读所拥有的窗口:Window Features。
顺便说一句,如果您一直使用运行时包而不是DLL,则包中的代码将连接到与主窗体相同的VCL。因此打包的代码将能够看到主窗体并适当地设置窗口所有者。这当然是使用包的一个优点。当然,很可能有充分的理由说明为什么需要使用DLL而不是包。