1. 程式人生 > >QAxWidget 呼叫ocx控制元件之 js雙向通訊

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;
}