On Fri, Sep 12, 2014 at 05:32:19PM +0800, Jactry Zeng wrote:
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]
Passing IRichEditOle is nicer than passing IRichEditOleImpl so that's a good improvement.
However, you really do want to do the allocation in this function (you then don't need the ITextRangeImpl param at all). This function should return E_OUTOFMEMORY on allocation failure. If GetDuplicate really needs to return E_FAIL, it can check for this function failing and return E_FAIL.
Huw.