项目需要开发一个ActiveX控件,前台客户端和页面端同时使用,在开发的过程中,需求有所改进,从单纯的展示到需要与后台进行交互,为了让控件能直接通过页面访问后台,需要在控件中调用页面的js,实验多次(网上不靠谱的太多了,尼玛,坑爹不偿命啊!)后,总结如下:
1.在项目中添加2个接口类文件,IOleClientSite接口和IOleContainer接口,两个接口的Guid貌似不能改,直接复制粘贴即可:
using System.Runtime.InteropServices;
[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();
}
using System.Runtime.InteropServices;
[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);
}
在控件的主文件中,添加对Microsoft.mshtml的引用:
using mshtml; //注意命名空间只有这个,没有前面的Microsoft
接下来在控件中添加一个方法,这里采用了一个string类型的参数,这样在控件需要调用JS的地方调用这个方法即可。
private void CallJS(string text)
{
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[]{text};//调用js时传过去的参数,有多个就加到这里可以
//获取页面的Script集合
IHTMLDocument pDoc2 = (IHTMLDocument)pObj;
object script = pDoc2.Script;
try
{
//调用JavaScript方法MyMethod并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理
script.GetType().InvokeMember("MyMethod",
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,null, script, args);
}
catch {
MessageBox.Show("与JS交互出现问题");
}
}
3.修改页面中的JavaScript代码,这里只Alert一下
<script type="text/javascript">
function MyMethod(msg)
{
alert(msg);
}
</script>
以上,如有不足欢迎补充~
[转载请注明]