Nikolay Sivov : riched20: Properly implement GetClientSite().
Alexandre Julliard
julliard at wine.codeweavers.com
Mon Jun 1 07:36:59 CDT 2015
Module: wine
Branch: master
Commit: 41687841bc3ef7a4140a5ad50a31b9c2949ca5e8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=41687841bc3ef7a4140a5ad50a31b9c2949ca5e8
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sun May 31 19:54:40 2015 +0300
riched20: Properly implement GetClientSite().
---
dlls/riched20/richole.c | 80 +++++++++++++++++++++++++------------------
dlls/riched20/tests/richole.c | 4 ---
2 files changed, 47 insertions(+), 37 deletions(-)
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index d637292..7c50304 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -214,8 +214,9 @@ typedef struct IRichEditOleImpl {
ME_TextEditor *editor;
ITextSelectionImpl *txtSel;
- IOleClientSiteImpl *clientSite;
+
struct list rangelist;
+ struct list clientsites;
} IRichEditOleImpl;
struct reole_child {
@@ -255,12 +256,11 @@ typedef struct ITextParaImpl {
} ITextParaImpl;
struct IOleClientSiteImpl {
+ struct reole_child child;
IOleClientSite IOleClientSite_iface;
IOleWindow IOleWindow_iface;
IOleInPlaceSite IOleInPlaceSite_iface;
LONG ref;
-
- IRichEditOleImpl *reOle;
};
static inline IRichEditOleImpl *impl_from_IRichEditOle(IRichEditOle *iface)
@@ -940,15 +940,20 @@ static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
if (!ref)
{
+ IOleClientSiteImpl *clientsite;
ITextRangeImpl *txtRge;
TRACE("Destroying %p\n", This);
This->txtSel->reOle = NULL;
This->editor->reOle = NULL;
ITextSelection_Release(&This->txtSel->ITextSelection_iface);
- IOleClientSite_Release(&This->clientSite->IOleClientSite_iface);
+
LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, child.entry)
txtRge->child.reole = NULL;
+
+ LIST_FOR_EACH_ENTRY(clientsite, &This->clientsites, IOleClientSiteImpl, child.entry)
+ clientsite->child.reole = NULL;
+
heap_free(This);
}
return ref;
@@ -1039,34 +1044,43 @@ IOleClientSite_fnQueryInterface(IOleClientSite *me, REFIID riid, LPVOID *ppvObj)
static ULONG WINAPI IOleClientSite_fnAddRef(IOleClientSite *iface)
{
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
- return InterlockedIncrement(&This->ref);
+ ULONG ref = InterlockedIncrement(&This->ref);
+ TRACE("(%p)->(%u)\n", This, ref);
+ return ref;
}
static ULONG WINAPI IOleClientSite_fnRelease(IOleClientSite *iface)
{
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
ULONG ref = InterlockedDecrement(&This->ref);
- if (ref == 0)
+
+ TRACE("(%p)->(%u)\n", This, ref);
+
+ if (ref == 0) {
+ if (This->child.reole) {
+ list_remove(&This->child.entry);
+ This->child.reole = NULL;
+ }
heap_free(This);
+ }
return ref;
}
static HRESULT WINAPI IOleClientSite_fnSaveObject(IOleClientSite *iface)
{
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
- if (!This->reOle)
+ if (!This->child.reole)
return CO_E_RELEASED;
FIXME("stub %p\n", iface);
return E_NOTIMPL;
}
-
static HRESULT WINAPI IOleClientSite_fnGetMoniker(IOleClientSite *iface, DWORD dwAssign,
DWORD dwWhichMoniker, IMoniker **ppmk)
{
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
- if (!This->reOle)
+ if (!This->child.reole)
return CO_E_RELEASED;
FIXME("stub %p\n", iface);
@@ -1077,7 +1091,7 @@ static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
IOleContainer **ppContainer)
{
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
- if (!This->reOle)
+ if (!This->child.reole)
return CO_E_RELEASED;
FIXME("stub %p\n", iface);
@@ -1087,7 +1101,7 @@ static HRESULT WINAPI IOleClientSite_fnGetContainer(IOleClientSite *iface,
static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
{
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
- if (!This->reOle)
+ if (!This->child.reole)
return CO_E_RELEASED;
FIXME("stub %p\n", iface);
@@ -1097,7 +1111,7 @@ static HRESULT WINAPI IOleClientSite_fnShowObject(IOleClientSite *iface)
static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL fShow)
{
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
- if (!This->reOle)
+ if (!This->child.reole)
return CO_E_RELEASED;
FIXME("stub %p\n", iface);
@@ -1107,7 +1121,7 @@ static HRESULT WINAPI IOleClientSite_fnOnShowWindow(IOleClientSite *iface, BOOL
static HRESULT WINAPI IOleClientSite_fnRequestNewObjectLayout(IOleClientSite *iface)
{
IOleClientSiteImpl *This = impl_from_IOleClientSite(iface);
- if (!This->reOle)
+ if (!This->child.reole)
return CO_E_RELEASED;
FIXME("stub %p\n", iface);
@@ -1155,12 +1169,16 @@ static HRESULT WINAPI IOleWindow_fnContextSensitiveHelp(IOleWindow *iface, BOOL
static HRESULT WINAPI IOleWindow_fnGetWindow(IOleWindow *iface, HWND *phwnd)
{
IOleClientSiteImpl *This = impl_from_IOleWindow(iface);
+
TRACE("(%p)->(%p)\n", This, phwnd);
+ if (!This->child.reole)
+ return CO_E_RELEASED;
+
if (!phwnd)
return E_INVALIDARG;
- *phwnd = This->reOle->editor->hWnd;
+ *phwnd = This->child.reole->editor->hWnd;
return S_OK;
}
@@ -1294,34 +1312,35 @@ static const IOleInPlaceSiteVtbl olestvt =
IOleInPlaceSite_fnOnPosRectChange
};
-static IOleClientSiteImpl *
-CreateOleClientSite(IRichEditOleImpl *reOle)
+static HRESULT CreateOleClientSite(IRichEditOleImpl *reOle, IOleClientSite **ret)
{
IOleClientSiteImpl *clientSite = heap_alloc(sizeof *clientSite);
+
if (!clientSite)
- return NULL;
+ return E_OUTOFMEMORY;
clientSite->IOleClientSite_iface.lpVtbl = &ocst;
clientSite->IOleWindow_iface.lpVtbl = &olewinvt;
clientSite->IOleInPlaceSite_iface.lpVtbl = &olestvt;
clientSite->ref = 1;
- clientSite->reOle = reOle;
- return clientSite;
+ clientSite->child.reole = reOle;
+ list_add_head(&reOle->clientsites, &clientSite->child.entry);
+
+ *ret = &clientSite->IOleClientSite_iface;
+ return S_OK;
}
static HRESULT WINAPI
-IRichEditOle_fnGetClientSite(IRichEditOle *me,
- LPOLECLIENTSITE *lplpolesite)
+IRichEditOle_fnGetClientSite(IRichEditOle *me, IOleClientSite **clientsite)
{
IRichEditOleImpl *This = impl_from_IRichEditOle(me);
- TRACE("%p,%p\n",This, lplpolesite);
+ TRACE("(%p)->(%p)\n", This, clientsite);
- if(!lplpolesite)
+ if (!clientsite)
return E_INVALIDARG;
- *lplpolesite = &This->clientSite->IOleClientSite_iface;
- IOleClientSite_AddRef(*lplpolesite);
- return S_OK;
+
+ return CreateOleClientSite(This, clientsite);
}
static HRESULT WINAPI
@@ -4964,15 +4983,10 @@ LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *p
heap_free(reo);
return 0;
}
- reo->clientSite = CreateOleClientSite(reo);
- if (!reo->clientSite)
- {
- ITextSelection_Release(&reo->txtSel->ITextSelection_iface);
- heap_free(reo);
- return 0;
- }
+
TRACE("Created %p\n",reo);
list_init(&reo->rangelist);
+ list_init(&reo->clientsites);
if (outer_unk)
reo->outer_unk = outer_unk;
else
diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c
index 0fc4169..318b386 100644
--- a/dlls/riched20/tests/richole.c
+++ b/dlls/riched20/tests/richole.c
@@ -1487,8 +1487,6 @@ static void test_GetClientSite(void)
create_interfaces(&w, &reOle, &txtDoc, NULL);
hres = IRichEditOle_GetClientSite(reOle, &clientSite);
ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
-
-todo_wine
EXPECT_REF(clientSite, 1);
hres = IOleClientSite_QueryInterface(clientSite, &IID_IRichEditOle, (void **)&reOle1);
@@ -1496,14 +1494,12 @@ todo_wine
hres = IRichEditOle_GetClientSite(reOle, &clientSite1);
ok(hres == S_OK, "got 0x%08x\n", hres);
-todo_wine
ok(clientSite != clientSite1, "got %p, %p\n", clientSite, clientSite1);
IOleClientSite_Release(clientSite1);
hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleClientSite, (void **)&clientSite1);
ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres);
ok(clientSite == clientSite1, "Should not return a new pointer.\n");
-todo_wine
EXPECT_REF(clientSite, 2);
/* IOleWindow interface */
More information about the wine-cvs
mailing list