是什么 TApplication.Handle?

  • 哪里来的?
  • 为什么存在?
  • 最重要的是:为什么所有形式必须作为他们的父窗口处理?

德尔福帮助说:

TApplication.手柄

提供了获取窗口处理 主要的形式(窗口)的 应用程序。

property Handle: HWND;

描述

使用时调用Windows API 职能,需要一个父窗口 处理。例如,DLL 显示其自己的顶级的弹出窗口 windows需要一个父窗口 显示其窗户 应用程序。使用的财产处理 使这种窗口的一部分 应用程序,以便它们 最小化,恢复,启用 残疾人与应用程序。

如果我重点放在单词"窗口处理的主要形式应用程序"和我的意思 窗口处理的主要形式应用程序, 然后我就可以比较:

  • "窗口处理的主要形式应用程序",
  • 窗口处理的 MainFormApplication

但他们不是相同的:

Application.MainForm.Handle: 11473728
Application.Handle: 11079574

是什么 Application.Handle?

  • 哪里来的?
  • 什么窗户®窗口处理呢?
  • 如果它 Windows窗口处理的 Application's MainForm, 然后他们为什么不匹配?
  • 如果它 窗口处理的 Application's MainForm, 然后是什么?
  • 更重要的是:为什么是它的最终 老板每个表格吗?
  • 而最重要的是:为什么一切就会失控,如果我尝试了一种形式是 unparented 无主的(所以我就可以出现在任务栏),或试图使用一些东西喜欢 IProgressDialog?

真的我要问的是:什么的设计理由,让 应用程序。手柄 存在吗?如果我可以理解为什么,应当如何成为显而易见的。


更新 了解通过一个游戏的二十个问题:

在谈论解决方案的制的一个窗口出现在任务栏通过使它的主人 null, 彼得低于2000年所说的:

这可能会导致一些问题模式的形式出示 辅助形式。

如果用户离开的应用程序而一个模式 形式上,然后回的形式显示,该模式可以 隐藏下形式。它能够处理这种通过确保 该模式是父[原文如此;他的意思是拥有]的形式,显示它(使用 params.WndParent 如上所述)

但这是不可能的标准 对话从 Dialogs 单元和 例外情况, 需要更多的努力, 让他们工作的权利(基本上处理 Application.OnActivate, 在寻找模式形式父 应用程序 通过 GetLastActivePopup 并把他们的顶部Z-order通过 SetWindowPos).

  • 为什么一个模式形式,最终陷落后于其他形式?
  • 什么样的机制通常带来了一个模式形成的前面,为什么不能在这里?
  • Windows®是负责展示窗叠。什么错了,窗®是不是显示正确的窗户?

他还谈到了使用新的窗口扩展式,部队的一个窗口出现在任务栏(当正常的规则,使联合国拥有的不足,不切实际的,或不希望的),通过加入 WS_EX_APPWINDOW 扩展风格:

procedure TForm2.CreateParams(var Params: TCreateParams); 
begin 
   inherited CreateParams( params ); 

   Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; 
end; 

但是然后他注意事项:

如果你点击次级形式的任务栏按钮而另一个应用程序是 活性,这将仍然把所有的应用程序形式以前。如果你 不要有选择

是谁把所有形式的当前形式的拥有者仍然是 Application.Handle.是 应用程序 这样做?为什么这样做?而不是做这个,不应该 可以这样做?有什么坏处的 这样做;我看到的缺点 它(系统菜单的工作不propertly、任务栏按钮略图都是不准确的,Windows®壳不能最小的窗口。


在另一个员额处理的 Application, 迈克Edenfield说,父窗口发送的其他窗口是他们最大限度地减少、最大限度地提高和恢复的消息:

这将增加的任务栏按钮你的形式,但还有其他一些次要的细节 处理。最明显的是,你的形式仍然收到降低/最大限度地获得发送到父 形式(主要形式应用程序)。为了避免这种,你可以安装一个消息 处理程序WM_SYSCOMMAND通过增加一行如:

procedure WMSysCommand(var Msg: TMessage); WM_SYSCOMMAND; 

procedure TParentForm.WMSysCommand(var Msg: TMessage); 
begin 
   if Msg.wParam = SC_MINIMIZE then 
   begin 
      // Send child windows message, don't 
      // send to windows with a taskbar button. 
   end; 
end; 

注意,此处理程序进去的 形成一个你想表现得独立地的>其余的应用程序,从而避免通过在减少的信息。你可以添加类似>码SC_MAXIMIZE,SC_RESTORE,等等。

它是如何尽量降低/最大化/恢复的消息我Windows视窗不要在我的窗口?这是因为消息往一个窗口,通过Windows®到窗口的所有者?在这种情况下的所有形式在德尔斐应用程序是"拥有" Application?并不意味着使所有人null:

procedure TForm2.CreateParams(var Params: TCreateParams);
begin
   inherited;
   Params.WndParent := 0; //NULL
end;

将删除 Application 它是窗口处理干扰我的形式,并Windows应该再次发送 我mimimize/最大化/恢复的信息?


也许如果我们比较和对比,现在"正常的"Windows的应用程序做的事情,如何Borland最初的设计应用德尔菲做的事情-关于这个 Application 对象和它的主要环。

  • 什么解决方案是的 Application 对象解决?
  • 什么改变了以后版本的德尔菲这样,这些相同的问题不存在吗?
  • 有没有变化,在以后版本的德尔菲未介绍其他问题,即初始应用程序的设计试过如此难以解决?
  • 怎么可以那些较新的应用程序仍然能没有用干扰他们吗?

显然Borland实现的缺陷,在他们最初的设计。什么是他们最初的设计,有什么问题就解决了,有什么缺陷,什么是重新设计,以及它如何解决这个问题?

有帮助吗?

解决方案

原因的申请窗口有点肮脏的历史。当发展中Delphi1,我们知道我们想要使用"SDI"(windows散落在桌面)ui模型的环境。我们还知道,Windows吸(和仍然不会)在这一模式。然而,我们也注意到这些基本届时采用这一模式似乎运作良好。在进一步审查,我们发现,VB使用一个特殊的"隐藏"停车窗被用作"主人"(Windows模糊的概念的父母和所有者的时候,但这种区别是相似VCL)对于所有其它可见的窗口。

这是我们如何解决的"问题"windows含有主菜单是很少集中如此处理Alt-F的文件菜单只是不工作。通过使用该中心的停车窗户为中介,我们可以更容易地跟踪和路线消息的适当的窗户。

这种安排也得到解决的另一个问题通常多顶级的窗户被完全独立的。通过使该应用程序处理的"所有者"的所有这些窗户,他们都会表现在音乐会。例如,你可能已经注意到,当你选择 任何 应用程序的窗户, 所有 的windows的应用程序移至前保留它们的z-order彼此相关。这也将使用最小化和恢复作为一种功能性的分组。

这是因为采用这种模式。我们 可能 手动完成所有这些工作,以保持直的,但设计理念是不要重新发明了窗户,但要利用它在哪里我们可能。这也是为什么一个TButton或TEdit是 真的 一窗口"用户"按钮和编辑窗口类和风格分别。

作为窗户的演变,即"SDI"模式开始脱落的赞成。事实上窗开始成为"敌意的"这样式应用程序。从Windows Vista开始并持续到7、用户壳似乎并不工作,以及与一个应用程序使用一个停车的窗口。因此,我们出发去洗牌的事情在VCL消除停车的窗口,并将其功能为主的形式。这提出了几个"鸡蛋"的问题由此我们需要有停车的窗口提供足够早的应用程序初始化,以便其他窗口可以"附加",但主要的形式本身可能不会构成足够很快。TApplication有跳过几个篮球得到这个工作,并已经有一些细微的边缘情况,造成问题,但大多数问题已经作出。然而,对于任何应用程序移动向前,它将保持使用较旧的停车窗模型。

其他提示

所有VCL应用程序有一个"隐藏"顶级窗口所谓的应用程序。这是自动应用程序的启动。除其他事项外,它是主要的windows的消息处理程序VCL--因此应用程序。ProcessMessages.

具有应用程序的顶级别窗口,隐藏的否会导致一些奇怪的事情,明显的不完整的系统菜单,显示在任务吧,和不正确的拇指指甲windows Vista。后来版本的德尔菲纠正这种情况。

然而,不是所有的窗户都必须有其作为父母,Windows只是倾向于更好地工作,如果它是。然而,任何形式创建的应用程序。CreateForm将它作为父母,而且它也将拥有的应用程序的对象。因为他们是拥有,他们将被释放,一旦申请被释放。这发生在幕后形式。DoneApplication

看来源形式。考绩制度(Delphi2009年),似乎他们创造一个"主人"窗口在win32gui应用程序,以允许电话来

  • TApplication.最小化
  • TApplication.恢复
  • 等等

它的出现,信息传递给 Application.Handle 转发作为相应的 MainForm, 如果它存在。这将使该程序作出响应,以尽量减少,等等如果主要的窗口没有被创建。通过修改该项目的来源,您可以创建一个特尔斐应用程序 没有 一个主要的窗口。

在这种情况下, TApplication 方法仍然会工作,甚至如果你还没有创建的一个主要的窗口。不知道,如果我掌握的所有目的,但是我没有时间去通过的所有TApplication代码。

每你的问题:

  • 哪里来的? 它是处理一窗口的建立在 TApplication.Create

  • 什么窗把手吗? 一个假的窗口,每gui德尔福应用程序需要的一部分TApplication抽象

  • 它是windows处理的应用程序的主要形式 没有

  • 如果它不处理的应用程序的mainform那么它是什么? 见上

  • 更重要的是:为什么是它最终的父母的每形式? 假设你是对的,其最终的父母,我假设它是如此,因为它可以很容易地找到所有形式在应用程序(列举了儿童的这种"主人"的形式)。

  • 而最重要的是:为什么一切就会失控,如果我尝试了一种形式是unparented 我想,因为隐藏的"主人"的形式得到系统的消息 应该 通过其儿童和/或mainform,但不能找到unparented形式。

无论如何,这就是我带上它。你也许可以了解更多的看TApplication宣言》和代码 forms.pas.底线我看到的是这是一个方便的抽象概念。

最好的问候,

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top