读好书,交益友
分类: JavaScript
2013-01-05 16:49:35
首先说做SSLVPN客户端的真苦逼,不断对付windows的升级,ie的升级,杀软的阻挠。
最近发现win8下sslvpn客户端可以安装,不能使用。调试了一下,发现js根本没有调用。
经过和vip菜鸟的讨论,他也没发现代码问题,但是建议根据返回值看看是否调用成功。
pScript->Invoke返回值0X80020003,无效的调用。
仔细看了一下
hr = pScript->GetIDsOfNames(IID_NULL, &bstrMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
得到的dispid是-1,hr的值是0X80020006 (DISP_E_UNKNOWNNAME)未知名称。
感到奇怪的是,这段代码在以前的IE版本中运行很正常。
看了一下csdn,建议使用
LPOLESTR pwFunName = L"m_strTest"; // 准备取得 Add 函数的序号 DispID
DISPID dispID; // 取得的序号,准备保存到这里
hr = pDispatch->lpVtbl->GetIDsOfNames( // 根据函数名,取得序号的函…
真是胡扯。
看了一下msdn,了解到
While IDispatch->GetIDsOfNames() fails to get a Dispatch ID of the variable in IE9, it turns out that using the result from get_Script() as IDispatchEx instead of IDispatch and calling:
这就很简单了,
CComPtr
hr = pDisp->QueryInterface(IID_IDispatchEx, (void**)&pDispEx);
得到IDispatchEx指针,
HRESULT hr = pDispEx->GetDispID( CComBSTR( name ), fdexNameImplicit, &id );
代替
HRESULT hr = pDisp->GetIDsOfNames( IID_NULL, &name, 1, LOCALE_SYSTEM_DEFAULT, &id )
然后使用IDispatchEx::InvokeEx ,他的参数传递和invoke 有很大区别。
基本就是这个样子
IDispatch *disp = pszBufData->pdispVal;
if (pszBufData->vt & VT_BYREF)
disp = *(pszBufData->ppdispVal);
// Get IDispatchEx on input IDispatch
CComQIPtr
if ( ! pdispexArray )
return E_NOINTERFACE;
// Get array length DISPID
DISPID dispidLength;
CComBSTR bstrLength(L"length");
HRESULT hr = pdispexArray->GetDispID(bstrLength, fdexNameCaseSensitive, &dispidLength);
if (FAILED(hr))
return false;
// Get length value using InvokeEx()
CComVariant varLength;
DISPPARAMS dispParamsNoArgs = {0};
hr = pdispexArray->InvokeEx(dispidLength, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParamsNoArgs, &varLength,
NULL, NULL);
if (FAILED(hr))
return hr;
ATLASSERT(varLength.vt == VT_I4);
const int count = varLength.intVal;
BYTE * pData = new BYTE[count];
// For each element in source array:
for (int i = 0; i < count; i++)
{
CString strIndex;
strIndex.Format(L"%d", i);
// Convert to BSTR, as GetDispID() wants BSTR's
CComBSTR bstrIndex(strIndex);
DISPID dispidIndex;
hr = pdispexArray->GetDispID(bstrIndex, fdexNameCaseSensitive, &dispidIndex);
if (FAILED(hr))
break;
// Get array item value using InvokeEx()
CComVariant varItem;
hr = pdispexArray->InvokeEx(dispidIndex, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispParamsNoArgs, &varItem,
NULL, NULL);
if (FAILED(hr))
break;
ATLASSERT(varItem.vt == VT_I4);
pData[i] = varItem.intVal;
}