Esto es evidentemente por diseño. Código de la muestra fragmento de '' ribbonactnctrls.pas:
procedure TRibbonBaseButtonControl.Click;
begin
inherited;
SetFocus(Application.MainForm.Handle);
end;
Como se puede ver que no hay condiciones controladas que ayudarían a evitar la llamada. También hay el mismo código en la selección de elementos del menú y en los controladores de pulsación de teclas.
Probablemente modificaría la fuente comentando las llamadas de enfoque, y trataré de ver si hay algún efecto secundario.
Como alternativa, puede restaurar el enfoque a su formulario después de que se cambie al formulario principal. Supongamos 'ActionList1' es el TActionList que contiene las acciones estándar en el formulario principal no :
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;
Este será sin embargo causar la forma principal a parpadear brevemente cada vez que se ejecuta una acción. Si no quieres eso, puedes cambiar el diseño para que el formulario principal sepa cuándo está recibiendo un enfoque no deseado y simular que no está enfocado.
En unidad1:
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;
en unit2:
uses
unit1;
procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
begin
Form1.IgnoreFocus := True;
PostMessage(Form1.Handle, UM_CANCELIGNOREFOCUS, NativeInt(Self), 0);
end;
Sin embargo, esto no es suficiente si no se ha configurado 'MainFormOnTaskBar' en la fuente del proyecto, desde entonces, la forma principal no solo ganará foco, sino que será llevado al frente. En este caso, ambas formas podrían responder al cambio/activación de foco no deseado congelando sus z-órdenes. El código entonces convertido para unidad1:
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;
y para unit2:
type
TForm2 = class(TForm)
..
procedure ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
private
procedure WMWindowPosChanging(var Msg: TWMWindowPosChanging);
message WM_WINDOWPOSCHANGING;
public
end;
var
Form2: TForm2;
implementation
uses
unit1;
{$R *.dfm}
procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
begin
Form1.IgnoreFocus := True;
PostMessage(Form1.Handle, UM_CANCELIGNOREFOCUS, NativeInt(Self), 0);
end;
procedure TForm2.WMWindowPosChanging(var Msg: TWMWindowPosChanging);
begin
inherited;
if Form1.IgnoreFocus then
Msg.WindowPos.flags := Msg.WindowPos.flags or SWP_NOZORDER;
end;
Una cinta pretende ser un elemento de interfaz de usuario en el formulario principal, lo hace, de hecho, "modificar" la forma es añadido a. Si pones una cinta en algún lugar que no sea en la forma principal de tu programa, y envía el foco a la aplicación. MainForm, no me sorprende; espera que sea parte de la forma principal. El VCL viene con el código fuente para que pueda abrir la unidad y ver si puede encontrar el código en cuestión. –
La aplicación que estoy diseñando va para una sensación de "Outlook", que, en su implementación, utiliza una cinta para el programa principal y una cinta diferente para crear correos electrónicos, elementos de calendario, contactos, etc. Siempre que utilizo una acción de cinta de Outlook en un correo electrónico, no devuelve mi enfoque a la ventana principal de Outlook. He buscado un poco a través de la fuente para el componente TRibbon, pero es cierto que es un poco grueso. Continuaré haciéndolo para ver si puedo descubrir dónde está sucediendo esto y si puedo anular este comportamiento.Hasta ahora, sin embargo, no he tenido suerte. – Aaron
Suena terriblemente como un error para mí. Ese comportamiento no debería suceder. Si puede repro en una aplicación simple, entonces debe informarlo al QC –