当从另一个表单的onActivate调用时,模态窗体中的控件不会获得焦点。为什么呢?

时间:2017-04-18 21:45:20

标签: delphi

在某些情况下,我的应用程序尝试在显示另一个表单(Form1)后自动打开某个表单(Form2)。我使用onFormActivate来呼叫ShowModal,但在显示第二个表单后,它的控件正在失去焦点。

重现:

  1. 创建新的VCL应用程序;
  2. 创建第二个表单并在其中删除TEdit;
  3. 在主表单上添加onFormActivate侦听器;
  4. '

    procedure TForm1.FormActivate(Sender: TObject);
    begin
      Form2.ShowModal;
    end;
    

    运行后,您将看到Form2正在显示。但编辑并没有得到关注。 如果我在项目文件中注释MainFormOnTaskbar,它就可以工作。

    // Application.MainFormOnTaskbar := True;
    

    但这不是我应该改变的。我想了解:为什么TEdit正在失去焦点?

1 个答案:

答案 0 :(得分:4)

当焦点正在转移时,

OnActivate被触发。中断这个过程是一个非常糟糕的主意。

如果您希望OnActivate事件触发ShowModal()调用,则应使用PostMessage()(或短TTimer)延迟调用,以便消息循环完成处理已经进行的焦点转移,然后可以在安全的情况下执行ShowModal()。例如:

const
  WM_SHOWMODAL_FORM2 = WM_APP + 1;

procedure TForm1.FormActivate(Sender: TObject);
begin
  PostMessage(Handle, WM_SHOWMODAL_FORM2, 0, 0);
end;

procedure TForm1.WndProc(var Message: TMessage);
begin
  if Message.Msg = WM_SHOWMODAL_FORM2 then
    Form2.ShowModal
  else
    inherited;
end;