Delphi 调用TCustomForm.SetFocusedControl函数后出现异常窗体

Delphi 调用TCustomForm.SetFocusedControl函数后出现异常窗体,delphi,Delphi,首先,我的目标不是把焦点放在一个控件上,而是试图理解为什么一个窗体在停用和重新激活后会有不同的外观 是TCustomForm.SetFocusedControl函数的描述: 将焦点设置为窗体上的控件 使用SetFocusedControl为表单输入焦点提供控件。如果控件参数指定的控件已在接收焦点的过程中,则SetFocusedControl返回false,否则返回true 注意:返回值true并不表示控件已成功接收输入焦点。如果控件不能具有焦点,例如,如果它不可见,SetFocusedContr

首先,我的目标不是把焦点放在一个控件上,而是试图理解为什么一个窗体在停用和重新激活后会有不同的外观

是TCustomForm.SetFocusedControl函数的描述:

将焦点设置为窗体上的控件

使用SetFocusedControl为表单输入焦点提供控件。如果控件参数指定的控件已在接收焦点的过程中,则SetFocusedControl返回false,否则返回true

注意:返回值true并不表示控件已成功接收输入焦点。如果控件不能具有焦点,例如,如果它不可见,SetFocusedControl仍将返回true,表示已进行尝试

为了重现观察到的行为,我创建了一个简单的测试应用程序:

以下是我复制这种行为的步骤:

1开始时,表格显示如下:

2点击按钮1后,我可以看到:

Memo1.Text报告Edit2是活动控件,但它没有聚焦的外观选择和光标

表单的标题不是灰色的,单击它不会导致任何更改

3我单击了windows任务栏上的窗体外部

表单的标题变成灰色

4我已通过单击表单标题重新激活了表单:

Edit2现在看起来有焦点了

有人能解释一下第2点和第4点表格的区别吗?在这两种情况下,Edit2都是主动控制,我无法理解这种外观差异

进一步资料:


在Delphi 2007、Windows 10 Pro上测试。

不管文档怎么说,TForm.SetFocusedControl实际上并没有将输入焦点设置到Edit2上。Win32函数没有被调用。按钮1在单击时接收输入焦点,并在调用SetFocusControl后保持焦点。这就是为什么Edit2不呈现为聚焦。如果要将输入焦点移动到Edit2,请调用Edit2.SetFocus而不是Self.SetFocusedControlEdit2

但是,调用SetFocusedControl确实会更改VCL的内部状态。它设置窗体的ActiveControl和FocusedControl属性,设置全局屏幕对象的ActiveControl、ActiveCustomForm、ActiveForm和FocusedForm属性,并对其CustomForms和Forms属性的条目重新排序


当窗体被停用然后重新激活时,VCL会将输入焦点设置为最后一个已知的焦点控件,该控件现在是Edit2,而不是Button1。

不管文档怎么说,TForm.SetFocusedControl实际上不会将输入焦点设置为Edit2。Win32函数不会被调用。按钮1在单击时接收输入焦点,并在调用SetFocusControl后保持焦点。这就是为什么Edit2不呈现为聚焦。如果要将输入焦点移动到Edit2,请调用Edit2.SetFocus而不是Self.SetFocusedControlEdit2

但是,调用SetFocusedControl确实会更改VCL的内部状态。它设置窗体的ActiveControl和FocusedControl属性,设置全局屏幕对象的ActiveControl、ActiveCustomForm、ActiveForm和FocusedForm属性,并对其CustomForms和Forms属性的条目重新排序


当窗体被停用然后重新激活时,VCL将输入焦点设置为最后一个已知的焦点控件,该控件现在是Edit2而不是Button1。

为什么要调用此函数?我想我们都同意你不应该这么做。你为什么要调用这个函数呢?我想我们都同意你不该这么做。
procedure TForm1.Button1Click(Sender: TObject);
var
  Res : Boolean;
begin
  Res := Self.SetFocusedControl(Edit2);
  if(Self.ActiveControl <> nil) then
  begin
    Memo1.Text :=
      'ActiveControl is ' + Self.ActiveControl.Name + sLineBreak +
      'SetFocusedControl result is ' + BoolToStr(Res, True);
  end;
end;