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