VC中如何调用Script中的函数? 脚本中传来的函数指针是LPDISPATCH,如果直接用ChangeType转为String,得到的结果是包含函数代码在内的整个函数而不是函数名[即便能通过分析来获得...],请问我要如何能够通过这个Dispatch指针来调用这个函数呢?难道只能生成一个调用字符串插入执行吗? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 JavaScript Calls from C++http://www.codeguru.com/ieprogram/JSCalls.html 我也看了一下,这个地址确实不错的:http://www.codeguru.com/ieprogram/JSCalls.html 确实不错,通过GetIDsOfNames获取函数名称对应的DISPID,然后Invoke。但是前提是我知道这个函数的名称啊,通过return funcHandle这种方式传回来的指针的Variant Type(vt)是VT_DISPATCH而不是函数名称,强制转换为BSTR也是包含了函数代码的。这种方法实际上还是要我回到解析强制转换后的字符串的老路子上啊...而且我也有点奇怪,为什么返回的是DISPATCH接口?而且这个接口下似乎没有实现任何属性/方法啊... 通过GetTypeInfo可以获得类型信息参见http://www.csdn.net/develop/read_article.asp?id=21702HRESULT 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();} 函数对象用DISPID=0来调用。pObj->Invoke(0,IID_NULL,0,DISPATCH_METHOD,&Params,&result,NULL,NULL); 阿拉真主,我赞美Analyst!哦,顺便赞美一下jiangsheng和saucer前辈~就是那个DISPID=0,看到一些相关资料里面有所谓调用该Dispatch接口的缺省方法的说法,不过不知道如何做,大概便是这个吧?谢了,头疼了两三天了:)顺便感谢另两位帮忙解惑的,看了那些资料也获益良多呢。真恨不得拿我剩下的10000可用分把你们脑子里的东西都挖出来,口黑口黑... Windows XP Sp2 tcp 问题 多线程提问 bool 和BOOL 的区别 缺少MFC42D.DLL 有在南昌搞开发的吗?聊聊! 超 级大难题:我的键盘鼠标都 不能用了 象这样“新建文字文档.txt,新建文字文档(2).txt”文件名的生成... 我现在正在做一个程序用来安装.inf文件,有没有人有关于setupapi的例子,或者有相关思路的? vc里边调用服务器端带参数的存储过程怎么调用? 如何向手机发短信息?? _beginthread问题 小弟想学VC,不知先参考什么资料会入门快点,请高手指点啊。
http://www.codeguru.com/ieprogram/JSCalls.html
参见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();}
pObj->Invoke(0,IID_NULL,0,DISPATCH_METHOD,&Params,&result,NULL,NULL);