如何在TscGPToolPager的OnChangePage事件中为TEdit设置焦点?
解决TscGPToolPager页面切换时设置控件焦点无效的问题
原因分析
在TscGPToolPager的OnChange事件中直接调用SetFocus无效,通常是因为事件触发时机过早——此时页面控件还未完成激活、显示的完整流程,焦点设置操作被后续的窗口状态更新覆盖。
方案1:用PostMessage延迟执行焦点设置
将焦点设置操作通过PostMessage投递到消息队列末尾,等当前页面切换的所有流程完成后再执行。
procedure TForm1.scGPToolPager1Change(Sender: TObject); var TargetEdit: TEdit; begin // 判断当前激活的页面 if scGPToolPager1.ActivePage = Page1 then begin TargetEdit := Page1.Edit1; // 发送WM_SETFOCUS消息延迟设置焦点 PostMessage(TargetEdit.Handle, WM_SETFOCUS, 0, 0); end else if scGPToolPager1.ActivePage = Page2 then begin TargetEdit := Page2.Edit2; PostMessage(TargetEdit.Handle, WM_SETFOCUS, 0, 0); end; end;
方案2:利用页面的OnEnter事件
TscGPToolPagerPage继承自TWinControl,自带OnEnter事件。当页面切换完成并获得输入焦点时,该事件会触发,此时设置焦点能直接生效。
- 在设计期选中目标
TscGPToolPagerPage控件 - 在Object Inspector中绑定
OnEnter事件到如下处理函数:
procedure TForm1.Page1Enter(Sender: TObject); begin Page1.Edit1.SetFocus; end; procedure TForm1.Page2Enter(Sender: TObject); begin Page2.Edit2.SetFocus; end;
方案3:子类化TscGPToolPagerPage捕获显示消息
如果需要更精准的显示触发时机,可以子类化TscGPToolPagerPage,捕获WM_SHOWWINDOW消息,在页面真正显示时设置焦点。
type // 子类化原控件 TCustomPagerPage = class(scGPToolPager.TscGPToolPagerPage) protected procedure WndProc(var Message: TMessage); override; end; // 自定义页面类(可选,若需在设计期创建可注册) TMyPagerPage = class(TCustomPagerPage) private FEdit: TEdit; public constructor Create(AOwner: TComponent); override; end; constructor TMyPagerPage.Create(AOwner: TComponent); begin inherited; FEdit := TEdit.Create(Self); FEdit.Parent := Self; FEdit.Name := 'PageEdit'; FEdit.SetBounds(10, 10, 150, 22); end; procedure TCustomPagerPage.WndProc(var Message: TMessage); var TargetEdit: TEdit; begin inherited; // 捕获窗口显示消息,wParam为True时表示显示 if (Message.Msg = WM_SHOWWINDOW) and Boolean(Message.WParam) then begin TargetEdit := FindChildControl('PageEdit') as TEdit; if Assigned(TargetEdit) then TargetEdit.SetFocus; end; end;
内容的提问来源于stack exchange,提问作者Stepel
相关产品推荐
相关产品推荐

