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

oldstable
Jactry Zeng 2014-10-28 20:10:46 +08:00 committed by Alexandre Julliard
parent 234310e752
commit a9491ec5d9
5 changed files with 104 additions and 13 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;