我想让TEdit
对点击做出反应,例如Chrome和Firefox中的Url栏。在第一次单击时,他们选择所有文本,然后单击以删除选择,如下所示:
我的方法:
// 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事件即将触发之前,将始终清除选择。我已经尝试将此代码放入OnMouseUp
和OnMouseDown
事件,但问题保持不变。
我该如何解决?有没有办法在不添加额外的boolean
变量的情况下执行此操作来保存当前状态?
答案 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为零,因此,在创建表单时(并因此选择)聚焦。这会影响第一次单击控件。