2011-12-06 22 views
6

Khi tôi đặt điều khiển TRibbon trên một biểu mẫu không phải là MainForm của ứng dụng, hành động của TRibbon (tức là Cắt, Dán) sẽ luôn trở về tiêu điểm đối với MainForm sau hành động được thực hiện.Delphi XE - Hành động TRibbon luôn gửi trọng tâm đến MainForm

Điều này xảy ra ngay cả khi TForm giữ TRibbon không phải là con của MainForm.

Tôi đang sử dụng Windows 7 64 bit, Embarcadero RAD Studio XE Phiên bản 15.0.3953.35171.

Tôi có đang sử dụng điều khiển TRibbon không chính xác hoặc đây có phải là vấn đề với TRibbon không?

+2

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. –

+1

Ứ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

+2

Â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 –

Trả lời

2

Đ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; 
+1

Phản hồi tuyệt vời! Tôi vẫn không biết liệu có ai có thể cho tôi biết tại sao họ thiết kế sự kiểm soát để hành xử theo cách ép buộc như vậy, khi nó có thể vừa mới kiểm soát được cha mẹ của Ribbon - tôi đoán đó chỉ là một bí ẩn Delphic. – Aaron