https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9e90c368efba5deba548f…
commit 9e90c368efba5deba548ffece95daeff5833a9d0
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Mon Jun 4 03:48:31 2018 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Mon Jun 4 03:48:31 2018 +0100
[RICHED20_WINETEST] Sync with Wine Staging 3.9. CORE-14656
---
modules/rostests/winetests/riched20/editor.c | 92 +++++++
modules/rostests/winetests/riched20/richole.c | 357 ++++++++++++++++++++++----
modules/rostests/winetests/riched20/txtsrv.c | 1 +
3 files changed, 401 insertions(+), 49 deletions(-)
diff --git a/modules/rostests/winetests/riched20/editor.c
b/modules/rostests/winetests/riched20/editor.c
index 0e0c960ba2..6712ab1a15 100644
--- a/modules/rostests/winetests/riched20/editor.c
+++ b/modules/rostests/winetests/riched20/editor.c
@@ -20,6 +20,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define COBJMACROS
+
#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
@@ -30,6 +32,7 @@
#include <winnls.h>
#include <ole2.h>
#include <richedit.h>
+#include <richole.h>
#include <commdlg.h>
#include <time.h>
#include <wine/test.h>
@@ -8798,6 +8801,94 @@ static void test_para_numbering(void)
DestroyWindow( edit );
}
+static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj,
+ LPSTORAGE pstg, LPOLECLIENTSITE polesite, LONG
sizel_cx,
+ LONG sizel_cy, DWORD aspect, DWORD flags, DWORD user)
+{
+ reobj->cbStruct = sizeof(*reobj);
+ reobj->clsid = CLSID_NULL;
+ reobj->cp = cp;
+ reobj->poleobj = poleobj;
+ reobj->pstg = pstg;
+ reobj->polesite = polesite;
+ reobj->sizel.cx = sizel_cx;
+ reobj->sizel.cy = sizel_cy;
+ reobj->dvaspect = aspect;
+ reobj->dwFlags = flags;
+ reobj->dwUser = user;
+}
+
+static void test_EM_SELECTIONTYPE(void)
+{
+ HWND hwnd = new_richedit(NULL);
+ IRichEditOle *reole = NULL;
+ static const char text1[] = "abcdefg\n";
+ int result;
+ REOBJECT reo1, reo2;
+ IOleClientSite *clientsite;
+ HRESULT hr;
+
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)text1);
+ SendMessageA(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&reole);
+
+ SendMessageA(hwnd, EM_SETSEL, 1, 1);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == SEL_EMPTY, "got wrong selection type: %x.\n", result);
+
+ SendMessageA(hwnd, EM_SETSEL, 1, 2);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == SEL_TEXT, "got wrong selection type: %x.\n", result);
+
+ SendMessageA(hwnd, EM_SETSEL, 2, 5);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == (SEL_TEXT | SEL_MULTICHAR), "got wrong selection type: %x.\n",
result);
+
+ SendMessageA(hwnd, EM_SETSEL, 0, 1);
+ hr = IRichEditOle_GetClientSite(reole, &clientsite);
+ ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
+ fill_reobject_struct(&reo1, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
+ DVASPECT_CONTENT, 0, 1);
+ hr = IRichEditOle_InsertObject(reole, &reo1);
+ ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+ IOleClientSite_Release(clientsite);
+
+ SendMessageA(hwnd, EM_SETSEL, 0, 1);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == SEL_OBJECT, "got wrong selection type: %x.\n", result);
+
+ SendMessageA(hwnd, EM_SETSEL, 0, 2);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == (SEL_TEXT | SEL_OBJECT), "got wrong selection type: %x.\n",
result);
+
+ SendMessageA(hwnd, EM_SETSEL, 0, 3);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT), "got wrong selection type:
%x.\n", result);
+
+ SendMessageA(hwnd, EM_SETSEL, 2, 3);
+ hr = IRichEditOle_GetClientSite(reole, &clientsite);
+ ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
+ fill_reobject_struct(&reo2, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
+ DVASPECT_CONTENT, 0, 2);
+ hr = IRichEditOle_InsertObject(reole, &reo2);
+ ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+ IOleClientSite_Release(clientsite);
+
+ SendMessageA(hwnd, EM_SETSEL, 0, 2);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == (SEL_OBJECT | SEL_TEXT), "got wrong selection type: %x.\n",
result);
+
+ SendMessageA(hwnd, EM_SETSEL, 0, 3);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == (SEL_OBJECT | SEL_MULTIOBJECT | SEL_TEXT), "got wrong selection
type: %x.\n", result);
+
+ SendMessageA(hwnd, EM_SETSEL, 0, 4);
+ result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == (SEL_TEXT| SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT), "got
wrong selection type: %x.\n", result);
+
+ IRichEditOle_Release(reole);
+ DestroyWindow(hwnd);
+}
+
static void test_window_classes(void)
{
static const struct
@@ -8905,6 +8996,7 @@ START_TEST( editor )
test_background();
test_eop_char_fmt();
test_para_numbering();
+ test_EM_SELECTIONTYPE();
/* Set the environment variable WINETEST_RICHED20 to keep windows
* responsive and open for 30 seconds. This is useful for debugging.
diff --git a/modules/rostests/winetests/riched20/richole.c
b/modules/rostests/winetests/riched20/richole.c
index 3a69819630..617d1f978b 100644
--- a/modules/rostests/winetests/riched20/richole.c
+++ b/modules/rostests/winetests/riched20/richole.c
@@ -3132,39 +3132,152 @@ static void test_SetFont(void)
ITextSelection_Release(selection);
}
+static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj,
+ LPSTORAGE pstg, LPOLECLIENTSITE polesite, LONG
sizel_cx,
+ LONG sizel_cy, DWORD aspect, DWORD flags, DWORD user)
+{
+ reobj->cbStruct = sizeof(*reobj);
+ reobj->clsid = CLSID_NULL;
+ reobj->cp = cp;
+ reobj->poleobj = poleobj;
+ reobj->pstg = pstg;
+ reobj->polesite = polesite;
+ reobj->sizel.cx = sizel_cx;
+ reobj->sizel.cy = sizel_cy;
+ reobj->dvaspect = aspect;
+ reobj->dwFlags = flags;
+ reobj->dwUser = user;
+}
+
+#define CHECK_REOBJECT_STRUCT(reobj,poleobj,pstg,polesite,user) \
+ _check_reobject_struct(reobj, poleobj, pstg, polesite, user, __LINE__)
+static void _check_reobject_struct(REOBJECT reobj, LPOLEOBJECT poleobj, LPSTORAGE pstg,
+ LPOLECLIENTSITE polesite, DWORD user, int line)
+{
+ ok_(__FILE__,line)(reobj.poleobj == poleobj, "got wrong object
interface.\n");
+ ok_(__FILE__,line)(reobj.pstg == pstg, "got wrong storage interface.\n");
+ ok_(__FILE__,line)(reobj.polesite == polesite, "got wrong site
interface.\n");
+ ok_(__FILE__,line)(reobj.dwUser == user, "got wrong user-defined value.\n");
+}
+
static void test_InsertObject(void)
{
+ static CHAR test_text1[] = "abcdefg";
IRichEditOle *reole = NULL;
ITextDocument *doc = NULL;
IOleClientSite *clientsite;
- REOBJECT reo;
+ REOBJECT reo1, reo2, reo3, received_reo1, received_reo2, received_reo3, received_reo4;
HRESULT hr;
HWND hwnd;
+ LONG count;
create_interfaces(&hwnd, &reole, &doc, NULL);
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
hr = IRichEditOle_InsertObject(reole, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
+ /* insert object1 in (0, 1)*/
+ SendMessageA(hwnd, EM_SETSEL, 0, 1);
hr = IRichEditOle_GetClientSite(reole, &clientsite);
- ok(hr == S_OK, "got 0x%08x\n", hr);
-
- reo.cbStruct = sizeof(reo);
- reo.cp = 0;
- memset(&reo.clsid, 0, sizeof(reo.clsid));
- reo.poleobj = NULL;
- reo.pstg = NULL;
- reo.polesite = clientsite;
- reo.sizel.cx = 10;
- reo.sizel.cy = 10;
- reo.dvaspect = DVASPECT_CONTENT;
- reo.dwFlags = 0;
- reo.dwUser = 0;
+ ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
+ fill_reobject_struct(&reo1, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
DVASPECT_CONTENT, 0, 1);
+ hr = IRichEditOle_InsertObject(reole, &reo1);
+ ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+ count = IRichEditOle_GetObjectCount(reole);
+ ok(count == 1, "got wrong object count: %d\n", count);
+ IOleClientSite_Release(clientsite);
- hr = IRichEditOle_InsertObject(reole, &reo);
- ok(hr == S_OK, "got 0x%08x\n", hr);
+ /* insert object2 in (2, 3)*/
+ SendMessageA(hwnd, EM_SETSEL, 2, 3);
+ hr = IRichEditOle_GetClientSite(reole, &clientsite);
+ ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
+ fill_reobject_struct(&reo2, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
DVASPECT_CONTENT, 0, 2);
+ hr = IRichEditOle_InsertObject(reole, &reo2);
+ ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+ count = IRichEditOle_GetObjectCount(reole);
+ ok(count == 2, "got wrong object count: %d\n", count);
+ IOleClientSite_Release(clientsite);
+ /* insert object3 in (1, 2)*/
+ SendMessageA(hwnd, EM_SETSEL, 1, 2);
+ hr = IRichEditOle_GetClientSite(reole, &clientsite);
+ ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
+ fill_reobject_struct(&reo3, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
DVASPECT_CONTENT, 0, 3);
+ hr = IRichEditOle_InsertObject(reole, &reo3);
+ ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+ count = IRichEditOle_GetObjectCount(reole);
+ ok(count == 3, "got wrong object count: %d\n", count);
IOleClientSite_Release(clientsite);
+
+ /* tests below show that order of rebject (from 0 to 2) is: reo1,reo3,reo2 */
+ received_reo1.cbStruct = sizeof(received_reo1);
+ hr = IRichEditOle_GetObject(reole, 0, &received_reo1, REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo1, NULL, NULL, reo1.polesite, 1);
+
+ received_reo2.cbStruct = sizeof(received_reo2);
+ hr = IRichEditOle_GetObject(reole, 1, &received_reo2, REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo2, NULL, NULL, reo3.polesite, 3);
+
+ received_reo3.cbStruct = sizeof(received_reo3);
+ hr = IRichEditOle_GetObject(reole, 2, &received_reo3, REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo3, NULL, NULL, reo2.polesite, 2);
+
+ hr = IRichEditOle_GetObject(reole, 2, NULL, REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
+
+ received_reo4.cbStruct = 0;
+ hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
+
+ received_reo4.cbStruct = sizeof(received_reo4);
+ hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_PSTG);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2);
+
+ hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_POLESITE);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
+
+ hr = IRichEditOle_GetObject(reole, 4, &received_reo4, REO_GETOBJ_POLESITE);
+ ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
+
+ hr = IRichEditOle_GetObject(reole, 1024, &received_reo4, REO_GETOBJ_POLESITE);
+ ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
+
+ /* received_reo4 will be zeroed before be used */
+ hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_NO_INTERFACES);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2);
+
+ received_reo4.cbStruct = sizeof(received_reo4);
+ received_reo4.cp = 0;
+ hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
+
+ received_reo4.cbStruct = sizeof(received_reo4);
+ received_reo4.cp = 1;
+ hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
+
+ received_reo4.cbStruct = sizeof(received_reo4);
+ received_reo4.cp = 2;
+ hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
+ CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
+
+ received_reo4.cbStruct = sizeof(received_reo4);
+ received_reo4.cp = 4;
+ hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
+ ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
+ /* received_reo4 didn't be zeroed in E_INVALIDARG case */
+ CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
+
release_interfaces(&hwnd, &reole, &doc, NULL);
}
@@ -3310,6 +3423,64 @@ static void test_ITextSelection_GetDuplicate(void)
ITextRange_Release(range);
}
+#define RESET_RANGE(range,start,end) \
+ _reset_range(range, start, end, __LINE__)
+static void _reset_range(ITextRange *range, LONG start, LONG end, int line)
+{
+ HRESULT hr;
+
+ hr = ITextRange_SetStart(range, start);
+ ok_(__FILE__,line)(hr == S_OK, "SetStart failed: 0x%08x\n", hr);
+ hr = ITextRange_SetEnd(range, end);
+ ok_(__FILE__,line)(hr == S_OK, "SetEnd failed: 0x%08x\n", hr);
+}
+
+#define CHECK_RANGE(range,expected_start,expected_end) \
+ _check_range(range, expected_start, expected_end, __LINE__)
+static void _check_range(ITextRange* range, LONG expected_start, LONG expected_end, int
line)
+{
+ HRESULT hr;
+ LONG value;
+
+ hr = ITextRange_GetStart(range, &value);
+ ok_(__FILE__,line)(hr == S_OK, "GetStart failed: 0x%08x\n", hr);
+ ok_(__FILE__,line)(value == expected_start, "Expected start %d got %d\n",
+ expected_start, value);
+ hr = ITextRange_GetEnd(range, &value);
+ ok_(__FILE__,line)(hr == S_OK, "GetEnd failed: 0x%08x\n", hr);
+ ok_(__FILE__,line)(value == expected_end, "Expected end %d got %d\n",
+ expected_end, value);
+}
+
+#define RESET_SELECTION(selection,start,end) \
+ _reset_selection(selection, start, end, __LINE__)
+static void _reset_selection(ITextSelection *selection, LONG start, LONG end, int line)
+{
+ HRESULT hr;
+
+ hr = ITextSelection_SetStart(selection, start);
+ ok_(__FILE__,line)(hr == S_OK, "SetStart failed: 0x%08x\n", hr);
+ hr = ITextSelection_SetEnd(selection, end);
+ ok_(__FILE__,line)(hr == S_OK, "SetEnd failed: 0x%08x\n", hr);
+}
+
+#define CHECK_SELECTION(selection,expected_start,expected_end) \
+ _check_selection(selection, expected_start, expected_end, __LINE__)
+static void _check_selection(ITextSelection *selection, LONG expected_start, LONG
expected_end, int line)
+{
+ HRESULT hr;
+ LONG value;
+
+ hr = ITextSelection_GetStart(selection, &value);
+ ok_(__FILE__,line)(hr == S_OK, "GetStart failed: 0x%08x\n", hr);
+ ok_(__FILE__,line)(value == expected_start, "Expected start %d got %d\n",
+ expected_start, value);
+ hr = ITextSelection_GetEnd(selection, &value);
+ ok_(__FILE__,line)(hr == S_OK, "GetEnd failed: 0x%08x\n", hr);
+ ok_(__FILE__,line)(value == expected_end, "Expected end %d got %d\n",
+ expected_end, value);
+}
+
static void test_Expand(void)
{
static const char test_text1[] = "TestSomeText";
@@ -3330,53 +3501,26 @@ static void test_Expand(void)
hr = ITextRange_Expand(range, tomStory, NULL);
ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = ITextRange_GetStart(range, &value);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(value == 0, "got %d\n", value);
- hr = ITextRange_GetEnd(range, &value);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(value == 13, "got %d\n", value);
+ CHECK_RANGE(range, 0, 13);
hr = ITextSelection_Expand(selection, tomStory, NULL);
ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = ITextSelection_GetStart(selection, &value);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(value == 0, "got %d\n", value);
- hr = ITextSelection_GetEnd(selection, &value);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(value == 13, "got %d\n", value);
+ CHECK_SELECTION(selection, 0, 13);
- hr = ITextRange_SetStart(range, 1);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = ITextRange_SetEnd(range, 2);
- ok(hr == S_OK, "got 0x%08x\n", hr);
-
- hr = ITextSelection_SetStart(selection, 1);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = ITextSelection_SetEnd(selection, 2);
- ok(hr == S_OK, "got 0x%08x\n", hr);
+ RESET_RANGE(range, 1, 2);
+ RESET_SELECTION(selection, 1, 2);
value = 0;
hr = ITextRange_Expand(range, tomStory, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 12, "got %d\n", value);
- hr = ITextRange_GetStart(range, &value);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(value == 0, "got %d\n", value);
- hr = ITextRange_GetEnd(range, &value);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(value == 13, "got %d\n", value);
+ CHECK_RANGE(range, 0, 13);
value = 0;
hr = ITextSelection_Expand(selection, tomStory, &value);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(value == 12, "got %d\n", value);
- hr = ITextSelection_GetStart(selection, &value);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(value == 0, "got %d\n", value);
- hr = ITextSelection_GetEnd(selection, &value);
- ok(hr == S_OK, "got 0x%08x\n", hr);
- ok(value == 13, "got %d\n", value);
+ CHECK_SELECTION(selection, 0, 13);
release_interfaces(&hwnd, &reole, &doc, NULL);
@@ -3396,6 +3540,120 @@ static void test_Expand(void)
ITextRange_Release(range);
}
+static void test_MoveEnd(void)
+{
+ static const char test_text1[] = "Word1 Word2";
+ IRichEditOle *reole = NULL;
+ ITextDocument *doc = NULL;
+ ITextSelection *selection;
+ ITextRange *range;
+ LONG delta;
+ HRESULT hr;
+ HWND hwnd;
+
+ create_interfaces(&hwnd, &reole, &doc, &selection);
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
+ SendMessageA(hwnd, EM_SETSEL, 1, 2);
+
+ hr = ITextDocument_Range(doc, 1, 2, &range);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = ITextRange_MoveEnd(range, tomStory, 0, &delta);
+ ok(hr == S_FALSE, "got 0x%08x\n", hr);
+ ok(delta == 0, "got %d\n", delta);
+ CHECK_RANGE(range, 1, 2);
+
+ hr = ITextRange_MoveEnd(range, tomStory, -1, &delta);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(delta == -1, "got %d\n", delta);
+ CHECK_RANGE(range, 0, 0);
+
+ hr = ITextRange_MoveEnd(range, tomStory, 1, &delta);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(delta == 1, "got %d\n", delta);
+ CHECK_RANGE(range, 0, 12);
+
+ hr = ITextRange_MoveEnd(range, tomStory, 1, &delta);
+ ok(hr == S_FALSE, "got 0x%08x\n", hr);
+ ok(delta == 0, "got %d\n", delta);
+ CHECK_RANGE(range, 0, 12);
+
+ RESET_RANGE(range, 1, 2);
+
+ hr = ITextRange_MoveEnd(range, tomStory, 3, &delta);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(delta == 1, "got %d\n", delta);
+ CHECK_RANGE(range, 1, 12);
+
+ RESET_RANGE(range, 2, 3);
+
+ hr = ITextRange_MoveEnd(range, tomStory, -3, &delta);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(delta == -1, "got %d\n", delta);
+ CHECK_RANGE(range, 0, 0);
+
+ hr = ITextRange_MoveEnd(range, tomStory, -1, &delta);
+ ok(hr == S_FALSE, "got 0x%08x\n", hr);
+ ok(delta == 0, "got %d\n", delta);
+ CHECK_RANGE(range, 0, 0);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, 0, &delta);
+ ok(hr == S_FALSE, "got 0x%08x\n", hr);
+ ok(delta == 0, "got %d\n", delta);
+ CHECK_SELECTION(selection, 1, 2);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, -1, &delta);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(delta == -1, "got %d\n", delta);
+ CHECK_SELECTION(selection, 0, 0);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(delta == 1, "got %d\n", delta);
+ CHECK_SELECTION(selection, 0, 12);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta);
+ ok(hr == S_FALSE, "got 0x%08x\n", hr);
+ ok(delta == 0, "got %d\n", delta);
+ CHECK_SELECTION(selection, 0, 12);
+
+ RESET_SELECTION(selection, 1, 2);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, 3, &delta);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(delta == 1, "got %d\n", delta);
+ CHECK_SELECTION(selection, 1, 12);
+
+ RESET_SELECTION(selection, 2, 3);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, -3, &delta);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(delta == -1, "got %d\n", delta);
+ CHECK_SELECTION(selection, 0, 0);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, -1, &delta);
+ ok(hr == S_FALSE, "got 0x%08x\n", hr);
+ ok(delta == 0, "got %d\n", delta);
+ CHECK_SELECTION(selection, 0, 0);
+
+ release_interfaces(&hwnd, &reole, &doc, NULL);
+
+ hr = ITextRange_MoveEnd(range, tomStory, 1, NULL);
+ ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
+
+ hr = ITextRange_MoveEnd(range, tomStory, 1, &delta);
+ ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, 1, NULL);
+ ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
+
+ hr = ITextSelection_MoveEnd(selection, tomStory, 1, &delta);
+ ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr);
+
+ ITextSelection_Release(selection);
+ ITextRange_Release(range);
+}
+
static void test_ITextRange_SetStart(void)
{
HWND w;
@@ -3890,4 +4148,5 @@ START_TEST(richole)
test_GetStoryLength();
test_ITextSelection_GetDuplicate();
test_Expand();
+ test_MoveEnd();
}
diff --git a/modules/rostests/winetests/riched20/txtsrv.c
b/modules/rostests/winetests/riched20/txtsrv.c
index 73ca7cd753..88b5adf13c 100644
--- a/modules/rostests/winetests/riched20/txtsrv.c
+++ b/modules/rostests/winetests/riched20/txtsrv.c
@@ -654,6 +654,7 @@ static void test_TxGetText(void)
hres = ITextServices_TxGetText(txtserv, &rettext);
ok(hres == S_OK, "ITextServices_TxGetText failed (result = %x)\n", hres);
+ SysFreeString(rettext);
ITextServices_Release(txtserv);
ITextHost_Release(host);