From: Jactry Zeng Subject: [PATCH] riched20: Stub for ITextRange interface and implement ITextDocument::Range. Message-Id: <53D90E94.1050006@jactry.com> Date: Wed, 30 Jul 2014 23:26:12 +0800 --- dlls/riched20/richole.c | 767 +++++++++++++++++++++++++++++++++++++++++- dlls/riched20/tests/richole.c | 34 +- 2 files changed, 798 insertions(+), 3 deletions(-) diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c index 487fcda..fdd8cb5 100644 --- a/dlls/riched20/richole.c +++ b/dlls/riched20/richole.c @@ -49,6 +49,7 @@ DEFINE_GUID(IID_ITextSelection, 0x8cc497c1, 0xa1df, 0x11ce, 0x80, 0x98, 0x00, 0x typedef struct ITextSelectionImpl ITextSelectionImpl; typedef struct IOleClientSiteImpl IOleClientSiteImpl; +typedef struct ITextRangeImpl ITextRangeImpl; typedef struct IRichEditOleImpl { IRichEditOle IRichEditOle_iface; @@ -58,8 +59,18 @@ typedef struct IRichEditOleImpl { ME_TextEditor *editor; ITextSelectionImpl *txtSel; IOleClientSiteImpl *clientSite; + ITextRangeImpl *txtRgehead, *txtRgetail; } IRichEditOleImpl; +struct ITextRangeImpl { + ITextRange ITextRange_iface; + LONG ref; + int start, end; + ITextRangeImpl *prev, *next; + + IRichEditOleImpl *reOle; +}; + struct ITextSelectionImpl { ITextSelection ITextSelection_iface; LONG ref; @@ -132,6 +143,8 @@ IRichEditOle_fnRelease(IRichEditOle *me) This->txtSel->reOle = NULL; ITextSelection_Release(&This->txtSel->ITextSelection_iface); IOleClientSite_Release(&This->clientSite->IOleClientSite_iface); + heap_free(This->txtRgehead); + heap_free(This->txtRgetail); heap_free(This); } return ref; @@ -443,6 +456,681 @@ static const IRichEditOleVtbl revt = { IRichEditOle_fnImportDataObject }; +/* ITextRange interface */ +static inline ITextRangeImpl *impl_from_ITextRange(ITextRange *iface) +{ + return CONTAINING_RECORD(iface, ITextRangeImpl, ITextRange_iface); +} + +static HRESULT WINAPI ITextRange_fnQueryInterface(ITextRange *me, REFIID riid, void **ppvObj) +{ + *ppvObj = NULL; + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IDispatch) + || IsEqualGUID(riid, &IID_ITextRange)) + { + *ppvObj = me; + ITextRange_AddRef(me); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI ITextRange_fnAddRef(ITextRange *me) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + return InterlockedIncrement(&This->ref); +} + +static ULONG WINAPI ITextRange_fnRelease(ITextRange *me) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE ("%p ref=%u\n", This, ref); + if (ref == 0) + { + This->reOle = NULL; + This->prev->next = This->next; + This->next->prev = This->prev; + heap_free(This); + } + return ref; +} + +static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange *me, UINT *pctinfo) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange *me, UINT iTInfo, LCID lcid, + ITypeInfo **ppTInfo) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange *me, REFIID riid, LPOLESTR *rgszNames, + UINT cNames, LCID lcid, DISPID *rgDispId) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnInvoke(ITextRange *me, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetText(ITextRange *me, BSTR *pbstr) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetText(ITextRange *me, BSTR bstr) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetChar(ITextRange *me, LONG *pch) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetChar(ITextRange *me, LONG ch) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange *me, ITextRange **ppRange) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange *me, ITextRange **ppRange) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange *me, ITextRange *pRange) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetStart(ITextRange *me, LONG *pcpFirst) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetStart(ITextRange *me, LONG cpFirst) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange *me, LONG *pcpLim) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange *me, LONG cpLim) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetFont(ITextRange *me, ITextFont **pFont) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetFont(ITextRange *me, ITextFont *pFont) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetPara(ITextRange *me, ITextPara **ppPara) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetPara(ITextRange *me, ITextPara *pPara) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange *me, LONG *pcch) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange *me, LONG *pValue) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnCollapse(ITextRange *me, LONG bStart) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnExpand(ITextRange *me, LONG Unit, LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange *me, LONG Unit, LONG *pIndex) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange *me, LONG Unit, LONG Index, + LONG Extend) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetRange(ITextRange *me, LONG cpActive, LONG cpOther) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnInRange(ITextRange *me, ITextRange *pRange, LONG *pb) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnInStory(ITextRange *me, ITextRange *pRange, LONG *pb) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange *me, ITextRange *pRange, LONG *pb) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSelect(ITextRange *me) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnStartOf(ITextRange *me, LONG Unit, LONG Extend, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnEndOf(ITextRange *me, LONG Unit, LONG Extend, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMove(ITextRange *me, LONG Unit, LONG Count, LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange *me, LONG Unit, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange *me, LONG Unit, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange *me, VARIANT *Cset, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange *me, VARIANT *Cset, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange *me, VARIANT *Cset, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange *me, VARIANT *Cset, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange *me, VARIANT *Cset, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange *me, VARIANT *Cset, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnFindText(ITextRange *me, BSTR bstr, LONG cch, LONG Flags, + LONG *pLength) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange *me, BSTR bstr, LONG cch, + LONG Flags, LONG *pLength) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange *me, BSTR bstr, LONG cch, + LONG Flags, LONG *pLength) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnDelete(ITextRange *me, LONG Unit, LONG Count, + LONG *pDelta) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnCut(ITextRange *me, VARIANT *pVar) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnCopy(ITextRange *me, VARIANT *pVar) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnPaste(ITextRange *me, VARIANT *pVar, LONG Format) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange *me, VARIANT *pVar, LONG Format, + LONG *pb) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange *me, LONG *pb) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange *me, LONG Type) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange *me, LONG Type, LONG *cx, LONG *cy) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange *me, LONG x, LONG y, LONG Type, + LONG Extend) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG Value) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange *me, IUnknown **ppv) +{ + ITextRangeImpl *This = impl_from_ITextRange(me); + if (!This->reOle) + return CO_E_RELEASED; + + FIXME("not implemented %p\n", This); + return E_NOTIMPL; +} + +static const ITextRangeVtbl trvt = { + ITextRange_fnQueryInterface, + ITextRange_fnAddRef, + ITextRange_fnRelease, + ITextRange_fnGetTypeInfoCount, + ITextRange_fnGetTypeInfo, + ITextRange_fnGetIDsOfNames, + ITextRange_fnInvoke, + ITextRange_fnGetText, + ITextRange_fnSetText, + ITextRange_fnGetChar, + ITextRange_fnSetChar, + ITextRange_fnGetDuplicate, + ITextRange_fnGetFormattedText, + ITextRange_fnSetFormattedText, + ITextRange_fnGetStart, + ITextRange_fnSetStart, + ITextRange_fnGetEnd, + ITextRange_fnSetEnd, + ITextRange_fnGetFont, + ITextRange_fnSetFont, + ITextRange_fnGetPara, + ITextRange_fnSetPara, + ITextRange_fnGetStoryLength, + ITextRange_fnGetStoryType, + ITextRange_fnCollapse, + ITextRange_fnExpand, + ITextRange_fnGetIndex, + ITextRange_fnSetIndex, + ITextRange_fnSetRange, + ITextRange_fnInRange, + ITextRange_fnInStory, + ITextRange_fnIsEqual, + ITextRange_fnSelect, + ITextRange_fnStartOf, + ITextRange_fnEndOf, + ITextRange_fnMove, + ITextRange_fnMoveStart, + ITextRange_fnMoveEnd, + ITextRange_fnMoveWhile, + ITextRange_fnMoveStartWhile, + ITextRange_fnMoveEndWhile, + ITextRange_fnMoveUntil, + ITextRange_fnMoveStartUntil, + ITextRange_fnMoveEndUntil, + ITextRange_fnFindText, + ITextRange_fnFindTextStart, + ITextRange_fnFindTextEnd, + ITextRange_fnDelete, + ITextRange_fnCut, + ITextRange_fnCopy, + ITextRange_fnPaste, + ITextRange_fnCanPaste, + ITextRange_fnCanEdit, + ITextRange_fnChangeCase, + ITextRange_fnGetPoint, + ITextRange_fnSetPoint, + ITextRange_fnScrollIntoView, + ITextRange_fnGetEmbeddedObject +}; +/* ITextRange interface */ + static HRESULT WINAPI ITextDocument_fnQueryInterface(ITextDocument* me, REFIID riid, void** ppvObject) @@ -651,8 +1339,40 @@ ITextDocument_fnRange(ITextDocument* me, LONG cp1, LONG cp2, ITextRange** ppRange) { IRichEditOleImpl *This = impl_from_ITextDocument(me); - FIXME("stub %p\n",This); - return E_NOTIMPL; + ITextRangeImpl *txtRge = NULL; + const int len = ME_GetTextLength(This->editor) + 1; + + TRACE("%p %p %d %d\n", This, ppRange, cp1, cp2); + if (!ppRange) + return E_INVALIDARG; + + if (cp1 < 0) cp1 = 0; + if (cp2 < 0) cp2 = 0; + if (cp1 > len) cp1 = len; + if (cp2 > len) cp2 = len; + if (cp1 >= cp2) + { + int tmp; + tmp = cp1; + cp1 = cp2; + cp2 = tmp; + } + + txtRge = heap_alloc(sizeof *txtRge); + if (!txtRge) + return E_OUTOFMEMORY; + txtRge->ITextRange_iface.lpVtbl = &trvt; + txtRge->ref = 1; + txtRge->reOle = This; + txtRge->start = cp1; + txtRge->end = cp2; + txtRge->next = This->txtRgehead->next; + This->txtRgehead->next->prev = txtRge; + This->txtRgehead->next = txtRge; + txtRge->prev = This->txtRgehead; + *ppRange = &txtRge->ITextRange_iface; + + return S_OK; } static HRESULT WINAPI @@ -1521,6 +2241,30 @@ CreateTextSelection(IRichEditOleImpl *reOle) return txtSel; } +static void CreateEmptyITextRangeImpl(IRichEditOleImpl *reOle, int type) +{ + ITextRangeImpl *txtRgeImpl; + if (type) + { + txtRgeImpl = reOle->txtRgehead; + txtRgeImpl->prev = NULL; + txtRgeImpl->next = reOle->txtRgetail; + } + else + { + txtRgeImpl = reOle->txtRgetail; + txtRgeImpl->prev = reOle->txtRgehead; + txtRgeImpl->next = NULL; + } + + txtRgeImpl->ITextRange_iface.lpVtbl = &trvt; + txtRgeImpl->ref = 1; + txtRgeImpl->reOle = NULL; + txtRgeImpl->start = 0; + txtRgeImpl->end = 0; + +} + LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj) { IRichEditOleImpl *reo; @@ -1549,6 +2293,25 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj) TRACE("Created %p\n",reo); *ppObj = reo; + reo->txtRgehead = heap_alloc(sizeof(ITextRangeImpl)); + if (!reo->txtRgehead) + { + ITextSelection_Release(&reo->txtSel->ITextSelection_iface); + IOleClientSite_Release(&reo->clientSite->IOleClientSite_iface); + heap_free(reo); + return 0; + } + reo->txtRgetail = heap_alloc(sizeof(ITextRangeImpl)); + if (!reo->txtRgetail) + { + ITextSelection_Release(&reo->txtSel->ITextSelection_iface); + IOleClientSite_Release(&reo->clientSite->IOleClientSite_iface); + heap_free(reo->txtRgehead); + heap_free(reo); + return 0; + } + CreateEmptyITextRangeImpl(reo, 1); + CreateEmptyITextRangeImpl(reo, 0); return 1; } diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c index 571e5cd..ed2b581 100644 --- a/dlls/riched20/tests/richole.c +++ b/dlls/riched20/tests/richole.c @@ -86,10 +86,11 @@ static void create_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txt static void release_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc, ITextSelection **txtSel) { + if(txtSel) + ITextSelection_Release(*txtSel); ITextDocument_Release(*txtDoc); IRichEditOle_Release(*reOle); DestroyWindow(*w); - ITextSelection_Release(*txtSel); } static ULONG get_refcount(IUnknown *iface) @@ -486,6 +487,36 @@ static void test_ITextSelection_GetText(void) release_interfaces(&w, &reOle, &txtDoc, &txtSel); } +static void test_ITextDocument_Range(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + ITextRange *txtRge = NULL; + ITextRange *pointer = NULL; + HRESULT hres; + ULONG refcount; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge); + ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres); + refcount = get_refcount((IUnknown *)txtRge); + ok(refcount == 1, "get wrong refcount: returned %d expected 1\n", refcount); + + pointer = txtRge; + hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge); + ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres); + ok(pointer != txtRge, "A new pointer should be returned\n"); + ITextRange_Release(pointer); + + hres = ITextDocument_Range(txtDoc, 0, 0, NULL); + ok(hres == E_INVALIDARG, "ITextDocument_Range should fail 0x%x.\n", hres); + + ITextRange_Release(txtRge); + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + + START_TEST(richole) { /* Must explicitly LoadLibrary(). The test has no references to functions in @@ -496,4 +527,5 @@ START_TEST(richole) test_Interfaces(); test_ITextDocument_Open(); test_ITextSelection_GetText(); + test_ITextDocument_Range(); }