#pragma once
#include "..\Head.h"
//_bstr_t需要的头文件
#include "comutil.h"
#pragma comment(lib, "comsuppw")
class ClientCall :public IDispatch
{
long _refNum;
public:
ClientCall()
{
_refNum = 1;
}
~ClientCall(void)
{
}
public:
// IUnknown Methods
STDMETHODIMP QueryInterface(REFIID iid, void**ppvObject)
{
*ppvObject = NULL;
if (iid == IID_IUnknown) *ppvObject = this;
else if (iid == IID_IDispatch) *ppvObject = (IDispatch*)this;
if (*ppvObject)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) AddRef()
{
return ::InterlockedIncrement(&_refNum);
}
STDMETHODIMP_(ULONG) Release()
{
::InterlockedDecrement(&_refNum);
if (_refNum == 0)
{
delete this;
}
return _refNum;
}
// IDispatch Methods
HRESULT _stdcall GetTypeInfoCount(
unsigned int * pctinfo)
{
return E_NOTIMPL;
}
HRESULT _stdcall GetTypeInfo(
unsigned int iTInfo,
LCID lcid,
ITypeInfo FAR* FAR* ppTInfo)
{
return E_NOTIMPL;
}
HRESULT _stdcall GetIDsOfNames(
REFIID riid,
OLECHAR FAR* FAR* rgszNames,
unsigned int cNames,
LCID lcid,
DISPID FAR* rgDispId
)
{
//对比函数名,设置一个dispId用与识别
if (lstrcmp(rgszNames[0], L"CppCall") == 0)
{
//网页调用window.external.CppCall时,会调用这个方法获取CppCall的ID
*rgDispId = 100;
}
if (lstrcmp(rgszNames[0], L"AddGoodsToList") == 0)
{
*rgDispId = 101;
}
return S_OK;
}
HRESULT _stdcall Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO* pExcepInfo,
unsigned int* puArgErr
)
{
//通过识别之前设置的dispId,调用对应函数
if (dispIdMember == 100)
{
//网页调用CppCall时,或根据获取到的ID调用Invoke方法
CppCall();
}
if (dispIdMember == 101)
{
wstring args = (_bstr_t)pDispParams->rgvarg[0];
//网页调用CppCall时,或根据获取到的ID调用Invoke方法
AddGoodsToList(args);
}
return S_OK;
}
//测试函数
void CppCall()
{
MessageBox(NULL, L"您调用了CppCall", L"提示(C++)", 0);
}
//添加商品
void AddGoodsToList(wstring args){
MessageBox(NULL, args.c_str(), L"AddGoodsToList参数", 0);
}
};
使用方法
//在duilib中,使用方法
class MainWnd: public CContainerUI,public CWebBrowserEventHandler
{
public:
ClientCall *pClientCall_;
CWebBrowserUI* m_pBrowser;
MainWnd(){
m_pBrowser = NULL;
pClientCall_ = new ClientCall();
}
//初始化CWebBrowserUI控件
void InitControl(){
m_pBrowser = static_cast<CWebBrowserUI*>(...));
//所有webbrowser事件和接口关联到当前this对象
if (m_pBrowser)
m_pBrowser->SetWebBrowserEventHandler(this);
}
//继承GetExternal,以便JS调用c++,window.external.CppCall();
virtual HRESULT STDMETHODCALLTYPE GetExternal(IDispatch **ppDispatch){
//重写GetExternal返回一个ClientCall对象
*ppDispatch = pClientCall_;
//计数器+1(很重要)
pClientCall_->AddRef();
return S_OK;
}
};
//JS代码
window.external.AddGoodsToList('this a cat');