Ian*_*dby 5 delphi z-order delphi-xe2
我使用Delphi XE2构建了下面的代码.它创建Form1,Form1立即创建Form2的实例.当我按下Form2上的按钮时,将创建第二个Form2.
现在,如果我将鼠标悬停在第二个,最上面的Form2上的按钮上,并等待工具提示出现,工具提示出现的那一刻,第一个 Form2来到前面,窃取焦点.
只有在出现问题Application.MainFormOnTaskbar
的True
.它还依赖于从Form1 FormCreate
方法创建的第一个Form2 .如果我使用PostMessage()
延迟创建第一个Form2直到应用程序完成初始化,问题就会消失.
我想知道为什么会这样.我已经知道Delphi的Application对象处理很多事情,包括提示显示,我知道Delphi可以在初始化期间重新创建一个窗口的句柄,但是我无法通过这个来完全解释上述行为(或者确实上述两个事实是否相关).
Project1.dpr
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True; // False makes problem go away
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
Run Code Online (Sandbox Code Playgroud)
Unit1.pas
unit Unit1;
interface
uses
Vcl.Forms, Unit2;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
public
procedure CreateForm2;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
CreateForm2;
end;
procedure TForm1.CreateForm2;
var
frm : TForm2;
begin
frm := TForm2.Create(Application); // (Could pass Self - makes no difference)
frm.Show;
end;
end.
Run Code Online (Sandbox Code Playgroud)
Unit2.pas
unit Unit2;
interface
uses
Vcl.Forms, System.Classes, Vcl.Controls, Vcl.StdCtrls, WinApi.Windows;
type
TForm2 = class(TForm)
Button1: TButton; // This button has a hint
procedure Button1Click(Sender: TObject);
end;
var
Form2: TForm2;
implementation
uses
System.SysUtils, Unit1;
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
Form1.CreateForm2;
end;
end.
Run Code Online (Sandbox Code Playgroud)
这里的关键问题是第一个实例TForm2
被创建为应用程序窗口所拥有的窗口,Application.Handle
.在这里,我指的是所有者的Windows含义.在VCL语言中,这称为弹出父级.
现在,当您创建第一个TForm2
实例时,该Application.MainForm
属性仍然是nil
.并且因为您没有明确分配PopupParent
,所以代码TCustomForm.CreateParams
将所有者设置为应用程序窗口.
您根本不希望您的窗口被隐藏的应用程序窗口拥有.这就是为什么第一个TForm2
实例有时出现在所有其他窗口后面的原因,特别是在主窗体后面.它只是由错误的所有者创建的.
获得的表单Application.Handle
显示在THintWindow.ActivateHint
.这是因为读取的行ParentWindow := Application.Handle
.接下来是调用SetWindowPos(Handle, ...)
,导致错误拥有的表单出现在前面.据推测,这种形式出现在前面,因为它也属于Application.Handle
.现在我对精确的机制没有明确的解释,但我没有发现那非常有趣,因为表格设置错误.
无论如何,根本问题在于您创建了一个错误拥有的窗口.因此,解决方案是确保窗口正确拥有.通过分配来做到这一点PopupParent
.例如:
procedure TForm1.CreateForm2;
var
frm : TForm2;
begin
frm := TForm2.Create(Application); // (Could pass Self - makes no difference)
frm.PopupParent := Self;
frm.Show;
end;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
874 次 |
最近记录: |