Jactry Zeng : riched20: Add COM aggregation support for IRichEditOle.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Oct 30 09:23:14 CDT 2014


Module: wine
Branch: master
Commit: 234310e752620dbcc55b6ecd76b860bd8c97218f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=234310e752620dbcc55b6ecd76b860bd8c97218f

Author: Jactry Zeng <jzeng at codeweavers.com>
Date:   Tue Oct 28 20:10:33 2014 +0800

riched20: Add COM aggregation support for IRichEditOle.

---

 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..375b162 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;
 }




More information about the wine-cvs mailing list