[PATCH 3/4] riched20: add ITextSelection stub

Caibin Chen tigersoldi at gmail.com
Wed Jul 31 02:00:26 CDT 2013


---
 dlls/riched20/Makefile.in |   1 +
 dlls/riched20/txtdoc.c    |  18 +-
 dlls/riched20/txtdoc.h    |   2 +
 dlls/riched20/txtrng.c    | 326 +++++++++++++++-
 dlls/riched20/txtrng.h    |   9 +
 dlls/riched20/txtsel.c    | 966 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/riched20/txtsel.h    |  42 ++
 7 files changed, 1352 insertions(+), 12 deletions(-)
 create mode 100644 dlls/riched20/txtsel.c
 create mode 100644 dlls/riched20/txtsel.h
-------------- next part --------------
From 045a64e7e9a11ad922d5df2b36ef6d0ad30b69ea Mon Sep 17 00:00:00 2001
From: Caibin Chen <tigersoldi at gmail.com>
Date: Tue, 30 Jul 2013 23:25:15 -0700
Subject: [PATCH 3/4] riched20: add ITextSelection stub

---
 dlls/riched20/Makefile.in |   1 +
 dlls/riched20/txtdoc.c    |  18 +-
 dlls/riched20/txtdoc.h    |   2 +
 dlls/riched20/txtrng.c    | 326 +++++++++++++++-
 dlls/riched20/txtrng.h    |   9 +
 dlls/riched20/txtsel.c    | 966 ++++++++++++++++++++++++++++++++++++++++++++++
 dlls/riched20/txtsel.h    |  42 ++
 7 files changed, 1352 insertions(+), 12 deletions(-)
 create mode 100644 dlls/riched20/txtsel.c
 create mode 100644 dlls/riched20/txtsel.h

diff --git a/dlls/riched20/Makefile.in b/dlls/riched20/Makefile.in
index bfad2af..29187a7 100644
--- a/dlls/riched20/Makefile.in
+++ b/dlls/riched20/Makefile.in
@@ -21,6 +21,7 @@ C_SRCS = \
 	txtdoc.c \
 	txthost.c \
 	txtrng.c \
+	txtsel.c \
 	txtsrv.c \
 	undo.c \
 	wrap.c \
diff --git a/dlls/riched20/txtdoc.c b/dlls/riched20/txtdoc.c
index f8d9138..fcac5e6 100644
--- a/dlls/riched20/txtdoc.c
+++ b/dlls/riched20/txtdoc.c
@@ -105,8 +105,14 @@ static HRESULT WINAPI ITextDocument_fnGetName(ITextDocument *iface, BSTR *pName)
 
 static HRESULT WINAPI ITextDocument_fnGetSelection(ITextDocument *me, ITextSelection **ppSel)
 {
-  FIXME("not implemented\n");
-  return E_NOTIMPL;
+  ReTxtDoc *This = impl_from_ITextDocument(me);
+
+  if (ppSel == NULL)
+    return E_INVALIDARG;
+
+  *ppSel = &This->txtSel->ITextSelection_iface;
+  ITextSelection_AddRef(*ppSel);
+  return S_OK;
 }
 
 static HRESULT WINAPI ITextDocument_fnGetStoryCount(ITextDocument *iface, LONG *pCount)
@@ -274,13 +280,21 @@ ReTxtDoc *ReTxtDoc_create(IUnknown *outer_unk, ME_TextEditor *editor)
   This->outer_unk = outer_unk;
   This->editor = editor;
   This->ITextDocument_iface.lpVtbl = &vtbl;
+  This->txtSel = ReTxtSel_create(editor);
   return This;
 }
 
 void ReTxtDoc_destroy(ReTxtDoc *document)
 {
+  ULONG selRef;
   TRACE("(%p)\n", document);
   document->outer_unk = NULL;
   document->editor = NULL;
+
+  selRef = ITextSelection_Release(&document->txtSel->ITextSelection_iface);
+  if (selRef != 0)
+  {
+    ReTxtSel_releaseEditor(document->txtSel);
+  }
   heap_free(document);
 }
diff --git a/dlls/riched20/txtdoc.h b/dlls/riched20/txtdoc.h
index a8a86bc..6198053 100644
--- a/dlls/riched20/txtdoc.h
+++ b/dlls/riched20/txtdoc.h
@@ -24,12 +24,14 @@
 #include <tom.h>
 
 #include "editstr.h"
+#include "txtsel.h"
 
 typedef struct tagReTxtDoc ReTxtDoc;
 struct tagReTxtDoc {
   IUnknown *outer_unk;
   ME_TextEditor *editor;
   ITextDocument ITextDocument_iface;
+  ReTxtSel *txtSel;
 };
 
 /**
diff --git a/dlls/riched20/txtrng.c b/dlls/riched20/txtrng.c
index ee5f71d..2682391 100644
--- a/dlls/riched20/txtrng.c
+++ b/dlls/riched20/txtrng.c
@@ -73,6 +73,11 @@ ULONG WINAPI ITextRange_fnRelease(ITextRange* iface)
 /* ITextRange - IDispatch methods */
 static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange* iface, UINT *pctinfo)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
@@ -80,6 +85,11 @@ static HRESULT WINAPI ITextRange_fnGetTypeInfoCount(ITextRange* iface, UINT *pct
 static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange* iface, UINT iTInfo, LCID lcid,
     ITypeInfo **ppTInfo)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
@@ -87,6 +97,11 @@ static HRESULT WINAPI ITextRange_fnGetTypeInfo(ITextRange* iface, UINT iTInfo, L
 static HRESULT WINAPI ITextRange_fnGetIDsOfNames(ITextRange* iface, REFIID riid, LPOLESTR *rgszNames,
     UINT cNames, LCID lcid, DISPID *rgDispId)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
@@ -95,6 +110,11 @@ static HRESULT WINAPI ITextRange_fnInvoke(ITextRange* iface, DISPID dispIdMember
     WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
     UINT *puArgErr)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
@@ -102,227 +122,417 @@ static HRESULT WINAPI ITextRange_fnInvoke(ITextRange* iface, DISPID dispIdMember
 /* ITextRange methods */
 static HRESULT WINAPI ITextRange_fnGetText(ITextRange* iface, BSTR *pbstr)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetText(ITextRange* iface, BSTR bstr)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetChar(ITextRange* iface, LONG *pch)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetChar(ITextRange* iface, LONG ch)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetDuplicate(ITextRange* iface, ITextRange **ppRange)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetFormattedText(ITextRange* iface, ITextRange **ppRange)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetFormattedText(ITextRange* iface, ITextRange *pRange)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetStart(ITextRange* iface, LONG *pcpFirst)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetStart(ITextRange* iface, LONG cpFirst)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetEnd(ITextRange* iface, LONG *pcpLim)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetEnd(ITextRange* iface, LONG cpLim)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetFont(ITextRange* iface, ITextFont **pFont)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetFont(ITextRange* iface, ITextFont *pFont)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetPara(ITextRange* iface, ITextPara **ppPara)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetPara(ITextRange* iface, ITextPara *pPara)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetStoryLength(ITextRange* iface, LONG *pcch)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetStoryType(ITextRange* iface, LONG *pValue)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnCollapse(ITextRange* iface, LONG bStart)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnExpand(ITextRange* iface, LONG Unit, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetIndex(ITextRange* iface, LONG Unit, LONG *pIndex)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetIndex(ITextRange* iface, LONG Unit, LONG Index, LONG Extend)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetRange(ITextRange* iface, LONG cpActive, LONG cpOther)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnInRange(ITextRange* iface, ITextRange *pRange, LONG *pb)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnInStory(ITextRange* iface, ITextRange *pRange, LONG *pb)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnIsEqual(ITextRange* iface, ITextRange *pRange, LONG *pb)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSelect(ITextRange* iface)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnStartOf(ITextRange* iface, LONG Unit, LONG Extend, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnEndOf(ITextRange* iface, LONG Unit, LONG Extend, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMove(ITextRange* iface, LONG Unit, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMoveStart(ITextRange* iface, LONG Unit, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMoveEnd(ITextRange* iface, LONG Unit, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMoveWhile(ITextRange* iface, VARIANT *Cset, LONG Count, LONG *pDelta) {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMoveStartWhile(ITextRange* iface, VARIANT *Cset, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMoveEndWhile(ITextRange* iface, VARIANT *Cset, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMoveUntil(ITextRange* iface, VARIANT *Cset, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMoveStartUntil(ITextRange* iface, VARIANT *Cset, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnMoveEndUntil(ITextRange* iface, VARIANT *Cset, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnFindText(ITextRange* iface, BSTR bstr, LONG cch, LONG Flags, LONG *pLength)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
@@ -330,6 +540,11 @@ static HRESULT WINAPI ITextRange_fnFindText(ITextRange* iface, BSTR bstr, LONG c
 static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange* iface, BSTR bstr, LONG cch, LONG Flags,
     LONG *pLength)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
@@ -337,72 +552,132 @@ static HRESULT WINAPI ITextRange_fnFindTextStart(ITextRange* iface, BSTR bstr, L
 static HRESULT WINAPI ITextRange_fnFindTextEnd(ITextRange* iface, BSTR bstr, LONG cch, LONG Flags,
     LONG *pLength)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnDelete(ITextRange* iface, LONG Unit, LONG Count, LONG *pDelta)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnCut(ITextRange* iface, VARIANT *pVar)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnCopy(ITextRange* iface, VARIANT *pVar)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnPaste(ITextRange* iface, VARIANT *pVar, LONG Format)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnCanPaste(ITextRange* iface, VARIANT *pVar, LONG Format, LONG *pb)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnCanEdit(ITextRange* iface, LONG *pb)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnChangeCase(ITextRange* iface, LONG Type)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetPoint(ITextRange* iface, LONG Type, LONG *cx, LONG *cy)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnSetPoint(ITextRange* iface, LONG x, LONG y, LONG Type, LONG Extend)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange* iface, LONG Value)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
 
 static HRESULT WINAPI ITextRange_fnGetEmbeddedObject(ITextRange* iface, IUnknown **ppv)
 {
+  ReTxtRng *This = impl_from_ITextRange(iface);
+
+  if (This->editor == NULL)
+    return CO_E_RELEASED;
+
   FIXME("not implemented\n");
   return E_NOTIMPL;
 }
@@ -470,26 +745,57 @@ ITextRangeVtbl rangeVtbl = {
 
 ReTxtRng *ReTxtRng_create(ME_TextEditor *editor, long first, long lim)
 {
-  ReTxtRng *This;
+  ReTxtRng *txtRng;
+  ME_Cursor *startCursor;
+  ME_Cursor *endCursor;
 
   TRACE("editor: %p, first: %ld, lim: %ld\n", editor, first, lim);
   if (editor == NULL)
     ERR("editor cannot be NULL\n");
   if (first < 0 || first > lim)
     ERR("invalid first or lim: %ld - %ld\n", first, lim);
+  startCursor = heap_alloc(sizeof *startCursor);
+  endCursor = heap_alloc(sizeof *endCursor);
+  ME_CursorFromCharOfs(editor, first, startCursor);
+  ME_CursorFromCharOfs(editor, lim, endCursor);
+  txtRng = ReTxtRng_createWithCursors(editor, startCursor, endCursor);
+  /* We should destroy these cursors by ourself. */
+  txtRng->ownsCursor = TRUE;
+  return txtRng;
+}
+
+ReTxtRng *ReTxtRng_createWithCursors(ME_TextEditor *editor,
+                                     ME_Cursor *start,
+                                     ME_Cursor *end)
+{
+  ReTxtRng *txtRng;
 
-  This = heap_alloc(sizeof *This);
-  This->ITextRange_iface.lpVtbl = &rangeVtbl;
-  This->ref = 1;
-  This->editor = editor;
-  This->first = heap_alloc(sizeof(*This->first));
-  This->lim = heap_alloc(sizeof(*This->lim));
-  return This;
+  txtRng = heap_alloc(sizeof *txtRng);
+  txtRng->ITextRange_iface.lpVtbl = &rangeVtbl;
+  txtRng->ref = 1;
+  txtRng->editor = editor;
+  txtRng->first = start;
+  txtRng->lim = end;
+  txtRng->ownsCursor = FALSE;
+  return txtRng;
 }
 
 static void ReTxtRng_destroy(ReTxtRng *txtRng)
 {
-  heap_free(txtRng->first);
-  heap_free(txtRng->lim);
+  if (txtRng->ownsCursor)
+  {
+    heap_free(txtRng->first);
+    heap_free(txtRng->lim);
+  }
   heap_free(txtRng);
 }
+
+void ReTxtRng_releaseEditor(ReTxtRng *txtRng)
+{
+  if (txtRng == NULL)
+  {
+    ERR("txtRng == NULL\n");
+    return;
+  }
+  txtRng->editor = NULL;
+}
diff --git a/dlls/riched20/txtrng.h b/dlls/riched20/txtrng.h
index 041cf8b..0784b3e 100644
--- a/dlls/riched20/txtrng.h
+++ b/dlls/riched20/txtrng.h
@@ -32,10 +32,19 @@ struct tagReTxtRng {
   ME_Cursor *first;
   ME_Cursor *lim;
   ME_TextEditor *editor;
+  BOOL ownsCursor;
 };
 
 ReTxtRng *ReTxtRng_create(ME_TextEditor *editor,
                           long first,
                           long lim);
+ReTxtRng *ReTxtRng_createWithCursors(ME_TextEditor *editor,
+                                     ME_Cursor *start,
+                                     ME_Cursor *end);
+/**
+ * Mark the attached editor as released so that all calls related to
+ * the editor will return CO_E_RELEASED.
+ */
+void ReTxtRng_releaseEditor(ReTxtRng *txtRng);
 
 #endif /* __TXTRNG_H */
diff --git a/dlls/riched20/txtsel.c b/dlls/riched20/txtsel.c
new file mode 100644
index 0000000..a5ac26f
--- /dev/null
+++ b/dlls/riched20/txtsel.c
@@ -0,0 +1,966 @@
+/*
+ * RichEdit - ITextSelection implementation
+ *
+ * Copyright 2013 by Caibin Chen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS              /* For COM objects interfaces definition */
+
+#include "txtsel.h"
+
+#include "editor.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(richedit);
+
+static void ReTxtSel_destroy(ReTxtSel *txtSel);
+
+/*** IUnknown methods ***/
+static inline ReTxtSel *impl_from_ITextSelection(ITextSelection *iface)
+{
+  return CONTAINING_RECORD(iface, ReTxtSel, ITextSelection_iface);
+}
+
+static HRESULT WINAPI ITextSelection_fnQueryInterface(
+                                                      ITextSelection *iface,
+                                                      REFIID riid,
+                                                      void **ppvObj)
+{
+  *ppvObj = NULL;
+  if (IsEqualGUID(riid, &IID_IUnknown)
+      || IsEqualGUID(riid, &IID_IDispatch)
+      || IsEqualGUID(riid, &IID_ITextRange)
+      || IsEqualGUID(riid, &IID_ITextSelection))
+  {
+    *ppvObj = iface;
+    ITextSelection_AddRef(iface);
+    return S_OK;
+  }
+
+  return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ITextSelection_fnAddRef(ITextSelection *iface)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  /* Delegate to ITextRange */
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+  return ITextRange_AddRef(rangeIface);
+}
+
+static ULONG WINAPI ITextSelection_fnRelease(ITextSelection *iface)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+  /* Delegate to ITextRange */
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+  ULONG ref = ITextRange_Release(rangeIface);
+  if (ref == 0)
+  {
+    This->txtRng = NULL;
+    ReTxtSel_destroy(This);
+  }
+  return ref;
+}
+
+/*** IDispatch methods ***/
+static HRESULT WINAPI ITextSelection_fnGetTypeInfoCount(ITextSelection *iface,
+                                                        UINT *pctinfo)
+{
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetTypeInfo(ITextSelection *iface,
+                                                   UINT iTInfo,
+                                                   LCID lcid,
+                                                   ITypeInfo **ppTInfo)
+{
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetIDsOfNames(ITextSelection *iface,
+                                                     REFIID riid,
+                                                     LPOLESTR *rgszNames,
+                                                     UINT cNames,
+                                                     LCID lcid,
+                                                     DISPID *rgDispId)
+{
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnInvoke(ITextSelection *iface,
+                                              DISPID dispIdMember,
+                                              REFIID riid,
+                                              LCID lcid,
+                                              WORD wFlags,
+                                              DISPPARAMS *pDispParams,
+                                              VARIANT *pVarResult,
+                                              EXCEPINFO *pExcepInfo,
+                                              UINT *puArgErr)
+{
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+/*** ITextRange methods ***/
+static HRESULT WINAPI ITextSelection_fnGetText(ITextSelection *iface, BSTR *pbstr)
+{
+  ReTxtSel *This;
+  ITextRange *rangeIface;
+
+  TRACE("(%p)\n", pbstr);
+  This = impl_from_ITextSelection(iface);
+  rangeIface = &This->txtRng->ITextRange_iface;
+  return ITextRange_GetText(rangeIface, pbstr);
+}
+
+static HRESULT WINAPI ITextSelection_fnSetText(ITextSelection *iface, BSTR bstr)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetChar(ITextSelection *iface, LONG *pch)
+{
+  ReTxtSel *This;
+  ITextRange *rangeIface;
+
+  TRACE("(%p)\n", pch);
+  This = impl_from_ITextSelection(iface);
+  rangeIface = &This->txtRng->ITextRange_iface;
+  return ITextRange_GetChar(rangeIface, pch);
+}
+
+static HRESULT WINAPI ITextSelection_fnSetChar(ITextSelection *iface, LONG ch)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetDuplicate(ITextSelection *iface,
+                                                    ITextRange **ppRange)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetFormattedText(ITextSelection *iface,
+                                                        ITextRange **ppRange)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnSetFormattedText(ITextSelection *iface, ITextRange *pRange)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetStart(ITextSelection *iface, LONG *pcpFirst)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+  return ITextRange_GetStart(rangeIface, pcpFirst);
+}
+
+static HRESULT WINAPI ITextSelection_fnSetStart(ITextSelection *iface, LONG cpFirst)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetEnd(ITextSelection *iface, LONG *pcpLim)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+  return ITextRange_GetEnd(rangeIface, pcpLim);
+}
+
+static HRESULT WINAPI ITextSelection_fnSetEnd(ITextSelection *iface, LONG cpLim)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetFont(ITextSelection *iface, ITextFont **pFont)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+  return ITextRange_GetFont(rangeIface, pFont);
+}
+
+static HRESULT WINAPI ITextSelection_fnSetFont(ITextSelection *iface, ITextFont *pFont)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetPara(ITextSelection *iface, ITextPara **ppPara)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+
+  return ITextRange_GetPara(rangeIface, ppPara);
+}
+
+static HRESULT WINAPI ITextSelection_fnSetPara(ITextSelection *iface, ITextPara *pPara)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetStoryLength(ITextSelection *iface, LONG *pcch)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+
+  return ITextRange_GetStoryLength(rangeIface, pcch);
+}
+
+static HRESULT WINAPI ITextSelection_fnGetStoryType(ITextSelection *iface, LONG *pValue)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+
+  return ITextRange_GetStoryType(rangeIface, pValue);
+}
+
+static HRESULT WINAPI ITextSelection_fnCollapse(ITextSelection *iface, LONG bStart)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnExpand(ITextSelection *iface, LONG Unit, LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetIndex(ITextSelection *iface, LONG Unit, LONG *pIndex)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  ITextRange *rangeIface = &This->txtRng->ITextRange_iface;
+
+  return ITextRange_GetIndex(rangeIface, Unit, pIndex);
+}
+
+static HRESULT WINAPI ITextSelection_fnSetIndex(ITextSelection *iface,
+                                                LONG Unit,
+                                                LONG Index,
+                                                LONG Extend)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnSetRange(ITextSelection *iface,
+                                                LONG cpActive,
+                                                LONG cpOther)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnInRange(ITextSelection *iface,
+                                               ITextRange *pRange,
+                                               LONG *pb)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnInStory(ITextSelection *iface,
+                                               ITextRange *pRange,
+                                               LONG *pb)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnIsEqual(ITextSelection *iface,
+                                               ITextRange *pRange,
+                                               LONG *pb)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnSelect(ITextSelection *iface)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnStartOf(ITextSelection *iface,
+                                               LONG Unit,
+                                               LONG Extend,
+                                               LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnEndOf(ITextSelection *iface,
+                                             LONG Unit,
+                                             LONG Extend,
+                                             LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMove(ITextSelection *iface,
+                                            LONG Unit,
+                                            LONG Count,
+                                            LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveStart(ITextSelection *iface,
+                                                 LONG Unit,
+                                                 LONG Count,
+                                                 LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveEnd(ITextSelection *iface,
+                                               LONG Unit,
+                                               LONG Count,
+                                               LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveWhile(ITextSelection *iface,
+                                                 VARIANT *Cset,
+                                                 LONG Count,
+                                                 LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveStartWhile(ITextSelection *iface,
+                                                      VARIANT *Cset,
+                                                      LONG Count,
+                                                      LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveEndWhile(ITextSelection *iface,
+                                                    VARIANT *Cset,
+                                                    LONG Count,
+                                                    LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveUntil(ITextSelection *iface,
+                                                 VARIANT *Cset,
+                                                 LONG Count,
+                                                 LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveStartUntil(ITextSelection *iface,
+                                                      VARIANT *Cset,
+                                                      LONG Count,
+                                                      LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveEndUntil(ITextSelection *iface,
+                                                    VARIANT *Cset,
+                                                    LONG Count,
+                                                    LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnFindText(ITextSelection *iface,
+                                                BSTR bstr,
+                                                LONG cch,
+                                                LONG Flags,
+                                                LONG *pLength)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnFindTextStart(ITextSelection *iface,
+                                                     BSTR bstr,
+                                                     LONG cch,
+                                                     LONG Flags,
+                                                     LONG *pLength)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnFindTextEnd(ITextSelection *iface,
+                                                   BSTR bstr,
+                                                   LONG cch,
+                                                   LONG Flags,
+                                                   LONG *pLength)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnDelete(ITextSelection *iface,
+                                              LONG Unit,
+                                              LONG Count,
+                                              LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnCut(ITextSelection *iface, VARIANT *pVar)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnCopy(ITextSelection *iface, VARIANT *pVar)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnPaste(ITextSelection *iface, VARIANT *pVar, LONG Format)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnCanPaste(ITextSelection *iface,
+                                                VARIANT *pVar,
+                                                LONG Format,
+                                                LONG *pb)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnCanEdit(ITextSelection *iface, LONG *pb)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnChangeCase(ITextSelection *iface, LONG Type)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetPoint(ITextSelection *iface,
+                                                LONG Type,
+                                                LONG *cx,
+                                                LONG *cy)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnSetPoint(ITextSelection *iface,
+                                                LONG x,
+                                                LONG y,
+                                                LONG Type,
+                                                LONG Extend)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnScrollIntoView(ITextSelection *iface, LONG Value)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetEmbeddedObject(ITextSelection *iface,
+                                                         IUnknown **ppv)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+/*** ITextSelection methods ***/
+static HRESULT WINAPI ITextSelection_fnGetFlags(ITextSelection *iface, LONG *pFlags)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnSetFlags(ITextSelection *iface, LONG Flags)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnGetType(ITextSelection *iface, LONG *pType)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveLeft(ITextSelection *iface,
+                                                LONG Unit,
+                                                LONG Count,
+                                                LONG Extend,
+                                                LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveRight(ITextSelection *iface,
+                                                 LONG Unit,
+                                                 LONG Count,
+                                                 LONG Extend,
+                                                 LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveUp(ITextSelection *iface,
+                                              LONG Unit,
+                                              LONG Count,
+                                              LONG Extend,
+                                              LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnMoveDown(ITextSelection *iface,
+                                                LONG Unit,
+                                                LONG Count,
+                                                LONG Extend,
+                                                LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnHomeKey(ITextSelection *iface,
+                                               LONG Unit,
+                                               LONG Extend,
+                                               LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnEndKey(ITextSelection *iface,
+                                              LONG Unit,
+                                              LONG Extend,
+                                              LONG *pDelta)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ITextSelection_fnTypeText(ITextSelection *iface, BSTR bstr)
+{
+  ReTxtSel *This = impl_from_ITextSelection(iface);
+
+  if (This->txtRng->editor == NULL)
+    return CO_E_RELEASED;
+
+  FIXME("not implemented\n");
+  return E_NOTIMPL;
+}
+
+static const ITextSelectionVtbl selectionVtbl = {
+  ITextSelection_fnQueryInterface,
+  ITextSelection_fnAddRef,
+  ITextSelection_fnRelease,
+  ITextSelection_fnGetTypeInfoCount,
+  ITextSelection_fnGetTypeInfo,
+  ITextSelection_fnGetIDsOfNames,
+  ITextSelection_fnInvoke,
+  ITextSelection_fnGetText,
+  ITextSelection_fnSetText,
+  ITextSelection_fnGetChar,
+  ITextSelection_fnSetChar,
+  ITextSelection_fnGetDuplicate,
+  ITextSelection_fnGetFormattedText,
+  ITextSelection_fnSetFormattedText,
+  ITextSelection_fnGetStart,
+  ITextSelection_fnSetStart,
+  ITextSelection_fnGetEnd,
+  ITextSelection_fnSetEnd,
+  ITextSelection_fnGetFont,
+  ITextSelection_fnSetFont,
+  ITextSelection_fnGetPara,
+  ITextSelection_fnSetPara,
+  ITextSelection_fnGetStoryLength,
+  ITextSelection_fnGetStoryType,
+  ITextSelection_fnCollapse,
+  ITextSelection_fnExpand,
+  ITextSelection_fnGetIndex,
+  ITextSelection_fnSetIndex,
+  ITextSelection_fnSetRange,
+  ITextSelection_fnInRange,
+  ITextSelection_fnInStory,
+  ITextSelection_fnIsEqual,
+  ITextSelection_fnSelect,
+  ITextSelection_fnStartOf,
+  ITextSelection_fnEndOf,
+  ITextSelection_fnMove,
+  ITextSelection_fnMoveStart,
+  ITextSelection_fnMoveEnd,
+  ITextSelection_fnMoveWhile,
+  ITextSelection_fnMoveStartWhile,
+  ITextSelection_fnMoveEndWhile,
+  ITextSelection_fnMoveUntil,
+  ITextSelection_fnMoveStartUntil,
+  ITextSelection_fnMoveEndUntil,
+  ITextSelection_fnFindText,
+  ITextSelection_fnFindTextStart,
+  ITextSelection_fnFindTextEnd,
+  ITextSelection_fnDelete,
+  ITextSelection_fnCut,
+  ITextSelection_fnCopy,
+  ITextSelection_fnPaste,
+  ITextSelection_fnCanPaste,
+  ITextSelection_fnCanEdit,
+  ITextSelection_fnChangeCase,
+  ITextSelection_fnGetPoint,
+  ITextSelection_fnSetPoint,
+  ITextSelection_fnScrollIntoView,
+  ITextSelection_fnGetEmbeddedObject,
+  ITextSelection_fnGetFlags,
+  ITextSelection_fnSetFlags,
+  ITextSelection_fnGetType,
+  ITextSelection_fnMoveLeft,
+  ITextSelection_fnMoveRight,
+  ITextSelection_fnMoveUp,
+  ITextSelection_fnMoveDown,
+  ITextSelection_fnHomeKey,
+  ITextSelection_fnEndKey,
+  ITextSelection_fnTypeText
+};
+
+ReTxtSel *ReTxtSel_create(ME_TextEditor *editor)
+{
+  ReTxtSel *txtSel;
+  ME_Cursor *startCursor;
+  ME_Cursor *endCursor;
+
+  txtSel = heap_alloc(sizeof *txtSel);
+  ME_GetSelection(editor, &startCursor, &endCursor);
+  txtSel->txtRng = ReTxtRng_createWithCursors(editor, startCursor, endCursor);
+  txtSel->ITextSelection_iface.lpVtbl = &selectionVtbl;
+  return txtSel;
+}
+
+static void ReTxtSel_destroy(ReTxtSel *txtSel)
+{
+  /* txtSel->txtRng should be self-destroyed in ITextSelection_fnRelease(). */
+  heap_free(txtSel);
+}
+
+void ReTxtSel_releaseEditor(ReTxtSel *txtSel)
+{
+  if (txtSel == NULL)
+  {
+    ERR("txtSel == NULL\n");
+    return;
+  }
+  ReTxtRng_releaseEditor(txtSel->txtRng);
+}
diff --git a/dlls/riched20/txtsel.h b/dlls/riched20/txtsel.h
new file mode 100644
index 0000000..e43e4a8
--- /dev/null
+++ b/dlls/riched20/txtsel.h
@@ -0,0 +1,42 @@
+/*
+ * RichEdit - ITextSelection implementation
+ *
+ * Copyright 2013 by Caibin Chen
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __TXTSEL_H
+#define __TXTSEL_H
+
+#include <tom.h>
+
+#include "editstr.h"
+#include "txtrng.h"
+
+typedef struct tagReTxtSel ReTxtSel;
+struct tagReTxtSel {
+  ITextSelection ITextSelection_iface;
+  ReTxtRng *txtRng;
+};
+
+ReTxtSel *ReTxtSel_create(ME_TextEditor *editor);
+/**
+ * Mark the attached editor as released so that all calls related to
+ * the editor will return CO_E_RELEASED.
+ */
+void ReTxtSel_releaseEditor(ReTxtSel *txtSel);
+
+#endif /* __TXTSEL_H */
-- 
1.8.3.4


More information about the wine-patches mailing list