Share Button

Parte 1 – Criando o Host | Parte 2 – Criando o Plugin | Parte 3 – Item de Menu

Os artigos anteriores mostrei como o plugin assina à um item de menu do aplicativo host.  Agora é a vez de um plugin que assina ao serviço de janela, permitindo que seja embutido (embedded) como um componente da janela.

embedded

Criar o Plugin

  1. Criar um projeto DLL em branco;
  2. Adicionar ao projeto um FORM a ser inserido no formulário do aplicativo HOST;
  3. Incluir as UNITs: plugin.Service, plugin.Control no FORM;
  4. na Seção Initialization registrar o Plugin na lista de plugins disponíveis na DLL:
    RegisterPlugin(TPluginControlService.create(TForm1,1,0,'my control embedded'));
  5. Copiar a DLL do projeto para a pasta de “Plugins” do aplicativo HOST;

Exemplo:


{$R *.dfm}

uses plugin.Service, plugin.Control;

........

initialization

RegisterPlugin(TPluginControlService.create(TForm1,9999,1,'my control embedded'));

finalization

end.

 

Inserindo o Plugin em uma janela do HOST

  1.  Se o projeto HOST ainda não tem recurso para suportar plugin – arrastar o componente  TPluginManager para o formulário principal;TPluginManager
  2. Escolher um formulário onde deseja inserir o plugin controle (embedded) – arrastar um TPanel para o local onde o plugin será inserido, para estabelecer a área a ser ocupada pelo plugin (interno no plugins ele executa Align=alClient no formulário);
  3. Incluir na uses a UNIT no formulário: plugin.Manager (a mesma utilizada pelo component TPluginManager);
  4. No evento OnShow do formulário fazer chamada ao Manager do plugin para encontrar o plugin ser incorporado:
      GetPluginManager.EmbedControl(Panel1.Handle,9999,1);

Observando os parâmetros da procedure

TPluginManager.EmbedControl(AParentHandle: THandle;
AControlID, AControlType: Int64);

cabe considerar:

  • AParentHandle -> é o handle do TPanel onde o plugin será incorporado;
  • AControlID -> é um identificador para carregar um determinado plugin em específico – identifica o ID da janela que irá consumir o plugin (valor fixo nos dois lados);
  • AControlType -> um ID para separar os vários plugins que uma mesma janela pode consumir;

Quando chama

GetPluginManager.EmbedControl(Panel1.Handle,9999,1); 
deve inserir no Panel1 um plugin de controle identificado por 9999 que contenha serviços do tipo 1;


Ver código de exemplo

 

Share Button

Parte 1 – Criando o Host | Parte 2 – Criando o Plugin

Registrando MenuItem no Host

No artigo anterior foi apresentado o exemplo de um plugin que assina o serviço de Menu do Host chamando o método:

PluginApplication.RegisterMenuItem('mnPlugins', 'Meu menu que adiciona um plugin', self as IPluginMenuItem);

 

Ao receber a chamada ao método do PluginApplication.RegisterMenuItem o host deverá coletar informações sobre o plugin bem como executar ações para disponibilizar o recurso solicitado.

Tratando-se de MenuItem, a implementação do host será criar o item de menu no local adequado para que seja visível ao usuário.

Um exemplo de como criar o item de menu no host:

 


  // um item de menu para guardar a interface que o plugin assina
  TPluginMenuItemInterf = class(TMenuItem)
  protected
    FProc: TProc<TObject>;  // anonimous
    procedure DoClick(Sender: TObject);
  public
    PluginMenuItem: IPluginMenuItem;
    constructor Create(AOwner: TComponent; AProc: TProc<TObject>); overload;
  end;

// implementação no TPluginManager -> para criar um item de menu no host
procedure TPluginManager.NewMenuItem(AMainMenu: TMainMenu;
  ADefaultMenu: TMenuItem; const APath, ACaption: string;
  ADoExecute: IPluginMenuItem; AProc: TProc<TObject>);
var
  it: TPluginMenuItemInterf;
  itClient: TMenuItem;
begin
  inc(itCount);
  // procura o menu para mostrar
  itClient := AMainMenu.FindItem(APath);
  if itClient = nil then
    itClient := ADefaultMenu; // se nao encontrou pega um padrao

  if not assigned(AProc) then
    AProc := (
      procedure(Sender: TObject)
      begin
        with TPluginMenuItemInterf(Sender) do
          PluginMenuItem.DoClick(0);
      end);

  // cria o menu
  it := TPluginMenuItemInterf.Create(AMainMenu, AProc);
  it.Name := 'mnPlugin_' + formatDatetime
    ('hhmmsszzz_' + intToStr(itCount), now);
  it.PluginMenuItem := ADoExecute;
  it.Caption := (it.PluginMenuItem as IPluginMenuItem).GetCaption;
  // adiciona o menu na lista
  itClient.Add(it);

end;

 

Pensando em facilitar a integração no HOST é possível registrar o componente na aba do Delphi – Arrastar e soltar o componente TPluginManager no formulário principal do HOST.

PluginManager

Explorando código padrão para o evento do TPluginManager.RegisterMenuItem  irá notar que já foi implementado as funcionalidades para inserir o plugin no menu do aplicativo. Caso deseje mudar o comportamento do evento padrão, basta implementar o evento do componente com funcionalidade personalizadas…

 

Fontes: Código base para o Plugin

Share Button

Parte 1 – Criando o Host

Na parte 1 deste artigo tracei as linhas básicas para a implementação do Aplicativo Principal HOST – se ainda não o leu, será mais produtivo fazê-lo antes de continuar.

Criando um Plugin
O Plugin em si consiste em uma DLL que “exports” 2 entradas:

  1. function LoadPlugin(AAplication: IPluginApplication): IPluginItems;
  2. procedure UnloadPlugin;

A base para a criação do plugin é a unit: plugin.Service

LoadPlugin
“LoadPlugin” é utilizado quando o HOST inicia o plugin; O parâmetro IPluginApplication representa os serviços publicados no HOST disponíveis para assinatura pelos plugins. Assim todos os serviços que o HOST implementar deve se publicada para que sejam visíveis aos plugins.

Nos casos em que houver necessidades de estender os serviços publicados pelo HOST, IPluginApplication será a interface base publicada adicionada de novos serviços…   IMyPluginApplication = interface( IPluginInterface) …

O Plugin registra-se à lista de plugins 

IPluginItems – é uma lista de plugins disponíveis na DLL;

Para que IPluginItems seja populada o plugin poderá escolher entre os serviços padrões, aquele a que deseja assinar.

initialization
RegisterPlugin(TPluginMenuItemService.Create(TForm1,'',1, 'Menu base de sample'));

DoStart
Após a inicialização do LoadPlugin, ocorrerá um evento “DoStart” que inicializa cada um dos plugins da lista registrada. É neste momento que o plugin fará o pedido de assinatura  no HOST… Tudo isto é feito internamente pelo objeto “TPluginMenuItemService” do exemplo.

procedure TPluginMenuItemService.DoStart;
begin
  inherited;
  PluginApplication.RegisterMenuItem(FMenuItemName, GetCaption, self);
end;

Um esqueleto para um plugin de MenuItem

unit uMenuItemSimple;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  plugin.Interf, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,
  Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    LabeledEdit1: TLabeledEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses plugin.Service, plugin.MenuItem, plugin.Control;

procedure TForm1.Button1Click(Sender: TObject);
begin
  close;
end;


initialization

RegisterPlugin(TPluginMenuItemService.Create(TForm1,'',1, 'Menu base de sample'));

finalization

end.