VC中如何调用Script中的函数?
脚本中传来的函数指针是LPDISPATCH,如果直接用ChangeType转为String,得到的结果是包含函数代码在内的整个函数而不是函数名[即便能通过分析来获得...],请问我要如何能够通过这个Dispatch指针来调用这个函数呢?
难道只能生成一个调用字符串插入执行吗?
问题点数:100、回复次数:8Top
1 楼saucer(思归)回复于 2003-11-17 04:29:13 得分 15
JavaScript Calls from C++
http://www.codeguru.com/ieprogram/JSCalls.htmlTop
2 楼yintongshun(左岸思雨)回复于 2003-11-17 08:41:48 得分 0
我也看了一下,这个地址确实不错的:http://www.codeguru.com/ieprogram/JSCalls.html
Top
3 楼iicup(双杯献酒)回复于 2003-11-17 08:53:27 得分 0
先看看去。Top
4 楼csdnzhu(我什么也不会)回复于 2003-11-17 09:03:11 得分 0
看看先Top
5 楼microant(源代码蚁)回复于 2003-11-17 18:35:44 得分 0
确实不错,通过GetIDsOfNames获取函数名称对应的DISPID,然后Invoke。但是前提是我知道这个函数的名称啊,通过return funcHandle这种方式传回来的指针的Variant Type(vt)是VT_DISPATCH而不是函数名称,强制转换为BSTR也是包含了函数代码的。
这种方法实际上还是要我回到解析强制转换后的字符串的老路子上啊...而且我也有点奇怪,为什么返回的是DISPATCH接口?而且这个接口下似乎没有实现任何属性/方法啊...Top
6 楼jiangsheng(蒋晟.Net[MVP])回复于 2003-11-17 19:14:22 得分 25
通过GetTypeInfo可以获得类型信息
参见http://www.csdn.net/develop/read_article.asp?id=21702
HRESULT CIEAutomationView::DumpTypeInfo(LPDISPATCH pDisp)
{
if(pDisp==NULL)return OLE_E_BLANK;
CComPtr<ITypeInfo> pTypeInfo;
HRESULT hr = S_OK;
hr= pDisp->GetTypeInfo(0, GetUserDefaultLCID(), &pTypeInfo);
if(FAILED(hr))return hr;
CSmartTypeAttr pTypeAttr( pTypeInfo );
CSmartFuncDesc pFuncDesc( pTypeInfo );
hr= pTypeInfo->GetTypeAttr( &pTypeAttr );
if(FAILED(hr))return hr;
for(int iMethod = 0; iMethod < pTypeAttr->cFuncs; iMethod++){
hr= pTypeInfo->GetFuncDesc(iMethod, &pFuncDesc);
if(FAILED(hr))return hr;
CString strInvokeType;
switch(pFuncDesc->invkind){
case INVOKE_FUNC :strInvokeType="Function";break;
case INVOKE_PROPERTYGET :strInvokeType="Property(Get)";break;
case INVOKE_PROPERTYPUT :strInvokeType="Property(Put)";break;
case INVOKE_PROPERTYPUTREF:strInvokeType="Property(Putref)";break;
default:break;
}
CComBSTR bstrName;
unsigned int nNames;
hr= pTypeInfo->GetNames(pFuncDesc->memid, &bstrName, 1,&nNames );
if(FAILED(hr))return hr;
ASSERT( nNames == 1 );
TRACE("%s\t%s\r\n",CString(bstrName.m_str),strInvokeType);
pFuncDesc.Release();
}
return S_OK;
}
void CIEAutomationView::OnDocumentComplete(LPDISPATCH pDisp, LPCTSTR lpszUrl)
{
// make sure the main frame has the new URL. This call also stops the animation
((CChildFrame*)GetParentFrame())->SetAddress(lpszUrl);
CString strURL(lpszUrl);
IUnknown* pUnkBrowser = NULL;
IUnknown* pUnkDisp = NULL;
TRACE(_T("Document %s Done\r\n"),lpszUrl);
//is it top level document?
HRESULT hr = m_pBrowserApp->QueryInterface( IID_IUnknown, (void**)&pUnkBrowser);
if ( SUCCEEDED(hr) ){
hr = pDisp->QueryInterface( IID_IUnknown, (void**)&pUnkDisp );
if ( SUCCEEDED(hr) ){
if ( pUnkBrowser == pUnkDisp ){
//top level
m_spHtmlDoc=NULL;
hr=m_pBrowserApp->get_Document(&m_spHtmlDoc);
TRACE(_T("Downloading Complete\r\n"),lpszUrl);
DumpTypeInfo(m_spHtmlDoc);
CComQIPtr<IHTMLDocument2> pHtmlDoc(m_spHtmlDoc);
IShellBrowser* pShellBrowser=(IShellBrowser*)m_wndBrowser.SendMessage(WM_USER+7,0,0);
if(pHtmlDoc){
CComPtr<IHTMLWindow2> pWindow;
pHtmlDoc->get_parentWindow(&pWindow);
CComQIPtr<IDispatch> spWindow(pWindow);
m_domExternal.SetMenuArguments(spWindow);
}
if(pShellBrowser){
CComPtr<IShellView> pIShellView;
pShellBrowser->QueryActiveShellView(&pIShellView);
if(pIShellView){
FOLDERSETTINGS fs;
pIShellView->GetCurrentInfo(&fs);
CComQIPtr<IFolderView> pIFolderView(pIShellView);
if(pIFolderView){
pIFolderView->SetCurrentViewMode(FVM_DETAILS);
}
}
TRACE("Get Shell Browser\r\n");
}
}
pUnkDisp->Release();
}
pUnkBrowser->Release();
}
}
void CIEAutomationView::CallScript(IHTMLWindow2* pWindow2
,BSTR bstrCode
,BSTR bstrLanguage)
{
ASSERT(pWindow2);
HRESULT hr = S_OK;
COleVariant ret;
hr = pWindow2->execScript(bstrCode, bstrLanguage, &ret);
}
void CIEAutomationView::CallScriptDirect(IHTMLWindow2* pWindow2
,BSTR bstrMethod)
{
DISPID dispidScriptObject, dispidMethodToInvoke;
IDispatch *pDispScriptObject;
DISPPARAMS dispparamsNoArgs = { NULL, NULL, 0, 0};
HRESULT hr;
OLECHAR *szScript = L"script";
OLECHAR *szFuncName = bstrMethod;
IHTMLDocument2* pDocument2 = NULL;
hr = pWindow2->get_document(&pDocument2);
ASSERT(SUCCEEDED(hr) && pDocument2);
IDispatch* pDocDisp = NULL;
hr = pDocument2->QueryInterface(IID_IDispatch, (void**)&pDocDisp);
ASSERT(SUCCEEDED(hr) && pDocDisp);
// Get the DISPID of the document's Script property.
hr = pDocDisp->GetIDsOfNames(IID_NULL, &szScript,
1, LOCALE_USER_DEFAULT, &dispidScriptObject);
ASSERT(SUCCEEDED(hr));
COleVariant varResult;
// Get the document's Script property.
hr = pDocDisp->Invoke(dispidScriptObject,
IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET,
&dispparamsNoArgs, &varResult, NULL, NULL);
ASSERT(SUCCEEDED(hr) && varResult.pdispVal);
pDispScriptObject = varResult.pdispVal;
varResult.Clear();
// Get the DISPID of the script method to invoke.
hr = pDispScriptObject->GetIDsOfNames(IID_NULL, &szFuncName, 1,
LOCALE_USER_DEFAULT, &dispidMethodToInvoke);
ASSERT(SUCCEEDED(hr));
// Invoke the script method.
hr = pDispScriptObject->Invoke(dispidMethodToInvoke, IID_NULL,
LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparamsNoArgs,
&varResult, NULL, NULL);
ASSERT(SUCCEEDED(hr));
pDocDisp->Release();
pDocument2->Release();
}Top
7 楼Analyst()回复于 2003-11-17 19:18:55 得分 60
函数对象用DISPID=0来调用。
pObj->Invoke(0,IID_NULL,0,DISPATCH_METHOD,&Params,&result,NULL,NULL);
Top
8 楼microant(源代码蚁)回复于 2003-11-17 20:56:45 得分 0
阿拉真主,我赞美Analyst!哦,顺便赞美一下jiangsheng和saucer前辈~
就是那个DISPID=0,看到一些相关资料里面有所谓调用该Dispatch接口的缺省方法的说法,不过不知道如何做,大概便是这个吧?
谢了,头疼了两三天了:)顺便感谢另两位帮忙解惑的,看了那些资料也获益良多呢。真恨不得拿我剩下的10000可用分把你们脑子里的东西都挖出来,口黑口黑...Top



