#include "StdAfx.h" #include "SDocHostUIHandler.h" #include #include namespace SOUI { SDocHostUIHandler::SDocHostUIHandler(IScriptCaller *sc) : m_disContextMenu(FALSE) , m_disF5(FALSE) , m_bDisableScrollBar(FALSE) , m_bDisable3DBorder(FALSE) , m_bDisableTextSelect(FALSE) { m_disp = new SJsCallCppIDispatch(sc); } SDocHostUIHandler::~SDocHostUIHandler(void) { } ////////////////////////////////////////////////////////////////////////// // IDocHostUIHandler HRESULT STDMETHODCALLTYPE SDocHostUIHandler::ShowContextMenu(DWORD dwID, POINT *ppt, IUnknown *pcmdtReserved, IDispatch *pdispReserved) { if (m_disContextMenu) { return S_OK; } return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::GetHostInfo(DOCHOSTUIINFO *pInfo) { if(!pInfo) return E_INVALIDARG; pInfo->cbSize = sizeof(DOCHOSTUIINFO); pInfo->dwFlags = DOCHOSTUIFLAG_DISABLE_HELP_MENU; if(m_bDisableTextSelect) pInfo->dwFlags |= DOCHOSTUIFLAG_DIALOG; if(m_bDisable3DBorder) pInfo->dwFlags |= DOCHOSTUIFLAG_NO3DBORDER; if(m_bDisableScrollBar) pInfo->dwFlags |= DOCHOSTUIFLAG_SCROLL_NO; pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT; return S_OK; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::ShowUI(DWORD dwID, IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget, IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::HideUI(void) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::UpdateUI(void) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::EnableModeless(BOOL fEnable) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::OnDocWindowActivate(BOOL fActivate) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::OnFrameWindowActivate(BOOL fActivate) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::ResizeBorder(LPCRECT prcBorder, IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::TranslateAccelerator(LPMSG lpMsg, const GUID *pguidCmdGroup, DWORD nCmdID) { if (lpMsg->message == WM_KEYDOWN || lpMsg->message == WM_KEYUP) { if (lpMsg->wParam == VK_F5 && m_disF5) { return S_OK; } else { return S_FALSE; } } return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::GetOptionKeyPath(__out LPOLESTR *pchKey, DWORD dw) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::GetDropTarget(IDropTarget *pDropTarget, IDropTarget **ppDropTarget) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::GetExternal(IDispatch **ppDispatch) { *ppDispatch = m_disp; (*ppDispatch)->AddRef(); return S_OK; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::TranslateUrl(DWORD dwTranslate, __in __nullterminated OLECHAR *pchURLIn, __out OLECHAR **ppchURLOut) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE SDocHostUIHandler::FilterDataObject(IDataObject *pDO, IDataObject **ppDORet) { return E_NOTIMPL; } ////////////////////////////////////////////////////////////////////////// // CImpIDispatch bool CallCpp(LPCWSTR pszParam) { return MessageBoxW(GetActiveWindow(),pszParam,L"jscall",MB_OKCANCEL)==IDOK?true:false; } STDMETHODIMP SJsCallCppIDispatch::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 ((wFlags & DISPATCH_PROPERTYGET) && pVarResult) { VariantInit(pVarResult); V_VT(pVarResult) = VT_BOOL; V_BOOL(pVarResult) = TRUE; } if ((wFlags & DISPATCH_METHOD) && m_sc) { std::vector args; if (pDispParams && (pDispParams->cArgs > 0)) { for (int i = pDispParams->cArgs - 1; i >= 0; --i) { VARIANTARG &rgvarg = pDispParams->rgvarg[i]; if (rgvarg.vt == VT_BSTR) { SStringW arg(rgvarg.bstrVal); arg.Trim(); args.push_back(std::wstring(arg)); } else { args.push_back(std::wstring(L"")); } } } m_sc->CallCPlusPlus(dispIdMember, args, pVarResult); } return S_OK; } STDMETHODIMP SJsCallCppIDispatch::GetIDsOfNames(/* [in] */ REFIID riid, /* [size_is][in] */ OLECHAR** rgszNames, /* [in] */ UINT cNames, /* [in] */ LCID lcid, /* [size_is][out] */ DISPID* rgDispId) { HRESULT hr = S_OK; // Assume some degree of success for (UINT i = 0; i < cNames; i++) { if (!m_sc || !m_sc->FunctionNameToDispatchId(rgszNames[i], rgDispId + i)) { // One or more are unknown so set the return code accordingly hr = ResultFromScode(DISP_E_UNKNOWNNAME); rgDispId[i] = DISPID_UNKNOWN; } } return hr; } STDMETHODIMP SJsCallCppIDispatch::GetTypeInfo(/* [in] */ UINT /*iTInfo*/, /* [in] */ LCID /*lcid*/, /* [out] */ ITypeInfo** /*ppTInfo*/) { return E_NOTIMPL; } STDMETHODIMP SJsCallCppIDispatch::GetTypeInfoCount(UINT* /*pctinfo*/) { return E_NOTIMPL; } VARIANT ExecuteScript(IWebBrowser2 *pWebBrowser, const SStringW & fun,SArray & params) { VARIANT varErr; VariantInit( &varErr ); //get document dispatch interface IDispatch* pDisp = NULL; HRESULT hr = pWebBrowser->get_Document( &pDisp ); if ( FAILED( hr ) || pDisp == NULL ) { return varErr; } IHTMLDocument2* pDoc = NULL; pDisp->QueryInterface( IID_IHTMLDocument2,(void**)&pDoc ); pDisp->Release(); IDispatch* pScript = NULL; hr = pDoc->get_Script( &pScript ); pDoc->Release(); if ( FAILED( hr ) || pScript == NULL ) { return varErr; } sbstr bstrMember((int)fun.GetLength(),fun ); DISPID dispid = 0; BSTR bstr = (BSTR)bstrMember; hr = pScript->GetIDsOfNames( IID_NULL,&(bstr),1,LOCALE_SYSTEM_DEFAULT,&dispid ); if ( FAILED( hr ) ) { return varErr; } DISPPARAMS dispparams; ::ZeroMemory( &dispparams,sizeof( DISPPARAMS ) ); dispparams.cArgs = (UINT)params.GetCount(); dispparams.rgvarg = new VARIANT[dispparams.cArgs]; dispparams.cNamedArgs = 0; for ( size_t i = 0;i < params.GetCount();i++ ) { size_t indx = params.GetCount() - i - 1; sbstr bstrParam((int)params[indx].GetLength(),params[indx]); dispparams.rgvarg[i].bstrVal = bstrParam.Release(); dispparams.rgvarg[i].vt = VT_BSTR; } EXCEPINFO excepinfo; ::ZeroMemory( &excepinfo,sizeof( EXCEPINFO ) ); VARIANT varRet; UINT nArgErr = (UINT)-1; //initialize to invalid arg hr = pScript->Invoke( dispid,IID_NULL,0,DISPATCH_METHOD,&dispparams,&varRet,&excepinfo,&nArgErr ); delete []dispparams.rgvarg; pScript->Release(); if ( FAILED( hr ) ) { return varErr; } return varRet; } }