>它从哪里来?
>为什么会存在?
>最重要的是:为什么所有的窗体都有它的父窗口句柄?
Delphi帮助说:
TApplication.Handle
Provides access to the window handle
of the main form (window) of the
application.06000
Description
Use Handle when calling Windows API
functions that require a parent window
handle. For example,a DLL that
displays its own top-level pop-up
windows needs a parent window to
display its windows in the
application. Using the Handle property
makes such windows part of the
application,so that they are
minimized,restored,enabled and
disabled with the application.
如果我专注于单词“应用程序的主窗体的窗口句柄”,我认为这意味着应用程序的主窗体的窗口句柄,然后我可以比较:
>“窗体句柄的主窗体的应用程序”,带
>应用程序的MainForm的窗口句柄
但是他们不一样:
Application.MainForm.Handle: 11473728 Application.Handle: 11079574
那么什么是Application.Handle呢?
>它从哪里来?
>什么Windows®窗口句柄是什么?
>如果它是应用程序的MainForm的Windows®窗口句柄,那么他们为什么不匹配?
>如果它不是应用程序的MainForm的窗口句柄,那么是什么呢?
>更重要的是:为什么它是每种形式的最终父母?
>最重要的是:为什么一切都会haywire如果我试图有一个形式是unparented(所以我可以出现在任务栏上),或者尝试使用像IProgressDialog的东西?
真正的问题是:Application.Handle存在的设计理由是什么?如果我能理解为什么,如何应该变得明显。
更新通过游戏的二十个问题了解:
在谈论解决方案使窗口出现在任务栏通过使其所有者null,Peter Below in 2000 said:
This can cause some problems with modal forms shown from
secondary forms.If the user switches away from the app while a modal
form is up,and then back to the form that showed it,the modal form may
hide beneath the form. It is possible to deal with this by making sure
the modal form is parented to the form that showed it (using
`params.WndParent“ as above)But this is not possible with the standard
dialogs from theDialogs
unit and exceptions,which need more effort to
get them to work right (basically handlingApplication.OnActivate
,
looking for modal forms parented to Application viaGetLastActivePopup
and bringing them to the top of the Z-order viaSetWindowPos
).
>为什么一个模态形式最终被卡在其他形式之后?
>什么机制通常带来的模式形式的前面,为什么它不功能这里?
>Windows®负责显示堆叠的窗口。什么错误Windows®没有显示正确的窗口?
他还谈到了通过添加WS_EX_APPWINDOW扩展样式,使用新的Windows扩展样式强制窗口显示在任务栏上(当使其不拥有的正常规则不够,不切实际或不受欢迎时)
procedure TForm2.CreateParams(var Params: TCreateParams); begin inherited CreateParams( params ); Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW; end;
但后来他警告:
If you click on a secondary forms taskbar button while another app is
active this will still bring all the applications forms to front. If you
do not want that there is option
当表单的所有者仍然是Application.Handle时,谁将所有的表单带到前端。应用程序这样做吗?为什么要这样做?而不是这样做,不应该不是这样做吗?不这样做的缺点是什么?我看到这样做的缺点(系统菜单不正常工作,任务栏按钮缩略图不准确,Windows®外壳不能最小化窗口。
在另一个处理应用程序的帖子中,Mike Edenfield says that the parent window sends other window’s their minimize,maximize and restore messages:
This will add the taskbar button for your form,but there are a few other minor details to
handle. Most obvIoUsly,your form still receives minimize/maximize that get sent to the parent
form (the main form of the application). In order to avoid this,you can install a message
handler for WM_SYSCOMMAND by adding a line such as:06003
Note that this handler goes in the PARENT form of the one you want to behave independantly of > the rest of the application,so as to avoid passing on the minimize message. You can add similar > code for SC_MAXIMIZE,SC_RESTORE,etc.
如何最小化/最大化/恢复消息的Windows®窗口不会到我的窗口?这是因为发送到窗口的消息被Windows®发送到窗口的所有者?在这种情况下,Delphi应用程序中的所有表单都是由应用程序“拥有”的?这不意味着使所有者null:
procedure TForm2.CreateParams(var Params: TCreateParams); begin inherited; Params.WndParent := 0; //NULL end;
将删除应用程序,它的窗口句柄干扰我的形式,Windows应该再次发送我我的最小化/最大化/恢复消息?
也许如果我们比较和对比现在一个“正常的”Windows应用程序做事情,Borland最初设计Delphi应用程序做事情 – 对于这个Application对象和它的主循环。
>什么解决方案是Application对象解决?
>使用更高版本的Delphi做了什么更改,以使这些相同的问题不存在?
> Delphi的更新版本的变化没有引入其他问题,初始应用程序设计尝试这么难解决?
>如果这些较新的应用程序仍然可以运行,而没有应用程序干扰他们?
显然,Borland意识到他们初始设计的缺陷。他们的初始设计是什么,解决什么问题,缺陷是什么,重新设计是什么,以及如何解决问题?
解决方法
这是我们如何解决“问题”,其中包含主菜单的窗口很少集中,所以处理Alt-F文件菜单根本不工作。通过使用这个中央停车窗口作为中介,我们可以更容易地跟踪和路由消息到适当的窗口。
这种布置也解决了另一个问题,其中通常多个顶级窗口是完全独立的。通过使应用程序处理所有这些窗口的“所有者”,他们都将一致行动。例如,您可能已经注意到,当您选择任何应用程序窗口时,所有应用程序窗口移动到前面并保持它们相对于彼此的z顺序。这也将使应用程序最小化和恢复为功能分组。
这是使用这个模型的结果。我们可以手动完成所有这些工作,以保持事情的直线,但设计哲学是不重新创造Windows,而是在我们可以利用它。这也是为什么一个TButton或TEdit真的是一个Windows“用户”BUTTON和EDIT窗口类和样式,为什么。
随着Windows的发展,“SDI”模式开始失去了青睐。事实上Windows本身开始变得“敌对”的那种风格的应用程序。从Windows Vista开始,继续到7,用户shell似乎不适合与使用停车窗口的应用程序。所以,我们开始在VCL中洗牌,以消除停车窗口并将其功能移动到主窗体中。这提出了几个“鸡和鸡蛋”问题,因此我们需要在应用程序初始化中足够早地提供停车窗口,以便其他窗口可以“附加”到它,但主窗体本身可能不会很快构建。 TApplication必须跳过几个圈来让这个工作,并有一些微妙的边缘情况下引起问题,但大多数的问题已经解决了。然而,对于任何应用程序,您向前移动,它将保持使用旧的停车窗口模型。