这个是一个关于external和页面交换的问题
dll程序
STDMETHODIMP CImpIDispatch::Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID /*riid*/,
/* [in] */ LCID /*lcid*/,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS* pDispParams,
/* [out] */ VARIANT* pVarResult,
/* [out] */ EXCEPINFO* /*pExcepInfo*/,
/* [out] */ UINT* puArgErr)
{
if(dispIdMember == DISPID_CB_IsOurCustomBrowser)
{
if(pDispParams->rgvarg[0].vt & VT_VARIANT)
{
pDispParams->rgvarg[0].vt = VT_VARIANT;
pDispParams->rgvarg[0].pvarVal->vt = VT_BSTR | VT_BYREF;
*pDispParams->rgvarg[0].pvarVal->pbstrVal = SysAllocString(L"你好");
}
}
........
.......
} 页面
var str = "";
Window.External.Action(str);alert(str);应该弹出 “你好”字符
但是不能显示 谁能指点,谢
dll程序
STDMETHODIMP CImpIDispatch::Invoke(
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID /*riid*/,
/* [in] */ LCID /*lcid*/,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS* pDispParams,
/* [out] */ VARIANT* pVarResult,
/* [out] */ EXCEPINFO* /*pExcepInfo*/,
/* [out] */ UINT* puArgErr)
{
if(dispIdMember == DISPID_CB_IsOurCustomBrowser)
{
if(pDispParams->rgvarg[0].vt & VT_VARIANT)
{
pDispParams->rgvarg[0].vt = VT_VARIANT;
pDispParams->rgvarg[0].pvarVal->vt = VT_BSTR | VT_BYREF;
*pDispParams->rgvarg[0].pvarVal->pbstrVal = SysAllocString(L"你好");
}
}
........
.......
} 页面
var str = "";
Window.External.Action(str);alert(str);应该弹出 “你好”字符
但是不能显示 谁能指点,谢
STDMETHOD(GetIDsOfNames)(REFIID /*riid*/, OLECHAR ** rgszNames, UINT cNames, LCID /*lcid*/, DISPID * rgDispId)
{
for (UINT i=0; i<cNames; i++)
{
rgDispId[i] = DISPID_UNKNOWN;
if (lstrcmpW(rgszNames[i], L"Action") == 0)
{
rgDispId[i] = DISPID_CB_IsOurCustomBrowser;
}
}
return S_OK;
}另外,pDispParams在这种情况下不是给你赋值用的,因为没有VT_BYREF,而是传给你一个只读字符串。如果你需要返回值,应该这样做:
if (pVarResult)
{
pVarResult->vt = VT_BSTR;
pValResult->pbstrVal = SysAllocString(L"你好");
}
return S_OK;在页面里这样调用:
var str = window.external.Action();
alert(str);
另一种解决方案,使用PROPERTYGET调用,但是跟上面我在1楼讲的方法调用原理是一样的。
代码如下:
typedef IDispatchImpl<IATLOpener, &IID_IATLOpener, &LIBID_ATLMASKWRAPPERLib> ATLOpenerType;
typedef IDispatchImpl<IATLOpenerUI, &IID_IATLOpenerUI, &LIBID_ATLMASKWRAPPERLib> ATLOpenerUIType;
const DISPID INTERFACEMASK = 0xFFFF0000;
const DISPID DISPIDMASK = 0x0000FFFF;
const DISPID IDISPATLOPENER = 0x00010000;
const DISPID IDISPATLOPENERUI = 0x00020000;/////////////////////////////////////////////////////////////////////////////
// CATLOpener
STDMETHODIMP CATLOpener::GetIDsOfNames(REFIID riid,
LPOLESTR* rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgdispid)
{
HRESULT hr = DISP_E_UNKNOWNNAME; hr = ATLOpenerType::GetIDsOfNames(riid,
rgszNames, cNames, lcid, rgdispid);
if (SUCCEEDED(hr))
{
rgdispid[0] |= IDISPATLOPENER;
return hr;
} hr = ATLOpenerUIType::GetIDsOfNames(riid,
rgszNames,
cNames,
lcid,
rgdispid);
if (SUCCEEDED(hr))
{
rgdispid[0] |= IDISPATLOPENERUI;
return hr;
} return hr;
}STDMETHODIMP CATLOpener::Invoke(DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr)
{
DWORD dwInterface = (dispidMember & INTERFACEMASK);
dispidMember &= DISPIDMASK; switch(dwInterface)
{ case IDISPATLOPENERUI:
return ATLOpenerUIType::Invoke(dispidMember,
riid,
lcid,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr); case IDISPATLOPENER:
default:
//return DISP_E_MEMBERNOTFOUND;
return ATLOpenerType::Invoke(dispidMember,
riid,
lcid,
wFlags,
pdispparams,
pvarResult,
pexcepinfo,
puArgErr);
}}
然后在添加你的Action方法,它的str参数是传入还是传出随便怎么实现都可以.
http://topic.csdn.net/u/20080227/14/8bce0844-bd15-42f0-9cda-a343d5d6601b.html?seed=2111206245
http://topic.csdn.net/u/20080227/14/8bce0844-bd15-42f0-9cda-a343d5d6601b.html?seed=2111206245