波斯马BOSSMA Information Technology

Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结(2)

发布时间:2010年5月30日 / 分类:ASP.NET / 18,607 次浏览 / 评论

上一节介绍了一个ActiveX的例子,后续的文章将针对这个例子进行扩充和说明。这篇文章将介绍C#如何在ActiveX控件中调用javascript的函数,这里参考网上的例子介绍两种方法,虽然代码不一样,但是殊途同归。而且都使用了mshtml。

1、方法一

(1)在VS项目中添加Com对象引用:Microsoft Html Object Library(mshtml.tlb)

(2)ActiveX中公开一个方法,传递window对象到ActiveX中
ActiveX中公开一个方法,接受传递进来的参数

? /// <summary>
??????? /// 将window对象传递进来
??????? /// </summary>
??????? /// <param name="obj">The obj.</param>
??????? public void SetHtml(object obj)
??????? {
??????????? html = (mshtml.HTMLWindow2Class)obj;
??????? }

在页面中调用ActiveX的公开方法,传递当前window对象进去:
?

window.onload = function() {
??????????? document.HelloBossma.SetHtml(this);
??????? };

(3)在ActiveX控件中添加一个按钮,当点击这个按钮时,触发页面中的javascript。

点击按钮的方法:

/// <summary>
??????? /// 调用页面Javascript
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void button1_Click(object sender, EventArgs e)
??????? {

??????????? html.execScript("CallByActiveX();", "javascript");
??????? }

现在卸载掉原来的ActiveX控件,安装新的控件,打开页面,点击按钮,看到如下效果,说明成功。

调用javascript时还可以传递参数,这里不做演示了,自己可以试一下。

参考:http://www.cnblogs.com/liubiqu/articles/92632.html

2、方法二

(1)在VS项目中添加Com对象引用:Microsoft Html Object Library(mshtml.tlb)

和第一种方法相同。

(2)用c#实现两个COM类,IOleClientSite和IOleContainer

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace HelloBossma
{
??? [ComImport,
???? Guid("00000118-0000-0000-C000-000000000046"),
???? InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
??? public interface IOleClientSite
??? {
??????? void SaveObject();
??????? void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
??????? void GetContainer(out IOleContainer ppContainer);
??????? void ShowObject();
??????? void OnShowWindow(bool fShow);
??????? void RequestNewObjectLayout();
??? }

??? [ComImport,
???? Guid("0000011B-0000-0000-C000-000000000046"),
???? InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
??? public interface IOleContainer
??? {
??????? void EnumObjects([In, MarshalAs(UnmanagedType.U4)] int grfFlags,
??????????? [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppenum);
??????? void ParseDisplayName([In, MarshalAs(UnmanagedType.Interface)] object pbc,
??????????? [MarshalAs(UnmanagedType.BStr)] string pszDisplayName,
??????????? [Out, MarshalAs(UnmanagedType.LPArray)] int[] pchEaten,
??????????? [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppmkOut);
??????? void LockContainer([In, MarshalAs(UnmanagedType.I4)] int fLock);
??? }
}

(3)在ActiveX中编写CallJavascript方法:

/// <summary>
??????? /// 调用Javascript
??????? /// </summary>
??????? /// <param name="Filenames">The filenames.</param>
?private void CallJavaScript(string param)
??????? {
??????????? //反射获取当前的控件的ClientSite
??????????? Type typeIOleObject = this.GetType().GetInterface("IOleObject", true);
??????????? object oleClientSite = typeIOleObject.InvokeMember("GetClientSite",
??????????? BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
??????????? null,
??????????? this,
??????????? null);

??????????? //获取Container
??????????? IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite;
??????????? IOleContainer pObj;
??????????? oleClientSite2.GetContainer(out pObj);

??????????? //参数数组??
??????????? object[] args = new object[1];
??????????? args[0] = param;

??????????? //获取页面的Script集合??
??????????? IHTMLDocument pDoc2 = (IHTMLDocument)pObj;
??????????? object script = pDoc2.Script;

??????????? try
??????????? {
??????????????? //调用JavaScript方法OnScaned并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理??
??????????????? script.GetType().InvokeMember("ShowNowTime", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
?????????????? null,
??????????????? script,
??????????????? args);
??????????? }
??????????? catch { }
??????? }

点击按钮时的操作:

/// <summary>
??????? /// 调用Javascript
??????? /// </summary>
??????? /// <param name="sender"></param>
??????? /// <param name="e"></param>
??????? private void button1_Click(object sender, EventArgs e)
??????? {
?????????????????????? CallJavaScript(this.label2.Text);
??????? }

(4)网页中的javascript

function ShowNowTime(nowtime) {
??????????? alert("当前时间:" + nowtime);
??????? }

卸载原来的ActiveX控件,重新安装,实际效果:

参考:http://blog.csdn.net/sabty/archive/2009/05/10/4165342.aspx

这篇文档到这里就结束了,关于这两个方法的使用,如果有问题,欢迎和我交流!

本博客所有文章如无特别注明均为原创。
复制或转载请以超链接形式注明转自波斯马,原文地址《Visual Studio 2008(c#)开发ActiveX控件及制作CAB包总结(2)

关键字:

建议订阅本站,及时阅读最新文章!
【上一篇】 【下一篇】

目前有4 条评论

  1. bossma 0楼:

    @leo
    这里有例子下载:http://blog.bossma.cn/dotnet/visual-studio-2008-csharp-activex-summary-4/

  2. leo 0楼:

    不错的文章,但我想请问下,在Activex调用js的第二种方法中:
    用c#实现两个COM类,IOleClientSite和IOleContainer
    这两个接口如何实现呢?有参考实现么?

  3. kanner 0楼:

    找了好久,谢谢你能整理的这么详细!

发表评论