ActiveX脚本宿主

    本文讨论如何使用MFC实现ActiveX脚本宿主.
    
    一个脚本宿主就是一个能运行其它脚本语言(VB脚本,VBA,Java脚本)并且能将应用程序内部的COM接口暴露给这些脚本的应用程序.微软的IE浏览器,Excel,Word,Access都是脚本宿主.IE用的是VB脚本,而其它的则是用的VBA.

    大部分关于如何实现脚本宿主的代码来自于Developer Studio光盘中的"Axscript"范例.该范例是用WIN32 API实现的.这里准备了三个工程来说明用MFC如何实现.

    第一步: 一个使你的MFC程序支持VB脚本的例子
    第二步: 暴露内部自动化对象到VB脚本引擎
    第三步: 添加VB脚本代码来控制由C++代码触发的事件

    将三个工程一个个编译运行,看看它们是如何工作的.运行程序后,选择菜单"VBScript->Load script file",会提示你载入一个脚本文件,选择工程目录下的"TestProgram.txt"文件,然后选择"VBScript->Run"菜单来运行脚本.

    第一个范例会显示一个消息对话框,每二个则绘制一些矩形,第三个会允许你会鼠标拖动这些矩形.

    注意:如果你的工程设置所有的编译结果放在同一目录,切换工程时不要忘记使用"Rebuild All"命令重新编译.

    要理解ActiveX脚本引擎是如何工作的请参考MSDN中的帮助,你可以在ActiveX相关帮助中的ActiveX scripting中找到.

    第一步:

    为了让你的程序运行VB脚本(或其它脚本)你必须通过IActiveScript和IActiveScriptParse接口与脚本引擎打交道.而且你的程序必须向IActiveScriptSite暴露对象,可能同时还要暴露给IActiveScriptSiteWindow.

    第一步的范例有一个CMainFrame对象,它同时支持IActiveScript和IActiveScriptParse接口.大部分的IActiveScript方法在该范例中没有实现.要理解如何在MFC中实现OLE接口,请参考相关文档.

    第二步:

    这一步要用类向导生成两个自动化对象.第一个对象CAXHostDoc由CDocument派生.第二个对象CAXSprite由CCmdTarget派生.CAXHostDoc有一个叫做Animation的对象,它能够管理子图形.CAXSprite是矩形子图形的一个OLE封装.子图形能够添加到Animation对象,能够被删除,移动,改变...,但是Animation对象什么也不做,直到你要求它绘制图像到特定的DC.不要管它到底是如何实现的.

    你的程序可以在脚本引擎中加入顶级的条目名称,它将在脚本中有效.这些条目名称应该与你的应用程序中的某些COM对象相对应.通常我们使用"Application"作为顶级对象.在这个示例中,是一个SDI应用,CAXHostApp对象有一个m_pDoc成员保存一个指向文档的指针.在CMainFrame::CreateScriptEngine方法中,"Document"对象名称被加入到脚本引擎.

COM对象与添加的条目名称间的关联就是在IActiveScriptSite::GetItemInfo方法中进行的.












    一旦这种关联被建立,你可以使用文档的方法与属性.如果你的应用中有一些方法返回接口到其它COM对象,你可以使用它们的方法与属性而不需要调用AddNamedItem.它们不是顶层对象,它们是由Document对象获得的(本例中只有一个对象-CAXSprite).

第三步:

    

    源程序下载
Step 3

In this example we make our program able to fire some events which can be handled by the VBScript engine. First of all we will need to provide ITypeInfo information to the script engine. The application object has some members to hold this information (you can use global variables).

ITypeInfo* ptinfoClsDoc; //coclass Document ITypeInfo* ptinfoIntDoc; //dispinterface IAXHost ITypeInfo* ptinfoClsSprite; //coclass Sprite ITypeInfo* ptinfoIntSprite; //dispinterface IAXSprite

To make your object fire events you need to create another interface to your object's events. Modify your ODL file.

Example:

In the CAXHostApp::InitInstance() method the type information was loaded

In the MainFrm.module:

The AddNamedItem was called with the SCRIPTITEM_ISSOURCE flag.

In the IActiveScriptSite::GetItemInfo ITypeInfo interface to the Document CLASS object has been provided to the scripting engine.

If you want your object support events, it must support IConnectionPointContainer interface and IProvideTypeInfo interface. See the article about CConnectionPoint MFC object. See how it was implemented with the CAXHostDoc object.

If you implement all the interfaces correctly, the scripting engine will establish a connection to your object and you will be able to fire events with help of a small function.

The iEvNum must be the same as in the ODL file. To fire the MouseDown event, for instance, i have to use iEvNum to be equal 1. Because [id(1)] void OnMouseDown([in] short x, [in] short y);

I should have made constants like IDEVENT_MOUSEDOWN and use them both in the ODL file and in my C++ code.

Example:

Observe the sequence of passing parameters to the variant array.

I am not sure that in this small description i have written all the tips to make your program work, but i send you the code which you can investigate. And you should alse see the "Axscript" example which does a little bit more. It provides a way how to make subclassing with VBScript. See the BuildTypeInfo function in the example to see how it has been done there.

If you have any questions, you can send me a message and i will try to answer. But i must confess that i am a novice in COM. COM is not difficult to understand but there are so many different objects and interfaces. And one must know how to use them in one's programs. The same can be said about the C++ language itself.

I also would like to get some examples on this matter if you have them. For example, i don't know how to implement debugging features (they say that Microsoft has already made a debugger fo VBScript), how to interrupt a running script (i think i should create an another thread and use an appropriate function), i tried to implement DUAL interfaces to my objects but the VBScript used just the IDispatch interfaces and i thought that VBScript did not support DUAL interfaces.

If you have any clues concerning this technology, please send them to me. I would like also your opinion whether this feature is interesting, for i can send some more examples. I mean not this sprites but a way of using this technology in business applications. For example, my program use special kinds of objects to work with SQL server databases and Access databases such as "recordsets", "idsets, "caches", "reports", "views" and others.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值