Jactry Zeng : riched20: Add IID_IRichEditOle and IID_ITextDocument support for ITextServices:: QueryInterface.

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


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

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

riched20: Add IID_IRichEditOle and IID_ITextDocument support for ITextServices::QueryInterface.

---

 dlls/riched20/editor.c       |  2 +-
 dlls/riched20/editor.h       |  2 ++
 dlls/riched20/richole.c      | 33 ++++++++++++++-------
 dlls/riched20/tests/txtsrv.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/riched20/txtsrv.c       | 11 ++++++-
 5 files changed, 104 insertions(+), 13 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 375b162..1e62fc1 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -2889,7 +2889,7 @@ void ME_DestroyEditor(ME_TextEditor *editor)
   ITextHost_Release(editor->texthost);
   if (editor->reOle)
   {
-    IRichEditOle_Release(editor->reOle);
+    DestroyIRichEditOle(editor->reOle);
     editor->reOle = NULL;
   }
   OleUninitialize();
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 255945e..d8abe4e 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -241,10 +241,12 @@ int ME_GetParaBorderWidth(const ME_Context *c, int flags) DECLSPEC_HIDDEN;
 
 /* richole.c */
 LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *ppvObj) DECLSPEC_HIDDEN;
+void DestroyIRichEditOle(IRichEditOle *iface) 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;
 void ME_DeleteReObject(REOBJECT* reo) DECLSPEC_HIDDEN;
+void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj) DECLSPEC_HIDDEN;
 
 /* editor.c */
 ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) DECLSPEC_HIDDEN;
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index 07ba279..0788125 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -143,17 +143,7 @@ static ULONG WINAPI IRichEditOleImpl_inner_fnRelease(IUnknown *iface)
     TRACE ("%p ref=%u\n", This, ref);
 
     if (!ref)
-    {
-        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, entry)
-            txtRge->reOle = NULL;
-        heap_free(This);
-    }
+        DestroyIRichEditOle(&This->IRichEditOle_iface);
     return ref;
 }
 
@@ -2375,6 +2365,21 @@ LRESULT CreateIRichEditOle(IUnknown *outer_unk, ME_TextEditor *editor, LPVOID *p
     return 1;
 }
 
+void DestroyIRichEditOle(IRichEditOle *iface)
+{
+    IRichEditOleImpl *This = impl_from_IRichEditOle(iface);
+    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, entry)
+        txtRge->reOle = NULL;
+    heap_free(This);
+}
+
 static void convert_sizel(const ME_Context *c, const SIZEL* szl, SIZE* sz)
 {
   /* sizel is in .01 millimeters, sz in pixels */
@@ -2578,3 +2583,9 @@ void ME_CopyReObject(REOBJECT* dst, const REOBJECT* src)
     if (dst->pstg)      IStorage_AddRef(dst->pstg);
     if (dst->polesite)  IOleClientSite_AddRef(dst->polesite);
 }
+
+void ME_GetITextDocumentInterface(IRichEditOle *iface, LPVOID *ppvObj)
+{
+    IRichEditOleImpl *This = impl_from_IRichEditOle(iface);
+    *ppvObj = &This->ITextDocument_iface;
+}
diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c
index 3401f8b..c154e2d 100644
--- a/dlls/riched20/tests/txtsrv.c
+++ b/dlls/riched20/tests/txtsrv.c
@@ -29,6 +29,8 @@
 #include <winbase.h>
 #include <objbase.h>
 #include <richedit.h>
+#include <tom.h>
+#include <richole.h>
 #include <initguid.h>
 #include <imm.h>
 #include <textserv.h>
@@ -862,6 +864,72 @@ static void test_COM(void)
     IUnknown_Release(unk_obj.inner_unk);
 }
 
+static ULONG get_refcount(IUnknown *iface)
+{
+    IUnknown_AddRef(iface);
+    return IUnknown_Release(iface);
+}
+
+static void test_QueryInterface(void)
+{
+    HRESULT hres;
+    IRichEditOle *reole, *txtsrv_reole;
+    ITextDocument *txtdoc, *txtsrv_txtdoc;
+    ULONG refcount;
+
+    if(!init_texthost())
+        return;
+
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 1, "got wrong ref count: %d\n", refcount);
+
+    /* IID_IRichEditOle */
+    hres = ITextServices_QueryInterface(txtserv, &IID_IRichEditOle, (void **)&txtsrv_reole);
+    ok(hres == S_OK, "ITextServices_QueryInterface: 0x%08x\n", hres);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+    refcount = get_refcount((IUnknown *)txtsrv_reole);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+
+    hres = IRichEditOle_QueryInterface(txtsrv_reole, &IID_ITextDocument, (void **)&txtdoc);
+    ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+    refcount = get_refcount((IUnknown *)txtsrv_reole);
+    ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+
+    ITextDocument_Release(txtdoc);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+    IRichEditOle_Release(txtsrv_reole);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 1, "got wrong ref count: %d\n", refcount);
+
+    /* IID_ITextDocument */
+    hres = ITextServices_QueryInterface(txtserv, &IID_ITextDocument, (void **)&txtsrv_txtdoc);
+    ok(hres == S_OK, "ITextServices_QueryInterface: 0x%08x\n", hres);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+    refcount = get_refcount((IUnknown *)txtsrv_txtdoc);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+
+    hres = ITextDocument_QueryInterface(txtsrv_txtdoc, &IID_IRichEditOle, (void **)&reole);
+    ok(hres == S_OK, "ITextDocument_QueryInterface: 0x%08x\n", hres);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+    refcount = get_refcount((IUnknown *)txtsrv_txtdoc);
+    ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+
+    IRichEditOle_Release(reole);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+    ITextDocument_Release(txtsrv_txtdoc);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 1, "got wrong ref count: %d\n", refcount);
+
+    free_texthost();
+}
+
 START_TEST( txtsrv )
 {
     setup_thiscall_wrappers();
@@ -887,6 +955,7 @@ START_TEST( txtsrv )
         test_TxSetText();
         test_TxGetNaturalSize();
         test_TxDraw();
+        test_QueryInterface();
     }
     if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE);
 }
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index 0ca1e1b..75bee6d 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -29,6 +29,7 @@
 #include "ole2.h"
 #include "oleauto.h"
 #include "richole.h"
+#include "tom.h"
 #include "imm.h"
 #include "textserv.h"
 #include "wine/debug.h"
@@ -79,7 +80,15 @@ static HRESULT WINAPI ITextServicesImpl_QueryInterface(IUnknown *iface, REFIID r
       *ppv = &This->IUnknown_inner;
    else if (IsEqualIID(riid, &IID_ITextServices))
       *ppv = &This->ITextServices_iface;
-   else {
+   else if (IsEqualIID(riid, &IID_IRichEditOle) || IsEqualIID(riid, &IID_ITextDocument)) {
+      if (!This->editor->reOle)
+         if (!CreateIRichEditOle(This->outer_unk, This->editor, (void **)(&This->editor->reOle)))
+            return E_OUTOFMEMORY;
+      if (IsEqualIID(riid, &IID_ITextDocument))
+         ME_GetITextDocumentInterface(This->editor->reOle, ppv);
+      else
+         *ppv = This->editor->reOle;
+   } else {
       *ppv = NULL;
       FIXME("Unknown interface: %s\n", debugstr_guid(riid));
       return E_NOINTERFACE;




More information about the wine-cvs mailing list