Jest to wyraźnie zgodne z projektem. Przykładowy kod urywek z „ribbonactnctrls.pas”:
procedure TRibbonBaseButtonControl.Click;
begin
inherited;
SetFocus(Application.MainForm.Handle);
end;
Jak widać nie ma warunków sprawdzane, które pomogą nam uniknąć połączenia. Ten sam kod znajduje się również w wyborze pozycji menu i kluczowych procedurach obsługi komunikatów.
Prawdopodobnie zmodyfikowałbym źródło komentując wywołania fokusu i spróbował sprawdzić, czy są jakieś efekty uboczne.
Jako alternatywę można przywrócić ostrość z powrotem do formularza po przełączeniu do formularza głównego. Załóżmy „ActionList1” jest TActionList że zawiera standardowe czynności na nie głównego formularza:
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;
Będzie to jednak spowodować główną postać krótko migać za każdym razem akcja jest wykonywana. Jeśli tego nie chcesz, możesz zmienić projekt tak, aby główna postać wiedziała, kiedy robi się niechciany fokus, i udawać, że nie jest skupiona.
W 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;
w Unit2:
uses
unit1;
procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
begin
Form1.IgnoreFocus := True;
PostMessage(Form1.Handle, UM_CANCELIGNOREFOCUS, NativeInt(Self), 0);
end;
Jednak to nie wystarczy, jeśli nie masz zestaw 'MainFormOnTaskBar' w źródle projektu, gdyż wtedy formularzu głównym nie tylko skupi się, ale zostanie postawiony na pierwszym planie. W takim przypadku obie formy mogą reagować na niechcianą zmianę/aktywację fokusa przez zamrożenie ich zleceń Z. Kod będzie wówczas stać na 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;
i 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;
Wstęga ma być elementem interfejsu użytkownika w swojej głównej postaci, to jednak w rzeczywistości „modyfikować” formularza jest dodano do. Jeśli umieścisz wstążkę gdzieś poza główną formą twojego programu, a ona wyśle fokus z powrotem do aplikacji.MainForm, nie jestem zaskoczony; spodziewa się, że jest częścią głównej formy. VCL zawiera kod źródłowy, więc możesz otworzyć jednostkę i sprawdzić, czy możesz znaleźć odpowiedni kod. –
Aplikacja, którą projektuję, ma wygląd "Outlook'a", który w swojej implementacji wykorzystuje Wstążkę dla głównego programu i inną Wstążkę do tworzenia wiadomości e-mail, elementów kalendarza, kontaktów itp. Za każdym razem, gdy używam akcji Wstążki Outlook w e-mailu nie wysyłam mojego zainteresowania z powrotem do głównego okna Outlooka. Zrobiłem trochę patrzenia przez źródło dla komponentu TRibbon, ale jest wprawdzie trochę gruby. Nadal będę to robił, aby sprawdzić, czy mogę stwierdzić, gdzie to się dzieje, i czy mogę zmienić to zachowanie.Jak dotąd jednak nie miałem szczęścia. – Aaron
Brzmi okropnie jak błąd dla mnie. Takie zachowanie nie powinno się zdarzyć. Jeśli możesz wymieniać się w prostej aplikacji, powinieneś zgłosić to do QC –