From: Jactry Zeng Subject: [PATCH 2/3] riched20: Add COM aggregation support for IRichEditOle. (try 4) Message-Id: <544F87B9.4030101@codeweavers.com> Date: Tue, 28 Oct 2014 20:10:33 +0800 Superseded patch 106775. ChangeLog: try 4: - Fix wrong pointer assignment in CreateIRichEditOle(). try 3: - Init ppvObj to NULL in IRichEditOle_inner_QueryInterface. try 2: - Rename inner unknown methods. --- dlls/riched20/editor.c | 4 +-- dlls/riched20/editor.h | 2 +- dlls/riched20/richole.c | 72 +++++++++++++++++++++++++++++++++++++------------ 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index a277510..375b1629 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -1194,7 +1194,7 @@ static BOOL ME_RTFInsertOleObject(RTF_Info *info, HENHMETAFILE hemf, HBITMAP hbm if (!info->lpRichEditOle) { - CreateIRichEditOle(info->editor, (VOID**)&info->lpRichEditOle); + CreateIRichEditOle(NULL, info->editor, (VOID**)&info->lpRichEditOle); } if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK && @@ -4474,7 +4474,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case EM_GETOLEINTERFACE: { if (!editor->reOle) - if (!CreateIRichEditOle(editor, (LPVOID *)&editor->reOle)) + if (!CreateIRichEditOle(NULL, editor, (LPVOID *)&editor->reOle)) return 0; *(LPVOID *)lParam = editor->reOle; IRichEditOle_AddRef(editor->reOle); diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h index 3987907..255945e 100644 --- a/dlls/riched20/editor.h +++ b/dlls/riched20/editor.h @@ -240,7 +240,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor) DECLSPEC_HIDDEN; int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN; /* richole.c */ -LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *) DECLSPEC_HIDDEN; +LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) DECLSPEC_HIDDEN; void ME_DrawOLE(ME_Context *c, int x, int y, ME_Run* run, ME_Paragraph *para, BOOL selected) DECLSPEC_HIDDEN; void ME_GetOLEObjectSize(const ME_Context *c, ME_Run *run, SIZE *pSize) DECLSPEC_HIDDEN; void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src) DECLSPEC_HIDDEN; diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 9e7c123..07ba279 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -52,8 +52,10 @@ typedef struct IOleClientSiteImpl IOleClientSiteImpl; typedef struct ITextRangeImpl ITextRangeImpl; typedef struct IRichEditOleImpl { + IUnknown IUnknown_inner; IRichEditOle IRichEditOle_iface; ITextDocument ITextDocument_iface; + IUnknown *outer_unk; LONG ref; ME_TextEditor *editor; @@ -95,44 +97,47 @@ static inline IRichEditOleImpl *impl_from_ITextDocument(ITextDocument *iface) return CONTAINING_RECORD(iface, IRichEditOleImpl, ITextDocument_iface); } -static HRESULT WINAPI -IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj) +static inline IRichEditOleImpl *impl_from_IUnknown(IUnknown *iface) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); + return CONTAINING_RECORD(iface, IRichEditOleImpl, IUnknown_inner); +} - TRACE("%p %s\n", This, debugstr_guid(riid) ); +static HRESULT WINAPI IRichEditOleImpl_inner_fnQueryInterface(IUnknown *iface, REFIID riid, LPVOID *ppvObj) +{ + IRichEditOleImpl *This = impl_from_IUnknown(iface); + + TRACE("%p %s\n", This, debugstr_guid(riid)); *ppvObj = NULL; - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IRichEditOle)) + if (IsEqualGUID(riid, &IID_IUnknown)) + *ppvObj = &This->IUnknown_inner; + else if (IsEqualGUID(riid, &IID_IRichEditOle)) *ppvObj = &This->IRichEditOle_iface; else if (IsEqualGUID(riid, &IID_ITextDocument)) *ppvObj = &This->ITextDocument_iface; if (*ppvObj) { - IRichEditOle_AddRef(me); + IUnknown_AddRef((IUnknown *)*ppvObj); return S_OK; } - FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid) ); + FIXME("%p: unhandled interface %s\n", This, debugstr_guid(riid)); return E_NOINTERFACE; } -static ULONG WINAPI -IRichEditOle_fnAddRef(IRichEditOle *me) +static ULONG WINAPI IRichEditOleImpl_inner_fnAddRef(IUnknown *iface) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); - ULONG ref = InterlockedIncrement( &This->ref ); + IRichEditOleImpl *This = impl_from_IUnknown(iface); + ULONG ref = InterlockedIncrement(&This->ref); TRACE("%p ref = %u\n", This, ref); return ref; } -static ULONG WINAPI -IRichEditOle_fnRelease(IRichEditOle *me) +static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface) { - IRichEditOleImpl *This = impl_from_IRichEditOle(me); + IRichEditOleImpl *This = impl_from_IUnknown(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE ("%p ref=%u\n", This, ref); @@ -152,6 +157,34 @@ IRichEditOle_fnRelease(IRichEditOle *me) return ref; } +static const IUnknownVtbl reo_unk_vtbl = +{ + IRichEditOleImpl_inner_fnQueryInterface, + IRichEditOleImpl_inner_fnAddRef, + IRichEditOleImpl_inner_fnRelease +}; + +static HRESULT WINAPI +IRichEditOle_fnQueryInterface(IRichEditOle *me, REFIID riid, LPVOID *ppvObj) +{ + IRichEditOleImpl *This = impl_from_IRichEditOle(me); + return IUnknown_QueryInterface(This->outer_unk, riid, ppvObj); +} + +static ULONG WINAPI +IRichEditOle_fnAddRef(IRichEditOle *me) +{ + IRichEditOleImpl *This = impl_from_IRichEditOle(me); + return IUnknown_AddRef(This->outer_unk); +} + +static ULONG WINAPI +IRichEditOle_fnRelease(IRichEditOle *me) +{ + IRichEditOleImpl *This = impl_from_IRichEditOle(me); + return IUnknown_Release(This->outer_unk); +} + static HRESULT WINAPI IRichEditOle_fnActivateAs(IRichEditOle *me, REFCLSID rclsid, REFCLSID rclsidAs) { @@ -2305,7 +2338,7 @@ CreateTextSelection(IRichEditOleImpl *reOle) return txtSel; } -LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj) +LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) { IRichEditOleImpl *reo; @@ -2313,6 +2346,7 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj) if (!reo) return 0; + reo->IUnknown_inner.lpVtbl = &reo_unk_vtbl; reo->IRichEditOle_iface.lpVtbl = &revt; reo->ITextDocument_iface.lpVtbl = &tdvt; reo->ref = 1; @@ -2331,8 +2365,12 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj) return 0; } TRACE("Created %p\n",reo); - *ppObj = reo; list_init(&reo->rangelist); + if (outer_unk) + reo->outer_unk = outer_unk; + else + reo->outer_unk = &reo->IUnknown_inner; + *ppvObj = &reo->IRichEditOle_iface; return 1; }