TEdit选择单击文本,如Chrome和Firefox中的URL栏

时间:2016-11-23 16:53:58

标签: delphi vcl delphi-10.1-berlin

我想让TEdit对点击做出反应,例如Chrome和Firefox中的Url栏。在第一次单击时,他们选择所有文本,然后单击以删除选择,如下所示:

enter image description here

我的方法:

// This method is bound to the OnClick event
procedure TForm.edt_SearchClick(Sender: TObject);
begin 
  if edt_Search.SelLength > 0 then
    edt_Search.SelLength := 0
  else
    edt_Search.SelectAll;
end;

此代码无法按预期工作,因为edt_Search.SelLength始终为0.在OnClick事件即将触发之前,将始终清除选择。我已经尝试将此代码放入OnMouseUpOnMouseDown事件,但问题保持不变。

我该如何解决?有没有办法在不添加额外的boolean变量的情况下执行此操作来保存当前状态?

1 个答案:

答案 0 :(得分:4)

要在控件获得焦点时选择TEdit控件中的所有文本,只需处理OnEnter事件即可:

procedure TForm1.Edit1Enter(Sender: TObject);
begin
  PostMessage(Edit1.Handle, EM_SETSEL, 0, -1);
end;

您无法使用Edit1.SelectAll,因为默认行为(在OnEnter之后发生)会清除编辑控件中的任何选择。发布消息可确保在剩余的默认行为完成后处理该消息。

要完全模拟这些浏览器中的地址栏,该字段在退出控件时也会取消选择,因此在OnExit

procedure TForm.Edit1Exit(Sender: TObject);
begin
  PostMessage(Edit1.Handle, EM_SETSEL, 0, 0);
end;

浏览器字段还允许您在第一次进入时选择文本,因此在这种情况下您需要更加小心。作为一个黑客你可以使用插入器来完成它,但理想情况下你可以制作一个自定义控件:

type
  TEdit = class(Vcl.StdCtrls.TEdit)
    private
      FDoEnterSelect : boolean;
  end;

然后

procedure TForm1.Edit1Enter(Sender: TObject);
begin
  Edit1.FDoEnterSelect := true;
end;

procedure TForm1.Edit1Exit(Sender: TObject);
begin
  PostMessage(Edit1.Handle, EM_SETSEL, 0, 0);
end;

procedure TForm1.Edit1MouseUp(Sender: TObject; Button: TMouseButton;
                              Shift: TShiftState; X, Y: Integer);
begin
  if Edit1.FDoEnterSelect and
     (Edit1.SelLength = 0) then
       PostMessage(Edit1.Handle, EM_SETSEL, 0, -1);
  Edit1.FDoEnterSelect := false;
end;

procedure TForm1.Edit1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  Edit1.FDoEnterSelect := false;
end;

KeyUp处理程序处理标签到控件的情况。唯一剩下的奇怪情况是编辑控件的TabOrder为零,因此,在创建表单时(并因此选择)聚焦。这会影响第一次单击控件。