什么是TApplication.Handle
?德尔福:什么是Application.Handle?
- 它从何而来?
- 它为什么存在?
- 而最重要的是:为什么所有表单都将它作为父窗口处理?
Delphi帮助说:
TApplication.Handle
提供对窗口办理 应用的主要形式(窗口)的 。调用Windows API的需要父窗口句柄 功能 时
property Handle: HWND;
说明
用途把手。例如, 显示其自己的顶层弹出窗口 一个DLL需要一个父窗口 在 应用显示其窗口。使用手柄财产 使得 应用程序的窗口等部分,让他们 最小化,恢复,启用和 与应用程序禁用。
如果我专注于词“应用的主要形式的窗口句柄”,我认为这意味着应用的主要形式的窗口句柄,然后我可以比较:
- “应用程序的主要形式的窗口句柄”,用
- 的
Application
MainForm
的窗口句柄
,但他们是不一样的:
Application.MainForm.Handle: 11473728
Application.Handle: 11079574
那么,什么是Application.Handle
?
- 它从何而来?
- 什么窗口®窗口句柄是它?
- 如果它是的Windows ®窗口句柄的
Application
的MainForm
,那他们为什么不匹配? - 如果是不是
Application
的窗口句柄MainForm
,那么它是什么? - 更重要的是:为什么它是每种形式的最终父母?
- 而且最重要的是:如果我试图让一个窗体没有显示(所以我可以显示在任务栏上),或者尝试使用类似IProgressDialog的东西,为什么一切都会失控?
真的,我问的是:什么是使Application.Handle存在的设计原理?如果我能理解为什么,那该如何变得明显。
更新通过的二十个问题游戏的认识:
此:
在谈论如何让一个窗口的解决方案通过使它的主人
null
,Peter Below in 2000 said出现在任务栏上可能会导致一些问题与 辅助形式显示的模态形式。如果用户在模态 表单启动时切换离开应用程序,然后回到显示它的表单,模式表单可能会隐藏在表单下方 。这是可能通过确保 模式窗体父到显示了它的形式( `params.WndParent``如上使用)
应对这种但这是不可能的从标准 对话
Dialogs
单元和例外,这就需要更多的努力 让他们的工作权利(基本处理Application.OnActivate
, 通过GetLastActivePopup
寻找父对象应用模式表单,并通过SetWindowPos
将他们的Z顺序的顶部) 。
- 为什么模式表单最终会被卡在其他表单之后?
- 什么机制通常将模态形式带到前面,为什么它在这里不起作用?
- Windows ®负责显示窗口堆叠。 Windows ®没有显示正确的窗口出了什么问题?
他还谈到使用新的Windows扩展样式,迫使一个窗口出现在任务栏上(当使它无主的一般规则是不够的,不切实际的,或不希望),通过添加WS_EX_APPWINDOW
扩展风格:
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(params);
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;
但他警告:
如果您在辅助形式单击任务栏按钮,而另一个应用是 活跃,这将仍然把所有的应用程序˚F orms前面。如果您 不希望有选择
谁把所有形式的前面,当窗体的所有者仍然是Application.Handle
。是应用程序这样做?它为什么这样做?而不是这样做,不应该不是要做到这一点吗? 不是这样做的缺点是什么;我看到的的缺点做它(系统菜单的不propertly工作,任务栏按钮的缩略图是不准确时,Windows ®外壳无法最小化窗口
在另一篇文章中涉及的Application
,Mike Edenfield says that the parent window sends other window's their minimize, maximize and restore messages:
这将增加任务栏按钮的形式,但也有其他一些小的细节 手柄。最明显的是,你的表格仍收到最小化/最大化获取发送到父 形式(理论上的主要形式e应用程序)。
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;
注意,此处理云在家长形式要表现的一个independantly的>:为了避免这种情况,你可以通过添加一条线,如安装WM_SYSCOMMAND消息 处理器应用程序的其余部分,以避免传递最小化消息。您可以添加类似>代码SC_MAXIMIZE,SC_RESTORE等
它是如何最小化/最大化/还原我的Windows ® Windows消息都不会到我的窗口?这是否是因为发往窗口的消息是由Windows ®发送给窗口的所有者?在这种情况下,Delphi应用程序中的所有表单均由Application
“拥有”?这是否并不意味着让车主空:
procedure TForm2.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.WndParent := 0; //NULL
end;
将删除Application
,并从我的形式,干扰它的窗口句柄,和Windows应该再次发出我我mimimize /最大化/还原邮件?
或许,如果我们比较和对照现在“正常”的Windows应用程序做的事情,与Borland如何最初设计Delphi应用程序做的事情 - 对于此Application
对象和它的主循环。
- 什么解决方案是
Application
对象解决? - Delphi的后续版本做了哪些修改,以便这些相同的问题不存在?
- Delphi的后续版本中的更改是否引入了其他问题,即初始应用程序设计如何努力解决?
- 这些较新的应用程序如何在没有Application干扰的情况下仍能正常工作?
很明显,Borland意识到了他们最初设计中的缺陷。他们最初的设计是什么?它解决了什么问题?缺陷是什么?重新设计了什么?它是如何解决问题的?
我想你会有兴趣了解这两个技巧:http://yoy.be/item.asp?i89 http://yoy.be/item.asp?i87 – 2010-02-05 07:12:30
@Stinh桑德斯:我'已经看到了这些,他们不解决问题。此外,绝对不要将GetDesktopWindow作为窗口的所有者传递,因为这些主题和其他帖子都暗示了这一点。这样做会导致Windows冻结。这是微软修补CreateWindow的一个问题,因此任何传递GetDesktopWindow作为所有者的人都改为使用NULL。如果我可以在** yoy.com **上编辑该帖子,我会的。 – 2010-02-05 14:52:39