[RICHED20_WINETEST] Sync with Wine Staging 4.18. CORE-16441
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 23 Nov 2019 11:11:20 +0000 (12:11 +0100)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 23 Nov 2019 11:11:20 +0000 (12:11 +0100)
modules/rostests/winetests/riched20/editor.c
modules/rostests/winetests/riched20/richole.c
modules/rostests/winetests/riched20/txtsrv.c

index 6712ab1..28f9849 100644 (file)
@@ -340,14 +340,12 @@ static void test_EM_FINDTEXT(BOOL unicode)
        hwndRichEdit = new_richedit(NULL);
 
   /* Empty rich edit control */
-  run_tests_EM_FINDTEXT(hwndRichEdit, "1", find_tests,
-      sizeof(find_tests)/sizeof(struct find_s), unicode);
+  run_tests_EM_FINDTEXT(hwndRichEdit, "1", find_tests, ARRAY_SIZE(find_tests), unicode);
 
   SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)haystack);
 
   /* Haystack text */
-  run_tests_EM_FINDTEXT(hwndRichEdit, "2", find_tests2,
-      sizeof(find_tests2)/sizeof(struct find_s), unicode);
+  run_tests_EM_FINDTEXT(hwndRichEdit, "2", find_tests2, ARRAY_SIZE(find_tests2), unicode);
 
   /* Setting a format on an arbitrary range should have no effect in search
      results. This tests correct offset reporting across runs. */
@@ -359,8 +357,7 @@ static void test_EM_FINDTEXT(BOOL unicode)
   SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
 
   /* Haystack text, again */
-  run_tests_EM_FINDTEXT(hwndRichEdit, "2-bis", find_tests2,
-      sizeof(find_tests2)/sizeof(struct find_s), unicode);
+  run_tests_EM_FINDTEXT(hwndRichEdit, "2-bis", find_tests2, ARRAY_SIZE(find_tests2), unicode);
 
   /* Yet another range */
   cf2.dwMask = CFM_BOLD | cf2.dwMask;
@@ -369,8 +366,7 @@ static void test_EM_FINDTEXT(BOOL unicode)
   SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
 
   /* Haystack text, again */
-  run_tests_EM_FINDTEXT(hwndRichEdit, "2-bisbis", find_tests2,
-      sizeof(find_tests2)/sizeof(struct find_s), unicode);
+  run_tests_EM_FINDTEXT(hwndRichEdit, "2-bisbis", find_tests2, ARRAY_SIZE(find_tests2), unicode);
 
   DestroyWindow(hwndRichEdit);
 }
@@ -404,7 +400,7 @@ static void test_EM_GETLINE(void)
   SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text);
 
   memset(origdest, 0xBB, nBuf);
-  for (i = 0; i < sizeof(gl)/sizeof(struct getline_s); i++)
+  for (i = 0; i < ARRAY_SIZE(gl); i++)
   {
     int nCopied;
     int expected_nCopied = min(gl[i].buffer_len, strlen(gl[i].text));
@@ -509,7 +505,7 @@ static void test_EM_LINELENGTH(void)
            {15, 4}, /* Line 3: |wine */
     };
     SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text1);
-    for (i = 0; i < sizeof(offset_test1)/sizeof(offset_test1[0]); i++) {
+    for (i = 0; i < ARRAY_SIZE(offset_test1); 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]);
@@ -755,6 +751,8 @@ static void test_EM_SETCHARFORMAT(void)
   HWND hwndRichEdit = new_richedit(NULL);
   CHARFORMAT2A cf2;
   CHARFORMAT2W cfW;
+  CHARFORMATA cf1a;
+  CHARFORMATW cf1w;
   int rc = 0;
   int tested_effects[] = {
     CFE_BOLD,
@@ -1342,6 +1340,23 @@ static void test_EM_SETCHARFORMAT(void)
   ok(cf2.dwEffects & CFE_UNDERLINE, "got %08x\n", cf2.dwEffects);
   ok(cf2.bUnderlineType == CFU_UNDERLINEDOUBLE, "got %x\n", cf2.bUnderlineType);
 
+  /* Check setting CFM_ALL2/CFM_EFFECTS2 in CHARFORMAT(A/W). */
+  memset(&cf1a, 0, sizeof(CHARFORMATA));
+  memset(&cf1w, 0, sizeof(CHARFORMATW));
+  cf1a.cbSize = sizeof(CHARFORMATA);
+  cf1w.cbSize = sizeof(CHARFORMATW);
+  cf1a.dwMask = cf1w.dwMask = CFM_ALL2;
+  cf1a.dwEffects = cf1w.dwEffects = CFM_EFFECTS2;
+  SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf1a);
+  SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf1a);
+  /* flags only valid for CHARFORMAT2 should be masked out */
+  ok((cf1a.dwMask & (CFM_ALL2 & ~CFM_ALL)) == 0, "flags were not masked out\n");
+  ok((cf1a.dwEffects & (CFM_EFFECTS2 & ~CFM_EFFECTS)) == 0, "flags were not masked out\n");
+  SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf1w);
+  SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf1w);
+  ok((cf1w.dwMask & (CFM_ALL2 & ~CFM_ALL)) == 0, "flags were not masked out\n");
+  ok((cf1w.dwEffects & (CFM_EFFECTS2 & ~CFM_EFFECTS)) == 0, "flags were not masked out\n");
+
   DestroyWindow(hwndRichEdit);
 }
 
@@ -2049,7 +2064,7 @@ static void test_EM_AUTOURLDETECT(void)
   urlRet=SendMessageA(hwndRichEdit, EM_AUTOURLDETECT, (WPARAM)"h", (LPARAM)"h");
   ok(urlRet==E_INVALIDARG, "Bad wParam2: urlRet is: %d\n", urlRet);
   /* for each url, check the text to see if CFE_LINK effect is present */
-  for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
+  for (i = 0; i < ARRAY_SIZE(urls); i++) {
 
     SendMessageA(hwndRichEdit, EM_AUTOURLDETECT, FALSE, 0);
     SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)urls[i].text);
@@ -2063,10 +2078,10 @@ static void test_EM_AUTOURLDETECT(void)
   DestroyWindow(hwndRichEdit);
 
   /* Test detection of URLs within normal text - WM_SETTEXT case. */
-  for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
+  for (i = 0; i < ARRAY_SIZE(urls); i++) {
     hwndRichEdit = new_richedit(parent);
 
-    for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
       char * at_pos;
       int at_offset;
       int end_offset;
@@ -2117,7 +2132,7 @@ static void test_EM_AUTOURLDETECT(void)
       }
     }
 
-    for (j = 0; j < sizeof(templates_non_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_non_delim); j++) {
       char * at_pos;
       int at_offset;
       int end_offset;
@@ -2158,7 +2173,7 @@ static void test_EM_AUTOURLDETECT(void)
       }
     }
 
-    for (j = 0; j < sizeof(templates_xten_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_xten_delim); j++) {
       char * at_pos;
       int at_offset;
       int end_offset;
@@ -2213,7 +2228,7 @@ static void test_EM_AUTOURLDETECT(void)
       }
     }
 
-    for (j = 0; j < sizeof(templates_neutral_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_neutral_delim); j++) {
       char * at_pos, * end_pos;
       int at_offset;
       int end_offset;
@@ -2421,7 +2436,7 @@ static void test_EM_AUTOURLDETECT(void)
      */
 
     /* Set entire text in one go, like WM_SETTEXT */
-    for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
       char * at_pos;
       int at_offset;
       int end_offset;
@@ -2476,7 +2491,7 @@ static void test_EM_AUTOURLDETECT(void)
     }
 
     /* Set selection with X to the URL */
-    for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
       char * at_pos;
       int at_offset;
       int end_offset;
@@ -2530,7 +2545,7 @@ static void test_EM_AUTOURLDETECT(void)
     }
 
     /* Set selection with X to the first character of the URL, then the rest */
-    for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
       char * at_pos;
       int at_offset;
       int end_offset;
@@ -2598,7 +2613,7 @@ static void test_EM_AUTOURLDETECT(void)
     hwndRichEdit = new_richedit(parent);
 
     /* Set selection with X to the URL */
-    for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
       char * at_pos;
       int at_offset;
       int end_offset;
@@ -2649,7 +2664,7 @@ static void test_EM_AUTOURLDETECT(void)
     }
 
     /* Set selection with X to the first character of the URL, then the rest */
-    for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
+    for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
       char * at_pos;
       int at_offset;
       int end_offset;
@@ -4933,7 +4948,7 @@ static void test_EM_EXSETSEL(void)
 {
     HWND hwndRichEdit = new_richedit(NULL);
     int i;
-    const int num_tests = sizeof(exsetsel_tests)/sizeof(struct exsetsel_s);
+    const int num_tests = ARRAY_SIZE(exsetsel_tests);
 
     /* sending some text to the window */
     SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"testing selection");
@@ -4955,7 +4970,7 @@ static void test_EM_EXSETSEL(void)
         /* Test with multibyte character */
         SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk");
         /*                                                 012345     6  78901 */
-        cr.cpMin = 4, cr.cpMax = 8;
+        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);
@@ -4988,7 +5003,7 @@ static void test_EM_SETSEL(void)
     char buffA[32] = {0};
     HWND hwndRichEdit = new_richedit(NULL);
     int i;
-    const int num_tests = sizeof(exsetsel_tests)/sizeof(struct exsetsel_s);
+    const int num_tests = ARRAY_SIZE(exsetsel_tests);
 
     /* sending some text to the window */
     SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"testing selection");
@@ -5623,7 +5638,7 @@ static void test_EM_FORMATRANGE(void)
 
   SendMessageA(hwndRichEdit, EM_FORMATRANGE, FALSE, 0);
 
-  for (i = 0; i < sizeof(fmtstrings)/sizeof(fmtstrings[0]); i++)
+  for (i = 0; i < ARRAY_SIZE(fmtstrings); i++)
   {
     GETTEXTLENGTHEX gtl;
     SIZE stringsize;
@@ -5758,6 +5773,30 @@ static DWORD CALLBACK test_EM_STREAMIN_esCallback_UTF8Split(DWORD_PTR dwCookie,
     return 0;
 }
 
+static DWORD CALLBACK test_EM_STREAMIN_null_bytes(DWORD_PTR cookie, BYTE *buf, LONG size, LONG *written)
+{
+    DWORD *phase = (DWORD *)cookie;
+
+    if (*phase == 0)
+    {
+        static const char first[] = "{\\rtf1\\ansi{Th\0is";
+        *written = sizeof(first);
+        memcpy(buf, first, *written);
+    }
+    else if (*phase == 1)
+    {
+        static const char second[] = " is a test}}";
+        *written = sizeof(second);
+        memcpy(buf, second, *written);
+    }
+    else
+        *written = 0;
+
+    ++*phase;
+
+    return 0;
+}
+
 struct StringWithLength {
     int length;
     char *buffer;
@@ -5831,7 +5870,7 @@ static void test_EM_STREAMIN(void)
   };
 
   const WCHAR streamText5[] = { 'T', 'e', 's', 't', 'S', 'o', 'm', 'e', 'T', 'e', 'x', 't' };
-  int length5 = sizeof(streamText5) / sizeof(WCHAR);
+  int length5 = ARRAY_SIZE(streamText5);
   struct StringWithLength cookieForStream5 = {
       sizeof(streamText5),
       (char *)streamText5,
@@ -6044,6 +6083,17 @@ static void test_EM_STREAMIN(void)
   result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
   ok (!strcmp(buffer, "line1"),
       "EM_STREAMIN: Unexpected text '%s'\n", buffer);
+
+  /* Test 0-bytes inside text */
+  hwndRichEdit = new_richedit_with_style(NULL, 0);
+  phase = 0;
+  es.dwCookie = (DWORD_PTR)&phase;
+  es.dwError = 0;
+  es.pfnCallback = test_EM_STREAMIN_null_bytes;
+  result = SendMessageA(hwndRichEdit, EM_STREAMIN, SF_RTF, (LPARAM)&es);
+  ok(result == 16, "got %ld, expected %d\n", result, 16);
+  result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
+  ok (!strcmp(buffer, "Th is  is a test"), "EM_STREAMIN: Unexpected text '%s'\n", buffer);
 }
 
 static void test_EM_StreamIn_Undo(void)
@@ -6868,7 +6918,7 @@ static void test_EN_LINK(void)
     GetCursorPos(&orig_cursor_pos);
     SetCursorPos(0, 0);
 
-    for (i = 0; i < sizeof(link_notify_tests)/sizeof(link_notify_tests[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(link_notify_tests); i++)
     {
         link_notify_test("cursor position simulated", i, hwnd, parent,
                          link_notify_tests[i].msg, link_notify_tests[i].wParam, link_notify_tests[i].lParam,
@@ -6878,7 +6928,7 @@ static void test_EN_LINK(void)
     ClientToScreen(hwnd, &cursor_screen_pos);
     SetCursorPos(cursor_screen_pos.x, cursor_screen_pos.y);
 
-    for (i = 0; i < sizeof(link_notify_tests)/sizeof(link_notify_tests[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(link_notify_tests); i++)
     {
         link_notify_test("cursor position set", i, hwnd, parent,
                          link_notify_tests[i].msg, link_notify_tests[i].wParam, link_notify_tests[i].lParam,
@@ -8178,7 +8228,7 @@ static void test_EM_FINDWORDBREAK_W(void)
     int i;
     HWND hwndRichEdit = new_richeditW(NULL);
     ok(IsWindowUnicode(hwndRichEdit), "window should be unicode\n");
-    for (i = 0; i < sizeof(delimiter_tests)/sizeof(delimiter_tests[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(delimiter_tests); i++)
     {
         WCHAR wbuf[2];
         int result;
@@ -8212,7 +8262,7 @@ static void test_EM_FINDWORDBREAK_A(void)
     HWND hwndRichEdit = new_richedit(NULL);
 
     ok(!IsWindowUnicode(hwndRichEdit), "window should not be unicode\n");
-    for (i = 0; i < sizeof(delimiter_tests)/sizeof(delimiter_tests[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(delimiter_tests); i++)
     {
         int result;
         char buf[2];
@@ -8228,12 +8278,21 @@ static void test_EM_FINDWORDBREAK_A(void)
     DestroyWindow(hwndRichEdit);
 }
 
+static void format_test_result(char *target, const char *src)
+{
+    int i;
+    for (i = 0; i < strlen(src); i++)
+        sprintf(target + 2*i, "%02x", src[i] & 0xFF);
+    target[2*i] = 0;
+}
+
 /*
  * This test attempts to show the effect of enter on a richedit
  * control v1.0 inserts CRLF whereas for higher versions it only
  * inserts CR. If shows that EM_GETTEXTEX with GT_USECRLF == WM_GETTEXT
  * and also shows that GT_USECRLF has no effect in richedit 1.0, but
  * does for higher. The same test is cloned in riched32 and riched20.
+ * Also shows the difference between WM_CHAR/WM_KEYDOWN in v1.0 and higher versions
  */
 static void test_enter(void)
 {
@@ -8254,15 +8313,14 @@ static void test_enter(void)
   char expectedbuf[1024];
   char resultbuf[1024];
   HWND hwndRichEdit = new_richedit(NULL);
-  UINT i,j;
-
-  for (i = 0; i < sizeof(testenteritems)/sizeof(testenteritems[0]); i++) {
-
-    char buf[1024] = {0};
-    LRESULT result;
-    GETTEXTEX getText;
-    const char *expected;
+  UINT i;
+  char buf[1024] = {0};
+  GETTEXTEX getText = {sizeof(buf)};
+  LRESULT result;
+  const char *expected;
 
+  for (i = 0; i < ARRAY_SIZE(testenteritems); i++)
+  {
     /* Set the text to the initial text */
     result = SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)testenteritems[i].initialtext);
     ok (result == 1, "[%d] WM_SETTEXT returned %ld instead of 1\n", i, result);
@@ -8276,12 +8334,8 @@ static void test_enter(void)
     result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buf);
     expected = testenteritems[i].expectedwmtext;
 
-    resultbuf[0]=0x00;
-    for (j = 0; j < (UINT)result; j++)
-      sprintf(resultbuf+strlen(resultbuf), "%02x", buf[j] & 0xFF);
-    expectedbuf[0] = '\0';
-    for (j = 0; j < strlen(expected); j++)
-      sprintf(expectedbuf+strlen(expectedbuf), "%02x", expected[j] & 0xFF);
+    format_test_result(resultbuf, buf);
+    format_test_result(expectedbuf, expected);
 
     result = strcmp(expected, buf);
     ok (result == 0,
@@ -8289,21 +8343,14 @@ static void test_enter(void)
         i, resultbuf, expectedbuf);
 
     /* 2. Retrieve with EM_GETTEXTEX, GT_DEFAULT */
-    getText.cb = sizeof(buf);
     getText.flags = GT_DEFAULT;
-    getText.codepage      = CP_ACP;
-    getText.lpDefaultChar = NULL;
-    getText.lpUsedDefChar = NULL;
+    getText.codepage = CP_ACP;
     buf[0] = 0x00;
     result = SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
     expected = testenteritems[i].expectedemtext;
 
-    resultbuf[0]=0x00;
-    for (j = 0; j < (UINT)result; j++)
-      sprintf(resultbuf+strlen(resultbuf), "%02x", buf[j] & 0xFF);
-    expectedbuf[0] = '\0';
-    for (j = 0; j < strlen(expected); j++)
-      sprintf(expectedbuf+strlen(expectedbuf), "%02x", expected[j] & 0xFF);
+    format_test_result(resultbuf, buf);
+    format_test_result(expectedbuf, expected);
 
     result = strcmp(expected, buf);
     ok (result == 0,
@@ -8311,21 +8358,14 @@ static void test_enter(void)
         i, resultbuf, expectedbuf);
 
     /* 3. Retrieve with EM_GETTEXTEX, GT_USECRLF */
-    getText.cb = sizeof(buf);
     getText.flags = GT_USECRLF;
-    getText.codepage      = CP_ACP;
-    getText.lpDefaultChar = NULL;
-    getText.lpUsedDefChar = NULL;
+    getText.codepage = CP_ACP;
     buf[0] = 0x00;
     result = SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
     expected = testenteritems[i].expectedemtextcrlf;
 
-    resultbuf[0]=0x00;
-    for (j = 0; j < (UINT)result; j++)
-      sprintf(resultbuf+strlen(resultbuf), "%02x", buf[j] & 0xFF);
-    expectedbuf[0] = '\0';
-    for (j = 0; j < strlen(expected); j++)
-      sprintf(expectedbuf+strlen(expectedbuf), "%02x", expected[j] & 0xFF);
+    format_test_result(resultbuf, buf);
+    format_test_result(expectedbuf, expected);
 
     result = strcmp(expected, buf);
     ok (result == 0,
@@ -8333,6 +8373,34 @@ static void test_enter(void)
         i, resultbuf, expectedbuf);
   }
 
+  /* Show that WM_CHAR is handled differently from WM_KEYDOWN */
+  getText.flags    = GT_DEFAULT;
+  getText.codepage = CP_ACP;
+
+  result = SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"");
+  ok (result == 1, "[%d] WM_SETTEXT returned %ld instead of 1\n", i, result);
+  SendMessageW(hwndRichEdit, WM_CHAR, 'T', 0);
+  SendMessageW(hwndRichEdit, WM_KEYDOWN, VK_RETURN, 0);
+
+  result = SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
+  ok(result == 2, "Got %d\n", (int)result);
+  format_test_result(resultbuf, buf);
+  format_test_result(expectedbuf, "T\r");
+  result = strcmp(resultbuf, expectedbuf);
+  ok (result == 0, "[%d] EM_GETTEXTEX, GT_DEFAULT unexpected '%s', expected '%s'\n", i, resultbuf, expectedbuf);
+
+  result = SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"");
+  ok (result == 1, "[%d] WM_SETTEXT returned %ld instead of 1\n", i, result);
+  SendMessageW(hwndRichEdit, WM_CHAR, 'T', 0);
+  SendMessageW(hwndRichEdit, WM_CHAR, '\r', 0);
+
+  result = SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
+  ok(result == 1, "Got %d\n", (int)result);
+  format_test_result(resultbuf, buf);
+  format_test_result(expectedbuf, "T");
+  result = strcmp(resultbuf, expectedbuf);
+  ok (result == 0, "[%d] EM_GETTEXTEX, GT_DEFAULT unexpected '%s', expected '%s'\n", i, resultbuf, expectedbuf);
+
   DestroyWindow(hwndRichEdit);
 }
 
@@ -8538,7 +8606,7 @@ static void test_alignment_style(void)
     EDITSTREAM es;
     int i;
 
-    for (i = 0; i < sizeof(align_style) / sizeof(align_style[0]); i++)
+    for (i = 0; i < ARRAY_SIZE(align_style); i++)
     {
         DWORD dwStyle, new_align;
 
@@ -8646,8 +8714,8 @@ static void test_rtf(void)
     result = SendMessageA( edit, EM_STREAMIN, SF_RTF, (LPARAM)&es );
     ok( result == 11, "got %ld\n", result );
 
-    result = SendMessageW( edit, WM_GETTEXT, sizeof(buf)/sizeof(buf[0]), (LPARAM)buf );
-    ok( result == sizeof(expect_specials)/sizeof(expect_specials[0]), "got %ld\n", result );
+    result = SendMessageW( edit, WM_GETTEXT, ARRAY_SIZE(buf), (LPARAM)buf );
+    ok( result == ARRAY_SIZE(expect_specials), "got %ld\n", result );
     ok( !memcmp( buf, expect_specials, sizeof(expect_specials) ), "got %s\n", wine_dbgstr_w(buf) );
 
     /* Show that \rtlpar propagates to the second paragraph and is
index 617d1f9..492bdc3 100644 (file)
@@ -113,10 +113,36 @@ static ULONG get_refcount(IUnknown *iface)
   return IUnknown_Release(iface);
 }
 
+#define CHECK_TYPEINFO(disp,expected_riid) _check_typeinfo((IDispatch *)disp, expected_riid, __LINE__)
+static void _check_typeinfo(IDispatch* disp, REFIID expected_riid, int line)
+{
+    ITypeInfo *typeinfo;
+    TYPEATTR *typeattr;
+    UINT count;
+    HRESULT hr;
+
+    count = 10;
+    hr = IDispatch_GetTypeInfoCount(disp, &count);
+    ok_(__FILE__,line)(hr == S_OK, "IDispatch_GetTypeInfoCount failed: 0x%08x.\n", hr);
+    ok_(__FILE__,line)(count == 1, "got wrong count: %u.\n", count);
+
+    hr = IDispatch_GetTypeInfo(disp, 0, LOCALE_SYSTEM_DEFAULT, &typeinfo);
+    ok_(__FILE__,line)(hr == S_OK, "IDispatch_GetTypeInfo failed: 0x%08x.\n", hr);
+
+    hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
+    ok_(__FILE__,line)(hr == S_OK, "ITypeInfo_GetTypeAttr failed: 0x%08x.\n", hr);
+    ok_(__FILE__,line)(IsEqualGUID(&typeattr->guid, expected_riid),
+                       "Unexpected type guid: %s.\n", wine_dbgstr_guid(&typeattr->guid));
+
+    ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
+    ITypeInfo_Release(typeinfo);
+}
+
 static void test_Interfaces(void)
 {
   IRichEditOle *reOle = NULL, *reOle1 = NULL;
   ITextDocument *txtDoc = NULL;
+  ITextDocument2Old *txtDoc2Old = NULL;
   ITextSelection *txtSel = NULL, *txtSel2;
   IUnknown *punk;
   HRESULT hres;
@@ -144,6 +170,7 @@ static void test_Interfaces(void)
                                  (void **) &txtDoc);
   ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
   ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
+  CHECK_TYPEINFO(txtDoc, &IID_ITextDocument);
 
   hres = ITextDocument_GetSelection(txtDoc, NULL);
   ok(hres == E_INVALIDARG, "ITextDocument_GetSelection: 0x%x\n", hres);
@@ -195,6 +222,16 @@ static void test_Interfaces(void)
   hres = IRichEditOle_QueryInterface(reOle, &IID_IOleInPlaceSite, (void **) &punk);
   ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
 
+  hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument2Old, (void **)&txtDoc2Old);
+  ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
+  ok(txtDoc2Old != NULL, "IRichEditOle_QueryInterface\n");
+  ok((ITextDocument *)txtDoc2Old == txtDoc, "interface pointer isn't equal.\n");
+  EXPECT_REF(txtDoc2Old, 5);
+  EXPECT_REF(reOle, 5);
+  CHECK_TYPEINFO(txtDoc2Old, &IID_ITextDocument);
+
+  ITextDocument2Old_Release(txtDoc2Old);
+
   ITextDocument_Release(txtDoc);
   IRichEditOle_Release(reOle);
   refcount = IRichEditOle_Release(reOle);
@@ -207,6 +244,19 @@ static void test_Interfaces(void)
   ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
 
   ITextSelection_Release(txtSel);
+
+  w = new_richedit(NULL);
+  res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
+  ok(res, "SendMessage\n");
+  ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
+
+  hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument2Old, (void **)&txtDoc2Old);
+  ok(hres == S_OK, "IRichEditOle_QueryInterface failed: 0x%08x.\n", hres);
+  ok(txtDoc2Old != NULL, "IRichEditOle_QueryInterface\n");
+  CHECK_TYPEINFO(txtDoc2Old, &IID_ITextDocument);
+  ITextDocument2Old_Release(txtDoc2Old);
+  IRichEditOle_Release(reOle);
+  DestroyWindow(w);
 }
 
 static void test_ITextDocument_Open(void)
@@ -247,8 +297,8 @@ static void test_ITextDocument_Open(void)
       tomReadOnly|tomShareDenyWrite, tomReadOnly|tomShareDenyRead
     };
 
-  int tomNumSingle =  sizeof(tomConstantsSingle)/sizeof(tomConstantsSingle[0]);
-  int tomNumMulti = sizeof(tomConstantsMulti)/sizeof(tomConstantsMulti[0]);
+  int tomNumSingle =  ARRAY_SIZE(tomConstantsSingle);
+  int tomNumMulti = ARRAY_SIZE(tomConstantsMulti);
   int i;
 
   V_VT(&testfile) = VT_BSTR;
@@ -481,21 +531,21 @@ static void test_GetText(void)
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
 
   /* ITextSelection */
-  first = 0, lim = 4;
+  first = 0; lim = 4;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_GetText(txtSel, &bstr);
   ok(hres == S_OK, "ITextSelection_GetText\n");
   ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
   SysFreeString(bstr);
 
-  first = 4, lim = 0;
+  first = 4; lim = 0;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_GetText(txtSel, &bstr);
   ok(hres == S_OK, "ITextSelection_GetText\n");
   ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
   SysFreeString(bstr);
 
-  first = 1, lim = 1;
+  first = 1; lim = 1;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_GetText(txtSel, &bstr);
   ok(hres == S_OK, "ITextSelection_GetText\n");
@@ -507,35 +557,35 @@ static void test_GetText(void)
       ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
     }
 
-  first = 8, lim = 12;
+  first = 8; lim = 12;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_GetText(txtSel, &bstr);
   ok(hres == S_OK, "ITextSelection_GetText\n");
   ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
   SysFreeString(bstr);
 
-  first = 8, lim = 13;
+  first = 8; lim = 13;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_GetText(txtSel, &bstr);
   ok(hres == S_OK, "ITextSelection_GetText\n");
   ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
   SysFreeString(bstr);
 
-  first = 12, lim = 13;
+  first = 12; lim = 13;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_GetText(txtSel, &bstr);
   ok(hres == S_OK, "ITextSelection_GetText\n");
   ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
   SysFreeString(bstr);
 
-  first = 0, lim = -1;
+  first = 0; lim = -1;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_GetText(txtSel, &bstr);
   ok(hres == S_OK, "ITextSelection_GetText\n");
   ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
   SysFreeString(bstr);
 
-  first = -1, lim = 9;
+  first = -1; lim = 9;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_GetText(txtSel, &bstr);
   ok(hres == S_OK, "ITextSelection_GetText\n");
@@ -707,7 +757,7 @@ static void test_ITextRange_GetChar(void)
   ITextRange_Release(txtRge);
   release_interfaces(&w, &reOle, &txtDoc, NULL);
 
-  first = 0, lim = 0;
+  first = 0; lim = 0;
   create_interfaces(&w, &reOle, &txtDoc, NULL);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
@@ -719,7 +769,7 @@ static void test_ITextRange_GetChar(void)
   ITextRange_Release(txtRge);
   release_interfaces(&w, &reOle, &txtDoc, NULL);
 
-  first = 12, lim = 12;
+  first = 12; lim = 12;
   create_interfaces(&w, &reOle, &txtDoc, NULL);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
@@ -731,7 +781,7 @@ static void test_ITextRange_GetChar(void)
   ITextRange_Release(txtRge);
   release_interfaces(&w, &reOle, &txtDoc, NULL);
 
-  first = 13, lim = 13;
+  first = 13; lim = 13;
   create_interfaces(&w, &reOle, &txtDoc, NULL);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
@@ -745,7 +795,7 @@ static void test_ITextRange_GetChar(void)
 
   create_interfaces(&w, &reOle, &txtDoc, NULL);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-  first = 12, lim = 12;
+  first = 12; lim = 12;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
   hres = ITextRange_GetChar(txtRge, NULL);
@@ -803,15 +853,19 @@ static void test_ITextRange_ScrollIntoView(void)
 
   /* Scroll to the top. */
   check_range(w, txtDoc, 0, 1, tomStart, 0);
+  check_range(w, txtDoc, 0, 1, tomEnd, 0);
 
   /* Scroll to the bottom. */
   check_range(w, txtDoc, 19, 20, tomStart, 1);
+  check_range(w, txtDoc, 19, 20, tomEnd, 1);
 
   /* Back up to the top. */
   check_range(w, txtDoc, 0, 1, tomStart, 0);
+  check_range(w, txtDoc, 0, 1, tomEnd, 0);
 
   /* Large range */
   check_range(w, txtDoc, 0, 20, tomStart, 0);
+  check_range(w, txtDoc, 0, 20, tomEnd, 1);
 
   hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
@@ -835,28 +889,28 @@ static void test_ITextSelection_GetChar(void)
   create_interfaces(&w, &reOle, &txtDoc, &txtSel);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
 
-  first = 0, lim = 4;
+  first = 0; lim = 4;
   SendMessageA(w, EM_SETSEL, first, lim);
   pch = 0xdeadbeef;
   hres = ITextSelection_GetChar(txtSel, &pch);
   ok(hres == S_OK, "ITextSelection_GetChar\n");
   ok(pch == 'T', "got wrong char: %c\n", pch);
 
-  first = 0, lim = 0;
+  first = 0; lim = 0;
   SendMessageA(w, EM_SETSEL, first, lim);
   pch = 0xdeadbeef;
   hres = ITextSelection_GetChar(txtSel, &pch);
   ok(hres == S_OK, "ITextSelection_GetChar\n");
   ok(pch == 'T', "got wrong char: %c\n", pch);
 
-  first = 12, lim = 12;
+  first = 12; lim = 12;
   SendMessageA(w, EM_SETSEL, first, lim);
   pch = 0xdeadbeef;
   hres = ITextSelection_GetChar(txtSel, &pch);
   ok(hres == S_OK, "ITextSelection_GetChar\n");
   ok(pch == '\r', "got wrong char: %c\n", pch);
 
-  first = 13, lim = 13;
+  first = 13; lim = 13;
   SendMessageA(w, EM_SETSEL, first, lim);
   pch = 0xdeadbeef;
   hres = ITextSelection_GetChar(txtSel, &pch);
@@ -890,7 +944,7 @@ static void test_ITextRange_GetStart_GetEnd(void)
   create_interfaces(&w, &reOle, &txtDoc, NULL);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
 
-  first = 1, lim = 6;
+  first = 1; lim = 6;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
   start = 0xdeadbeef;
@@ -903,7 +957,7 @@ static void test_ITextRange_GetStart_GetEnd(void)
   ok(end == 6, "got wrong end value: %d\n", end);
   ITextRange_Release(txtRge);
 
-  first = 6, lim = 1;
+  first = 6; lim = 1;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
   start = 0xdeadbeef;
@@ -916,7 +970,7 @@ static void test_ITextRange_GetStart_GetEnd(void)
   ok(end == 6, "got wrong end value: %d\n", end);
   ITextRange_Release(txtRge);
 
-  first = -1, lim = 13;
+  first = -1; lim = 13;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
   start = 0xdeadbeef;
@@ -929,7 +983,7 @@ static void test_ITextRange_GetStart_GetEnd(void)
   ok(end == 13, "got wrong end value: %d\n", end);
   ITextRange_Release(txtRge);
 
-  first = 13, lim = 13;
+  first = 13; lim = 13;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
   start = 0xdeadbeef;
@@ -1109,7 +1163,7 @@ static void test_ITextSelection_GetStart_GetEnd(void)
   create_interfaces(&w, &reOle, &txtDoc, &txtSel);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
 
-  first = 2, lim = 5;
+  first = 2; lim = 5;
   SendMessageA(w, EM_SETSEL, first, lim);
   start = 0xdeadbeef;
   hres = ITextSelection_GetStart(txtSel, &start);
@@ -1120,7 +1174,7 @@ static void test_ITextSelection_GetStart_GetEnd(void)
   ok(hres == S_OK, "ITextSelection_GetEnd\n");
   ok(end == 5, "got wrong end value: %d\n", end);
 
-  first = 5, lim = 2;
+  first = 5; lim = 2;
   SendMessageA(w, EM_SETSEL, first, lim);
   start = 0xdeadbeef;
   hres = ITextSelection_GetStart(txtSel, &start);
@@ -1131,7 +1185,7 @@ static void test_ITextSelection_GetStart_GetEnd(void)
   ok(hres == S_OK, "ITextSelection_GetEnd\n");
   ok(end == 5, "got wrong end value: %d\n", end);
 
-  first = 0, lim = -1;
+  first = 0; lim = -1;
   SendMessageA(w, EM_SETSEL, first, lim);
   start = 0xdeadbeef;
   hres = ITextSelection_GetStart(txtSel, &start);
@@ -1142,7 +1196,7 @@ static void test_ITextSelection_GetStart_GetEnd(void)
   ok(hres == S_OK, "ITextSelection_GetEnd\n");
   ok(end == 13, "got wrong end value: %d\n", end);
 
-  first = 13, lim = 13;
+  first = 13; lim = 13;
   SendMessageA(w, EM_SETSEL, first, lim);
   start = 0xdeadbeef;
   hres = ITextSelection_GetStart(txtSel, &start);
@@ -1315,7 +1369,7 @@ static void test_ITextRange_GetDuplicate(void)
 
   create_interfaces(&w, &reOle, &txtDoc, NULL);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-  first = 0, lim = 4;
+  first = 0; lim = 4;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
 
@@ -1358,7 +1412,7 @@ static void test_ITextRange_Collapse(void)
   create_interfaces(&w, &reOle, &txtDoc, NULL);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
 
-  first = 4, lim = 8;
+  first = 4; lim = 8;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
   hres = ITextRange_Collapse(txtRge, tomTrue);
@@ -1420,7 +1474,7 @@ static void test_ITextRange_Collapse(void)
   ok(end == 4, "got wrong end value: %d\n", end);
   ITextRange_Release(txtRge);
 
-  first = 6, lim = 6;
+  first = 6; lim = 6;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
   hres = ITextRange_Collapse(txtRge, tomEnd);
@@ -1433,7 +1487,7 @@ static void test_ITextRange_Collapse(void)
   ok(end == 6, "got wrong end value: %d\n", end);
   ITextRange_Release(txtRge);
 
-  first = 8, lim = 8;
+  first = 8; lim = 8;
   hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
   ok(hres == S_OK, "got 0x%08x\n", hres);
   hres = ITextRange_Collapse(txtRge, tomStart);
@@ -1469,7 +1523,7 @@ static void test_ITextSelection_Collapse(void)
   create_interfaces(&w, &reOle, &txtDoc, &txtSel);
   SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
 
-  first = 4, lim = 8;
+  first = 4; lim = 8;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_Collapse(txtSel, tomTrue);
   ok(hres == S_OK, "ITextSelection_Collapse\n");
@@ -1506,7 +1560,7 @@ static void test_ITextSelection_Collapse(void)
   ok(start == 4, "got wrong start value: %d\n", start);
   ok(end == 4, "got wrong end value: %d\n", end);
 
-  first = 6, lim = 6;
+  first = 6; lim = 6;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_Collapse(txtSel, tomEnd);
   ok(hres == S_FALSE, "ITextSelection_Collapse\n");
@@ -1514,7 +1568,7 @@ static void test_ITextSelection_Collapse(void)
   ok(start == 6, "got wrong start value: %d\n", start);
   ok(end == 6, "got wrong end value: %d\n", end);
 
-  first = 8, lim = 8;
+  first = 8; lim = 8;
   SendMessageA(w, EM_SETSEL, first, lim);
   hres = ITextSelection_Collapse(txtSel, tomStart);
   ok(hres == S_FALSE, "ITextSelection_Collapse\n");
@@ -3278,6 +3332,61 @@ static void test_InsertObject(void)
   /* received_reo4 didn't be zeroed in E_INVALIDARG case */
   CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
 
+  SendMessageA(hwnd, EM_SETSEL, 0, 1);
+  received_reo4.cbStruct = sizeof(received_reo4);
+  received_reo4.cp = 1;
+  hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &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);
+
+  SendMessageA(hwnd, EM_SETSEL, 1, 2);
+  received_reo4.cbStruct = sizeof(received_reo4);
+  received_reo4.cp = 0;
+  hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &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);
+
+  SendMessageA(hwnd, EM_SETSEL, 2, 3);
+  received_reo4.cbStruct = sizeof(received_reo4);
+  received_reo4.cp = 0;
+  hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &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);
+
+  SendMessageA(hwnd, EM_SETSEL, 0, 2);
+  received_reo4.cbStruct = sizeof(received_reo4);
+  received_reo4.cp = 0;
+  hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &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);
+
+  SendMessageA(hwnd, EM_SETSEL, 1, 3);
+  received_reo4.cbStruct = sizeof(received_reo4);
+  received_reo4.cp = 0;
+  hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &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);
+
+  SendMessageA(hwnd, EM_SETSEL, 2, 0);
+  received_reo4.cbStruct = sizeof(received_reo4);
+  received_reo4.cp = 0;
+  hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &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);
+
+  SendMessageA(hwnd, EM_SETSEL, 0, 6);
+  received_reo4.cbStruct = sizeof(received_reo4);
+  received_reo4.cp = 0;
+  hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &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);
+
+  SendMessageA(hwnd, EM_SETSEL, 4, 5);
+  received_reo4.cbStruct = sizeof(received_reo4);
+  received_reo4.cp = 0;
+  hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
+  ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
+
   release_interfaces(&hwnd, &reole, &doc, NULL);
 }
 
@@ -3481,6 +3590,51 @@ static void _check_selection(ITextSelection *selection, LONG expected_start, LON
                      expected_end, value);
 }
 
+static void test_ITextRange_SetRange(void)
+{
+  static const CHAR test_text1[] = "TestSomeText";
+  ITextDocument *txtDoc = NULL;
+  IRichEditOle *reOle = NULL;
+  ITextRange *txtRge = NULL;
+  HRESULT hr;
+  HWND w;
+
+  create_interfaces(&w, &reOle, &txtDoc, NULL);
+  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
+  ITextDocument_Range(txtDoc, 0, 0, &txtRge);
+
+  hr = ITextRange_SetRange(txtRge, 2, 4);
+  ok(hr == S_OK, "got 0x%08x.\n", hr);
+  CHECK_RANGE(txtRge, 2, 4);
+
+  hr = ITextRange_SetRange(txtRge, 2, 4);
+  ok(hr == S_FALSE, "got 0x%08x.\n", hr);
+  CHECK_RANGE(txtRge, 2, 4);
+
+  hr = ITextRange_SetRange(txtRge, 4, 2);
+  ok(hr == S_FALSE, "got 0x%08x.\n", hr);
+  CHECK_RANGE(txtRge, 2, 4);
+
+  hr = ITextRange_SetRange(txtRge, 14, 14);
+  ok(hr == S_OK, "got 0x%08x.\n", hr);
+  CHECK_RANGE(txtRge, 12, 12);
+
+  hr = ITextRange_SetRange(txtRge, 15, 15);
+  ok(hr == S_FALSE, "got 0x%08x.\n", hr);
+  CHECK_RANGE(txtRge, 12, 12);
+
+  hr = ITextRange_SetRange(txtRge, 14, 1);
+  ok(hr == S_OK, "got 0x%08x.\n", hr);
+  CHECK_RANGE(txtRge, 1, 13);
+
+  hr = ITextRange_SetRange(txtRge, -1, 4);
+  ok(hr == S_OK, "got 0x%08x.\n", hr);
+  CHECK_RANGE(txtRge, 0, 4);
+
+  ITextRange_Release(txtRge);
+  release_interfaces(&w, &reOle, &txtDoc, NULL);
+}
+
 static void test_Expand(void)
 {
   static const char test_text1[] = "TestSomeText";
@@ -3922,183 +4076,6 @@ static void test_ITextRange_GetPara(void)
   ITextPara_Release(txtPara);
 }
 
-static void test_ITextRange_GetText(void)
-{
-  HWND w;
-  IRichEditOle *reOle = NULL;
-  ITextDocument *txtDoc = NULL;
-  ITextRange *txtRge = NULL;
-  HRESULT hres;
-  BSTR bstr = NULL;
-  static const CHAR test_text1[] = "TestSomeText";
-  static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
-  static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
-  static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
-  static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
-                                'e', 'T', 'e', 'x', 't', '\r', 0};
-  static const WCHAR bufW5[] = {'\r', 0};
-
-
-#define TEST_TXTRGE_GETTEXT(first, lim, expected_string)                \
-  create_interfaces(&w, &reOle, &txtDoc, NULL);                         \
-  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);                   \
-  ITextDocument_Range(txtDoc, first, lim, &txtRge);                     \
-  hres = ITextRange_GetText(txtRge, &bstr);                             \
-  ok(hres == S_OK, "ITextRange_GetText\n");                             \
-  ok(!lstrcmpW(bstr, expected_string), "got wrong text: %s\n", wine_dbgstr_w(bstr)); \
-  SysFreeString(bstr);                                                  \
-  ITextRange_Release(txtRge);                                           \
-  release_interfaces(&w, &reOle, &txtDoc, NULL);
-
-  TEST_TXTRGE_GETTEXT(0, 4, bufW1)
-  TEST_TXTRGE_GETTEXT(4, 0, bufW1)
-  TEST_TXTRGE_GETTEXT(8, 12, bufW3)
-  TEST_TXTRGE_GETTEXT(8, 13, bufW2)
-  TEST_TXTRGE_GETTEXT(12, 13, bufW5)
-  TEST_TXTRGE_GETTEXT(0, 13, bufW4)
-  TEST_TXTRGE_GETTEXT(1, 1, NULL)
-}
-
-static void test_ITextRange_SetRange(void)
-{
-  HWND w;
-  IRichEditOle *reOle = NULL;
-  ITextDocument *txtDoc = NULL;
-  ITextRange *txtRge = NULL;
-  HRESULT hres;
-  int start, end;
-  static const CHAR test_text1[] = "TestSomeText";
-
-  create_interfaces(&w, &reOle, &txtDoc, NULL);
-  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-  ITextDocument_Range(txtDoc, 0, 0, &txtRge);
-
-#define TEST_TXTRGE_SETRANGE(first, lim, expected_start, expected_end, expected_return) \
-  hres = ITextRange_SetRange(txtRge, first, lim);                       \
-  ok(hres == expected_return, "ITextRange_SetRange\n");                 \
-  ITextRange_GetStart(txtRge, &start);                                  \
-  ITextRange_GetEnd(txtRge, &end);                                      \
-  ok(start == expected_start, "got wrong start value: %d\n", start);    \
-  ok(end == expected_end, "got wrong end value: %d\n", end);
-
-  TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_OK)
-  TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_FALSE)
-  TEST_TXTRGE_SETRANGE(4, 2, 2, 4, S_FALSE)
-  TEST_TXTRGE_SETRANGE(14, 14, 12, 12, S_OK)
-  TEST_TXTRGE_SETRANGE(15, 15, 12, 12, S_FALSE)
-  TEST_TXTRGE_SETRANGE(14, 1, 1, 13, S_OK)
-  TEST_TXTRGE_SETRANGE(-1, 4, 0, 4, S_OK)
-
-  ITextRange_Release(txtRge);
-  release_interfaces(&w, &reOle, &txtDoc, NULL);
-}
-
-static void test_ITextRange_IsEqual2(void)
-{
-  HWND w;
-  IRichEditOle *reOle = NULL;
-  ITextDocument *txtDoc = NULL;
-  ITextRange *txtRge1 = NULL, *txtRge2 = NULL;
-  HRESULT hres;
-  static const CHAR test_text1[] = "TestSomeText";
-  LONG res;
-
-  create_interfaces(&w, &reOle, &txtDoc, NULL);
-  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-  ITextDocument_Range(txtDoc, 2, 4, &txtRge1);
-  ITextDocument_Range(txtDoc, 2, 4, &txtRge2);
-
-#define TEST_TXTRGE_ISEQUAL(expected_hres, expected_res)                \
-  hres = ITextRange_IsEqual(txtRge1, txtRge2, &res);                    \
-  ok(hres == expected_hres, "ITextRange_IsEqual\n");                    \
-  ok(res == expected_res, "got wrong return value: %d\n", res);
-
-  TEST_TXTRGE_ISEQUAL(S_OK, tomTrue)
-  ITextRange_SetRange(txtRge2, 1, 2);
-  TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse)
-
-  ITextRange_SetRange(txtRge1, 1, 1);
-  ITextRange_SetRange(txtRge2, 2, 2);
-  TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse)
-
-  ITextRange_SetRange(txtRge2, 1, 1);
-  TEST_TXTRGE_ISEQUAL(S_OK, tomTrue)
-
-  hres = ITextRange_IsEqual(txtRge1, txtRge1, &res);
-  ok(hres == S_OK, "ITextRange_IsEqual\n");
-  ok(res == tomTrue, "got wrong return value: %d\n", res);
-
-  hres = ITextRange_IsEqual(txtRge1, txtRge2, NULL);
-  ok(hres == S_OK, "ITextRange_IsEqual\n");
-
-  hres = ITextRange_IsEqual(txtRge1, NULL, NULL);
-  ok(hres == S_FALSE, "ITextRange_IsEqual\n");
-
-  ITextRange_Release(txtRge1);
-  ITextRange_Release(txtRge2);
-  release_interfaces(&w, &reOle, &txtDoc, NULL);
-}
-
-static void test_ITextRange_GetStoryLength(void)
-{
-  HWND w;
-  IRichEditOle *reOle = NULL;
-  ITextDocument *txtDoc = NULL;
-  ITextRange *txtRge = NULL;
-  HRESULT hres;
-  LONG count;
-  static const CHAR test_text1[] = "TestSomeText";
-  int len = strlen(test_text1) + 1;
-
-  create_interfaces(&w, &reOle, &txtDoc, NULL);
-  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-  ITextDocument_Range(txtDoc, 0, 0, &txtRge);
-
-  hres = ITextRange_GetStoryLength(txtRge, &count);
-  ok(hres == S_OK, "ITextRange_GetStoryLength\n");
-  ok(count == len, "got wrong length: %d\n", count);
-
-  ITextRange_SetRange(txtRge, 1, 2);
-  hres = ITextRange_GetStoryLength(txtRge, &count);
-  ok(hres == S_OK, "ITextRange_GetStoryLength\n");
-  ok(count == len, "got wrong length: %d\n", count);
-
-  hres = ITextRange_GetStoryLength(txtRge, NULL);
-  ok(hres == E_INVALIDARG, "ITextRange_GetStoryLength\n");
-
-  ITextRange_Release(txtRge);
-  release_interfaces(&w, &reOle, &txtDoc, NULL);
-}
-
-static void test_ITextSelection_GetStoryLength(void)
-{
-  HWND w;
-  IRichEditOle *reOle = NULL;
-  ITextDocument *txtDoc = NULL;
-  ITextSelection *txtSel = NULL;
-  HRESULT hres;
-  LONG count;
-  static const CHAR test_text1[] = "TestSomeText";
-  int len = strlen(test_text1) + 1;
-
-  create_interfaces(&w, &reOle, &txtDoc, &txtSel);
-  SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-
-  hres = ITextSelection_GetStoryLength(txtSel, &count);
-  ok(hres == S_OK, "ITextSelection_GetStoryLength\n");
-  ok(count == len, "got wrong length: %d\n", count);
-
-  SendMessageA(w, EM_SETSEL, 1, 2);
-  hres = ITextSelection_GetStoryLength(txtSel, &count);
-  ok(hres == S_OK, "ITextSelection_GetStoryLength\n");
-  ok(count == len, "got wrong length: %d\n", count);
-
-  hres = ITextSelection_GetStoryLength(txtSel, NULL);
-  ok(hres == E_INVALIDARG, "ITextSelection_GetStoryLength\n");
-
-  release_interfaces(&w, &reOle, &txtDoc, &txtSel);
-}
-
 START_TEST(richole)
 {
   /* Must explicitly LoadLibrary(). The test has no references to functions in
@@ -4115,21 +4092,17 @@ START_TEST(richole)
   test_ITextSelection_SetEnd();
   test_ITextSelection_Collapse();
   test_ITextSelection_GetFont();
-  test_ITextSelection_GetStoryLength();
   test_ITextDocument_Range();
   test_ITextRange_GetChar();
   test_ITextRange_ScrollIntoView();
   test_ITextRange_GetStart_GetEnd();
+  test_ITextRange_SetRange();
   test_ITextRange_GetDuplicate();
   test_ITextRange_SetStart();
   test_ITextRange_SetEnd();
   test_ITextRange_Collapse();
   test_ITextRange_GetFont();
   test_ITextRange_GetPara();
-  test_ITextRange_GetText();
-  test_ITextRange_SetRange();
-  test_ITextRange_IsEqual2();
-  test_ITextRange_GetStoryLength();
   test_GetClientSite();
   test_IOleWindow_GetWindow();
   test_IOleInPlaceSite_GetWindow();
index 88b5adf..5a59c87 100644 (file)
@@ -48,7 +48,7 @@ static PCreateTextServices pCreateTextServices;
 
 /* Use a special table for x86 machines to convert the thiscall
  * calling convention.  This isn't needed on other platforms. */
-#ifdef __i386__
+#if defined(__i386__) && !defined(__MINGW32__)
 static ITextServicesVtbl itextServicesStdcallVtbl;
 #define TXTSERV_VTABLE(This) (&itextServicesStdcallVtbl)
 #else /* __i386__ */
@@ -85,6 +85,7 @@ typedef struct ITextHostTestImpl
 {
     ITextHost ITextHost_iface;
     LONG refCount;
+    CHARFORMAT2W char_format;
 } ITextHostTestImpl;
 
 static inline ITextHostTestImpl *impl_from_ITextHost(ITextHost *iface)
@@ -534,7 +535,7 @@ typedef struct
 
 static void setup_thiscall_wrappers(void)
 {
-#ifdef __i386__
+#if defined(__i386__) && !defined(__MINGW32__)
     void** pVtable;
     void** pVtableEnd;
     THISCALL_TO_STDCALL_THUNK *thunk;
@@ -600,6 +601,21 @@ static void setup_thiscall_wrappers(void)
 #endif /* __i386__ */
 }
 
+static void hf_to_cf(HFONT hf, CHARFORMAT2W *cf)
+{
+    LOGFONTW lf;
+
+    GetObjectW(hf, sizeof(lf), &lf);
+    lstrcpyW(cf->szFaceName, lf.lfFaceName);
+    cf->yHeight = MulDiv(abs(lf.lfHeight), 1440, GetDeviceCaps(GetDC(NULL), LOGPIXELSY));
+    if (lf.lfWeight > FW_NORMAL) cf->dwEffects |= CFE_BOLD;
+    if (lf.lfItalic) cf->dwEffects |= CFE_ITALIC;
+    if (lf.lfUnderline) cf->dwEffects |= CFE_UNDERLINE;
+    if (lf.lfStrikeOut) cf->dwEffects |= CFE_SUBSCRIPT;
+    cf->bPitchAndFamily = lf.lfPitchAndFamily;
+    cf->bCharSet = lf.lfCharSet;
+}
+
 /*************************************************************************/
 /* Conformance test functions. */
 
@@ -609,6 +625,7 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
     ITextHostTestImpl *dummyTextHost;
     IUnknown *init;
     HRESULT result;
+    HFONT hf;
 
     dummyTextHost = CoTaskMemAlloc(sizeof(*dummyTextHost));
     if (dummyTextHost == NULL) {
@@ -617,6 +634,11 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
     }
     dummyTextHost->ITextHost_iface.lpVtbl = &itextHostVtbl;
     dummyTextHost->refCount = 1;
+    memset(&dummyTextHost->char_format, 0, sizeof(dummyTextHost->char_format));
+    dummyTextHost->char_format.cbSize = sizeof(dummyTextHost->char_format);
+    dummyTextHost->char_format.dwMask = CFM_ALL2;
+    hf = GetStockObject(DEFAULT_GUI_FONT);
+    hf_to_cf(hf, &dummyTextHost->char_format);
 
     /* MSDN states that an IUnknown object is returned by
        CreateTextServices which is then queried to obtain a
@@ -682,6 +704,8 @@ static void test_TxSetText(void)
     ok(memcmp(rettext,settext,SysStringByteLen(rettext)) == 0,
                  "String returned differs\n");
 
+    SysFreeString(rettext);
+
     /* Null-pointer should behave the same as empty-string */
 
     hres = ITextServices_TxSetText(txtserv, 0);
@@ -697,81 +721,68 @@ static void test_TxSetText(void)
     ITextHost_Release(host);
 }
 
+#define CHECK_TXGETNATURALSIZE(res,width,height,hdc,rect,string) \
+    _check_txgetnaturalsize(res, width, height, hdc, rect, string, __LINE__)
+static void _check_txgetnaturalsize(HRESULT res, LONG width, LONG height, HDC hdc, RECT rect, LPCWSTR string, int line)
+{
+    RECT expected_rect = rect;
+    LONG expected_width, expected_height;
+
+    DrawTextW(hdc, string, -1, &expected_rect, DT_LEFT | DT_CALCRECT | DT_NOCLIP | DT_EDITCONTROL | DT_WORDBREAK);
+    expected_width = expected_rect.right - expected_rect.left;
+    expected_height = expected_rect.bottom - expected_rect.top;
+    ok_(__FILE__,line)(res == S_OK, "ITextServices_TxGetNaturalSize failed: 0x%08x.\n", res);
+    ok_(__FILE__,line)(width >= expected_width && width <= expected_width + 1,
+                       "got wrong width: %d, expected: %d {+1}.\n", width, expected_width);
+    ok_(__FILE__,line)(height == expected_height, "got wrong height: %d, expected: %d.\n",
+                       height, expected_height);
+}
+
 static void test_TxGetNaturalSize(void)
 {
     ITextServices *txtserv;
     ITextHost *host;
     HRESULT result;
-    BOOL ret;
-
-    /* This value is used when calling TxGetNaturalSize.  MSDN says
-       that this is not supported however a null pointer cannot be
-       used as it will cause a segmentation violation.  The values in
-       the structure being pointed to are required to be INT_MAX
-       otherwise calculations can give wrong values. */
-    const SIZEL psizelExtent = {INT_MAX,INT_MAX};
-
-    static const WCHAR oneA[] = {'A',0};
-
-    /* Results of measurements */
-    LONG xdim, ydim;
-
-    /* The device context to do the tests in */
+    SIZEL extent;
+    static const WCHAR test_text[] = {'T','e','s','t','S','o','m','e','T','e','x','t',0};
+    LONG width, height;
     HDC hdcDraw;
-
-    /* Variables with the text metric information */
-    INT charwidth_caps_text[26];
-    TEXTMETRICA tmInfo_text;
+    HWND hwnd;
+    RECT rect;
+    CHARFORMAT2W cf;
+    LRESULT lresult;
+    HFONT hf;
 
     if (!init_texthost(&txtserv, &host))
         return;
 
-    hdcDraw = GetDC(NULL);
-    SaveDC(hdcDraw);
-
-    /* Populate the metric strucs */
+    hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
+                           0, 0, 100, 100, 0, 0, 0, NULL);
+    hdcDraw = GetDC(hwnd);
     SetMapMode(hdcDraw,MM_TEXT);
-    GetTextMetricsA(hdcDraw, &tmInfo_text);
-    SetLastError(0xdeadbeef);
-    ret = GetCharWidth32A(hdcDraw,'A','Z',charwidth_caps_text);
-    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
-        win_skip("GetCharWidth32 is not available\n");
-        goto cleanup;
-    }
-
-    /* Make measurements in MM_TEXT */
-    SetMapMode(hdcDraw,MM_TEXT);
-    xdim = 0; ydim = 0;
-
-    result = ITextServices_TxSetText(txtserv, oneA);
-    ok(result == S_OK, "ITextServices_TxSetText failed (result = %x)\n", result);
-    if (result != S_OK) {
-        skip("Could not set text\n");
-        goto cleanup;
-    }
-
-    SetLastError(0xdeadbeef);
-    result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT,
-                                            hdcDraw, NULL, NULL,
-                                            TXTNS_FITTOCONTENT, &psizelExtent,
-                                            &xdim, &ydim);
-    todo_wine ok(result == S_OK || broken(result == E_FAIL), /* WINXP Arabic Language */
-        "TxGetNaturalSize gave unexpected return value (result = %x)\n", result);
-    if (result == S_OK) {
-    todo_wine ok(ydim == tmInfo_text.tmHeight,
-                 "Height calculated incorrectly (expected %d, got %d)\n",
-                 tmInfo_text.tmHeight, ydim);
-    /* The native DLL adds one pixel extra when calculating widths. */
-    todo_wine ok(xdim >= charwidth_caps_text[0] && xdim <= charwidth_caps_text[0] + 1,
-                 "Width calculated incorrectly (expected %d {+1}, got %d)\n",
-                 charwidth_caps_text[0], xdim);
-    } else
-        skip("TxGetNaturalSize measurements not performed (xdim = %d, ydim = %d, result = %x, error = %x)\n",
-             xdim, ydim, result, GetLastError());
-
-cleanup:
-    RestoreDC(hdcDraw,1);
-    ReleaseDC(NULL,hdcDraw);
+    GetClientRect(hwnd, &rect);
+
+    memset(&cf, 0, sizeof(cf));
+    cf.cbSize = sizeof(cf);
+    cf.dwMask = CFM_ALL2;
+    hf = GetStockObject(DEFAULT_GUI_FONT);
+    hf_to_cf(hf, &cf);
+    result = ITextServices_TxSendMessage(txtserv, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM)&cf, &lresult);
+    ok(result == S_OK, "ITextServices_TxSendMessage failed: 0x%08x.\n", result);
+    SelectObject(hdcDraw, hf);
+
+    result = ITextServices_TxSetText(txtserv, test_text);
+    ok(result == S_OK, "ITextServices_TxSetText failed: 0x%08x.\n", result);
+
+    extent.cx = -1; extent.cy = -1;
+    width = rect.right - rect.left;
+    height = 0;
+    result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT, hdcDraw, NULL, NULL,
+                                            TXTNS_FITTOCONTENT, &extent, &width, &height);
+    todo_wine CHECK_TXGETNATURALSIZE(result, width, height, hdcDraw, rect, test_text);
+
+    ReleaseDC(hwnd, hdcDraw);
+    DestroyWindow(hwnd);
     ITextServices_Release(txtserv);
     ITextHost_Release(host);
 }
@@ -894,6 +905,7 @@ static void test_QueryInterface(void)
     HRESULT hres;
     IRichEditOle *reole, *txtsrv_reole;
     ITextDocument *txtdoc, *txtsrv_txtdoc;
+    ITextDocument2Old *txtdoc2old, *txtsrv_txtdoc2old;
     ULONG refcount;
 
     if(!init_texthost(&txtserv, &host))
@@ -920,6 +932,17 @@ static void test_QueryInterface(void)
     ITextDocument_Release(txtdoc);
     refcount = get_refcount((IUnknown *)txtserv);
     ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+
+    hres = IRichEditOle_QueryInterface(txtsrv_reole, &IID_ITextDocument2Old, (void **)&txtdoc2old);
+    ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+    refcount = get_refcount((IUnknown *)txtsrv_reole);
+    ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+
+    ITextDocument2Old_Release(txtdoc2old);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
     IRichEditOle_Release(txtsrv_reole);
     refcount = get_refcount((IUnknown *)txtserv);
     ok(refcount == 1, "got wrong ref count: %d\n", refcount);
@@ -946,6 +969,77 @@ static void test_QueryInterface(void)
     refcount = get_refcount((IUnknown *)txtserv);
     ok(refcount == 1, "got wrong ref count: %d\n", refcount);
 
+    /* ITextDocument2Old */
+    hres = ITextServices_QueryInterface(txtserv, &IID_ITextDocument2Old, (void **)&txtsrv_txtdoc2old);
+    ok(hres == S_OK, "ITextServices_QueryInterface: 0x%08x\n", hres);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+    refcount = get_refcount((IUnknown *)txtsrv_txtdoc2old);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+
+    hres = ITextDocument2Old_QueryInterface(txtsrv_txtdoc2old, &IID_IRichEditOle, (void **)&reole);
+    ok(hres == S_OK, "ITextDocument2Old_QueryInterface: 0x%08x\n", hres);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+    refcount = get_refcount((IUnknown *)txtsrv_txtdoc2old);
+    ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+
+    IRichEditOle_Release(reole);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+    ITextDocument2Old_Release(txtsrv_txtdoc2old);
+    refcount = get_refcount((IUnknown *)txtserv);
+    ok(refcount == 1, "got wrong ref count: %d\n", refcount);
+
+    ITextServices_Release(txtserv);
+    ITextHost_Release(host);
+}
+
+static void test_default_format(void)
+{
+    ITextServices *txtserv;
+    ITextHost *host;
+    HRESULT result;
+    LRESULT lresult;
+    CHARFORMAT2W cf2;
+    const CHARFORMATW *host_cf;
+    DWORD expected_effects;
+
+    if (!init_texthost(&txtserv, &host))
+        return;
+
+    cf2.cbSize = sizeof(CHARFORMAT2W);
+    result = ITextServices_TxSendMessage(txtserv, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&cf2, &lresult);
+    ok(result == S_OK, "ITextServices_TxSendMessage failed: 0x%08x.\n", result);
+
+    ITextHostImpl_TxGetCharFormat(host, &host_cf);
+    ok(!lstrcmpW(host_cf->szFaceName, cf2.szFaceName), "got wrong font name: %s.\n", wine_dbgstr_w(cf2.szFaceName));
+    ok(cf2.yHeight == host_cf->yHeight, "got wrong yHeight: %d, expected %d.\n", cf2.yHeight, host_cf->yHeight);
+    expected_effects = (cf2.dwEffects & ~(CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR));
+    ok(host_cf->dwEffects == expected_effects, "got wrong dwEffects: %x, expected %x.\n", cf2.dwEffects, expected_effects);
+    ok(cf2.bPitchAndFamily == host_cf->bPitchAndFamily, "got wrong bPitchAndFamily: %x, expected %x.\n",
+       cf2.bPitchAndFamily, host_cf->bPitchAndFamily);
+    ok(cf2.bCharSet == host_cf->bCharSet, "got wrong bCharSet: %x, expected %x.\n", cf2.bCharSet, host_cf->bCharSet);
+
+    ITextServices_Release(txtserv);
+    ITextHost_Release(host);
+}
+
+static void test_TxGetScroll(void)
+{
+    ITextServices *txtserv;
+    ITextHost *host;
+    HRESULT ret;
+
+    if (!init_texthost(&txtserv, &host))
+        return;
+
+    ret = ITextServices_TxGetHScroll(txtserv, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == S_OK, "ITextSerHices_GetVScroll failed: 0x%08x.\n", ret);
+
+    ret = ITextServices_TxGetVScroll(txtserv, NULL, NULL, NULL, NULL, NULL);
+    ok(ret == S_OK, "ITextServices_GetVScroll failed: 0x%08x.\n", ret);
+
     ITextServices_Release(txtserv);
     ITextHost_Release(host);
 }
@@ -980,6 +1074,8 @@ START_TEST( txtsrv )
         test_TxGetNaturalSize();
         test_TxDraw();
         test_QueryInterface();
+        test_default_format();
+        test_TxGetScroll();
     }
     if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE);
 }