JavaScript与C#开发ActiveX控件相互调用

浏览器插件之C#开发"ActiveX"(一)

浏览器插件之C#开发"ActiveX"(二)

前面已经用C#开发ActiveX控件,并成功嵌入到WEB网页中。下面讲述本人Javascript与ActiveX相互调用的步骤。

一、js调用ActiveX

1.1.在类库UserControls1.cs文件中添加三个函数(名字以123区分,未进行函数重载,原因是实践过程中发现js无法识别)

       public void  FunctionInActiveX()
        {
            MessageBox.Show(Properties.Resources.Str3, Properties.Resources.Str2, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        public object FunctionInActiveX2(object arg)
        {
            MessageBox.Show("javascript传过来的参数是:" + (arg == null ? "空" : arg.ToString()), Properties.Resources.Str2, MessageBoxButtons.OK,                     MessageBoxIcon.Information);
            return "activex返回的字符串";
        }
        public double FunctionInActiveX3(double num1,double num2)
        {
            return num1 +num2;
        }

如下图

1.2.在html为先前的Object标签元素添加ID为A_SHIJIERUCIMEIHAO,并添加相应javascript代码和网页按钮

<object id="A_SHIJIERUCIMEIHAO"
   classid="clsid:9A15E63F-1761-4f99-B740-512AD1C63D7E"
>

<script type="text/javascript">
function CallActiveXFunction(){
  var activeObj=document.getElementById("A_SHIJIERUCIMEIHAO");
  if(activeObj){
  activeObj.FunctionInActiveX();
  alert(activeObj.FunctionInActiveX2("js的参数"));
  alert("ActiveX计算返回的结果:"+activeObj.FunctionInActiveX3(1,2));
  }
}
</script>

<input type="button" onClick="javascript:CallActiveXFunction();" value="网页的按钮"></input>

整体如下图

用IE打开该网页

1.3点击网页的按钮 并对所提示允许,(网上很多介绍在Activex实现如何去掉限制的方法,但都是C++的,现在我还不知道这里咋整)

后面依次弹出四个对话框

二、ActiveX调用js

这里主要根据网上的资料实践的。

先来个简单的方法(可能不实用),

首先由js调用activex控件方法,目的是把html的window窗体传递给activex控件,进而获得IHTMLWindow2对象,然后activex控件根据获得IHTMLWindow2对象再调用js函数。

2.1在html里面添加代码后如下:

<html>
<head>
<title>我要睡觉了</title>
<script type="text/javascript">
function CallActiveXFunction(){ 
var activeObj=document.getElementById("A_SHIJIERUCIMEIHAO");
  if(activeObj){
  activeObj.FunctionInActiveX();
  alert(activeObj.FunctionInActiveX2("js的参数"));
  alert("ActiveX计算返回的结果:"+activeObj.FunctionInActiveX3(1,2));
  }
}
function setWindowToActiveX(){
var activeObj=document.getElementById("A_SHIJIERUCIMEIHAO"); 
  if(activeObj){
  activeObj.SetWindowOfHtml(window);
  }
}
function funcInJS(obj){
alert("给ActiveX调用的js函数--"+obj);
}
</script>
</head>
<body onLoad="javascript:setWindowToActiveX();">
 <b align=center>下面是嵌入的ActiveX控件哦</b>
</br>
<input type="button" onClick="javascript:CallActiveXFunction();" value="网页的按钮"></input>
</br>
<object id="A_SHIJIERUCIMEIHAO"
   classid="clsid:9A15E63F-1761-4f99-B740-512AD1C63D7E"
>
</object>
</body>
</html>

2.2 activex控件中添加一个textbox控件用于输入要调用的js函数名称,一个按钮用于调用js函数

如下图

2.3添加引用Microsoft.mshtml.dll

2.4在UserControl1

.cs添加代码如下:

  #region 调用js代码
        IHTMLWindow2 htmlWin;
        public void SetWindowOfHtml(object win)
        {
             htmlWin = (win as IHTMLWindow2);          
        }
        public void CallJSFunction(string JSFuncName)
        {
            if (htmlWin == null || string.IsNullOrEmpty(JSFuncName))
            {
                MessageBox.Show("错误");
            }
            else
            {                
                //调用js代码1,反射的方法;2,JS代码语法
                //方法1。 
                htmlWin.GetType().InvokeMember(JSFuncName,
                   BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
                   null, htmlWin, new object[] { "C#参数" });
                //方法2。 
                string jsCode = string.Format("{0}('{1}')", JSFuncName, "C#参数");
                htmlWin.execScript(jsCode, "jscript");
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            CallJSFunction(textBox1.Text);
        }
        #endregion

2.3运行程序,点击"调用js函数"按钮,结果如图:

好。后面用另一种比较复杂方法,但不用先由js调用activex控件代码....

首先用c#实现两个COM类,IOleClientSite和IOleContainer

 [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,
         [In, 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);
    }

在UserControl1.cs中就可以编写如下的CallJavaScript方法:

      private void CallJavaScript(string arg)
        {
            Type typeIOleObject = this.GetType().GetInterface("IOleObject", true);
            object oleClientSite = typeIOleObject.InvokeMember("GetClientSite",
            BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
            null, this, null);
            IOleClientSite oleClientSite2 = oleClientSite as IOleClientSite;
            IOleContainer pObj;
            oleClientSite2.GetContainer(out pObj);
            //参数数组
            object[] args = new object[1];
            args[0] = arg;
            //获取页面的Script集合
            IHTMLDocument pDoc2 = (IHTMLDocument)pObj;
            object script = pDoc2.Script;
            try
            {
                //调用JavaScript方法funcInJS并传递参数
                script.GetType().InvokeMember("funcInJS",
                BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, script, args);
            }
            catch { }
        }

再添加一个按钮,单击事件添加代码

private void button3_Click(object sender, EventArgs e)
{   
    CallJavaScript("C#参数");
}

OK ,搞定

代码工程已上传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值