Delphi 12.1中Windows 11 VCL应用的TSearchBox获取焦点时自动选中文本失效问题
Delphi 12.1中Windows 11 VCL应用的TSearchBox获取焦点时自动选中文本失效问题
我之前在Windows 11环境下用Delphi 12.1开发VCL应用时,也碰到过TSearchBox自动选中文本失效的问题,太懂这种头疼的感觉了!你已经尝试的两种方法:
- 设计时将
AutoSelect属性设置为True - 在
OnEnter事件中手动设置SelStart、SelLength或者调用SelectAll
之所以没效果,核心原因是Windows 11自带的搜索框原生控件有自己的焦点处理逻辑,会在我们的代码执行后重置选中状态,直接调用的操作被覆盖了。
给你两个亲测有效的解决方案:
方案一:用PostMessage延迟发送选中文本指令
在OnEnter事件里通过PostMessage把选中文本的消息放到消息队列末尾,等控件完成焦点初始化后再执行:
procedure TForm1.SearchBoxMainEnter(Sender: TObject); var TargetSearchBox: TSearchBox; begin TargetSearchBox := Sender as TSearchBox; // 发送EM_SETSEL消息,参数0和-1表示选中全部文本 PostMessage(TargetSearchBox.Handle, EM_SETSEL, 0, -1); end;
方案二:用TThread.Queue异步执行SelectAll
借助TThread.Queue让选中文本的操作在主线程空闲时执行,避开控件的焦点初始化流程:
procedure TForm1.SearchBoxMainEnter(Sender: TObject); var TargetSearchBox: TSearchBox; begin TargetSearchBox := Sender as TSearchBox; TThread.Queue(nil, procedure begin TargetSearchBox.SelectAll; end); end;
如果需要长期复用这个功能,还可以自定义一个TSearchBox子类,重写WM_SETFOCUS消息处理:
type TMySearchBox = class(TSearchBox) protected procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS; end; procedure TMySearchBox.WMSetFocus(var Message: TWMSetFocus); begin inherited; // 先执行原生的焦点处理逻辑 PostMessage(Handle, EM_SETSEL, 0, -1); // 再发送选中文本的消息 end;
之后把你的TSearchBox换成这个自定义控件,就能自动实现获焦选中文本的效果了。
备注:内容来源于stack exchange,提问作者user1580348




