No primeiro momento não entendi direito.. achei que não pudesse ser feito; em casa, tomando banho (como sempre ocorre) me veio a solução (ou melhor, eu entendi o problema :). Vamos ao que interessa, o exemplo.
- A primeira coisa que temos que entender é que o JScript (da Microsoft) é implementado utilizando-se a Script Engine que nada mais é que um punhado de componentes COM (ok estou simplificando um pouco as coisas). Assim sendo é natural que objetos em JScript suportem o modelo do COM.
- Ótimo, o próximo ponto que devemos ter em mente é que sendo uma linguagem de script também é natural que estes objetos suportem a interface IDispatch.
- Com isto em mente podemos escrever nosso código JScript que deve
- Implementar uma classe
- Instanciar um componente COM
- Passar, de alguma forma, uma referância do objeto JScript para o componente COM
0: function MinhaClasse_Teste1(i)Nas linhas 10-15 declaramos uma classe (a função MinhaClasse() é tratada como o construtor da classe); dentro do construtor adicionamos os métodos/propriedades à classe (através de atribuição).
1: {
2: this.Valor = i * 2;
3: }
4:
5: function MinhaClasse_Teste2()
6: {
7: return this.Valor;
8: }
9:
10: function MinhaClasse()
11: {
12: this.Teste1 = MinhaClasse_Teste1;
13: this.Teste2 = MinhaClasse_Teste2;
14: this.Valor = 1;
15: }
16:
17: var obj;
18: obj = new MinhaClasse();
19:
20: obj.Teste1(10);
21: WScript.Echo("Valor: " +
22: obj.Teste2() +
23: " [Antes de ter o callback executado]");
24:
25: var t = new ActiveXObject("TestScript.ScriptCallBack");
26: t.Callback = obj;
27: t.DoSomeAction(40);
28:
29: WScript.Echo("Valor: " +
30: obj.Teste2() +
31: " [Depois de executar o objeto COM]");
Pronto! Nossa classe já esta definida! A mesma possui dois métodos (Teste1() e Teste2()) e uma propriedade (Valor).
Nas linhas 17-23 executamos alguns métodos da classe apenas a título de teste.
Na linha 25 instanciamos o objeto COM que iremos utilizar.
Na linha 26 informamos a este objeto qual o objeto deve ser utilizado para realizar o callback (note que o mesmo deve possuir conhecimento prévio da estrutura da classe, ou seja, o objeto COM deve saber o nome do método e número de parâmetros do método a ser executado como callback).
Finalmente na linha 27 executamos o método do objeto COM que irá (em algum momento) executar o método do objeto JScript. O método DoSomeAction() irá chamar a função Teste1() da classe MinhaClasse() (JScript).
Neste ponto finalizamos a parte do script. Agora vamos abordar o componente COM:
0: #include "stdafx.h"
1: #include "TestScript.h"
2: #include "TestScriptImpl.h"
3:
4: STDMETHODIMP CScriptCallBack::put_Callback(IDispatch* rhs)
5: {
6: if (obj)
7: {
8: obj.Release();
9: }
10:
11: if (rhs)
12: {
13: obj = rhs;
14: }
15:
16: return S_OK;
17: }
18:
19: STDMETHODIMP CScriptCallBack::DoSomeAction(INT i)
20: {
21: HRESULT hr = E_UNEXPECTED;
22: if (obj)
23: {
24: CComVariant param(i);
25: hr = obj.Invoke1(OLESTR("Teste1"), ¶m);
26: }
27:
28: return hr;
29: }
Este é um componente típico, sem maiores complicadores. O ponto importante no mesmo é a propriedade Callback; a mesma espera um ponteiro para uma interface do tipo IDispatch que implemente um método com a seguinte assinatura:
Teste1(int n)
Quando o método DoSomeAction() é executado o mesmo chama o método Teste1() do objeto passado para a propriedade Callback.
Observe que para o componente COM não importa se o objeto apontado pela interface IDispatch em questão é ou não um objeto JScript; tudo que é necessário é que este objeto implemente a interface IDispatch e possua o método Teste1() com uma assinatura compatível.
Aproveitando a oportunidade, você consegue ver um problema em potencial neste código? Então fique atento... este será o assunto de um post futuro na série: "Oque esta errado com este código - parte N" :)
Have fun!
[+/-] mostrar/esconder este post
0 Comments:
Postar um comentário
<< Home