ActiveX(三)ActiveX 调用 Js
在上一篇随笔: ActiveX(二)Js 监听 ActiveX中的事件 中,已经可以实现 Js 监听 ActiveX中的事件,至此、Js 和 ActiveX 已经可以实现双向通讯了。但是、这样的实现方式,都是站在Js的角度去实现的,那么 ActiveX 能否主动调用 Js 呢?答案无疑是肯定的,在该篇随笔中、我们将逐渐揭开这一层神秘的面纱。
我第一次接触用C#代码调用Js是在四年前,那时候正在实习做Windows应用、需要借用 WebBrowser 控件操作js、完成一些特殊需求。当时的代码大致如下:
// 执行JS
private void ExecJs()
{
try
{
if (this.webBrowser.Document != null)
{
mshtml.IHTMLDocument2 currentDoc = (mshtml.IHTMLDocument2)this.webBrowser.Document.DomDocument;
if (currentDoc != null)
{
mshtml.IHTMLWindow2 win = (mshtml.IHTMLWindow2)currentDoc.parentWindow;
if (win != null)
{
//调用 函数F、传递一个宽度做参数
win.execScript(string.Format("F('{0}')", this.webBrowser.Width), "javascript");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
由上述代码、可以看出,其核心方法为 mshtml.IHTMLWindow2.execScript,注意:我们再仔细看一下方法名,有没有觉得很熟悉?如果你还没想起来,那我们继续看一下 mshtml.IHTMLWindow2 这个类型中还有什么成员吧。
[Guid("332C4427-26CB-11D0-B483-00C04FD90119")]
[TypeLibType()]
public interface IHTMLWindow2 : IHTMLFramesCollection2
{
[DispId()]
dynamic _newEnum { get; }
[DispId()]
HTMLNavigator clientInformation { get; }
[DispId()]
bool closed { get; }
[DispId()]
string defaultStatus { get; set; }
[DispId()]
IHTMLDocument2 document { get; }
[DispId()]
IHTMLEventObj @event { get; }
[DispId()]
dynamic external { get; }
[DispId()]
FramesCollection frames { get; }
[DispId()]
HTMLHistory history { get; }
[DispId()]
HTMLImageElementFactory Image { get; }
[DispId()]
int length { get; }
[DispId()]
HTMLLocation location { get; }
[DispId()]
string name { get; set; }
[DispId()]
HTMLNavigator navigator { get; }
[DispId()]
dynamic offscreenBuffering { get; set; }
[DispId(-)]
dynamic onbeforeunload { get; set; }
[DispId(-)]
dynamic onblur { get; set; }
[DispId(-)]
dynamic onerror { get; set; }
[DispId(-)]
dynamic onfocus { get; set; }
[DispId(-)]
dynamic onhelp { get; set; }
[DispId(-)]
dynamic onload { get; set; }
[DispId(-)]
dynamic onresize { get; set; }
[DispId(-)]
dynamic onscroll { get; set; }
[DispId(-)]
dynamic onunload { get; set; }
[DispId()]
dynamic opener { get; set; }
[DispId()]
HTMLOptionElementFactory Option { get; }
[DispId()]
IHTMLWindow2 parent { get; }
[DispId()]
IHTMLScreen screen { get; }
[DispId()]
IHTMLWindow2 self { get; }
[DispId()]
string status { get; set; }
[DispId()]
IHTMLWindow2 top { get; }
[DispId()]
IHTMLWindow2 window { get; } [DispId()]
void alert(string message = "");
[DispId()]
void blur();
[DispId()]
void clearInterval(int timerID);
[DispId()]
void clearTimeout(int timerID);
[DispId()]
void close();
[DispId()]
bool confirm(string message = "");
[DispId()]
dynamic execScript(string code, string language = "JScript");
[DispId()]
void focus();
[DispId()]
dynamic item(ref object pvarIndex);
[DispId()]
void moveBy(int x, int y);
[DispId()]
void moveTo(int x, int y);
[DispId()]
void navigate(string url);
[DispId()]
IHTMLWindow2 open(string url = "", string name = "", string features = "", bool replace = false);
[DispId()]
dynamic prompt(string message = "", string defstr = "undefined");
[DispId()]
void resizeBy(int x, int y);
[DispId()]
void resizeTo(int x, int y);
[DispId()]
void scroll(int x, int y);
[DispId()]
void scrollBy(int x, int y);
[DispId()]
void scrollTo(int x, int y);
[DispId()]
int setInterval(string expression, int msec, ref object language = Type.Missing);
[DispId()]
int setTimeout(string expression, int msec, ref object language = Type.Missing);
[DispId()]
void showHelp(string helpURL, object helpArg = Type.Missing, string features = "");
[DispId()]
dynamic showModalDialog(string dialog, ref object varArgIn = Type.Missing, ref object varOptions = Type.Missing);
[DispId()]
string toString();
}
IHTMLWindow2
想起来了没有? 如果还没有、那只能说你一行Js代码都没写过。 没错,js 中的 window 对象 实现了 mshtml.IHTMLWindow2 这个接口。既然如此,我们通过一个初始化函数将 window 对象传入,就可以得到 mshtml.IHTMLWindow2 接口了。
哈哈,补充一下, mshtml 命名空间 源自:Microsoft.mshtml.dll.
当知道了如上的信息后,一切就变的‘简单’了:
/// <summary>
/// 调用Js函数
/// </summary>
/// <param name="functionName">js函数名</param>
/// <param name="args">参数</param>
/// <returns></returns>
private dynamic RunJs(string functionName, string args = "")
{
dynamic dy = null; // 方法返回值永远为 null
if (this.window2 != null)
{
//调用函数
dy = this.window2.execScript(string.Format("{0}('{1}')", functionName, args), "javascript");
} return dy;
}
通过如上的代码,确实可以调用Js、但是、还有一个Bug... 返回值一直为Null.
那怎么办呢? 反射——没错,就是反射调用Js,也许你现在还想不明白, 先看一下代码吧,看完后你也许会恍然大悟:
/// <summary>
/// 调用Js函数
/// </summary>
/// <param name="functionName">js函数名</param>
/// <param name="args">参数</param>
/// <returns></returns>
private dynamic RunJs(string functionName, string args = "")
{
dynamic dy = null;// 第二种方式 反射调用 Js
// 被调用的js函数必须有一个参数
if (this.window2 != null)
{
dy = this.window2.GetType().InvokeMember(functionName,
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
null, this.window2, new object[] { args });
} return dy;
}
有没有想到呢 —— 全局的Js函数其实是属于window对象的,当然可以用反射去调用啦。
完整的测试项目demo: TestActiveX.zip
下一篇,我们将探究强大的 Microsoft.mshtml.dll,有点期待。
(未完待续...)
ActiveX(三)ActiveX 调用 Js的更多相关文章
- Unreal Engine 4 Radiant UI 插件入门(三)——从蓝图中调用JS
不知道大家有没有混淆.这篇教程说的是从蓝图中调用JS的功能(以改变H5内的内容). 在安装了UE4和RadiantUI的前提下学习这篇教程.本篇教程接着上一篇教程,建议请先看上一篇. 第一步:在网页中 ...
- VC与JavaScript交互(二) --- 调用JS函数
这一章,我们来动手实践VC调用JS函数. 我们动手写一个HTML,其中包含这样一段JS代码: //[html] <script type="text/javascript"& ...
- Web网页中内嵌Activex的Activex插件开发 .
转载自: http://blog.csdn.net/tttyd/article/details/5258096 源代码下载 http://files.cnblogs.com/tttyd/Activex ...
- Delphi 中调用JS文件中的方法
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- java调用js脚本
有些情况下,需要java去调用js,groovy等脚本语言,传入参数获取脚本运行的结果. js脚本例子: function add(a,b){ return a + b + number; } jav ...
- JS调用OC方法并传值,OC调用JS方法并传值////////////////////////zz
iOS开发-基于原生JS与OC方法互相调用并传值(附HTML代码) 最近项目里面有有个商品活动界面,要与web端传值,将用户在网页点击的商品id 传给客户端,也就是js交互,其实再说明白一点 ...
- Magento中调用JS文件的几种方法
一.全局调用方法: 通过该方法每个页面都会引用这个JS文件,除非是类似jQuery这样的系统文件,不然不推荐这种方法. 文件路径:/app/design/frontend/default/Your_T ...
- ios开发--网页中调用JS与JS注入
先将网页弄到iOS项目中: 网页内容如下, 仅供测试: <html> <head> <meta xmlns="http://www.w3.org/1999/xh ...
- 服务端调用js:javax.script
谈起js在服务端的应用,大部分人的第一反应都是node.js.node.js作为一套服务器端的 JavaScript 运行环境,有自己的独到之处,但不是所有的地方都需要使用它. 例如在已有的服务端代码 ...
随机推荐
- ASP.NET安全
ASP.NET 安全 概述 安全在web领域是一个永远都不会过时的话题,今天我们就来看一看一些在开发ASP.NET MVC应用程序时一些值得我们注意的安全问题.本篇主要包括以下几个内容 : 认证 授权 ...
- Redis性能问题排查解决手册(七)
阅读目录: 性能相关的数据指标 内存使用率used_memory 命令处理总数total_commands_processed 延迟时间 内存碎片率 回收key 总结 性能相关的数据指标 通过Red ...
- 在Windows中安装Memcached
Memcached是一个高并发的内存键值对缓存系统,它的主要作用是将数据库查询结果,内容,以及其它一些耗时的计算结果缓存到系统内存中,从而加速Web应用程序的响应速度. Memcached最开始是作为 ...
- [已招满,谢谢关注]Sogou招聘C#开发人员,有意者请进
职位名称:c#开发工程师 工作地点:搜狐网络大厦 职责:搜狗商业平台桌面产品 职位要求: 1. 计算机或者相关专业本科或以上学历 2. 精通c#,两年以上实际项目开发经验 3. 熟悉C/S开发架构和设 ...
- JavaScript 函数的两种声明方式
1.函数声明的方式 JavaScript声明函数有两种选择:函数声明法,表达式定义法. 函数声明法 function sum (num1 ,num2){ return num1+num2 } 表达式定 ...
- Nginx配置文件nginx.conf详解
#定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错误日志定义类型,[ debug | ...
- 【WP 8.1开发】How to 图像处理
在今天的吹牛节目开始之前,先交代一件事: 关于玩WP 8.1开发所使用的VS版本问题.对版本的要求是2013的Update2,这是最低要求,只要是这个版本或以上都可以,而update3,update4 ...
- .NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程
在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑) 与 .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB中,介绍了LiteDB的基本使用情况以及部 ...
- [ASP.NET MVC] 利用自定义的AuthenticationFilter实现Basic认证
很多情况下目标Action方法都要求在一个安全上下文中被执行,这里所谓的安全上下文主要指的是当前请求者是一个经过授权的用户.授权的本质就是让用户在他许可的权限范围内做他能够做的事情,授权的前提是请求者 ...
- C#线程同步自动重置事件——AutoResetEvent
AutoResetEvent对象用来进行线程同步操作,AutoResetEvent类继承waitHandle类. AutoResetEvent对象有终止和非终止两种状态,终止状态是线程继续执行,非终止 ...