[prev in list] [next in list] [prev in thread] [next in thread]
List: wine-devel
Subject: Patches for adding IRichEditOle/ITextDocument support for ITextServices::QueryInterface ask for revi
From: Jactry Zeng <jactry92 () gmail ! com>
Date: 2014-09-24 7:44:43
Message-ID: CAManwExWvMuuObGGfeXgk8oadfb5DS7Bp5K-==+7XeJyBTXjdA () mail ! gmail ! com
[Download RAW message or body]
[Attachment #2 (multipart/alternative)]
Hi folks,
I wrote two patches for adding IRichEditOle/ITextDocument support for
ITextServices::QueryInterface(for bug 17042[1]), but I'm
no sure is it the correct way. I need your review and comment! I will
really appreciate it!
There are some tests for ITextServices::QueryInterface in
dlls/riched20/txtsrv.c: test_QueryInterfaces():
1.
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\n");
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 2, "got wrong ref count: %d\n", refcount);
From this case we know ref count of ITextServices will increase after get a
IRichEditOle interface from
ITextServices::QueryInterface.
ITextServices::QueryInterface(&IID_ITextDocument) is also similar.
2.
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 2, "got wrong ref count: %d\n", refcount);
if (SUCCEEDED(hres)) {
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);
From this case we know when a IRichEditOle was got by
ITextServices::QueryInterface(&IID_IRichEditOle) then
we used IRichEditOle::QueryInterface to get another interface, the ref
count of ITextServices will increase too.
For implementing this feature I added IUnknown *parent in IRichEditOleImpl
and passed ITextServices interface into
CreateIRichEditOle when we call it in ITextServices::QueryInterface:
dlls/riched20/richole.c
---snip---
typedef struct IRichEditOleImpl {
IRichEditOle IRichEditOle_iface;
ITextDocument ITextDocument_iface;
LONG ref;
ME_TextEditor *editor;
ITextSelectionImpl *txtSel;
IOleClientSiteImpl *clientSite;
struct list rangelist;
IUnknown *parent;
} IRichEditOleImpl;
---snip---
dlls/riched20/txtsrv.c
---snip---
else if (IsEqualIID(riid, &IID_IRichEditOle) || IsEqualIID(riid,
&IID_ITextDocument)) {
if (!This->editor->reOle)
CreateIRichEditOle(This->editor, (LPVOID
*)&(This->editor->reOle), iface);
IRichEditOle_QueryInterface(This->editor->reOle, riid, (void **)ppv);
return S_OK;
} else {
---snip---
3. By some other tests, I found when a ITextServices was got by
IRichEditOle::QueryInterface, then
we use ITextServices::QueryInterface to got another interface, the ref
count of IRichEditOle will increase
too.
Thanks!
[1] https://bugs.winehq.org/show_bug.cgi?id=17042
--
Regards,
Jactry Zeng
[Attachment #5 (text/html)]
<div dir="ltr">Hi folks,<div><br></div><div>I wrote two patches for adding \
IRichEditOle/ITextDocument support for ITextServices::QueryInterface(for bug \
17042[1]), but I'm</div><div>no sure is it the correct way. I need your review \
and comment! I will really appreciate it!</div><div><br></div><div>There are some \
tests for ITextServices::QueryInterface in dlls/riched20/txtsrv.c: \
test_QueryInterfaces():</div><div>1. </div><div><div> refcount = \
get_refcount((IUnknown *)txtserv);</div><div> ok(refcount == 1, "got wrong \
ref count: %d\n", refcount);</div><div><br></div><div> /* IID_IRichEditOle \
*/</div><div> hres = ITextServices_QueryInterface(txtserv, \
&IID_IRichEditOle, (void **)&txtsrv_reOle);</div><div> ok(hres == S_OK, \
"ITextServices_QueryInterface\n");</div><div><br></div><div> refcount \
= get_refcount((IUnknown *)txtserv);</div><div> ok(refcount == 2, "got \
wrong ref count: %d\n", refcount);</div></div><div><br></div><div>From this case \
we know ref count of ITextServices will increase after get a IRichEditOle interface \
from</div><div>ITextServices::QueryInterface. \
ITextServices::QueryInterface(&IID_ITextDocument) is also \
similar.</div><div><br></div><div>2. </div><div> refcount = \
get_refcount((IUnknown *)txtserv);</div><div> ok(refcount == 2, "got wrong \
ref count: %d\n", refcount);</div><div><br></div><div> if (SUCCEEDED(hres)) \
{</div><div> refcount = get_refcount((IUnknown *)txtsrv_reOle);</div><div> \
ok(refcount == 2, "got wrong ref count: %d\n", \
refcount);</div><div><br></div><div> hres = \
IRichEditOle_QueryInterface(txtsrv_reOle, &IID_ITextDocument, (void \
**)&txtDoc);</div><div> ok(hres == S_OK, \
"IRichEditOle_QueryInterface: 0x%08x\n", hres);</div><div> \
refcount = get_refcount((IUnknown *)txtserv);</div><div> ok(refcount == 3, \
"got wrong ref count: %d\n", refcount);</div><div> refcount = \
get_refcount((IUnknown *)txtsrv_reOle);</div><div> ok(refcount == 3, \
"got wrong ref count: %d\n", refcount);</div><div><br></div><div><div>From \
this case we know when a IRichEditOle was got by \
ITextServices::QueryInterface(&IID_IRichEditOle) then</div><div>we used \
IRichEditOle::QueryInterface to get another interface, the ref count of ITextServices \
will increase too.</div><div>For implementing this feature I added IUnknown *parent \
in IRichEditOleImpl and passed ITextServices interface into \
</div><div>CreateIRichEditOle when we call it in \
ITextServices::QueryInterface:</div><div>dlls/riched20/richole.c</div><div>---snip---</div><div><div>typedef \
struct IRichEditOleImpl {</div><div> IRichEditOle IRichEditOle_iface;</div><div> \
ITextDocument ITextDocument_iface;</div><div> LONG \
ref;</div><div><br></div><div> ME_TextEditor *editor;</div><div> \
ITextSelectionImpl *txtSel;</div><div> IOleClientSiteImpl \
*clientSite;</div><div> struct list rangelist;</div><div> IUnknown \
*parent;</div><div>} \
IRichEditOleImpl;</div></div><div>---snip---</div><div>dlls/riched20/txtsrv.c</div><div>---snip---</div><div><div> \
else if (IsEqualIID(riid, &IID_IRichEditOle) || IsEqualIID(riid, \
&IID_ITextDocument)) {</div><div> if \
(!This->editor->reOle)</div><div> \
CreateIRichEditOle(This->editor, (LPVOID *)&(This->editor->reOle), \
iface);</div><div> IRichEditOle_QueryInterface(This->editor->reOle, \
riid, (void **)ppv);</div><div> return S_OK;</div><div> } else \
{</div></div><div>---snip---</div><div><br></div><div>3. By some other tests, I found \
when a ITextServices was got by IRichEditOle::QueryInterface, then</div><div>we use \
ITextServices::QueryInterface to got another interface, the ref count of IRichEditOle \
will increase</div><div>too.</div><div><br></div><div>Thanks!</div><div><br></div><div>[1] \
<a href="https://bugs.winehq.org/show_bug.cgi?id=17042" \
target="_blank">https://bugs.winehq.org/show_bug.cgi?id=17042</a></div><div><br></div>-- \
<br><div dir="ltr"><div>Regards,<br></div><div>Jactry Zeng</div><div><br></div></div> \
</div></div>
--047d7bdc0c6ce29a070503caddd6--
["0001-riched20-Add-IID_IRichEditOle-support-for-ITextService.txt" (text/plain)]
From 5e3b4d8dda41a79679a3f76afe242eefc4a17d23 Mon Sep 17 00:00:00 2001
From: Jactry Zeng <jzeng@codeweavers.com>
Date: Wed, 24 Sep 2014 10:01:54 +0800
Subject: [PATCH 1/2] riched20: Add IID_IRichEditOle support for
ITextServices::QueryInterface.
To: wine-patches <wine-patches@winehq.org>
Reply-To: wine-devel <wine-devel@winehq.org>
---
dlls/riched20/editor.c | 4 ++--
dlls/riched20/editor.h | 2 +-
dlls/riched20/richole.c | 11 ++++++++-
dlls/riched20/tests/txtsrv.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
dlls/riched20/txtsrv.c | 7 +++++-
5 files changed, 72 insertions(+), 5 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 3c0d970..d19fb05 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(info->editor, (VOID**)&info->lpRichEditOle, NULL);
}
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(editor, (LPVOID *)&editor->reOle, NULL))
return 0;
*(LPVOID *)lParam = editor->reOle;
IRichEditOle_AddRef(editor->reOle);
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index edbac8e..111d318 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(ME_TextEditor *editor, LPVOID *ppObj, IUnknown *parent) \
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 f7e7870..26142fb 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -60,6 +60,7 @@ typedef struct IRichEditOleImpl {
ITextSelectionImpl *txtSel;
IOleClientSiteImpl *clientSite;
struct list rangelist;
+ IUnknown *parent;
} IRichEditOleImpl;
struct ITextRangeImpl {
@@ -126,6 +127,9 @@ IRichEditOle_fnAddRef(IRichEditOle *me)
TRACE("%p ref = %u\n", This, ref);
+ if (This->parent)
+ IUnknown_AddRef(This->parent);
+
return ref;
}
@@ -137,6 +141,8 @@ IRichEditOle_fnRelease(IRichEditOle *me)
TRACE ("%p ref=%u\n", This, ref);
+ if (This->parent)
+ IUnknown_Release(This->parent);
if (!ref)
{
ITextRangeImpl *txtRge;
@@ -146,6 +152,8 @@ IRichEditOle_fnRelease(IRichEditOle *me)
IOleClientSite_Release(&This->clientSite->IOleClientSite_iface);
LIST_FOR_EACH_ENTRY(txtRge, &This->rangelist, ITextRangeImpl, entry)
txtRge->reOle = NULL;
+ This->editor->reOle = NULL;
+ This->parent = NULL;
heap_free(This);
}
return ref;
@@ -2304,7 +2312,7 @@ CreateTextSelection(IRichEditOleImpl *reOle)
return txtSel;
}
-LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj)
+LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj, IUnknown *parent)
{
IRichEditOleImpl *reo;
@@ -2316,6 +2324,7 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID \
*ppObj) reo->ITextDocument_iface.lpVtbl = &tdvt;
reo->ref = 1;
reo->editor = editor;
+ reo->parent = parent;
reo->txtSel = CreateTextSelection(reo);
if (!reo->txtSel)
{
diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c
index 3401f8b..003a274 100644
--- a/dlls/riched20/tests/txtsrv.c
+++ b/dlls/riched20/tests/txtsrv.c
@@ -28,6 +28,8 @@
#include <windef.h>
#include <winbase.h>
#include <objbase.h>
+#include <tom.h>
+#include <richole.h>
#include <richedit.h>
#include <initguid.h>
#include <imm.h>
@@ -862,6 +864,56 @@ 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 *txtsrv_reOle;
+ ITextDocument *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\n");
+
+ refcount = get_refcount((IUnknown *)txtserv);
+ ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+
+ if (SUCCEEDED(hres)) {
+ 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);
+ } else {
+ win_skip("IRichEditOle not available\n");
+ }
+
+ free_texthost();
+}
+
START_TEST( txtsrv )
{
setup_thiscall_wrappers();
@@ -887,6 +939,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 636efff..15fcdd8 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -79,7 +79,12 @@ 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)) {
+ if (!This->editor->reOle)
+ CreateIRichEditOle(This->editor, (LPVOID *)&(This->editor->reOle), \
iface); + IRichEditOle_QueryInterface(This->editor->reOle, &IID_IRichEditOle, \
(void **)ppv); + return S_OK;
+ } else {
*ppv = NULL;
FIXME("Unknown interface: %s\n", debugstr_guid(riid));
return E_NOINTERFACE;
--
2.0.2
["0002-riched20-Add-IID_ITextDocument-support-for-ITextServic.txt" (text/plain)]
From 73e01cce0760454777401a9dd5c9a1f4f3dee14c Mon Sep 17 00:00:00 2001
From: Jactry Zeng <jzeng@codeweavers.com>
Date: Tue, 23 Sep 2014 15:36:31 +0800
Subject: [PATCH 2/2] riched20: Add IID_ITextDocument support for
ITextServices::QueryInterface.
To: wine-patches <wine-patches@winehq.org>
Reply-To: wine-devel <wine-devel@winehq.org>
---
dlls/riched20/tests/txtsrv.c | 30 ++++++++++++++++++++++++++++--
dlls/riched20/txtsrv.c | 5 +++--
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c
index 003a274..7b7db20 100644
--- a/dlls/riched20/tests/txtsrv.c
+++ b/dlls/riched20/tests/txtsrv.c
@@ -873,8 +873,8 @@ static ULONG get_refcount(IUnknown *iface)
static void test_QueryInterface(void)
{
HRESULT hres;
- IRichEditOle *txtsrv_reOle;
- ITextDocument *txtDoc;
+ IRichEditOle *txtsrv_reOle, *reOle;
+ ITextDocument *txtsrv_txtDoc, *txtDoc;
ULONG refcount;
if(!init_texthost())
@@ -911,6 +911,32 @@ static void test_QueryInterface(void)
win_skip("IRichEditOle not available\n");
}
+ /* 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);
+
+ if (SUCCEEDED(hres)) {
+ 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();
}
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index 15fcdd8..ae38640 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -33,6 +33,7 @@
#include "textserv.h"
#include "wine/debug.h"
#include "editstr.h"
+#include "tom.h"
#ifdef __i386__ /* thiscall functions are i386-specific */
@@ -79,10 +80,10 @@ static HRESULT WINAPI ITextServicesImpl_QueryInterface(IUnknown *iface, REFIID r
*ppv = &This->IUnknown_inner;
else if (IsEqualIID(riid, &IID_ITextServices))
*ppv = &This->ITextServices_iface;
- else if (IsEqualIID(riid, &IID_IRichEditOle)) {
+ else if (IsEqualIID(riid, &IID_IRichEditOle) || IsEqualIID(riid, &IID_ITextDocument)) {
if (!This->editor->reOle)
CreateIRichEditOle(This->editor, (LPVOID *)&(This->editor->reOle), iface);
- IRichEditOle_QueryInterface(This->editor->reOle, &IID_IRichEditOle, (void **)ppv);
+ IRichEditOle_QueryInterface(This->editor->reOle, riid, (void **)ppv);
return S_OK;
} else {
*ppv = NULL;
--
2.0.2
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic