答案 0 :(得分:48)
应用程序窗口的原因有一点肮脏的历史。在开发Delphi 1时,我们知道我们想要为IDE使用“SDI”(遍布桌面的窗口)ui模型。我们也知道Windows在该模型上吸引了(并且仍然存在)。但是我们也注意到当时的Visual Basic使用了该模型,它似乎运行良好。经过进一步检查,我们发现VB使用了一个特殊的“隐藏”停车窗口,用作所有其他可见窗口的“所有者”(Windows模糊了父级和所有者的概念,但区别类似于VCL)
这就是我们解决“问题”的方法,其中包含主菜单的窗口很少被聚焦,因此处理文件菜单的Alt-F根本不起作用。通过使用这个中央停车窗口作为中介,我们可以更容易地跟踪消息并将消息路由到适当的窗口。
这种安排也解决了通常多个顶级窗口完全独立的另一个问题。通过使应用程序处理所有这些窗口的“所有者”,它们都会表现得很好。例如,您可能已经注意到,当您选择任何应用程序窗口时, all 应用程序窗口移到前面并保持它们相对于彼此的z顺序。这也可以使应用程序最小化并恢复为功能分组。
这是使用此模型的结果。我们可以手动完成所有这些工作以保持一致,但设计理念是不重新发明Windows,而是尽可能地利用它。这也是TButton或TEdit分别真正 Windows“用户”BUTTON和EDIT窗口类和样式的原因。
随着Windows的发展,“SDI”模式开始失宠。事实上,Windows本身开始变得对这种应用程序“充满敌意”。从Windows Vista开始并继续到7,用户shell似乎无法与使用停车窗口的应用程序一起使用。因此,我们开始在VCL中改变现状以消除停车窗口并将其功能转移到主窗体中。这提出了几个“鸡和鸡蛋”问题,我们需要在应用程序初始化中尽早提供停车窗口,以便其他窗口可以“附加”到它,但主窗体本身可能不会很快构建。 TApplication必须通过几个环节来实现这一点,并且有一些微妙的边缘情况引起了问题,但大多数问题已经解决了。但是,对于您前进的任何应用程序,它将继续使用旧的停车窗口模型。
答案 1 :(得分:12)
所有VCL应用程序都有一个名为“应用程序”的“隐藏”顶级窗口。这是在应用程序启动时自动创建的。除此之外,它还是VCL的主要Windows消息处理程序 - 因此是Application.ProcessMessages。
隐藏应用程序顶级窗口会导致一些奇怪的事情,显然是任务栏中显示的不完整的系统菜单,以及Vista中不正确的缩略图窗口。更高版本的Delphi纠正了这一点。
然而,并非所有的Windows都必须将它作为父级,Windows只是倾向于更好地工作。 但是,使用Application.CreateForm创建的任何表单都将将其作为父项,并且它也将由Application对象拥有。由于它们是拥有的,因此一旦应用程序被释放,它们将被释放。这发生在Forms.DoneApplication
的幕后答案 2 :(得分:8)
通过查看forms.pas(Delphi 2009)中的来源,看来他们在win32 gui应用程序中创建了一个“主”窗口以允许调用
传递给Application.Handle
的邮件似乎会根据情况转发给MainForm
(如果存在)。如果尚未创建主窗口,这将允许应用程序响应最小化等。通过修改项目源,您可以在不使用主窗口的情况下创建delphi应用程序。
在这种情况下,即使您尚未创建主窗口,TApplication
方法仍然有效。不确定我是否掌握了所有目的,但我没有时间完成所有的TApplication代码。
根据你的问题:
它来自何处?它是在TApplication.Create
它处理的窗口是什么?每个gui delphi应用程序需要的假窗口作为TApplication抽象的一部分
它是appliation主窗体的窗口句柄否
如果它不是应用程序主变形的句柄那么它是什么?见上文
更重要的是:为什么它是每种形式的最终父母?假设你是对的最终父母,我认为它是如此,因为它使它很容易找到应用程序中的所有表单(枚举此“主”表单的子项)。
并且最重要的是:如果我尝试将表单设为无表示,为什么一切都会变得混乱我认为因为隐藏的“主”表单正在获取系统消息应该传递给它的子项和/或主表单,但找不到无表格的表单。
无论如何,这是我的看法。您可以通过查看forms.pas
中的TApplication声明和代码来了解更多信息。我所看到的底线是一个方便的抽象。
致以最诚挚的问候,
唐