Как прикрепить контекстное меню к браузеру TChromium - PullRequest
5 голосов
/ 07 декабря 2011

У меня есть броузер TChromium от Delphi Chromium Embedded (http://code.google.com/p/delphichromiumembedded). Я хотел бы присоединить к нему контекстное меню. Как мне этого добиться?

Ответы [ 2 ]

5 голосов
/ 07 декабря 2011

Вам необходимо обработать событие OnBeforeMenu.В этом обработчике событий достаточно установить для выходного параметра Result значение True, что будет подавлять всплывающие контекстные меню по умолчанию.После этого вы можете отобразить свое собственное меню на позициях, полученных из структуры menuInfo.

Вот пример кода с пользовательским всплывающим меню:

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;

Обновление:

Для динамически создаваемого экземпляра необходимо назначить обработчик событий вручную.Попробуйте следующий код.

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;
4 голосов
/ 29 мая 2015

на самом деле вам не нужно popupmenu, и вам не нужно добавлять модуль vcl.menus в ваше приложение, если вы уже можете создать контекстное меню chromium. Кроме того, собственное меню Chromium более современное и четкое, выглядит быстрее и быстрее, чем Vcl, в котором используется винтажная библиотека Win32 API.

У cef3 полностью настраиваемое меню:

 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;

<ч /> примечание: ярлыки SetAccelerator работают только при появлении всплывающего окна. поэтому может потребоваться onPreKeyEvent

...