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