Thread View: borland.public.cppbuilder.internet.web
3 messages
3 total messages
Started by SD
Tue, 29 Mar 2005 16:34
IOleClientSite implementation (subclass)
Author: SD
Date: Tue, 29 Mar 2005 16:34
Date: Tue, 29 Mar 2005 16:34
275 lines
7186 bytes
7186 bytes
Hi to all,
I isn't able to understand if the following is the right way to implement
the
IDocHostUIHander with the IOleClientSite. I've tried to paste code found on
internet and create the bottom class. The code don't work very fine,
I've alvays got Access Error when program exit...
Usage:
<snip from Form1.h>
__published:
TCppWebBrowser *Browser;
private...
QCppWebBrowserWrapper *FCppWebBrowserWrapper;
<snip from Form1.cpp>
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
// sets default members data values
FCppWebBrowserWrapper = new QCppWebBrowserWrapper;
FCppWebBrowserWrapper->Initialize(Browser);
}
__fastcall TForm1::~TForm1()
{
// frees objects
delete FCppWebBrowserWrapper;
}
class QCppWebBrowserWrapper : public IOleClientSite, IDocHostUIHandler
{
long FRefCount;
TCppWebBrowser *FWebBrowser;
IOleClientSite *FIOleClientSite;
public:
QCppWebBrowserWrapper()
{
FRefCount = 1;
FWebBrowser = NULL;
FIOleClientSite = NULL;
}
~QCppWebBrowserWrapper()
{
IOleObject* OleObject = NULL;
((IDispatch *) FWebBrowser->OleObject)->QueryInterface(IID_IOleObject,
(void **) &OleObject);
OleObject->SetClientSite(FIOleClientSite);
}
virtual void STDMETHODCALLTYPE Initialize(TCppWebBrowser *WebBrowser)
{
FWebBrowser = WebBrowser;
IOleObject* OleObject = NULL;
((IDispatch *) FWebBrowser->OleObject)->QueryInterface(IID_IOleObject,
(void **) &OleObject);
OleObject->GetClientSite(&FIOleClientSite);
OleObject->SetClientSite((IOleClientSite *) this);
}
// ======================= //
// IUnknown implementation //
// ======================= //
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID classid, void**
intf)
{
// return FIOleClientSite->QueryInterface(classid, intf);
if (classid == IID_IDocHostUIHandler)
{
*intf = (IDocHostUIHandler *) this;
return S_OK;
}
else
return FIOleClientSite->QueryInterface(classid, intf);
}
virtual ULONG STDMETHODCALLTYPE AddRef()
{
// return FIOleClientSite->AddRef();
// InterlockedIncrement(&FRefCount);
return FRefCount;
}
virtual ULONG STDMETHODCALLTYPE Release()
{
// return FIOleClientSite->Release();
// InterlockedDecrement(&FRefCount);
if (FRefCount == 0)
delete this;
return FRefCount;
}
// ============================= //
// IOleClientSite implementation //
// ============================= //
virtual HRESULT STDMETHODCALLTYPE SaveObject(void)
{
return FIOleClientSite->SaveObject();
}
virtual HRESULT STDMETHODCALLTYPE GetMoniker
(
/* [in] */ DWORD dwAssign,
/* [in] */ DWORD dwWhichMoniker,
/* [out] */ IMoniker __RPC_FAR *__RPC_FAR *ppmk
)
{
return FIOleClientSite->GetMoniker(dwAssign, dwWhichMoniker, ppmk);
}
virtual HRESULT STDMETHODCALLTYPE GetContainer
(
/* [out] */ IOleContainer __RPC_FAR *__RPC_FAR *ppContainer
)
{
return FIOleClientSite->GetContainer(ppContainer);
}
virtual HRESULT STDMETHODCALLTYPE ShowObject(void)
{
return FIOleClientSite->ShowObject();
}
virtual HRESULT STDMETHODCALLTYPE OnShowWindow
(
/* [in] */ BOOL fShow
)
{
return FIOleClientSite->OnShowWindow(fShow);
}
virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(void)
{
return FIOleClientSite->RequestNewObjectLayout();
}
// =================================//
// IDocHostUIHandler implementation //
// ================================ //
virtual HRESULT STDMETHODCALLTYPE ShowContextMenu
(
/* [in] */ DWORD dwID,
/* [in] */ POINT __RPC_FAR *ppt,
/* [in] */ IUnknown __RPC_FAR *pcmdtReserved,
/* [in] */ IDispatch __RPC_FAR *pdispReserved
)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetHostInfo
(
/* [out][in] */ DOCHOSTUIINFO __RPC_FAR *pInfo
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ShowUI
(
/* [in] */ DWORD dwID,
/* [in] */ IOleInPlaceActiveObject __RPC_FAR *pActiveObject,
/* [in] */ IOleCommandTarget __RPC_FAR *pCommandTarget,
/* [in] */ IOleInPlaceFrame __RPC_FAR *pFrame,
/* [in] */ IOleInPlaceUIWindow __RPC_FAR *pDoc
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE HideUI(void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE UpdateUI(void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE EnableModeless
(
/* [in] */ BOOL fEnable
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate
(
/* [in] */ BOOL fActivate
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate
(
/* [in] */ BOOL fActivate
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ResizeBorder
(
/* [in] */ LPCRECT prcBorder,
/* [in] */ IOleInPlaceUIWindow __RPC_FAR *pUIWindow,
/* [in] */ BOOL fRameWindow
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator
(
/* [in] */ LPMSG lpMsg,
/* [in] */ const GUID __RPC_FAR *pguidCmdGroup,
/* [in] */ DWORD nCmdID
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath
(
/* [out] */ LPOLESTR __RPC_FAR *pchKey,
/* [in] */ DWORD dw
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetDropTarget
(
/* [in] */ IDropTarget __RPC_FAR *pDropTarget,
/* [out] */ IDropTarget __RPC_FAR *__RPC_FAR *ppDropTarget
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetExternal
(
/* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppDispatch
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE TranslateUrl
(
/* [in] */ DWORD dwTranslate,
/* [in] */ OLECHAR __RPC_FAR *pchURLIn,
/* [out] */ OLECHAR __RPC_FAR *__RPC_FAR *ppchURLOut
)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE FilterDataObject
(
/* [in] */ IDataObject __RPC_FAR *pDO,
/* [out] */ IDataObject __RPC_FAR *__RPC_FAR *ppDORet
)
{
return E_NOTIMPL;
}
};
Re: IOleClientSite implementation (subclass)
Author: Remy Lebeau (TeamB)
Date: Tue, 29 Mar 2005 20:20
Date: Tue, 29 Mar 2005 20:20
283 lines
8642 bytes
8642 bytes
"SD" <nospawm@please.it> wrote in message
news:424983a3@newsgroups.borland.com...
> __fastcall TForm1::~TForm1()
> {
> // frees objects
> delete FCppWebBrowserWrapper;
> }
Don't use delete here. Interfaces are reference counted. The browser is
probably still holding on to the interface, so call the object's Release()
method instead. When the browser is done with the interface, it will call
Release() as well. When the reference count falls to 0, the interface
should delete itself only at that time.
> IOleClientSite *FIOleClientSite;
<snip>
> ~QCppWebBrowserWrapper()
> {
> IOleObject* OleObject = NULL;
> ((IDispatch *) FWebBrowser->OleObject)->QueryInterface(IID_IOleObject,
> (void **) &OleObject);
> OleObject->SetClientSite(FIOleClientSite);
> }
You don't need to do any of that. You are solely responsible for providing
the IOleClientSite to the browser, so you will only have 1 IOleClientSite
available. There is nothing to give back to the browser when your
IOleClientSite is being destroyed.
> virtual void STDMETHODCALLTYPE Initialize(TCppWebBrowser *WebBrowser)
> {
> FWebBrowser = WebBrowser;
> IOleObject* OleObject = NULL;
> ((IDispatch *) FWebBrowser->OleObject)->QueryInterface(IID_IOleObject,
> (void **) &OleObject);
> OleObject->GetClientSite(&FIOleClientSite);
> OleObject->SetClientSite((IOleClientSite *) this);
> }
You are not calling Release() on the OleObject. You are also not validating
that the OleObject is even a valid object before accessing it. You should
be querying the IOleObject from the browser's ControlInterface anyway, not
its OleObject property.
> virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID classid, void**
> intf)
> {
> // return FIOleClientSite->QueryInterface(classid, intf);
> if (classid == IID_IDocHostUIHandler)
> {
> *intf = (IDocHostUIHandler *) this;
> return S_OK;
> }
> else
> return FIOleClientSite->QueryInterface(classid, intf);
> }
Since you should not be holding on to the browser's IOleClientSite to begin
with, that implementation is completely wrong.
> virtual ULONG STDMETHODCALLTYPE AddRef()
> {
> // return FIOleClientSite->AddRef();
> // InterlockedIncrement(&FRefCount);
> return FRefCount;
> }
You are never incrementing the reference count at all.
> virtual ULONG STDMETHODCALLTYPE Release()
> {
> // return FIOleClientSite->Release();
> // InterlockedDecrement(&FRefCount);
> if (FRefCount == 0)
> delete this;
> return FRefCount;
> }
You are never decrementing the reference count at all. Not only that, but
if the reference count ever did get decremented to 0, your code would crash
because you would be returning to return FRefCount via an invalid 'this'
pointer.
With all of that said, try this code:
class QCppWebBrowserWrapper :
public IOleClientSite,
public IDocHostUIHandler
{
private:
ULONG FRefCount;
TCppWebBrowser *FWebBrowser;
public:
QCppWebBrowserWrapper(TCppWebBrowser *WebBrowser)
: FRefCount(1), FWebBrowser(WebBrowser)
{
if( (FWebBrowser) && (FWebBrowser->ControlInterface) )
{
IOleObject *pObj = NULL;
if(
SUCCEEDED(FWebBrowser->ControlInterface->QueryInterface(IID_IOleObject,
(void **) &pObj)) )
{
pObj->SetClientSite(this);
pObj->Release();
}
}
}
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void**
intf)
{
if( intf == NULL )
return E_POINTER;
*intf = NULL;
if( riid == IID_IUnknown )
// workaround for a compiler error
*intf = (IUnknown*) ((IDocHostUIHandler*) this);
else if( riid == IID_IOleClientSite )
*intf = (IOleClientSite*) this;
else if( riid == IID_IDocHostUIHandler )
*intf = (IDocHostUIHandler*) this;
if( *intf == NULL )
return E_NOINTERFACE;
AddRef();
return S_OK;
}
virtual ULONG STDMETHODCALLTYPE AddRef()
{
return ++FRefCount;
}
virtual ULONG STDMETHODCALLTYPE Release()
{
if( --FRefCount == 0 )
{
delete this;
return 0;
}
return FRefCount;
}
virtual HRESULT STDMETHODCALLTYPE SaveObject(void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetMoniker(DWORD, DWORD,
IMoniker**)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetContainer(IOleContainer **)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ShowObject(void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnShowWindow(BOOL)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE RequestNewObjectLayout(void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ShowContextMenu(DWORD, POINT*,
IUnknown*, IDispatch*)
{
return S_OK;
}
virtual HRESULT STDMETHODCALLTYPE GetHostInfo(DOCHOSTUIINFO*)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ShowUI(DWORD,
IOleInPlaceActiveObject*, IOleCommandTarget*, IOleInPlaceFrame*,
IOleInPlaceUIWindow*)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE HideUI(void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE UpdateUI(void)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE EnableModeless(BOOL)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate(BOOL)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(BOOL)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE ResizeBorder(LPCRECT,
IOleInPlaceUIWindow*, BOOL)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(LPMSG, const
GUID*, DWORD)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath(LPOLESTR*, DWORD)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetDropTarget(IDropTarget*,
IDropTarget**)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE GetExternal(IDispatch**)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE TranslateUrl(DWORD, OLECHAR*,
OLECHAR**)
{
return E_NOTIMPL;
}
virtual HRESULT STDMETHODCALLTYPE FilterDataObject(IDataObject*,
IDataObject**)
{
return E_NOTIMPL;
}
};
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
FWrapper = new QCppWebBrowserWrapper(CppWebBrowser1);
}
__fastcall TForm1::~TForm1()
{
if( FWrapper )
FWrapper->Release();
}
Gambit
Re: IOleClientSite implementation (subclass)
Author: SD
Date: Wed, 30 Mar 2005 07:56
Date: Wed, 30 Mar 2005 07:56
14 lines
1335 bytes
1335 bytes
Dear Mr.Remy Lebeau with this I would to thank you very much for your suggestions and code, now all work very fine :) I work around this problem for more than a week without obtain same results, unfortunately I can tell me about a good C++ programmer but I don't know and using MS COM matter so your help is been very precious. Thanks again... and sorry for my bad English Silverio Diquigiovanni
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads