Пак за IWebBrowser2
4 отговора
138 прегледа
Пак за IWebBrowser2
Някой знае ли какви точно изисквания от към интерфейси и поддържани методи трябва да покрива един клас за да хоства тоз контрол? Най-ценни ще са, разбира се, примерчета с чист код (без MFC & ATL)
Si Vis Pacem, Para Bellum
Si Vis Pacem, Para Bellum
Re: Пак за IWebBrowser2
IOleClientSite и IOleInPlaceSite за задължителни.
освен тях може - IDocHostUIHandler, IDocHostShowUI, IOleInPlaceUIWindow.
(+IDispatch (за DWebEvents2))
изобщо гледай сорс кода на ATL-то. (ATLHOST.H)
ще пасте-на малко код от моя програмка която хоства IE-то.
на C++ е защото поне инициализацията на виртуалните таблици е автоматична, иначе от C++ друго не се ползва... даже по отношение C++ има малко неудобство, че когато ти правят QueryInterface - не знаеш през кой интерфейс ти го правят, понякога това много, ама наистина много ценно.
class HostWin : public IOleClientSite, public IOleInPlaceSite, public IDispatch, public IServiceProvider
/* IOleControlSite not needed :)
IDocHostUIHandler - good for IE. IDocHostShowUI
IOleInPlaceUIWindow } за UI-то.
*/
{
private:
STDMETHOD (QueryInterface)( REFIID riid, void **ppvObject )
{
if( NULL == ppvObject )
return E_POINTER;
if( riid == IID_IUnknown )
{
_D(("IUnknown\r\n" ));
*ppvObject = (IOleClientSite*)this;
refCount++;
return S_OK;
}
if( riid == IID_IOleClientSite )
{
_D(("IOleClientSite\r\n" ));
*ppvObject = (IOleClientSite*)this;
refCount++;
return S_OK;
}
if( riid == IID_IOleWindow )
{
_D(("IOleWindow\r\n" ));
*ppvObject = (IOleWindow*)this;
refCount++;
return S_OK;
}
if( riid == IID_IOleInPlaceSite )
{
_D(("IOleInPlaceSite\r\n" ));
*ppvObject = (IOleInPlaceSite*)this;
refCount++;
return S_OK;
}
if( riid == DIID_DWebBrowserEvents2 )
{
_D(("DWebBrowserEvents2\r\n" ));
*ppvObject = (IDispatch*)this;
refCount++;
return S_OK;
}
if( riid == IID_IDispatch )
{
_D(("IDispatch\r\n" ));
*ppvObject = (IDispatch*)this;
refCount++;
return S_OK;
}
if( riid == IID_IServiceProvider )
{
_D(("IServiceProvider\r\n" ));
*ppvObject = (IServiceProvider *)this;
refCount++;
return S_OK;
}
_D(("QI " ));
{
WCHAR buf[40];
StringFromGUID2( riid, buf, 40 );
OutputDebugStringW( buf );
OutputDebugString( "\r\n");
}
return E_NOINTERFACE;
}
STDMETHOD_ (ULONG, AddRef)(void)
{
refCount++;
return refCount;
}
STDMETHOD_ (ULONG, Release)(void)
{
refCount--;
return refCount;
}
// IOleClientSite Methods
private:
STDMETHOD(SaveObject)(void)
{
_D(("IOleClientSite::SaveObject\r\n"));
return E_NOTIMPL;
}
STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
{
_D(("IOleClientSite::GetMoniker\r\n"));
return E_NOTIMPL;
}
STDMETHOD(GetContainer)(IOleContainer **ppContainer)
{
_D(("IOleClientSite::GetContainer\r\n"));
return E_NOTIMPL;
}
STDMETHOD(ShowObject)(void)
{
_D(("IOleClientSite::ShowObject\r\n"));
return E_NOTIMPL;
}
STDMETHOD(OnShowWindow)(BOOL fShow)
{
_D(("IOleClientSite::OnShowWindow\r\n"));
return E_NOTIMPL;
}
STDMETHOD(RequestNewObjectLayout)(void)
{
_D(("IOleClientSite::RequestNewObjectLayout\r\n"));
return E_NOTIMPL;
}
// IOleWindow IOleInPlaceSite
private:
STDMETHOD(GetWindow)(HWND *phwnd)
{
_D(("IOleWindow::GetWindow\r\n"));
*phwnd = hWnd;
return S_OK;
}
STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode)
{
_D(("IOleWindow::CanInPlaceActivate"));
return E_NOTIMPL;
}
// IOleInPlaceSite
private:
STDMETHOD(CanInPlaceActivate)(void)
{
_D(("IOleInPlaceSite::CanInPlaceActivate\r\n"));
return S_OK;
}
STDMETHOD(OnInPlaceActivate)(void)
{
_D(("IOleInPlaceSite::OnInPlaceActivate\r\n"));
return S_OK;
}
STDMETHOD(OnUIActivate)(void)
{
_D(("IOleInPlaceSite::OnUIActivate\r\n"));
return E_NOTIMPL;
}
STDMETHOD(GetWindowContext)(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc,
LPRECT lprcPosRect, LPRECT lprcClipRect,
LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
_D(( "IOleInPlaceSite::GetWindowContext\r\n"));
GetClientRect(hWnd, lprcPosRect);
GetClientRect(hWnd, lprcClipRect);
return S_OK;
}
STDMETHOD(Scroll)(SIZE scrollExtant)
{
_D(("IOleInPlaceSite::Scroll\r\n"));
return E_NOTIMPL;
}
STDMETHOD(OnUIDeactivate)(BOOL fUndoable)
{
_D(("IOleInPlaceSite::OnUIDeactivate\r\n"));
return E_NOTIMPL;
}
STDMETHOD(OnInPlaceDeactivate)( void)
{
_D(("IOleInPlaceSite::OnInPlaceDeactivate\r\n"));
return S_OK;
}
STDMETHOD(DiscardUndoState)( void)
{
_D(("IOleInPlaceSite::DiscardUndoState\r\n"));
return E_NOTIMPL;
}
STDMETHOD(DeactivateAndUndo)( void)
{
_D(("IOleInPlaceSite::DeactivateAndUndo\r\n"));
return E_NOTIMPL;
}
STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect)
{
_D(("IOleInPlaceSite::OnPosRectChange\r\n"));
return E_NOTIMPL;
}
//IDispatch
STDMETHODIMP GetTypeInfoCount ( UINT __RPC_FAR *pctinfo)
{
_D(("GetTypeInfoCount\r\n"));
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
{
_D(("GetTypeInfo\r\n"));
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames ( REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId)
{
_D(("GetIDsOfNames\r\n"));
return E_NOTIMPL;
}
STDMETHODIMP Invoke (
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
/* [out] */ VARIANT __RPC_FAR *pVarResult,
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
/* [out] */ UINT __RPC_FAR *puArgErr)
{
if( dispIdMember == DISPID_BEFORENAVIGATE2 )
{
if (pDispParams->cArgs >= 5 && pDispParams->rgvarg[5].vt == (VT_BYREF|VT_VARIANT))
{
URL_COMPONENTS UrlComponents = {0};
CHAR url[1024];
_D(("BeforeNavigate2 "));
VARIANT URL = *pDispParams->rgvarg[5].pvarVal;
WideCharToMultiByte( CP_ACP, 0, URL.bstrVal, -1, url, 1024, NULL, NULL );
UrlComponents.dwStructSize = sizeof(UrlComponents);
InternetCrackUrl( url, 0, 0, &UrlComponents );
OutputDebugStringW( URL.bstrVal );
}
}
return S_OK;
};
//IServiceProvider
STDMETHOD (QueryService)(REFGUID guidService, REFIID riid, void **ppv )
{
HRESULT hr = SVC_E_UNKNOWNSERVICE; return hr;
};
}
hWnd е ясно какво е.
_D е макрос подобен на TRACE в MFC - прави OutputDebugString.
IDispatch не е необходим, освен ако не искаме да се закачаме за DWebBrowserEvents2 (в случая съм искал)
IServiceProvider - спокойно може без него.
това е.
освен тях може - IDocHostUIHandler, IDocHostShowUI, IOleInPlaceUIWindow.
(+IDispatch (за DWebEvents2))
изобщо гледай сорс кода на ATL-то. (ATLHOST.H)
ще пасте-на малко код от моя програмка която хоства IE-то.
на C++ е защото поне инициализацията на виртуалните таблици е автоматична, иначе от C++ друго не се ползва... даже по отношение C++ има малко неудобство, че когато ти правят QueryInterface - не знаеш през кой интерфейс ти го правят, понякога това много, ама наистина много ценно.
class HostWin : public IOleClientSite, public IOleInPlaceSite, public IDispatch, public IServiceProvider
/* IOleControlSite not needed :)
IDocHostUIHandler - good for IE. IDocHostShowUI
IOleInPlaceUIWindow } за UI-то.
*/
{
private:
STDMETHOD (QueryInterface)( REFIID riid, void **ppvObject )
{
if( NULL == ppvObject )
return E_POINTER;
if( riid == IID_IUnknown )
{
_D(("IUnknown\r\n" ));
*ppvObject = (IOleClientSite*)this;
refCount++;
return S_OK;
}
if( riid == IID_IOleClientSite )
{
_D(("IOleClientSite\r\n" ));
*ppvObject = (IOleClientSite*)this;
refCount++;
return S_OK;
}
if( riid == IID_IOleWindow )
{
_D(("IOleWindow\r\n" ));
*ppvObject = (IOleWindow*)this;
refCount++;
return S_OK;
}
if( riid == IID_IOleInPlaceSite )
{
_D(("IOleInPlaceSite\r\n" ));
*ppvObject = (IOleInPlaceSite*)this;
refCount++;
return S_OK;
}
if( riid == DIID_DWebBrowserEvents2 )
{
_D(("DWebBrowserEvents2\r\n" ));
*ppvObject = (IDispatch*)this;
refCount++;
return S_OK;
}
if( riid == IID_IDispatch )
{
_D(("IDispatch\r\n" ));
*ppvObject = (IDispatch*)this;
refCount++;
return S_OK;
}
if( riid == IID_IServiceProvider )
{
_D(("IServiceProvider\r\n" ));
*ppvObject = (IServiceProvider *)this;
refCount++;
return S_OK;
}
_D(("QI " ));
{
WCHAR buf[40];
StringFromGUID2( riid, buf, 40 );
OutputDebugStringW( buf );
OutputDebugString( "\r\n");
}
return E_NOINTERFACE;
}
STDMETHOD_ (ULONG, AddRef)(void)
{
refCount++;
return refCount;
}
STDMETHOD_ (ULONG, Release)(void)
{
refCount--;
return refCount;
}
// IOleClientSite Methods
private:
STDMETHOD(SaveObject)(void)
{
_D(("IOleClientSite::SaveObject\r\n"));
return E_NOTIMPL;
}
STDMETHOD(GetMoniker)(DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
{
_D(("IOleClientSite::GetMoniker\r\n"));
return E_NOTIMPL;
}
STDMETHOD(GetContainer)(IOleContainer **ppContainer)
{
_D(("IOleClientSite::GetContainer\r\n"));
return E_NOTIMPL;
}
STDMETHOD(ShowObject)(void)
{
_D(("IOleClientSite::ShowObject\r\n"));
return E_NOTIMPL;
}
STDMETHOD(OnShowWindow)(BOOL fShow)
{
_D(("IOleClientSite::OnShowWindow\r\n"));
return E_NOTIMPL;
}
STDMETHOD(RequestNewObjectLayout)(void)
{
_D(("IOleClientSite::RequestNewObjectLayout\r\n"));
return E_NOTIMPL;
}
// IOleWindow IOleInPlaceSite
private:
STDMETHOD(GetWindow)(HWND *phwnd)
{
_D(("IOleWindow::GetWindow\r\n"));
*phwnd = hWnd;
return S_OK;
}
STDMETHOD(ContextSensitiveHelp)(BOOL fEnterMode)
{
_D(("IOleWindow::CanInPlaceActivate"));
return E_NOTIMPL;
}
// IOleInPlaceSite
private:
STDMETHOD(CanInPlaceActivate)(void)
{
_D(("IOleInPlaceSite::CanInPlaceActivate\r\n"));
return S_OK;
}
STDMETHOD(OnInPlaceActivate)(void)
{
_D(("IOleInPlaceSite::OnInPlaceActivate\r\n"));
return S_OK;
}
STDMETHOD(OnUIActivate)(void)
{
_D(("IOleInPlaceSite::OnUIActivate\r\n"));
return E_NOTIMPL;
}
STDMETHOD(GetWindowContext)(IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc,
LPRECT lprcPosRect, LPRECT lprcClipRect,
LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
_D(( "IOleInPlaceSite::GetWindowContext\r\n"));
GetClientRect(hWnd, lprcPosRect);
GetClientRect(hWnd, lprcClipRect);
return S_OK;
}
STDMETHOD(Scroll)(SIZE scrollExtant)
{
_D(("IOleInPlaceSite::Scroll\r\n"));
return E_NOTIMPL;
}
STDMETHOD(OnUIDeactivate)(BOOL fUndoable)
{
_D(("IOleInPlaceSite::OnUIDeactivate\r\n"));
return E_NOTIMPL;
}
STDMETHOD(OnInPlaceDeactivate)( void)
{
_D(("IOleInPlaceSite::OnInPlaceDeactivate\r\n"));
return S_OK;
}
STDMETHOD(DiscardUndoState)( void)
{
_D(("IOleInPlaceSite::DiscardUndoState\r\n"));
return E_NOTIMPL;
}
STDMETHOD(DeactivateAndUndo)( void)
{
_D(("IOleInPlaceSite::DeactivateAndUndo\r\n"));
return E_NOTIMPL;
}
STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect)
{
_D(("IOleInPlaceSite::OnPosRectChange\r\n"));
return E_NOTIMPL;
}
//IDispatch
STDMETHODIMP GetTypeInfoCount ( UINT __RPC_FAR *pctinfo)
{
_D(("GetTypeInfoCount\r\n"));
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo( UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
{
_D(("GetTypeInfo\r\n"));
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames ( REFIID riid, LPOLESTR __RPC_FAR *rgszNames, UINT cNames, LCID lcid, DISPID __RPC_FAR *rgDispId)
{
_D(("GetIDsOfNames\r\n"));
return E_NOTIMPL;
}
STDMETHODIMP Invoke (
/* [in] */ DISPID dispIdMember,
/* [in] */ REFIID riid,
/* [in] */ LCID lcid,
/* [in] */ WORD wFlags,
/* [out][in] */ DISPPARAMS __RPC_FAR *pDispParams,
/* [out] */ VARIANT __RPC_FAR *pVarResult,
/* [out] */ EXCEPINFO __RPC_FAR *pExcepInfo,
/* [out] */ UINT __RPC_FAR *puArgErr)
{
if( dispIdMember == DISPID_BEFORENAVIGATE2 )
{
if (pDispParams->cArgs >= 5 && pDispParams->rgvarg[5].vt == (VT_BYREF|VT_VARIANT))
{
URL_COMPONENTS UrlComponents = {0};
CHAR url[1024];
_D(("BeforeNavigate2 "));
VARIANT URL = *pDispParams->rgvarg[5].pvarVal;
WideCharToMultiByte( CP_ACP, 0, URL.bstrVal, -1, url, 1024, NULL, NULL );
UrlComponents.dwStructSize = sizeof(UrlComponents);
InternetCrackUrl( url, 0, 0, &UrlComponents );
OutputDebugStringW( URL.bstrVal );
}
}
return S_OK;
};
//IServiceProvider
STDMETHOD (QueryService)(REFGUID guidService, REFIID riid, void **ppv )
{
HRESULT hr = SVC_E_UNKNOWNSERVICE; return hr;
};
}
hWnd е ясно какво е.
_D е макрос подобен на TRACE в MFC - прави OutputDebugString.
IDispatch не е необходим, освен ако не искаме да се закачаме за DWebBrowserEvents2 (в случая съм искал)
IServiceProvider - спокойно може без него.
това е.
Re: Пак за IWebBrowser2
Мамка му, нещо ми се губи...
Виж това:
IOleObject *pOleObj;
CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC, IID_IOleObject, (void**)&pOleObj);
pOleObj->SetClientSite(this);
pOleObj->DoVerb(OLEIVERB_INPLACEACTIVATE, &msg, this, 0, m_hWnd, &rcClient);
Значи SetClientSite си минава, но проблемът е в DoVerb
Ако класа не поддържа IDispatch, то DoVerb директно гърми. Ако пък поддържа, то DoVerb извиква GetIDsOfNames, очевидно без много да му трябва. Това ме навежда на мисълта, че изпускам някой метод, който е нужен, но не се сещам кой е...
Si Vis Pacem, Para Bellum
Виж това:
IOleObject *pOleObj;
CoCreateInstance(CLSID_WebBrowser, NULL, CLSCTX_INPROC, IID_IOleObject, (void**)&pOleObj);
pOleObj->SetClientSite(this);
pOleObj->DoVerb(OLEIVERB_INPLACEACTIVATE, &msg, this, 0, m_hWnd, &rcClient);
Значи SetClientSite си минава, но проблемът е в DoVerb
Ако класа не поддържа IDispatch, то DoVerb директно гърми. Ако пък поддържа, то DoVerb извиква GetIDsOfNames, очевидно без много да му трябва. Това ме навежда на мисълта, че изпускам някой метод, който е нужен, но не се сещам кой е...
Si Vis Pacem, Para Bellum
Re: Пак за IWebBrowser2
хм...
каква грешка ти дава DoVerb?
какво има в msg структурата - аз там си предавам NULL и всичко си ми работи...
каква грешка ти дава DoVerb?
какво има в msg структурата - аз там си предавам NULL и всичко си ми работи...
Re: Пак за IWebBrowser2
Ох, усетих си бозата
Грешката си е в моя телевизор, извинявай, че те накарах да мислиш :)
Дай icq за по-директна връзка
Si Vis Pacem, Para Bellum
Грешката си е в моя телевизор, извинявай, че те накарах да мислиш :)
Дай icq за по-директна връзка
Si Vis Pacem, Para Bellum