Hi Huw, This is a newer version: static HRESULT CreateITextRange(IRichEditOle *reOle, LONG start, LONG end, ITextRangeImpl *txtRge, ITextRange** ppRange) { IRichEditOleImpl *reOleImpl = impl_from_IRichEditOle(reOle); txtRge->ITextRange_iface.lpVtbl = &trvt; txtRge->ref = 1; IRichEditOle_AddRef(reOle); txtRge->reOle = reOleImpl; txtRge->start = start; txtRge->end = end; list_add_head(&reOleImpl->rangelist, &txtRge->entry); *ppRange = &txtRge->ITextRange_iface; return S_OK; } I will prefer passing ITextRangeImpl into CreateITextRange instead of ITextRange interface. So we don't need to impl_from_ITextRange again. Is it also ok? btw, I didn't alloc txtRge (txtRge = heap_alloc(sizeof(ITextRangeImpl));) in CreateITextRange(), because CreateITextRange() was just created for sharing code with ITextRange::GetDuplicate and GetDuplicate will return E_FAIL for all any other error[0] when ITextDocument::Range returning E_OUTOFMEMORY.[1] Thanks. [0] http://msdn.microsoft.com/en-us/library/windows/desktop/bb787840(v=vs.85).as... [1] http://msdn.microsoft.com/en-us/library/windows/desktop/bb774097(v=vs.85).as... 2014-09-12 15:53 GMT+08:00 Huw Davies <huw(a)codeweavers.com>:
On Fri, Sep 12, 2014 at 10:47:44AM +0800, Jactry Zeng wrote:
2014-09-12 4:43 GMT+08:00 Sebastian Lackner <sebastian(a)fds-team.de>:
Are you sure? Doesn't this test below show exactly the opposite? It
seems to
be safe
to release the ITextDocument, and afterwards call an ITextRange function - it will just return CO_E_RELEASED since the parent object was already released. Or am I misunderstanding this code?
So sorry, I made a mistake yesterday here. I added more a ITextRange::Release before the ITextRange calling in my new tests code yesterday. Functions of ITextRange will return CO_E_RELEASED after reOle/txtDoc were released and will crash after the ITextRange was released.
In that case let's go with your proposed implementation.
Huw.
-- Regards, Jactry Zeng