Escrevendo um Expert para a IDE do Delphi
Já aconteceu de você ter uma idéia de algo que poderia ter na IDE do Delphi para facilitar sua vida? Uma opção é fazer uma solicitação e esperar que seja implementado. Uma outra opção é arregaçar a mangas e implementar você mesmo.
A IDE do Delphi é bastante extensível. Existe uma API chamada Open Tools API (OTA) que permite customizar vários pontos da IDE, integrando seu código em várias partes. Apesar de a documentação ser um pouco escassa e ser um pouco difícil de descobrir algumas coisas, é bem possível escrever experts para quase tudo na IDE.
Por enquanto, vou deixar a implementação do seu expert com você. Vou mostrar como passar pelo primeiro problema no meio do caminho, carregar seu expert integrado na IDE.
Um expert geralmente é uma BPL (pode ser uma DLL também, mas é um pouco mais complicado). Crie, então um novo package, salve um algum lugar e adicione uma unit nele.
A OTA é baseada em interfaces, e a maioria delas está definida em ToolsAPI.pas. Adicione então ToolsAPI no uses do seu package. Por padrão, se você compilar agora, o compilador não vai encontrar essa unit. Não saia procurando ela e alterando seu Library Path ou o Search Path do projeto – não é para você compilar essa unit – ela está dentro de DesignIDE.dcp. Vá no nó de Requires do project manager, clique com o direito e selecione Add Reference, e navegue até a pasta Lib dentro da instalação do seu Delphi, encontrando DesignIDE.dcp lá. Depois de adicionar essa referência, o projeto já compila corretamente encontrando ToolsApi sem problemas.
O Expert mais simples que podemos criar agora é chamado de “Wizard” pela OTA. Você pode abrir ToolsAPI.pas e procurar IOTAWizard lá para ver o que precisamos implementar para criar um Wizard:
IOTAWizard = interface(IOTANotifier)
['{B75C0CE0-EEA6-11D1-9504-00608CCBF153}']
{ Expert UI strings }
function GetIDString: string;
function GetName: string;
function GetState: TWizardState;
{ Launch the AddIn }
procedure Execute;
end;
As três primeiras funções devem ser implementadas para retornar um ID único para seu wizard, o nome dele, e o seu estado (que pode ser habilitado, assinalado, os dois ou nenhum). O quarto método que precisamos preencher é o Execute, que é onde vamos colocar nosso código para a ação vai acontecer realmente.
Não adianta muito ter um wizard se ele não aparecer em lugar algum. Vamos implementar a interface IOTAMenuWizard também, para que nosso wizard apareça no menu da IDE. Se você for dar uma olhada no ToolsAPI.pas, ele está declarado assim:
IOTAMenuWizard = interface(IOTAWizard)
['{B75C0CE2-EEA6-11D1-9504-00608CCBF153}']
function GetMenuText: string;
end;
Nessa interface, só temos que implementar uma função que retorne o texto que vai aparecer no menu. A interface wizard é descendente de IOTANotifier. Para não precisarmos implementar mais métodos que não vamos usar por enquanto, vamos usar a implementação padrão dessa interface que o ToolsAPI inclui como base, o TNotifierObject. Minha implementação ficou assim:
uses
Dialogs, ToolsAPI;
type
TPrimeiroWizard = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
public
// IOTAWizard:
function GetIDString: string;
function GetName: string;
function GetState: TWizardState;
procedure Execute;
// IOTAMenuWizard:
function GetMenuText: string;
end;
function TPrimeiroWizard.GetIDString: string;
begin
Result := 'PrimeiroWizard';
end;
function TPrimeiroWizard.GetName: string;
begin
Result := 'Primeiro Wizard';
end;
function TPrimeiroWizard.GetState: TWizardState;
begin
Result := [wsEnabled];
end;
procedure TPrimeiroWizard.Execute;
begin
ShowMessage('Primeiro Wizard!');
end;
function TPrimeiroWizard.GetMenuText: string;
begin
Result := 'Primeiro Wizard';
end;
Vamos a implementação das duas interfaces, retornando as informações necessárias. Finalmente, precisamos registrar esse wizard para que possamos utilizá-lo. Vamos utilizar a seção de initialization da unit para isso:
initialization RegisterPackageWizard(TPrimeiroWizard.Create);
E pronto. Agora basta clicar com o direito na sua package dentro do Project Manager, selecionar Install. Se tudo deu certo, um menu com o caption “Primeiro Wizard” apareceu no item Help do Menu principal da IDE. Clicando nele, uma mensagem dizendo “Primeiro Wizard” aparece.
Partindo disso como modelo, é fácil implementar qualquer coisa que quiser agora dentro do Execute do seu expert. É claro, o menu Help não é o melhor lugar para ter um item de menu, e com certeza você quer acessar mais informações da IDE. Vamos fazer isso da próxima vez!
Em 25 de fevereiro de 2007 às 13:55
Puxa, que maravilha. Não sabia sua existência.
Não tem como fazer outra matéria utilizando um exemplo?
De qualquer forma, foi uma grande ajuda!
Em 26 de fevereiro de 2007 às 14:25
Sim, pretendo continuar escrevendo sobre isso, com alguns novos exemplos. Bom que isso é util!
Em 27 de fevereiro de 2007 às 10:42
Leonel, o link RSS não está funcionando ou é problema aqui?
Abraço.
Em 27 de fevereiro de 2007 às 14:31
Do site ou do artigo? Aqui os dois funcionam normalmente, abrindo no FireFox. O do site tem o protocolo feed:/ que talvez esteja criando problemas, tente apagá-lo. Se for isso me avise que mudo o link.
Em 25 de abril de 2007 às 20:03
Segui o artigo, e até que funcionou. Só que o menu do meu wizard foi incluído no menu ‘Help’. Como faço para incluir no menu ‘Tools’?
Em 25 de abril de 2007 às 22:30
É necessário adicionar o item no menu em tempo de execução. Vou escrever um artigo completo com mais detalhes logo logo.
Em 04 de março de 2008 às 09:55
Não consegui fazer funcionar, de início, eu devo criar uma nova Unit ? poderia me enviar passo a passo no meu email charlesgarrotti@gmail.com
Abraços
Em 23 de novembro de 2009 às 18:06
Valeu pela dica, era o pontapé inicial que eu tava precisando ler.
Acabei de fazer um expert que ajusta o versioninfo do projeto quando ele é aberto…
Se ele estiver cadastrado, muda pra versão.ano.mes.dia… (o mesmo expert tem um form via menu help, e recebe notificação… tudo perfeitinho!)
Obrigado!
Em 30 de dezembro de 2009 às 14:19
Muito bom.. mas como disse boa parte de nossos colegas.. e o artigo completo??
Pra que desenvolve para desenvolvedores isso ai é uma santa mão na roda com modelos de projetos pequenos e pacotes em projetos grandes.
ps.: Rola um artigo de Repository não? hehe