A primeira providência é criar uma estrutura com as informações que poderão ser manipuladas, isto é, o saldo e a cor do Form. O Form então manterá uma instância dessa estrutura e poderá passá-la para a interface que criei no outro post usando para isso a função InitData:
{ A estrutura ...}
DoublePtr = ^Double;
TWDados = record
Saldo : DoublePtr;
ParentForm : TForm;
end;
TWDadosPtr = ^TWDados;
DoublePtr = ^Double;
TWDados = record
Saldo : DoublePtr;
ParentForm : TForm;
end;
TWDadosPtr = ^TWDados;
Veja que criei o Saldo como um ponteiro para Double. A intenção é que esta estrutura sirva de ponte para variáveis reais do meu programa. Assim, quando o script referenciar o Saldo estará referenciando exatamente a mesma variável que existe internamente no programa.
Agora, o Form pode criar uma instância de classe que implementa a nossa interface e transferir para ela a estrutura alimentada. O IDE do Delphi monta automaticamente uma classe (a CoClass) que cria tal instância, ligando a interface a uma classe concreta, que no nosso caso é a TExemplo, cujo esqueleto também foi montado pelo IDE do Delphi.
{ A classe TExemplo }
TExemplo = class(TAutoObject, IExemplo)
private
_Dados : TWDadosPtr;
{ ...}
end;
{ No construtor do Form }
_Saldo := 0;
_Dados.Saldo := @_Saldo;
_Dados.ParentForm := Self;
_VarExemplo := CoExemplo.Create;
_VarExemplo.InitData(@_Dados);
{ ...}
TExemplo = class(TAutoObject, IExemplo)
private
_Dados : TWDadosPtr;
{ ...}
end;
{ No construtor do Form }
_Saldo := 0;
_Dados.Saldo := @_Saldo;
_Dados.ParentForm := Self;
_VarExemplo := CoExemplo.Create;
_VarExemplo.InitData(@_Dados);
{ ...}
Observe a declaração da classe TExemplo : ela é uma herança do TAutoObject (um objeto COM para automação, definindo o programa como um COM Server) e também implementa a interface IExemplo, com as propriedades e métodos que planejamos permitir interação através de scripts. Como ela é a classe concreta para a interação, inclui nela um membro do tipo TWDadosPtr para receber a estrutura que é mantida pelo Form.
Ao preencher os esqueletos de métodos gerados pelo Delphi para a classe concreta TExemplo, usamos a estrutura informada pelo InitData. Por exemplo:
procedure TExemplo.InitData(AInfo: PChar);
begin
_Dados := TWDadosPtr (AInfo);
end;
function TExemplo.Get_CorForm: Integer;
begin
Result := integer (_Dados.ParentForm.Color);
end;
function TExemplo.Get_Saldo: Double;
begin
Result := _Dados.Saldo^;
end;
begin
_Dados := TWDadosPtr (AInfo);
end;
function TExemplo.Get_CorForm: Integer;
begin
Result := integer (_Dados.ParentForm.Color);
end;
function TExemplo.Get_Saldo: Double;
begin
Result := _Dados.Saldo^;
end;
O que a função CoExemplo.Create retorna é um ponteiro para a interface e não para a classe concreta. Por isso, _VarExemplo deve ser declarada no Form como sendo do tipo interface.
private
_VarExemplo: IExemplo;
_VarExemplo: IExemplo;
Só falta incluir a variável do programa no engine do Script Control para permitir que ela seja acessada por scripts. Para isso, basta usar o método AddObject.
_ScriptControl.AddObject('Vars', _VarExemplo, true);
O nome Vars passa a representar a instância de nossa interface nos scripts. Então, o código abaixo é reconhecido como válido para um script executado por nosso programa:
Vars.Saldo = Vars.Saldo + 1
Vars.CorForm = RGB (0, 255, 0)
Vars.CorForm = RGB (0, 255, 0)
O programa completo com os exemplos incluídos nos posts sobre Script com Delphi (incluindo o executável, os fontes e a type library) pode ser baixado neste link.
Mais Informações
Acrescentando suporte a Scripts em aplicações Delphi - parte 1 (métodos e propriedades do MS Script Control), parte 2 (avaliação de expressões), parte 3 (criação de rotinas complexas) e parte 4 (acessando variáveis do programa no script).
Acrescentando suporte a Scripts em aplicações Delphi - parte 1 (métodos e propriedades do MS Script Control), parte 2 (avaliação de expressões), parte 3 (criação de rotinas complexas) e parte 4 (acessando variáveis do programa no script).
4 comentários :
cara pode me mostrar como adicionar um componente com o addobject?
Gustavo
Qualquer objeto - incluindo componentes - que implemente a interface IDispatch pode ser adicionado diretamente com o AddObject.
Para os componentes que não fazem essa implementação, você terá que criar uma classe "wrapper" (envólucro) para publicar as propriedades e métodos que desejar. Neste caso, o caminho é exatamente o mesmo usado no exemplo desse post para a propriedade de cor do Form.
obrigado existe a possibilidade de realizar o msm procedimento ou algo parecido em c#?
Gustavo
O Script Control é distribuído como um componente COM. Isso significa que pode ser utilizado exatamente do mesmo modo no .NET, bastando incluir em seu projeto uma referência à biblioteca COM.
O.NET, no entanto, possui recursos nativos para permitir scripting dinâmico. Dê uma pesquisada na classe CSharpCodeProvider. Há exemplo do uso dela neste site.
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.