26 de agosto de 2009

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

No último post, montei uma aplicação Delphi mostrando como usar o Script Control para avaliar uma expressão VBScript em tempo de execução. Lá, usei algumas funções básicas do componente e uma técnica simples para interagir com o usuário. Agora, vou avançar um pouco, modificando o programa do post anterior para dar a ele suporte à criação de rotinas completas que poderão também ser usadas para avaliar expressões. Ou seja, o usuário poderá avaliar expressões mais complexas, tendo também a liberdade de criar funções que encapsulam seus cálculos mais comuns.

Acrescentei ao programa uma nova guia com título "Métodos e Funções" na qual inclui um TRichEdit (onde o usuário poderá criar suas funções), um TListBox (apenas para listar as funções disponíveis após a criação) e um botão. A resposta ao clique do botão adiciona ao engine do VBScript as funções criadas pelo usuário:
_ScriptControl.Reset;
InitScriptControl;
try
_ScriptControl.AddCode(reFuncao.Text);
except
end;
A primeira instrução, Reset, faz com que a instância do componente Script Control descarte todo a configuração feita nele anteriormente, incluindo funções e métodos que já tenham sido adicionados. Isto evita que se tente criar uma função com um nome que já existe - todas elas serão recriadas e poderão até mesmo executar cálculos diferentes da versão que havia antes. Como toda a configuração foi descartada, a segunda linha é uma função que agrupa os comandos de configuração que haviam no OnCreate do Form, mostrado no outro post.

O que está dentro do Try/Except adiciona ao engine do VBScript no componente as funções digitadas pelo usuário no Rich Text. Erros de sintaxe embutidos no código das funções só serão reportados quando for avaliada uma expressão que use a função problemática.

Após termos adicionado as funções, podemos recuperar no programa informações a respeito delas na propriedade Procedures do componente. O código abaixo põe no ListBox o nome das funções criadas com o AddCode:
lbFuncoes.Clear;
for i := 1 to _ScriptControl.Procedures.Count do
lbFuncoes.AddItem(_ScriptControl.Procedures.Item[i].Name, Nil);
A propriedade Procedures é uma lista com as funções e métodos que adicionamos ao engine e cada elemento recuperado em Item traz informações sobre uma dessas funções/métodos, dizendo se aceitam parâmetros e em qual quantidade, se têm valor de retorno, etc.

Algo importante a observar aqui é que todo código solto que seja adicionado através do método AddCode é executado imediatamente. Por código solto quero dizer as linhas de script que não façam parte da declaração de uma função ou método. Esta técnica permite executar um script inteiro de uma vez, bastando adicionar todo o código numa única chamada ao AddCode. Isto também dá abertura a uma solução rudimentar para o problema de fazer o script enxergar variáveis do programa. Crie no script uma variável - digamos que se chame y - e a adicione ao componente com AddCode:
Dim y
No programa Delphi, antes de avaliar uma expressão que vá precisar do valor de y, adicione uma atribuição como a seguinte:
_ScriptControl.AddCode('y = ' + IntToStr (Y));
Ao fazer isso, o valor da variável y do seu programa Delphi é imediatamente transferido para a variável y que existe no script. A partir desse momento, qualquer avaliação de expressão que use y enxergará o mesmo valor do programa Delphi.

Há uma forma mais elegante de se fazer isso e a mostrarei em outro post.Para baixar o exemplo completo - incluindo código e executável - clique aqui. O programa foi feito com Delphi 2005 mas deve funcionar com pouca ou nenhuma alteração em outras versões.


Mais Informações
Acrescentando suporte a Scripts em aplicações Delphi - parte 1 e parte 2, Documentação do ScriptControl no MSDN, Programando com VBScript

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.