QAxWidget 呼叫ocx控制元件之 js雙向通訊
1 示例: QAxWidget 載入 IE外掛
第一步 載入ie控制元件
void CActivexWidget::InitActiveX() //其中 CActivexWidget 派生自QAxWidget
{
setControl("Shell.Explorer");//HKEY_CLASSES_ROOT\Shell.Explorer
setObjectName(QString::fromUtf8("mywebkit"));//隨便設定一個名字啦
}
第二步 瀏覽http或https
m_pAxWidget->dynamicCall("Navigate(const QString&)", sAppPath);//其中 m_pAxWidget 為CActivexWidget一個指標
第三步: qt呼叫html函式
QString sValue ;
sValue=QString::fromLocal8Bit(pData);
QAxObject *document =m_pAxWidget->querySubObject("Document");
if(!document)
return ;
QAxObject *parentWindow = document->querySubObject("parentWindow");
if(parentWindow)
{
OutLog("put data to html %s",pData);
parentWindow->dynamicCall("OnDataFromExternal (QString&)", sValue); //其中 OnDataFromExternal 為html裡的函式
}
第四部 html呼叫qt
這一步比較麻煩 需要繼承幾個類
第一步 繼承QAxWidget 並重寫QAxAggregated *createAggregate();
class CActivexWidget : public QAxWidget
{
public:
CActivexWidget(QWidget *parent);
~CActivexWidget();
public:
virtual QAxAggregated *createAggregate();
virtual void InitActiveX();
protected:
CAxAggregated *m_pAggregated;
};
第二步 繼承 QAxAggregated 並重寫 virtual long queryInterface(const QUuid &iid, void **iface);
class CAxAggregated :
public QAxAggregated
{
public:
CAxAggregated(void);
virtual ~CAxAggregated(void);
virtual long queryInterface(const QUuid &iid, void **iface);
protected:
CExternalDocHostUIHandler *m_pExternalHandle ;
};
第三步 寫一個類 繼承 IDocHostUIHandler
class CExternalDocHostUIHandler :
public IDocHostUIHandler
{
//實現 IDocHostUIHandler的所有介面
//著重實現 HRESULT STDMETHODCALLTYPE GetExternal( IDispatch **ppDispatch)
}
HRESULT CExternalDocHostUIHandler::GetExternal( IDispatch **ppDispatch)//其中 m_pJSCall 為一個繼承自IDispatch的類指標
{
m_pJSCall->QueryInterface(IID_IDispatch,(void**)ppDispatch);;
(*ppDispatch)->AddRef();
return S_OK;
}
到這裡就把自定義的external物件傳遞給了html
剩下的方法 你自己就知道怎麼呼叫了
class CJSCall:public IDispatch
{
long _refNum;
public:
CJSCall();
~CJSCall(void);
// IUnknown Methods
public:
STDMETHODIMP QueryInterface(REFIID iid,void**ppvObject);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
// IDispatch Methods
HRESULT _stdcall GetTypeInfoCount(unsigned int * pctinfo) ;
HRESULT _stdcall GetTypeInfo(unsigned int iTInfo,LCID lcid,ITypeInfo FAR* FAR* ppTInfo) ;
HRESULT _stdcall GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames,
LCID lcid, DISPID FAR* rgDispId );
HRESULT _stdcall Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS* pDispParams,
VARIANT* pVarResult,EXCEPINFO* pExcepInfo,unsigned int* puArgErr);
};
CJSCall::CJSCall()
{
_refNum = 1;
}
CJSCall::~CJSCall(void)
{
}
STDMETHODIMP CJSCall::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) CJSCall::AddRef()
{
return ::InterlockedIncrement(&_refNum);
}
STDMETHODIMP_(ULONG) CJSCall::Release()
{
::InterlockedDecrement(&_refNum);
if(_refNum == 0)
{
delete this;
}
return _refNum;
}
// IDispatch Methods
HRESULT _stdcall CJSCall::GetTypeInfoCount(
unsigned int * pctinfo)
{
return E_NOTIMPL;
}
HRESULT _stdcall CJSCall::GetTypeInfo(
unsigned int iTInfo,
LCID lcid,
ITypeInfo FAR* FAR* ppTInfo)
{
return E_NOTIMPL;
}
HRESULT _stdcall CJSCall::GetIDsOfNames(
REFIID riid,
OLECHAR FAR* FAR* rgszNames,
unsigned int cNames,
LCID lcid,
DISPID FAR* rgDispId
)
{
if(lstrcmpW(rgszNames[0], NOTICEDATATOEXTERNAL)==0)
{
//網頁呼叫window.external.CppCall時,會呼叫這個方法獲取CppCall的ID
*rgDispId = FUNC_NOTICEDATATOEXTERNAL_ID;
}
return S_OK;
}
HRESULT _stdcall CJSCall::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pDispParams,
VARIANT* pVarResult,
EXCEPINFO* pExcepInfo,
unsigned int* puArgErr
)
{
if(dispIdMember == FUNC_NOTICEDATATOEXTERNAL_ID)
{
if(pDispParams->rgvarg->vt!=VT_BSTR)
return E_FAIL ;
char* lpszText2 = _com_util::ConvertBSTRToString(pDispParams->rgvarg->bstrVal);
OutLog("recv html Data %s",lpszText2);
g_pQtH5InterAct->FromH5Data(lpszText2);
delete[] lpszText2;
/*VARIANT varRet ;
VariantInit(pVarResult);
varRet.vt =VT_BSTR ;
varRet.bstrVal=SysAllocString(L"Gas");
*pVarResult = varRet;*/
}
return S_OK;
}