Board logo

Subject: 请问 CnActiveScriptWindow 如何使用?? [Print This Page]

Author: ben2000    Time: 2008-10-6 18:10     Subject: 请问 CnActiveScriptWindow 如何使用??

我在CB6.0中,为什么我的 code 脚本并不执行?? 谢谢各位指教

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    WideString code="";
    code+=L"Function Func() \r\n";
    code +=L"Func = 12 \r\n";
    code +=L"msgbox Func \r\n";
    code +=L"End Function \r\n";

    OleVariant s=this->CnActiveScriptWindow1->Execute(code);
    if (!s.IsNull())
    {
        ShowMessage(String(s));
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CnActiveScriptWindow1Error(TObject *Sender,
      int Line, int Pos, AnsiString ASrc, AnsiString ADescription)
{
    ShowMessage("错误" + String(ASrc) + "\r\n" + ADescription );
}
Author: jAmEs_    Time: 2008-10-6 21:19

这样行不?
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    WideString code="";
    code+=L"Function Func() \r\n";
    code +=L"Func = 12 \r\n";
    code +=L"msgbox Func \r\n";
    code +=L"End Function \r\n";
    code +=L"Func \r\n"; // 增加一行

    OleVariant s=this->CnActiveScriptWindow1->Execute(code);
    if (!s.IsNull())
    {
        ShowMessage(String(s));
    }
}
Author: ben2000    Time: 2008-10-6 23:01

非常感谢楼上的大哥回复,果然能执行了,但是还有一个小问题,就是我在VBSCRIPT 脚本中的的计算结果 Func = 12 并不传回
OleVariant s=this->CnActiveScriptWindow1->Execute(code) 给 s ,我想取回运行结果,应该怎么办???
Author: ben2000    Time: 2008-10-7 09:27

再求各位大哥帮帮我,谢谢!!

如何返回 脚本中的运行结果给程序??
或者告诉我,有关这个控件的使用帮助哪里有??

[ 本帖最后由 ben2000 于 2008-10-7 09:33 编辑 ]
Author: ben2000    Time: 2008-10-7 11:06

沉了,再顶,希望各位大侠帮帮我
Author: jAmEs_    Time: 2008-10-7 11:26

問下其他人吧,我這個沒試過,這個組件也許不支持這個,但是可以做計算:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    WideString code="";
    code=L"\"12\"";

    OleVariant s=this->CnActiveScriptWindow1->RunExpression(code);
    if (!s.IsNull())
    {
        ShowMessage(String(s));
    }
}
如果要計算帶函數,可能要用到TScriptControl
Author: ben2000    Time: 2008-10-7 12:02

哦,执行表达式的话,我试过了,可以返回值的,但是就是执行函数不能返回值??这是cnpack 官方论坛,如果这里都问不到人的话,我想没有人会知道了,求哪个知道的大哥,出来解释一下,是没有这个功能呢,还是我用法不对??

楼上的这样大哥,谢谢你的回复,你说的TScriptControl 是微软的Activex的控件 msscript.ocx 吗??
Author: jAmEs_    Time: 2008-10-7 15:44

是的
可以網上找一下例子
Author: zjy    Time: 2008-10-7 15:54

CnPack 中 CnActiveScript 组件只是对 MS 的 ActiveScript 的封装,最初的设计目的是为了用 ActiveScript 脚本来调用 Delphi 的对象和函数,不过这部分功能目前还不太完善,源代码中 CnASHostServices.pas,CnASIDispatchProxy.pas,CnASInvoker.pas 等单元就是用来在 Delphi 对象和 ActiveSctipt 中搭桥的。

如果只是简单的在程序中使用 ActiveScript 脚本来计算的话,可以这样使用:
var
  a: OleVariant;
begin
  CnActiveScriptWindow1.CleanBeforeRun := False;  // 防止脚本执行完成后释放脚本引擎
  CnActiveScriptWindow1.Execute(                  // 先调用脚本引擎实现函数定义
    'Function Func()' + #13#10 +
    '  Func = 12' + #13#10 +
    '  msgbox Func' + #13#10 +
    'End Function' + #13#10);
  a := CnActiveScriptWindow1.RunExpression('Func');  // 再将已定义的函数作为表达式计算
end;
Author: ben2000    Time: 2008-10-7 16:47

谢谢!!
还是老大有办法呀,
我把软件修改如下,基本上可以满足我的要求了,再次感谢

WideString code="";
    code+=L"Function Func(a,b) \r\n";
    code +=L"Func = a * b \r\n";
    code +=L"'msgbox Func \r\n";
    code +=L"End Function \r\n";
    code +=L"Func c,d \r\n";

    this->CnActiveScriptWindow1->CleanBeforeRun=false;
    this->CnActiveScriptWindow1->Execute(code);
    OleVariant s=this->CnActiveScriptWindow1->RunExpression("Func(2.15,5)");

    if (!s.IsNull())
    {
        ShowMessage("结果:" +  String(s));
    }
Author: zjy    Time: 2008-10-7 16:52     Subject: 刚写了个 CnActiveScript 的例子

演示了使用脚本调用 Delphi 对象的方法,需要 D6/CB6 以上版本,已提交到CVS中。
附件解压到 cnpack\Examples 目录下,在 Delphi7 下测试通过。

Attachment: CnActiveScript.rar (2008-10-7 16:52, 9.57 K) / Download count 404
http://bbs.cnpack.org/attachment.php?aid=517
Author: jAmEs_    Time: 2008-10-7 17:17

還是老大牛,呵呵
本來也想通過CleanBeforeRun來處理的,但是搞不清怎么搞
不過這樣我想問問:
Execute再RunExpression,是不是等於執行兩次了?

本來也想通過AddNamedItem來交換數據的,誰知道直接傳遞接口對象不行,原來是這樣調用的,呵呵
Author: jAmEs_    Time: 2008-10-7 17:22

剛才看了一下源碼,突然想到,我的接口是沒有實現雙重接口的,腳本語言調用部分沒有實現,只能用例子裡面的GetIDispatchProxy來產生雙重接口的接口吧,難怪不行。
Author: zjy    Time: 2008-10-7 17:31

TCnActiveScriptSite 里头封装了一个 IActiveScript 接口的引擎,每个引擎创建后内部状态会保持,如果不清理引擎就可以实现分段执行脚本的功能。

AddNamedItem 增加的接口要求是支持 IDispatch 的接口,因为脚本只能通过方法名或ID用 Invoke 来调用。而在 Delphi 里头直接创建支持 IDispatch 接口的对象很麻烦,要用自动化对象和 tlb 这些东西。CnASIDispatchProxy 和 CnASInvoker 就是通过使用 D6 中为支持 SOAP 而引入的接口 RTTI 来创建一个支持动态 Invoke 的 IDispatch 代理接口以便脚本调用。最初的想法是将 VCL 中常用的类作为公共项注册到脚本引擎中,也就是 CnASCommon.pas 中计划完成的功能。后来没时间来完善,就把这个半成品放到组件包里了。貌似没人对这个组件有兴趣,也就没做文档和 Demo。

jAmEs_ 要是有兴趣的话,可以继续来完善它。
Author: zjy    Time: 2008-10-10 16:55     Subject: 新思路

刚才看到橙子的blog:
D2009反射?新功能还是骗局?
http://hi.baidu.com/rarnu/blog/item/17f0fff2d8ef2f15b17ec5dc.html

原来在D7下就可以动态调用方法,看来通过接口RTTI来间接实现动态调用的方法就可以不用了,有空再来改改。




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0