Điều này rõ ràng là do thiết kế. Đoạn mã mẫu từ 'ribbonactnctrls.pas':
procedure TRibbonBaseButtonControl.Click;
begin
inherited;
SetFocus(Application.MainForm.Handle);
end;
Như bạn thấy không có điều kiện được kiểm tra có thể giúp chúng tôi tránh cuộc gọi. Có cùng mã cũng trong lựa chọn mục menu và trình xử lý nhấn phím.
Tôi có thể sửa đổi nguồn nhận xét cuộc gọi trọng tâm và thử xem có bất kỳ tác dụng phụ nào không.
Thay vào đó, bạn có thể khôi phục tiêu điểm trở lại biểu mẫu của mình sau khi được chuyển sang biểu mẫu chính. Giả sử 'ActionList1' là TActionList chứa hành động tiêu chuẩn về hình thức chính không: Tuy nhiên
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;
này sẽ làm cho hình thức chính để flash một thời gian ngắn mỗi lần một hành động được thực thi. Nếu bạn không muốn điều đó, bạn có thể thay đổi thiết kế sao cho biểu mẫu chính biết khi nào nó nhận được tiêu điểm không mong muốn và giả mạo rằng nó không tập trung.
Trong 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;
trong unit2:
uses
unit1;
procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
begin
Form1.IgnoreFocus := True;
PostMessage(Form1.Handle, UM_CANCELIGNOREFOCUS, NativeInt(Self), 0);
end;
Tuy nhiên, điều này là không đủ nếu bạn không có bộ 'MainFormOnTaskBar' trong mã nguồn của dự án, từ đó hình thức chính sẽ không chỉ được tập trung mà sẽ được đưa lên phía trước. Trong trường hợp này, cả hai biểu mẫu có thể phản hồi sự thay đổi/kích hoạt tiêu điểm không mong muốn bằng cách đóng băng các đơn đặt hàng z của chúng. Đoạn mã sau đó sẽ trở thành cho 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;
và cho 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;
Một dải ruy băng được thiết kế để trở thành một yếu tố giao diện người dùng theo hình thức chính của bạn, nó trong thực tế "sửa đổi" hình thức nó là được thêm vào. Nếu bạn đặt một dải ruy băng ở đâu đó khác với hình thức chính của chương trình của bạn, và nó đang gửi tiêu điểm trở lại ứng dụng.MainForm, tôi không ngạc nhiên; nó hy vọng nó là một phần của hình thức chính. VCL đi kèm với mã nguồn để bạn có thể mở thiết bị và xem liệu bạn có thể tìm thấy mã được đề cập hay không. –
Ứng dụng tôi đang thiết kế sẽ cho cảm giác "Outlook", trong đó, sử dụng Ribbon cho chương trình chính và Ribbon khác để tạo email, mục lịch, danh bạ, v.v. Bất cứ khi nào tôi sử dụng hành động Ribbon của Outlook trong một email, nó không gửi tiêu điểm của tôi trở lại cửa sổ chính của Outlook. Tôi đã thực hiện một chút xem xét nguồn cho thành phần TRibbon, nhưng nó được thừa nhận là hơi dày. Tôi sẽ tiếp tục làm như vậy để xem liệu tôi có thể khám phá ra điều này đang xảy ra ở đâu không, và nếu tôi có thể ghi đè hành vi này.Cho đến nay, mặc dù, tôi đã không có may mắn. – Aaron
Âm thanh khủng khiếp như một lỗi đối với tôi. Hành vi đó không nên xảy ra. Nếu bạn có thể repro trong một ứng dụng đơn giản thì bạn nên báo cáo cho QC –