[PATCH] richedit: EM_GETLINE: honor CR and LF counters. Add richedit 1.0 tests for EM_GETLINE.

Alex Villacís Lasso alex at karlalex.palosanto.com
Sat Apr 26 16:43:14 CDT 2008


---
 dlls/riched20/editor.c       |   50 ++++++++++++++++----------
 dlls/riched32/tests/editor.c |   79 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 110 insertions(+), 19 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 7a0dce7..da61cd2 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -2608,11 +2608,9 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
   {
     ME_DisplayItem *run;
     const unsigned int nMaxChars = *(WORD *) lParam;
-    unsigned int nEndChars, nCharsLeft = nMaxChars;
+    unsigned int nCharsLeft = nMaxChars;
     char *dest = (char *) lParam;
-    /* rich text editor 1.0 uses \r\n for line end, 2.0 uses just \r; 
-    we need to know how if we have the extra \n or not */
-    int nLF = editor->bEmulateVersion10;
+    BOOL wroteNull = FALSE;
 
     TRACE("EM_GETLINE: row=%d, nMaxChars=%d (%s)\n", (int) wParam, nMaxChars,
           unicode ? "Unicode" : "Ansi");
@@ -2640,24 +2638,38 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam,
       nCharsLeft -= nCopy;
     }
 
-    /* append \r\0 (or \r\n\0 in 1.0), space allowing */
-    nEndChars = min(nCharsLeft, 2 + nLF);
-    nCharsLeft -= nEndChars;
-    if (unicode)
+    /* append line termination, space allowing */
+    if (nCharsLeft > 0)
     {
-      const WCHAR src[] = {'\r', '\0'};
-      const WCHAR src10[] = {'\r', '\n', '\0'};
-      lstrcpynW((LPWSTR) dest, nLF ? src10 : src, nEndChars);
+      if (run && (run->member.run.nFlags & MERF_ENDPARA))
+      {
+        unsigned int i;
+        /* Write as many \r as encoded in end-of-paragraph, space allowing */
+        for (i = 0; i < run->member.run.nCR && nCharsLeft > 0; i++, nCharsLeft--)
+        {
+          *((WCHAR *)dest) = '\r';
+          dest += unicode ? sizeof(WCHAR) : 1;
+        }
+        /* Write as many \n as encoded in end-of-paragraph, space allowing */
+        for (i = 0; i < run->member.run.nLF && nCharsLeft > 0; i++, nCharsLeft--)
+        {
+          *((WCHAR *)dest) = '\n';
+          dest += unicode ? sizeof(WCHAR) : 1;
+        }
+      }
+      if (nCharsLeft > 0)
+      {
+        if (unicode)
+          *((WCHAR *)dest) = '\0';
+        else
+          *dest = '\0';
+        nCharsLeft--;
+        wroteNull = TRUE;
+      }
     }
-    else
-      lstrcpynA(dest, nLF ? "\r\n" : "\r", nEndChars);
-
-    TRACE("EM_GETLINE: got %u bytes\n", nMaxChars - nCharsLeft);
 
-    if (nEndChars == 2 + nLF)
-      return nMaxChars - nCharsLeft - 1; /* don't count \0 */
-    else
-      return nMaxChars - nCharsLeft;
+    TRACE("EM_GETLINE: got %u characters\n", nMaxChars - nCharsLeft);
+    return nMaxChars - nCharsLeft - (wroteNull ? 1 : 0);
   }
   case EM_GETLINECOUNT:
   {
diff --git a/dlls/riched32/tests/editor.c b/dlls/riched32/tests/editor.c
index bb8ce4b..612e89a 100644
--- a/dlls/riched32/tests/editor.c
+++ b/dlls/riched32/tests/editor.c
@@ -353,6 +353,84 @@ static void test_EM_STREAMOUT(void)
   DestroyWindow(hwndRichEdit);
 }
 
+static const struct getline_s {
+  int line;
+  size_t buffer_len;
+  const char *text;
+  int wine_todo;
+} gl[] = {
+  {0, 10, "foo bar\r\n", 0},
+  {1, 10, "\n", 1},
+  {2, 10, "bar\n", 1},
+  {3, 10, "\r\n", 0},
+
+  /* Buffer smaller than line length */
+  {0, 2, "foo bar\r", 0},
+  {0, 1, "foo bar\r", 0},
+  {0, 0, "foo bar\r", 0}
+};
+
+static void test_EM_GETLINE(void)
+{
+  int i;
+  HWND hwndRichEdit = new_richedit(NULL);
+  static const int nBuf = 1024;
+  char dest[1024], origdest[1024];
+  const char text[] = "foo bar\r\n"
+      "\n"
+      "bar\n";
+
+  SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text);
+
+  memset(origdest, 0xBB, nBuf);
+  for (i = 0; i < sizeof(gl)/sizeof(struct getline_s); i++)
+  {
+    int nCopied;
+    int expected_nCopied = min(gl[i].buffer_len, strlen(gl[i].text));
+    int expected_bytes_written = min(gl[i].buffer_len, strlen(gl[i].text) + 1);
+    memset(dest, 0xBB, nBuf);
+    *(WORD *) dest = gl[i].buffer_len;
+
+    /* EM_GETLINE appends a "\r\0" to the end of the line
+     * nCopied counts up to and including the '\r' */
+    nCopied = SendMessage(hwndRichEdit, EM_GETLINE, gl[i].line, (LPARAM) dest);
+    if (gl[i].wine_todo) todo_wine {
+    ok(nCopied == expected_nCopied, "%d: %d!=%d\n", i, nCopied,
+       expected_nCopied);
+    } else
+    ok(nCopied == expected_nCopied, "%d: %d!=%d\n", i, nCopied,
+       expected_nCopied);
+    /* two special cases since a parameter is passed via dest */
+    if (gl[i].buffer_len == 0)
+      ok(!dest[0] && !dest[1] && !strncmp(dest+2, origdest+2, nBuf-2),
+         "buffer_len=0\n");
+    else if (gl[i].buffer_len == 1)
+      ok(dest[0] == gl[i].text[0] && !dest[1] &&
+         !strncmp(dest+2, origdest+2, nBuf-2), "buffer_len=1\n");
+    else
+    {
+      if (gl[i].wine_todo) todo_wine {
+      ok(!strncmp(dest, gl[i].text, expected_bytes_written),
+         "%d: expected_bytes_written=%d\n", i, expected_bytes_written);
+      ok(!strncmp(dest + expected_bytes_written, origdest
+                  + expected_bytes_written, nBuf - expected_bytes_written),
+         "%d: expected_bytes_written=%d\n", i, expected_bytes_written);
+      }
+      else
+      {
+      ok(!strncmp(dest, gl[i].text, expected_bytes_written),
+         "%d: expected_bytes_written=%d\n", i, expected_bytes_written);
+      ok(!strncmp(dest + expected_bytes_written, origdest
+                  + expected_bytes_written, nBuf - expected_bytes_written),
+         "%d: expected_bytes_written=%d\n", i, expected_bytes_written);
+      }
+    }
+  }
+
+  DestroyWindow(hwndRichEdit);
+}
+
+
 START_TEST( editor )
 {
   MSG msg;
@@ -367,6 +445,7 @@ START_TEST( editor )
   test_WM_GETTEXTLENGTH();
   test_EM_STREAMIN();
   test_EM_STREAMOUT();
+  test_EM_GETLINE();
 
   /* Set the environment variable WINETEST_RICHED32 to keep windows
    * responsive and open for 30 seconds. This is useful for debugging.
-- 
1.5.4.1


--------------090600030301060909020706--



More information about the wine-patches mailing list