BHO自定义showmodaldialog窗口

来源:互联网 发布:淘宝凑单是什么意思 编辑:程序博客网 时间:2024/06/09 22:18

    之前一直在弄BHO,想监控页面的一些操作。基本上都还算顺利,但是一到了showmodaldialog就卡住了,根据监控不了!
    之后就是一轮网上找资料,资料一大堆,能实现的也不少,但都不是我想要的。结合前辈的经验,说可以通过覆盖window.showmodaldialog=自定义showmodaldialog 来实现。于是又搞了一大轮.....
    看到弹出了自己的showmodaldialog时一阵兴奋啊!快乐总是过得很快,当我传了3个参数后,发现showmodaldialog报错了!!!发现第2个参数根据没传到页面来。众所周知,window.showmodaldialog有3个参数(URL地址字符串,窗口参数,窗口样式字符串),第2个参数可以是字符串或者对象。如果是字符串,则在Invoke的DISPPARAMS里面体现的是VT_BSTR,这个类型的好处理;如果是对象(数组/json)则在Invoke的DISPPARAMS里面体现的是VT_DISPATCH,这种类型很复杂,不好弄,参照了
http://blog.csdn.net/xt_chaoji/article/details/7290018
http://www.codeproject.com/KB/COM/JSCalls/JSCalls_src.zip
JsArray(地址忘记了)
等等,都弄不好(本人知识,技术有限问题)。
    没办法,只能再想出路。后来想到,既然字符串类型很好处理,为啥不只传字符串,之后通过eval转成对象返回给页面?于是就有了以下……
1、自定义一个JS函数,通过BHO在页面完成时加载到页面中去
function window.showModalDialog(sURL,   vArguments,   sFeatures) { 
var tag="";
if(sURL.toLowerCase().indexOf(":")>-1) {
tag=sURL;
} else {
if(sURL.toLowerCase().indexOf("/")==0) {
tag=document.location.protocol+"//"+document.location.host+sURL;
} else {
var dt = location.href.split("?")[0].split("/");
dt.length--;
while(sURL.indexOf("../")==0) {
sURL = sURL.slice(3);dt.length--;
}
tag= unescape(dt.join("/")+"/"+sURL);
}
}
var _vArguments = EgdEnCode(vArguments);//将对象(数组/JSON)转成字符串,EgdEnCode函数不是JS标准的转换函数,网上一大堆。
window.returnValue=window.external.ShowModalDialog(tag,   _vArguments,   sFeatures);
window.returnValue;
}
2、实现扩展接口window.external.ShowModalDialog,这个dialog自己设置,不截图,有个4个参数的构造函数,带web控件的就OK。
XXXDIALOG(CComVariant sURL, CComVariant vArguments, CComBSTR sFeatures, CComVariant& pVarResult)
{
}
3、添加XXXDIALOG里面web控件的DownloadComplete事件,在事件里面添加如下代码,将字符串通过eval转成对象给window.dialogArguments:
CComQIPtr<IHTMLWindow2> spWin2;
hr = pDoc->get_parentWindow(&spWin2);
if(SUCCEEDED(hr) && spWin2 && pDoc)
{
spWin2->QueryInterface(IID_IDispatch, (void**)&pWindow2Disp);
// 先创建一个dialogArguments属性
CComBSTR bstrScript = SysAllocString(L"window.dialogArguments = eval('('+'");
bstrScript.Append(SysAllocString(_vArguments.bstrVal));// _vArguments是传过来的第二个参数 
bstrScript.Append(SysAllocString(L"'+')');"));
CComBSTR bstrLanguage = SysAllocString(L"javascript");
VARIANT vEmpty = {0};
hr = spWin2->execScript(bstrScript, bstrLanguage, &vEmpty);
}


至此,完毕。终于可以将数组,JSON对象“解析”出来了,对于其他类型没试过,觉得只要能转成字符串的应该都没问题。
另外还有一个问题,window.returnValue的值也有2种的VT_BSTR和VT_DISPATCH,但是很奇怪,直接通过Invoke,DISPATCH_PROPERTYGET获取属性得到的直接给pVarResult就OK,居然不用再通过遍历长度,下标,GetIDsOfNames和Invoke解析。为啥传入不能直接通过Invoke,DISPATCH_PROPERTYPUT设置属性,传出却可以直接读取,而且JS还能解析出来?




0 0
原创粉丝点击