惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
小众软件
小众软件
J
Java Code Geeks
I
InfoQ
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
腾讯CDC
L
LangChain Blog
博客园 - 司徒正美
量子位
Y
Y Combinator Blog
C
Check Point Blog
T
Tailwind CSS Blog
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
N
Netflix TechBlog - Medium
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
F
Fortinet All Blogs
云风的 BLOG
云风的 BLOG
A
About on SuperTechFans
B
Blog RSS Feed
酷 壳 – CoolShell
酷 壳 – CoolShell
大猫的无限游戏
大猫的无限游戏
V
V2EX
阮一峰的网络日志
阮一峰的网络日志

博客园 - yesry

程序员专用IM新版本发布,诸多创新非模仿 VC的强大 + ExtJS的漂亮 + (MySQL+SQlite)数据库 + JavaScript的动态语言的灵活 通过桥接器,Java调用任何DLL 学生的福音:做错之题管理 Google 和 baidu 搜索结果二次加工 键鼠模拟的妙用 汉编卷土重来? 用贾樟柯访谈评《疯狂的程序员》 Widgets 引擎的设计和实现 Duceland Widgets Engine 例子一 作为软件从业员面对番茄事件的尴尬立场 招聘Windows API 熟悉人 招IE插件精通人 史上最不安全的浏览器——Dangerous Browser PHP能参与桌面项目吗?适合吗?——C#客户端 嵌入 PHP 一例 互联网公司老板的十大谎言之解——时间成本和竞争成本 我在外资公司的2个月 让大家见识一下新一代分析源代码生成流程图的东东吧 如何进行界面和业务逻辑分开的原型化开发
VC调用 JavaScript 难题:如何使当前程序的对象进入脚本
yesry · 2008-08-26 · via 博客园 - yesry

本文所指的  JavaScript 为 MS Script,引入msscript.ocx 实现的,也就是ECMAScript(下载本例源代码)。从题目咋眼看来对于没有写过VC调用msscript.ocx的人来说不是很好理解,因为这样做似乎太容易了,何来难题?

例如写JavaScript实 现数值计算,例如: _variant_t outpar=pScriptControl->Eval(_bstr_t("1+4*5")); 这样的数值计算不涉及js调用脚本外部的对象,例子到处可见,但是应用范围非常窄小。也就是说,从现有的文献来看,用VC调用 JavaScript 都是 JavaScript 单向的,但是从来没见过把VC中的现有的对象交给 JavaScript 反过来调用(也就是双向调用)。有些人已经实现或者看到, JavaScript 可以通过 obj = new ActiveXObject(...);的方式,把用VC编写COM,然后让 JavaScript 创建调用,但是,这样new出来的对象,仍然不是VC应用的现有对象。如果要调用现有对象,需要通过被new的COM对象间接调用才行,而且应用程序被调 用的对象也是COM规范。如果通过COM来实现这个难题,应用程序结构比较复杂,JavaScript 创建COM,所创建的COM能访问应用程序对象。

所以要扩大 JavaScript 的应用范围,必须实现这样的核心问题:双向调用

双向调用的一个分解问题是,VC对象如何进入脚本呢?下面介绍一种实现方法。

一、界面:

 

二、主要代码

1 声明定义可以被JavaScript调用的类和对象

//声明可以被JavaScript调用的类并创建一个转接对象g_Dialogimpl

BEGIN_DSRE_POPULAR_OBJECT(CCppCallJavaScriptDlg)

    DEFINE_POPULAR_METHOD(CCppCallJavaScriptDlg,Rectangle);
    DEFINE_POPULAR_METHOD(CCppCallJavaScriptDlg,MoveTo);
    DEFINE_POPULAR_METHOD(CCppCallJavaScriptDlg,LineTo);
    DEFINE_POPULAR_METHOD(CCppCallJavaScriptDlg,TextOut);
END_DSRE_POPULAR_OBJECT()g_Dialogimpl;

//定义可以被JavaScript调用的函数,分别是Rectangle, MoveTo, LineTo, TextOut
DEFINE_DSRE_FUNCTION(CCppCallJavaScriptDlg,Rectangle)
{
    
int x,y,cx,cy;
    x
=(*args)[0]->AsInt();
    y
=(*args)[1]->AsInt();
    cx
=(*args)[2]->AsInt();
    cy
=(*args)[3]->AsInt();

    ::Rectangle(m_hDC,x,y,cx,cy);
}


DEFINE_DSRE_FUNCTION(CCppCallJavaScriptDlg,MoveTo)

{
    
int x,y;
    x
=(*args)[0]->AsInt();
    y
=(*args)[1]->AsInt();

    ::MoveToEx(m_hDC,x,y,NULL);
}


DEFINE_DSRE_FUNCTION(CCppCallJavaScriptDlg,LineTo)

{
    
int x,y;
    x
=(*args)[0]->AsInt();
    y
=(*args)[1]->AsInt();

    ::LineTo(m_hDC,x,y);
}


DEFINE_DSRE_FUNCTION(CCppCallJavaScriptDlg,TextOut)

{
    
int x,y;
    x
=(*args)[0]->AsInt();
    y
=(*args)[1]->AsInt();
    wchar_t 
*text=(*args)[2]->AsString()->GetText();
    ::TextOutW(m_hDC,x,y,text,(
*args)[2]->AsString()->GetLength());
}

 2 向msscript.ocx添加代码

    code_w=L"function OnDialogPaint(dialog){dialog.Rectangle(20,20,220,220);dialog.MoveTo(270,20);dialog.LineTo(300,120);dialog.TextOut(280,150,\"Text from JavaScript\");}";
    code
=code_w.GetText();
    JScriptWrapper
->Invoke(NULL,L"AddCode",&code,&ret);

3 在VC的 OnPaint 事件调用 JavaScript 

        LWideString code_w=L"OnDialogPaint(theCppDialog);";
        code
=code_w.GetText();
        JScriptWrapper
->Invoke(NULL,L"Eval",&code,&ret);

这样就完成了一下调用过程:

 

为真正的双向调用。

后记:

如果有了双向调用技术,不难想象Flash的ActionScript的实现方法,也不难想象Maxthon的Plug-in可以用MS Script来做。如果不能实现双向,只能像WPS那样,Script只能作为Add-on,而不是Plug-in(没有贬低WPS之意)。