2011-12-06 31 views

Trả lời

5

Bạn cần xử lý sự kiện OnBeforeMenu. Trong trình xử lý sự kiện đó, đủ để đặt thông số đầu ra Result thành True điều gì sẽ chặn menu ngữ cảnh mặc định thành bật lên. Sau đó bạn có thể hiển thị menu của riêng bạn trên các vị trí thu được từ cấu trúc menuInfo.

Dưới đây là các mẫu mã với một menu tùy chỉnh popup:

uses 
    ceflib, cefvcl; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    Chromium1.Load('www.example.com'); 
end; 

procedure TForm1.Chromium1BeforeMenu(Sender: TObject; 
    const browser: ICefBrowser; const menuInfo: PCefHandlerMenuInfo; 
    out Result: Boolean); 
begin 
    Result := True; 
    PopupMenu1.Popup(menuInfo.x, menuInfo.y); 
end; 

procedure TForm1.PopupMenuItemClick(Sender: TObject); 
begin 
    ShowMessage('You''ve clicked on a custom popup item :)'); 
end; 

Cập nhật:

Ví dụ tự động tạo ra bạn phải gán các xử lý sự kiện bằng tay. Hãy thử đoạn mã sau.

uses 
    ceflib, cefvcl; 

type 
    TForm1 = class(TForm) 
    Panel1: TPanel; 
    Button1: TButton; 
    PopupMenu1: TPopupMenu; 
    procedure Button1Click(Sender: TObject); 
    private 
    procedure ChromiumOnBeforeMenu(Sender: TObject; 
     const browser: ICefBrowser; const menuInfo: PCefHandlerMenuInfo; 
     out Result: Boolean); 
    public 
    { Public declarations } 
    end; 

implementation 

procedure Form1.ChromiumOnBeforeMenu(Sender: TObject; const browser: ICefBrowser; 
    const menuInfo: PCefHandlerMenuInfo; out Result: Boolean); 
begin 
    Result := True; 
    PopupMenu1.Popup(menuInfo.x, menuInfo.y); 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Chromium: TChromium; 
begin 
    // owner is responsible for destroying the component 
    // in this case you are telling to Panel1 to destroy 
    // the Chromium instance before he destroys itself, 
    // it doesn't affect the event handling 
    Chromium := TChromium.Create(Panel1); 

    Chromium.Parent := Panel1; 
    Chromium.Left := 10; 
    Chromium.Top := 10; 
    Chromium.Width := Panel1.Width - 20; 
    Chromium.Height := Panel1.Height - 20; 

    // this line is important, you are assigning the event 
    // handler for OnBeforeMenu event, so in fact you tell 
    // to the Chromium; hey if the OnBeforeMenu fires, run 
    // the code I'm pointing at, in this case will execute 
    // the ChromiumOnBeforeMenu procedure 
    Chromium.OnBeforeMenu := ChromiumOnBeforeMenu; 

    Chromium.Load('www.example.com'); 
end; 
+0

Trên thực tế gắn popup menu để cha mẹ TPanel làm việc khá OK nhưng tôi sẽ chấp nhận của bạn câu trả lời là chính xác và thẳng thắn. –

+0

Có thể bạn đang tạo điều khiển chromium động, nhưng hãy thử thiết kế nó trên một biểu mẫu. Và ngay cả điều này là lạ, tôi sẽ nói rằng crom nên giữ menu popup của nó bất cứ điều gì là chủ sở hữu của nó. Bằng cách này được thiết kế để ghi đè menu bật lên;) – TLama

+0

Tôi vẫn không thể làm cho nó hoạt động khi Trình duyệt được tạo tại thời gian chạy với TPanel làm chủ sở hữu. Trình xử lý sự kiện đơn giản là không được gọi. Ý tưởng nào? –

3

thực sự bạn không cần popupmenu và bạn không phải thêm đơn vị vcl.menus vào ứng dụng nếu bạn đã có thể tạo menu ngữ cảnh của chromium. trình đơn của riêng Chromium cũng hiện đại hơn và rõ ràng hơn giống như và nhanh hơn vẽ perfrmance hơn là một vcl trong đó sử dụng thư viện win32 api vintage.

cef3 có trình đơn hoàn toàn có thể định cấu hình như thế này.

procedure Tfmmain.Chromium1BeforeContextMenu(Sender: TObject; 
    const browser: ICefBrowser; const frame: ICefFrame; 
    const params: ICefContextMenuParams; const model: ICefMenuModel); 
    begin 
    model.Clear; 
    model.AddItem(1, 'Your Command 1'); 
    model.AddItem(2, 'Your Command 2'); 
    model.AddSeparator; 
    model.AddItem(3, 'Your Command 3'); 
    model.AddItem(4, 'your Command 4'); 
    model.AddSeparator; 
    model.AddItem(999, 'Quit'); 

    model.SetAccelerator(1, VK_RIGHT, false, false, false); 
    model.SetAccelerator(2, VK_LEFT, false, false, false); 

    model.SetAccelerator(3, VK_DOWN, false, false, false); 
    model.SetAccelerator(4, VK_UP, false, false, false); 

    model.SetAccelerator(999, VK_ESCAPE, false, false, false); 

    end; 

procedure Tfmmain.Chromium1ContextMenuCommand(Sender: TObject; 
    const browser: ICefBrowser; const frame: ICefFrame; 
    const params: ICefContextMenuParams; commandId: Integer; 
    eventFlags: TCefEventFlags; out Result: Boolean); 
    begin 
    case commandId of 
     1: 
     begin 
      DoIt1; 
      Result := true; 
     end; 
     2: 
     begin 
     DoIt2; 
      Result := true; 
     end; 
     3: 
     begin 
     DoIt3; 
      Result := true; 
     end; 
     4: 
     DoIt4; 
      Result := true; 
     end; 
     999: 
     begin 
      Application.MainForm.Close; 
      Result := true; 
     end; 
    end; 

    end; 


lưu ý: các phím tắt SetAccelerator chỉ chức năng nếu cửa sổ bật lên appears.so bạn có thể cần onPreKeyEvent

+0

Cách tiếp cận này cũng cho phép bạn giữ các mục bật lên Chromium hiện có nếu bạn muốn chúng; nhưng lưu ý [Tất cả các id lệnh do người dùng xác định phải nằm trong khoảng từ MENU_ID_USER_FIRST đến MENU_ID_USER_LAST] (http://magpcss.org/ceforum/apidocs3/projects/ (mặc định) /CefMenuModel.html) –

Các vấn đề liên quan