[RICHED20_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 5 Mar 2016 09:58:36 +0000 (09:58 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 5 Mar 2016 09:58:36 +0000 (09:58 +0000)
svn path=/trunk/; revision=70924

rostests/winetests/riched20/editor.c

index 31af4b2..e32d403 100644 (file)
@@ -46,6 +46,7 @@ static CHAR string1[MAX_PATH], string2[MAX_PATH], string3[MAX_PATH];
        format, string1, string2, string3);
 
 static HMODULE hmoduleRichEdit;
        format, string1, string2, string3);
 
 static HMODULE hmoduleRichEdit;
+static BOOL is_lang_japanese;
 
 static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent) {
   HWND hwnd;
 
 static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent) {
   HWND hwnd;
@@ -486,6 +487,28 @@ static void test_EM_LINELENGTH(void)
         offset_test[i][0], result, offset_test[i][1]);
   }
 
         offset_test[i][0], result, offset_test[i][1]);
   }
 
+  /* Test with multibyte character */
+  if (!is_lang_japanese)
+    skip("Skip multibyte character tests on non-Japanese platform\n");
+  else
+  {
+    const char *text1 =
+          "wine\n"
+          "richedit\x8e\xf0\n"
+          "wine";
+    int offset_test1[3][2] = {
+           {0, 4},  /* Line 1: |wine\n */
+           {5, 9},  /* Line 2: |richedit\x8e\xf0\n */
+           {15, 4}, /* Line 3: |wine */
+    };
+    SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text1);
+    for (i = 0; i < sizeof(offset_test1)/sizeof(offset_test1[0]); i++) {
+      result = SendMessageA(hwndRichEdit, EM_LINELENGTH, offset_test1[i][0], 0);
+      ok(result == offset_test1[i][1], "Length of line at offset %d is %ld, expected %d\n",
+         offset_test1[i][0], result, offset_test1[i][1]);
+    }
+  }
+
   DestroyWindow(hwndRichEdit);
 }
 
   DestroyWindow(hwndRichEdit);
 }
 
@@ -1519,6 +1542,19 @@ static void test_EM_GETTEXTRANGE(void)
     ok(result == strlen(text2), "EM_GETTEXTRANGE returned %ld\n", result);
     ok(!strcmp(text2, buffer), "EM_GETTEXTRANGE filled %s\n", buffer);
 
     ok(result == strlen(text2), "EM_GETTEXTRANGE returned %ld\n", result);
     ok(!strcmp(text2, buffer), "EM_GETTEXTRANGE filled %s\n", buffer);
 
+    /* Test with multibyte character */
+    if (!is_lang_japanese)
+        skip("Skip multibyte character tests on non-Japanese platform\n");
+    else
+    {
+        SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk");
+        textRange.chrg.cpMin = 4;
+        textRange.chrg.cpMax = 8;
+        result = SendMessageA(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange);
+        todo_wine ok(result == 5, "EM_GETTEXTRANGE returned %ld\n", result);
+        todo_wine ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETTEXTRANGE filled %s\n", buffer);
+    }
+
     DestroyWindow(hwndRichEdit);
 }
 
     DestroyWindow(hwndRichEdit);
 }
 
@@ -1535,15 +1571,27 @@ static void test_EM_GETSELTEXT(void)
 
     SendMessageA(hwndRichEdit, EM_SETSEL, 4, 11);
     result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer);
 
     SendMessageA(hwndRichEdit, EM_SETSEL, 4, 11);
     result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer);
-    ok(result == 7, "EM_GETTEXTRANGE returned %ld\n", result);
-    ok(!strcmp(expect, buffer), "EM_GETTEXTRANGE filled %s\n", buffer);
+    ok(result == 7, "EM_GETSELTEXT returned %ld\n", result);
+    ok(!strcmp(expect, buffer), "EM_GETSELTEXT filled %s\n", buffer);
 
     SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text2);
 
     SendMessageA(hwndRichEdit, EM_SETSEL, 4, 11);
     result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer);
 
     SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text2);
 
     SendMessageA(hwndRichEdit, EM_SETSEL, 4, 11);
     result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer);
-    ok(result == 7, "EM_GETTEXTRANGE returned %ld\n", result);
-    ok(!strcmp(expect, buffer), "EM_GETTEXTRANGE filled %s\n", buffer);
+    ok(result == 7, "EM_GETSELTEXT returned %ld\n", result);
+    ok(!strcmp(expect, buffer), "EM_GETSELTEXT filled %s\n", buffer);
+
+    /* Test with multibyte character */
+    if (!is_lang_japanese)
+        skip("Skip multibyte character tests on non-Japanese platform\n");
+    else
+    {
+        SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk");
+        SendMessageA(hwndRichEdit, EM_SETSEL, 4, 8);
+        result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer);
+        todo_wine ok(result == 5, "EM_GETSELTEXT returned %ld\n", result);
+        todo_wine ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETSELTEXT filled %s\n", buffer);
+    }
 
     DestroyWindow(hwndRichEdit);
 }
 
     DestroyWindow(hwndRichEdit);
 }
@@ -3676,8 +3724,9 @@ static void test_EM_SETTEXTEX(void)
 
   setText.codepage = CP_ACP;
   setText.flags = ST_SELECTION;
 
   setText.codepage = CP_ACP;
   setText.flags = ST_SELECTION;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText,
-              (LPARAM)"{\\rtf 1\\par 2\\par 3\\par 4\\par 5\\par 6\\par 7\\par 8\\par 9\\par}");
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText,
+                        (LPARAM)"{\\rtf 1\\par 2\\par 3\\par 4\\par 5\\par 6\\par 7\\par 8\\par 9\\par}");
+  todo_wine ok(result == 18, "EM_SETTEXTEX returned %d, expected 18\n", result);
   si.cbSize = sizeof(si);
   si.fMask = SIF_ALL;
   GetScrollInfo(hwndRichEdit, SB_VERT, &si);
   si.cbSize = sizeof(si);
   si.fMask = SIF_ALL;
   GetScrollInfo(hwndRichEdit, SB_VERT, &si);
@@ -3692,8 +3741,9 @@ static void test_EM_SETTEXTEX(void)
   hwndRichEdit = new_richedit(NULL);
   setText.codepage = CP_ACP;
   setText.flags = ST_SELECTION;
   hwndRichEdit = new_richedit(NULL);
   setText.codepage = CP_ACP;
   setText.flags = ST_SELECTION;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText,
-              (LPARAM)"{\\rtf 1\\par 2\\par 3\\par 4\\par 5\\par 6\\par 7\\par 8\\par 9\\par}");
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText,
+                        (LPARAM)"{\\rtf 1\\par 2\\par 3\\par 4\\par 5\\par 6\\par 7\\par 8\\par 9\\par}");
+  todo_wine ok(result == 18, "EM_SETTEXTEX returned %d, expected 18\n", result);
   si.cbSize = sizeof(si);
   si.fMask = SIF_ALL;
   GetScrollInfo(hwndRichEdit, SB_VERT, &si);
   si.cbSize = sizeof(si);
   si.fMask = SIF_ALL;
   GetScrollInfo(hwndRichEdit, SB_VERT, &si);
@@ -3706,8 +3756,9 @@ static void test_EM_SETTEXTEX(void)
    * but this time it is because the selection is at the beginning. */
   setText.codepage = CP_ACP;
   setText.flags = ST_DEFAULT;
    * but this time it is because the selection is at the beginning. */
   setText.codepage = CP_ACP;
   setText.flags = ST_DEFAULT;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText,
-              (LPARAM)"{\\rtf 1\\par 2\\par 3\\par 4\\par 5\\par 6\\par 7\\par 8\\par 9\\par}");
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText,
+                        (LPARAM)"{\\rtf 1\\par 2\\par 3\\par 4\\par 5\\par 6\\par 7\\par 8\\par 9\\par}");
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   si.cbSize = sizeof(si);
   si.fMask = SIF_ALL;
   GetScrollInfo(hwndRichEdit, SB_VERT, &si);
   si.cbSize = sizeof(si);
   si.fMask = SIF_ALL;
   GetScrollInfo(hwndRichEdit, SB_VERT, &si);
@@ -3724,7 +3775,8 @@ static void test_EM_SETTEXTEX(void)
   getText.lpUsedDefChar = NULL;
 
   setText.flags = 0;
   getText.lpUsedDefChar = NULL;
 
   setText.flags = 0;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1);
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1);
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem1) == 0,
       "EM_GETTEXTEX results not what was set by EM_SETTEXTEX\n");
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem1) == 0,
       "EM_GETTEXTEX results not what was set by EM_SETTEXTEX\n");
@@ -3739,7 +3791,8 @@ static void test_EM_SETTEXTEX(void)
   getText.lpDefaultChar = NULL;
   getText.lpUsedDefChar = NULL;
   setText.flags = 0;
   getText.lpDefaultChar = NULL;
   getText.lpUsedDefChar = NULL;
   setText.flags = 0;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem2);
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem2);
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem2) == 0,
       "EM_GETTEXTEX results not what was set by EM_SETTEXTEX\n");
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem2) == 0,
       "EM_GETTEXTEX results not what was set by EM_SETTEXTEX\n");
@@ -3784,7 +3837,8 @@ static void test_EM_SETTEXTEX(void)
   getText.lpDefaultChar = NULL;
   getText.lpUsedDefChar = NULL;
   setText.flags = 0;
   getText.lpDefaultChar = NULL;
   getText.lpUsedDefChar = NULL;
   setText.flags = 0;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem3);
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem3);
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem3_after) == 0,
       "EM_SETTEXTEX did not convert properly\n");
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem3_after) == 0,
       "EM_SETTEXTEX did not convert properly\n");
@@ -3797,7 +3851,8 @@ static void test_EM_SETTEXTEX(void)
   getText.lpDefaultChar = NULL;
   getText.lpUsedDefChar = NULL;
   setText.flags = 0;
   getText.lpDefaultChar = NULL;
   getText.lpUsedDefChar = NULL;
   setText.flags = 0;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem3alt);
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem3alt);
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem3_after) == 0,
       "EM_SETTEXTEX did not convert properly\n");
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem3_after) == 0,
       "EM_SETTEXTEX did not convert properly\n");
@@ -3810,7 +3865,8 @@ static void test_EM_SETTEXTEX(void)
   getText.lpDefaultChar = NULL;
   getText.lpUsedDefChar = NULL;
   setText.flags = 0;
   getText.lpDefaultChar = NULL;
   getText.lpUsedDefChar = NULL;
   setText.flags = 0;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem4);
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem4);
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem4_after) == 0,
       "EM_SETTEXTEX did not convert properly\n");
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem4_after) == 0,
       "EM_SETTEXTEX did not convert properly\n");
@@ -3825,7 +3881,8 @@ static void test_EM_SETTEXTEX(void)
 
   /* put some text back: !ST_SELECTION && Unicode && !\rtf */
   setText.flags = 0;
 
   /* put some text back: !ST_SELECTION && Unicode && !\rtf */
   setText.flags = 0;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1);
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1);
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   /* select some text */
   cr.cpMax = 1;
   cr.cpMin = 3;
   /* select some text */
   cr.cpMax = 1;
   cr.cpMin = 3;
@@ -3840,7 +3897,8 @@ static void test_EM_SETTEXTEX(void)
   
   /* put some text back: !ST_SELECTION && Unicode && !\rtf */
   setText.flags = 0;
   
   /* put some text back: !ST_SELECTION && Unicode && !\rtf */
   setText.flags = 0;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1);
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1);
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   /* select some text */
   cr.cpMax = 1;
   cr.cpMin = 3;
   /* select some text */
   cr.cpMax = 1;
   cr.cpMin = 3;
@@ -3878,7 +3936,8 @@ static void test_EM_SETTEXTEX(void)
   getText.lpUsedDefChar = NULL;
 
   setText.flags = 0;
   getText.lpUsedDefChar = NULL;
 
   setText.flags = 0;
-  SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)buf);
+  result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)buf);
+  ok(result == 1, "EM_SETTEXTEX returned %d, expected 1\n", result);
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem1) == 0,
       "EM_GETTEXTEX results not what was set by EM_SETTEXTEX\n");
   SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
   ok(lstrcmpW(buf, TestItem1) == 0,
       "EM_GETTEXTEX results not what was set by EM_SETTEXTEX\n");
@@ -3997,6 +4056,41 @@ static void test_EM_SETTEXTEX(void)
   result = strcmp(bufACP, "TestUTF8WithBOM");
   ok(result == 0, "EM_SETTEXTEX: Test UTF8 with BOM set wrong text: Result: %s\n", bufACP);
 
   result = strcmp(bufACP, "TestUTF8WithBOM");
   ok(result == 0, "EM_SETTEXTEX: Test UTF8 with BOM set wrong text: Result: %s\n", bufACP);
 
+  /* Test multibyte character */
+  if (!is_lang_japanese)
+    skip("Skip multibyte character tests on non-Japanese platform\n");
+  else
+  {
+    SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1);
+    setText.flags = ST_SELECTION;
+    setText.codepage = CP_ACP;
+    result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)"abc\x8e\xf0");
+    todo_wine ok(result == 5, "EM_SETTEXTEX incorrectly returned %d, expected 5\n", result);
+    result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)bufACP);
+    ok(result == 5, "WM_GETTEXT incorrectly returned %d, expected 5\n", result);
+    ok(!strcmp(bufACP, "abc\x8e\xf0"),
+       "EM_SETTEXTEX: Test multibyte character set wrong text: Result: %s\n", bufACP);
+
+    setText.flags = ST_DEFAULT;
+    setText.codepage = CP_ACP;
+    result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)"abc\x8e\xf0");
+    ok(result == 1, "EM_SETTEXTEX incorrectly returned %d, expected 1\n", result);
+    result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)bufACP);
+    ok(result == 5, "WM_GETTEXT incorrectly returned %d, expected 5\n", result);
+    ok(!strcmp(bufACP, "abc\x8e\xf0"),
+       "EM_SETTEXTEX: Test multibyte character set wrong text: Result: %s\n", bufACP);
+
+    SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1);
+    setText.flags = ST_SELECTION;
+    setText.codepage = CP_ACP;
+    result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)"{\\rtf abc\x8e\xf0}");
+    todo_wine ok(result == 4, "EM_SETTEXTEX incorrectly returned %d, expected 4\n", result);
+    result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)bufACP);
+    ok(result == 5, "WM_GETTEXT incorrectly returned %d, expected 5\n", result);
+    todo_wine ok(!strcmp(bufACP, "abc\x8e\xf0"),
+                 "EM_SETTEXTEX: Test multibyte character set wrong text: Result: %s\n", bufACP);
+  }
+
   DestroyWindow(hwndRichEdit);
 }
 
   DestroyWindow(hwndRichEdit);
 }
 
@@ -4484,13 +4578,9 @@ static void check_EM_EXSETSEL(HWND hwnd, const struct exsetsel_s *setsel, int id
 
     SendMessageA(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
 
 
     SendMessageA(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
 
-    if (setsel->todo) {
-        todo_wine {
-            ok(start == setsel->expected_getsel_start && end == setsel->expected_getsel_end, "EM_EXSETSEL(%d): expected (%d,%d) actual:(%d,%d)\n", id, setsel->expected_getsel_start, setsel->expected_getsel_end, start, end);
-        }
-    } else {
-        ok(start == setsel->expected_getsel_start && end == setsel->expected_getsel_end, "EM_EXSETSEL(%d): expected (%d,%d) actual:(%d,%d)\n", id, setsel->expected_getsel_start, setsel->expected_getsel_end, start, end);
-    }
+    todo_wine_if (setsel->todo)
+        ok(start == setsel->expected_getsel_start && end == setsel->expected_getsel_end, "EM_EXSETSEL(%d): expected (%d,%d) actual:(%d,%d)\n",
+            id, setsel->expected_getsel_start, setsel->expected_getsel_end, start, end);
 }
 
 static void test_EM_EXSETSEL(void)
 }
 
 static void test_EM_EXSETSEL(void)
@@ -4508,6 +4598,27 @@ static void test_EM_EXSETSEL(void)
         check_EM_EXSETSEL(hwndRichEdit, &exsetsel_tests[i], i);
     }
 
         check_EM_EXSETSEL(hwndRichEdit, &exsetsel_tests[i], i);
     }
 
+    if (!is_lang_japanese)
+        skip("Skip multibyte character tests on non-Japanese platform\n");
+    else
+    {
+        CHARRANGE cr;
+        char bufA[MAX_BUF_LEN] = {0};
+        LRESULT result;
+
+        /* Test with multibyte character */
+        SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk");
+        /*                                                 012345     6  78901 */
+        cr.cpMin = 4, cr.cpMax = 8;
+        result =  SendMessageA(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM)&cr);
+        ok(result == 8, "EM_EXSETSEL return %ld expected 8\n", result);
+        result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, sizeof(bufA), (LPARAM)bufA);
+        ok(!strcmp(bufA, "ef\x8e\xf0g"), "EM_GETSELTEXT return incorrect string\n");
+        SendMessageA(hwndRichEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
+        ok(cr.cpMin == 4, "Selection start incorrectly: %d expected 4\n", cr.cpMin);
+        ok(cr.cpMax == 8, "Selection end incorrectly: %d expected 8\n", cr.cpMax);
+    }
+
     DestroyWindow(hwndRichEdit);
 }
 
     DestroyWindow(hwndRichEdit);
 }
 
@@ -4521,18 +4632,14 @@ static void check_EM_SETSEL(HWND hwnd, const struct exsetsel_s *setsel, int id)
 
     SendMessageA(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
 
 
     SendMessageA(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
 
-    if (setsel->todo) {
-        todo_wine {
-            ok(start == setsel->expected_getsel_start && end == setsel->expected_getsel_end, "EM_SETSEL(%d): expected (%d,%d) actual:(%d,%d)\n", id, setsel->expected_getsel_start, setsel->expected_getsel_end, start, end);
-        }
-    } else {
-        ok(start == setsel->expected_getsel_start && end == setsel->expected_getsel_end, "EM_SETSEL(%d): expected (%d,%d) actual:(%d,%d)\n", id, setsel->expected_getsel_start, setsel->expected_getsel_end, start, end);
-    }
+    todo_wine_if (setsel->todo)
+        ok(start == setsel->expected_getsel_start && end == setsel->expected_getsel_end, "EM_SETSEL(%d): expected (%d,%d) actual:(%d,%d)\n",
+            id, setsel->expected_getsel_start, setsel->expected_getsel_end, start, end);
 }
 
 static void test_EM_SETSEL(void)
 {
 }
 
 static void test_EM_SETSEL(void)
 {
-    char buffA[32];
+    char buffA[32] = {0};
     HWND hwndRichEdit = new_richedit(NULL);
     int i;
     const int num_tests = sizeof(exsetsel_tests)/sizeof(struct exsetsel_s);
     HWND hwndRichEdit = new_richedit(NULL);
     int i;
     const int num_tests = sizeof(exsetsel_tests)/sizeof(struct exsetsel_s);
@@ -4551,6 +4658,25 @@ static void test_EM_SETSEL(void)
     SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffA);
     ok(buffA[0] == 0, "selection text %s\n", buffA);
 
     SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffA);
     ok(buffA[0] == 0, "selection text %s\n", buffA);
 
+    if (!is_lang_japanese)
+        skip("Skip multibyte character tests on non-Japanese platform\n");
+    else
+    {
+        int sel_start, sel_end;
+        LRESULT result;
+
+        /* Test with multibyte character */
+        SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk");
+        /*                                                 012345     6  78901 */
+        result =  SendMessageA(hwndRichEdit, EM_SETSEL, 4, 8);
+        ok(result == 8, "EM_SETSEL return %ld expected 8\n", result);
+        result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, sizeof(buffA), (LPARAM)buffA);
+        ok(!strcmp(buffA, "ef\x8e\xf0g"), "EM_GETSELTEXT return incorrect string\n");
+        result = SendMessageA(hwndRichEdit, EM_GETSEL, (WPARAM)&sel_start, (LPARAM)&sel_end);
+        ok(sel_start == 4, "Selection start incorrectly: %d expected 4\n", sel_start);
+        ok(sel_end == 8, "Selection end incorrectly: %d expected 8\n", sel_end);
+    }
+
     DestroyWindow(hwndRichEdit);
 }
 
     DestroyWindow(hwndRichEdit);
 }
 
@@ -4561,6 +4687,8 @@ static void test_EM_REPLACESEL(int redraw)
     int r;
     GETTEXTEX getText;
     CHARRANGE cr;
     int r;
     GETTEXTEX getText;
     CHARRANGE cr;
+    CHAR rtfstream[] = "{\\rtf1 TestSomeText}";
+    CHAR urtfstream[] = "{\\urtf1 TestSomeText}";
 
     /* sending some text to the window */
     SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"testing selection");
 
     /* sending some text to the window */
     SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"testing selection");
@@ -4833,6 +4961,76 @@ static void test_EM_REPLACESEL(int redraw)
     r = SendMessageA(hwndRichEdit, EM_GETLINECOUNT, 0, 0);
     ok(r == 7, "EM_GETLINECOUNT returned %d, expected 7\n", r);
 
     r = SendMessageA(hwndRichEdit, EM_GETLINECOUNT, 0, 0);
     ok(r == 7, "EM_GETLINECOUNT returned %d, expected 7\n", r);
 
+    /* Test with  multibyte character */
+    if (!is_lang_japanese)
+        skip("Skip multibyte character tests on non-Japanese platform\n");
+    else
+    {
+        SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
+        r = SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"abc\x8e\xf0");
+        todo_wine ok(r == 5, "EM_REPLACESEL returned %d, expected 5\n", r);
+        r = SendMessageA(hwndRichEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
+        ok(r == 0, "EM_EXGETSEL returned %d, expected 0\n", r);
+        ok(cr.cpMin == 4, "EM_EXGETSEL returned cpMin=%d, expected 4\n", cr.cpMin);
+        ok(cr.cpMax == 4, "EM_EXGETSEL returned cpMax=%d, expected 4\n", cr.cpMax);
+        r = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+        ok(!strcmp(buffer, "abc\x8e\xf0"), "WM_GETTEXT returned incorrect string\n");
+        ok(r == 5, "WM_GETTEXT returned %d, expected 5\n", r);
+
+        SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
+        r = SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"{\\rtf abc\x8e\xf0}");
+        todo_wine ok(r == 4, "EM_REPLACESEL returned %d, expected 4\n", r);
+        r = SendMessageA(hwndRichEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
+        ok(r == 0, "EM_EXGETSEL returned %d, expected 0\n", r);
+        todo_wine ok(cr.cpMin == 4, "EM_EXGETSEL returned cpMin=%d, expected 4\n", cr.cpMin);
+        todo_wine ok(cr.cpMax == 4, "EM_EXGETSEL returned cpMax=%d, expected 4\n", cr.cpMax);
+        r = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+        todo_wine ok(!strcmp(buffer, "abc\x8e\xf0"), "WM_GETTEXT returned incorrect string\n");
+        todo_wine ok(r == 5, "WM_GETTEXT returned %d, expected 5\n", r);
+    }
+
+    SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
+    r = SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)rtfstream);
+    todo_wine ok(r == 12, "EM_REPLACESEL returned %d, expected 12\n", r);
+    r = SendMessageA(hwndRichEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
+    ok(0 == r, "EM_EXGETSEL returned %d, expected 0\n", r);
+    todo_wine ok(cr.cpMin == 12, "EM_EXGETSEL returned cpMin=%d, expected 12\n", cr.cpMin);
+    todo_wine ok(cr.cpMax == 12, "EM_EXGETSEL returned cpMax=%d, expected 12\n", cr.cpMax);
+    SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+    todo_wine ok(!strcmp(buffer, "TestSomeText"), "WM_GETTEXT returned incorrect string\n");
+
+    SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
+    r = SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)urtfstream);
+    todo_wine ok(r == 12, "EM_REPLACESEL returned %d, expected 12\n", r);
+    r = SendMessageA(hwndRichEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
+    ok(0 == r, "EM_EXGETSEL returned %d, expected 0\n", r);
+    todo_wine ok(cr.cpMin == 12, "EM_EXGETSEL returned cpMin=%d, expected 12\n", cr.cpMin);
+    todo_wine ok(cr.cpMax == 12, "EM_EXGETSEL returned cpMax=%d, expected 12\n", cr.cpMax);
+    SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+    todo_wine ok(!strcmp(buffer, "TestSomeText"), "WM_GETTEXT returned incorrect string\n");
+
+    SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"Wine");
+    SendMessageA(hwndRichEdit, EM_SETSEL, 1, 2);
+    todo_wine r = SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)rtfstream);
+    todo_wine ok(r == 12, "EM_REPLACESEL returned %d, expected 12\n", r);
+    r = SendMessageA(hwndRichEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
+    ok(0 == r, "EM_EXGETSEL returned %d, expected 0\n", r);
+    todo_wine ok(cr.cpMin == 13, "EM_EXGETSEL returned cpMin=%d, expected 13\n", cr.cpMin);
+    todo_wine ok(cr.cpMax == 13, "EM_EXGETSEL returned cpMax=%d, expected 13\n", cr.cpMax);
+    SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+    todo_wine ok(!strcmp(buffer, "WTestSomeTextne"), "WM_GETTEXT returned incorrect string\n");
+
+    SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"{\\rtf1 Wine}");
+    SendMessageA(hwndRichEdit, EM_SETSEL, 1, 2);
+    todo_wine r = SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)rtfstream);
+    todo_wine ok(r == 12, "EM_REPLACESEL returned %d, expected 12\n", r);
+    r = SendMessageA(hwndRichEdit, EM_EXGETSEL, 0, (LPARAM)&cr);
+    ok(0 == r, "EM_EXGETSEL returned %d, expected 0\n", r);
+    todo_wine ok(cr.cpMin == 13, "EM_EXGETSEL returned cpMin=%d, expected 13\n", cr.cpMin);
+    todo_wine ok(cr.cpMax == 13, "EM_EXGETSEL returned cpMax=%d, expected 13\n", cr.cpMax);
+    SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+    todo_wine ok(!strcmp(buffer, "WTestSomeTextne"), "WM_GETTEXT returned incorrect string\n");
+
     if (!redraw)
         /* This is needed to avoid interferring with keybd_event calls
          * on other tests that simulate keyboard events. */
     if (!redraw)
         /* This is needed to avoid interferring with keybd_event calls
          * on other tests that simulate keyboard events. */
@@ -7620,15 +7818,10 @@ static void test_EM_FINDWORDBREAK_W(void)
         wbuf[1] = 0;
         SendMessageW(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)wbuf);
         result = SendMessageW(hwndRichEdit, EM_FINDWORDBREAK, WB_ISDELIMITER,0);
         wbuf[1] = 0;
         SendMessageW(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)wbuf);
         result = SendMessageW(hwndRichEdit, EM_FINDWORDBREAK, WB_ISDELIMITER,0);
-        if (wbuf[0] == 0x20 || wbuf[0] == 0xf020)
-            todo_wine
-                ok(result == delimiter_tests[i].isdelimiter,
-                   "wanted ISDELIMITER_W(0x%x) %d, got %d\n",
-                   delimiter_tests[i].c, delimiter_tests[i].isdelimiter,result);
-        else
+        todo_wine_if (wbuf[0] == 0x20 || wbuf[0] == 0xf020)
             ok(result == delimiter_tests[i].isdelimiter,
             ok(result == delimiter_tests[i].isdelimiter,
-               "wanted ISDELIMITER_W(0x%x) %d, got %d\n",
-               delimiter_tests[i].c, delimiter_tests[i].isdelimiter, result);
+                "wanted ISDELIMITER_W(0x%x) %d, got %d\n",
+                delimiter_tests[i].c, delimiter_tests[i].isdelimiter, result);
     }
     DestroyWindow(hwndRichEdit);
 }
     }
     DestroyWindow(hwndRichEdit);
 }
@@ -7658,12 +7851,7 @@ static void test_EM_FINDWORDBREAK_A(void)
         buf[1] = 0;
         SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)buf);
         result = SendMessageA(hwndRichEdit, EM_FINDWORDBREAK, WB_ISDELIMITER, 0);
         buf[1] = 0;
         SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)buf);
         result = SendMessageA(hwndRichEdit, EM_FINDWORDBREAK, WB_ISDELIMITER, 0);
-        if (buf[0] == 0x20)
-            todo_wine
-                ok(result == delimiter_tests[i].isdelimiter,
-                   "wanted ISDELIMITER_A(0x%x) %d, got %d\n",
-                   delimiter_tests[i].c, delimiter_tests[i].isdelimiter,result);
-        else
+        todo_wine_if (buf[0] == 0x20)
             ok(result == delimiter_tests[i].isdelimiter,
                "wanted ISDELIMITER_A(0x%x) %d, got %d\n",
                delimiter_tests[i].c, delimiter_tests[i].isdelimiter, result);
             ok(result == delimiter_tests[i].isdelimiter,
                "wanted ISDELIMITER_A(0x%x) %d, got %d\n",
                delimiter_tests[i].c, delimiter_tests[i].isdelimiter, result);
@@ -8035,6 +8223,37 @@ static void test_alignment_style(void)
     DestroyWindow(richedit);
 }
 
     DestroyWindow(richedit);
 }
 
+static void test_WM_GETTEXTLENGTH(void)
+{
+    HWND hwndRichEdit = new_richedit(NULL);
+    static const char text1[] = "aaa\r\nbbb\r\nccc\r\nddd\r\neee";
+    static const char text2[] = "aaa\r\nbbb\r\nccc\r\nddd\r\neee\r\n";
+    static const char text3[] = "abcdef\x8e\xf0";
+    int result;
+
+    SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text1);
+    result = SendMessageA(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
+    ok(result == lstrlenA(text1), "WM_GETTEXTLENGTH returned %d, expected %d\n",
+       result, lstrlenA(text1));
+
+    SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text2);
+    result = SendMessageA(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
+    ok(result == lstrlenA(text2), "WM_GETTEXTLENGTH returned %d, expected %d\n",
+       result, lstrlenA(text2));
+
+    /* Test with multibyte character */
+    if (!is_lang_japanese)
+        skip("Skip multibyte character tests on non-Japanese platform\n");
+    else
+    {
+        SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text3);
+        result = SendMessageA(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0);
+        todo_wine ok(result == 8, "WM_GETTEXTLENGTH returned %d, expected 8\n", result);
+    }
+
+    DestroyWindow(hwndRichEdit);
+}
+
 START_TEST( editor )
 {
   BOOL ret;
 START_TEST( editor )
 {
   BOOL ret;
@@ -8042,6 +8261,7 @@ START_TEST( editor )
    * RICHED20.DLL, so the linker doesn't actually link to it. */
   hmoduleRichEdit = LoadLibraryA("riched20.dll");
   ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
    * RICHED20.DLL, so the linker doesn't actually link to it. */
   hmoduleRichEdit = LoadLibraryA("riched20.dll");
   ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
+  is_lang_japanese = (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_JAPANESE);
 
   test_WM_CHAR();
   test_EM_FINDTEXT(FALSE);
 
   test_WM_CHAR();
   test_EM_FINDTEXT(FALSE);
@@ -8078,6 +8298,7 @@ START_TEST( editor )
   test_EM_FORMATRANGE();
   test_unicode_conversions();
   test_EM_GETTEXTLENGTHEX();
   test_EM_FORMATRANGE();
   test_unicode_conversions();
   test_EM_GETTEXTLENGTHEX();
+  test_WM_GETTEXTLENGTH();
   test_EM_REPLACESEL(1);
   test_EM_REPLACESEL(0);
   test_WM_NOTIFY();
   test_EM_REPLACESEL(1);
   test_EM_REPLACESEL(0);
   test_WM_NOTIFY();