delphi – MainFormOnTaskbar工具提示导致焦点窃取

delphi – MainFormOnTaskbar工具提示导致焦点窃取,第1张

概述我使用Delphi XE2构建了下面的代码.它创建Form1,Form1立即创建Form2的实例.当我按下Form2上的按钮时,将创建第二个Form2. 现在,如果我将鼠标悬停在第二个,最上面的Form2上的按钮上,并等待工具提示出现,工具提示出现的那一刻,第一个Form2来到前面,窃取焦点. 仅当Application.MainFormOnTaskbar为True时才会出现此问题.它还依赖于从F 我使用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.

Unit1.pas

unit Unit1;interfaceuses  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.

Unit2.pas

unit Unit2;interfaceuses  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;implementationuses  System.SysUtils,Unit1;{$R *.dfm}procedure TForm2.button1Click(Sender: TObject);begin  Form1.CreateForm2;end;end.
解决方法 这里的关键问题是TForm2的第一个实例被创建为应用程序窗口Application.Handle所拥有的窗口.在这里我指的是 Windows meaning of owner.在VCL语言中,这被称为d出式父级.

现在,当您创建第一个TForm2实例时,Application.MainForm属性仍为零.并且因为您没有显式指定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;
总结

以上是内存溢出为你收集整理的delphi – MainFormOnTaskbar工具提示导致焦点窃取全部内容,希望文章能够帮你解决delphi – MainFormOnTaskbar工具提示导致焦点窃取所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/langs/1265334.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存