From: Jactry Zeng Subject: [PATCH] riched20: Don't create too many IRichEditOle interface for a RichEdit. (try 4) Message-Id: <53B18B7C.8010506@jactry.com> Date: Tue, 01 Jul 2014 00:08:28 +0800 --- dlls/riched20/editor.c | 13 +++++++++++-- dlls/riched20/editstr.h | 1 + dlls/riched20/tests/richole.c | 19 ++++++++++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 2af2582..06d8690 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -2886,6 +2886,11 @@ static void ME_DestroyEditor(ME_TextEditor *editor) if(editor->lpOleCallback) IRichEditOleCallback_Release(editor->lpOleCallback); ITextHost_Release(editor->texthost); + if (editor->reOle) + { + IRichEditOle_Release(editor->reOle); + editor->reOle = NULL; + } OleUninitialize(); FREE_OBJ(editor->pBuffer); @@ -4467,8 +4472,12 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_GETOLEINTERFACE: { - LPVOID *ppvObj = (LPVOID*) lParam; - return CreateIRichEditOle(editor, ppvObj); + if (!editor->reOle) + if (!CreateIRichEditOle(editor, (LPVOID *)&editor->reOle)) + return 0; + *(LPVOID *)lParam = editor->reOle; + IRichEditOle_AddRef(editor->reOle); + return 1; } case EM_GETPASSWORDCHAR: { diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h index f139c29..4fd965c 100644 --- a/dlls/riched20/editstr.h +++ b/dlls/riched20/editstr.h @@ -388,6 +388,7 @@ typedef struct tagME_TextEditor { HWND hWnd, hwndParent; ITextHost *texthost; + IRichEditOle *reOle; BOOL bEmulateVersion10; ME_TextBuffer *pBuffer; ME_Cursor *pCursors; diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c index 5a3ffbe..d10c063 100644 --- a/dlls/riched20/tests/richole.c +++ b/dlls/riched20/tests/richole.c @@ -92,15 +92,22 @@ static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **tx ITextSelection_Release(*txtSel); } +static ULONG get_refcount(IUnknown *iface) +{ + IUnknown_AddRef(iface); + return IUnknown_Release(iface); +} + static void test_Interfaces(void) { - IRichEditOle *reOle = NULL; + IRichEditOle *reOle = NULL, *reOle1 = NULL; ITextDocument *txtDoc = NULL; ITextSelection *txtSel = NULL; IUnknown *punk; HRESULT hres; LRESULT res; HWND w; + ULONG refcount; w = new_richedit(NULL); if (!w) { @@ -111,6 +118,14 @@ static void test_Interfaces(void) res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle); ok(res, "SendMessage\n"); ok(reOle != NULL, "EM_GETOLEINTERFACE\n"); + refcount = get_refcount((IUnknown *)reOle); + ok(refcount == 2, "got wrong ref count: %d\n", refcount); + + res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle1); + ok(res == 1, "SendMessage\n"); + ok(reOle1 == reOle, "Should not return a new IRichEditOle interface\n"); + refcount = get_refcount((IUnknown *)reOle); + ok(refcount == 3, "got wrong ref count: %d\n", refcount); hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument, (void **) &txtDoc); @@ -142,6 +157,8 @@ static void test_Interfaces(void) ITextDocument_Release(txtDoc); IRichEditOle_Release(reOle); + refcount = IRichEditOle_Release(reOle); + ok(refcount == 1, "got wrong ref count: %d\n", refcount); DestroyWindow(w); /* Methods should return CO_E_RELEASED if the backing document has