21 de setembro de 2009

Acrescentando suporte a Scripts em aplicações Delphi - parte 4

Comecei uma série de posts em Agosto para mostrar como fazer com que uma aplicação Delphi permita interação com o usuário através de scripts usando o componente COM da Microsoft chamado Script Control. Ficou faltando falar sobre a publicação de variáveis do programa no engine no Script Control, o que na prática dará ao usuário acesso a essa variável. Num primeiro momento, pode parecer um risco permitir tal acesso mas pense na liberdade para o usuário customizar fórmulas dentro da aplicação, por exemplo. Dependendo do objetivo, é possível planejar uma estrutura em que o usuário poderá até mesmo customizar o funcionamento e a aparência de funções inteiras da aplicação.

Na verdade, a publicação tem que ser feita através de interfaces o que significa que você publicará o objeto inteiro que implementar tal interface. No entanto, pelas características do funcionamento das interfaces, o script enxergará apenas o que você desejar - os métodos e propriedades declarados na tal interface.

O primeiro passo, portanto, é planejar o quê o usuário poderá manipular. Vou estender o exemplo que usei nos outros posts e acrescentar uma interface que permita ao usuário manipular um saldo e a cor do form. Como as duas informações não têm qualquer relação entre si, o ideal seria colocá-las em interfaces distintas. Mas como se trata de um exemplo ...

Para criar a interface da forma que o COM precisa teremos que descrevê-la em uma Type Library. Uma Type Library define tipos de dados usando uma sintaxe que independe de linguagens de programação. Um IDE como o Delphi é capaz de ler essas informações e gerar automaticamente classes para lidar com o componente COM que a Type Library descreve. Uma aplicação ou biblioteca que implemente a interface nesses termos é classificada como um Servidor COM (COM Server) pois ela é capaz de suprir as chamadas dirigidas à interface.

Nosso objetivo, então, é transformar a aplicação num servidor COM e a forma mais prática de fazer isso em Delphi (e C++ Builder) é criando um Automation Object. Com o projeto da aplicação aberto, escolha o menu File, opção New e Other. No diálogo que aparece, localize a opção Active X e, finalmente, Automation Object. O IDE se encarregará de criar uma Type Library e uma classe capaz de criar uma instância da classe concreta (chamada de CoClass) que implementa nossa interface. Também criará código para ligar isso tudo. Dei o nome de Exemplo quando o IDE pediu :
Criação do Automation Object

No editor de Type Library, acrescentei à interface IExemplo as propriedades relativas aos valores que escolhemos anteriormente para publicação : o saldo e a cor do Form. Veja na reprodução abaixo que há também uma função com o nome de InitData.
Type Library Exemplo

Quando trabalho com interfaces COM eu tenho problemas em obter o ponteiro para a classe original e fazê-la interagir com outras classes do programa - é o mesmo tipo de problema enfrentado quando se trabalha com interfaces no Delphi. Por essa razão, introduzi a função InitData com um parâmetro PChar, que é um ponteiro genérico. Desse jeito, mesmo que o programa só consiga enxergar as propriedades e métodos definidos na interface, eu posso passar à classe que implementa essa interface um ponteiro para uma estrutura interna minha, com os valores que eu quero permitir interação. Essa estrutura pode até ser uma classe minha ou todo o Form Delphi, se for necessário.

Mas tudo que está numa interface não é público ? Desse jeito, alguém com más intenções não pode passar um lixo qualquer nessa função através do script e derrubar a aplicação ? Pode sim. Para evitar isso, marquei na guia Flags do editor de Type Library as caixas Hidden e Restricted. Com isso, apenas o meu programa consegue enxergar a função InitData, restringindo o acesso quando a chamada parte de um Client COM qualquer.

Agora que tenho uma interface COM, falta preencher o código por trás dela (a CoClass) e permitir que o Script Engine embutido na aplicação enxergue uma variável que a implemente. Faço isso no próximo post e publico o programa de exemplo.

Mais Informações
Acrescentando suporte a Scripts em aplicações Delphi - parte 1, parte 2 e parte 3, Interfaces com Delphi.

Nenhum comentário :

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.