Delphi XE – TRIBbon动作总是将焦点发送给MainForm
发布时间:2020-12-15 09:50:58 所属栏目:大数据 来源:网络整理
导读:当我将TRibbon控件放在不是应用程序MainForm的表单上时,TRibbon的操作(即剪切,粘贴)将始终在执行操作后将焦点返回到MainForm. 即使持有TRibbon的TForm不是MainForm的子代,也会发生这种情况. 我使用的是Windows 7 64位,Embarcadero RAD Studio XE版本15.0.395
当我将TRibbon控件放在不是应用程序MainForm的表单上时,TRibbon的操作(即剪切,粘贴)将始终在执行操作后将焦点返回到MainForm.
即使持有TRibbon的TForm不是MainForm的子代,也会发生这种情况. 我使用的是Windows 7 64位,Embarcadero RAD Studio XE版本15.0.3953.35171. 我是否错误地使用了TRibbon控件,或者这是TRibbon的一个问题? 解决方法
这显然是设计上的. ‘ribbonactnctrls.pas’的示例代码段:
procedure TRibbonBaseButtonControl.Click; begin inherited; SetFocus(Application.MainForm.Handle); end; 如您所见,没有检查条件可以帮助我们避免通话.菜单项选择和按键处理程序中也有相同的代码. 我可能会修改注释焦点调用的源,并尝试查看是否有任何副作用. 作为替代方案,您可以在切换到主窗体后将焦点恢复到窗体.假设’ActionList1’是包含非主窗体上的标准动作的TActionList: type TForm2 = class(TForm) .. procedure ActionList1Execute(Action: TBasicAction; var Handled: Boolean); private .. procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean); begin PostMessage(Handle,WM_SETFOCUS,WPARAM(True),0); end; 但是,这会导致主表单在每次执行操作时都会短暂闪烁.如果您不想这样做,您可以更改设计,以便主表单知道何时获得不需要的焦点,并假设它没有聚焦. 在unit1中: const UM_CANCELIGNOREFOCUS = WM_USER + 7; type TForm1 = class(TForm) .. private FIgnoreFocus: Boolean; procedure UMCancelIgnoreFocus(var Msg: TMessage); message UM_CANCELIGNOREFOCUS; procedure WMNCActivate(var Msg: TWMNCActivate); message WM_NCACTIVATE; public property IgnoreFocus: Boolean write FIgnoreFocus; end; ... uses Unit2; procedure TForm1.WMNCActivate(var Msg: TWMNCActivate); begin Msg.Result := 0; if not (Msg.Active and FIgnoreFocus) then inherited; end; procedure TForm1.UMCancelIgnoreFocus(var Msg: TMessage); begin FIgnoreFocus := False; TForm(Msg.WParam).SetFocus; end; 在unit2: uses unit1; procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean); begin Form1.IgnoreFocus := True; PostMessage(Form1.Handle,UM_CANCELIGNOREFOCUS,NativeInt(Self),如果你没有在项目源中设置’MainFormOnTaskBar’,这还不够,因为那时主窗体不仅会获得焦点,而且会被带到前面.在这种情况下,两种形式都可以通过冻结它们的z顺序来响应不需要的焦点变化/激活.然后代码将变为unit1:const UM_CANCELIGNOREFOCUS = WM_USER + 7; type TForm1 = class(TForm) .. private FIgnoreFocus: Boolean; procedure UMCancelIgnoreFocus(var Msg: TMessage); message UM_CANCELIGNOREFOCUS; procedure WMNCActivate(var Msg: TWMNCActivate); message WM_NCACTIVATE; procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging); message WM_WINDOWPOSCHANGING; public property IgnoreFocus: Boolean read FIgnoreFocus write FIgnoreFocus; end; var Form1: TForm1; implementation {$R *.dfm} uses Unit2; procedure TForm1.WMNCActivate(var Msg: TWMNCActivate); begin Msg.Result := 0; if not (Msg.Active and FIgnoreFocus) then inherited; end; procedure TForm1.WMWindowPosChanging(var Msg: TWMWindowPosChanging); begin inherited; if FIgnoreFocus then Msg.WindowPos.flags := Msg.WindowPos.flags or SWP_NOZORDER; end; procedure TForm1.UMCancelIgnoreFocus(var Msg: TMessage); begin FIgnoreFocus := False; TForm(Msg.WParam).SetFocus; end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |