Module: wine Branch: master Commit: 3968a67eb9faa428365c5a2ca42d15e0f14d4d9c URL: http://source.winehq.org/git/wine.git/?a=commit;h=3968a67eb9faa428365c5a2ca4...
Author: Alex Villacís Lasso a_villacis@palosanto.com Date: Sat Apr 26 16:43:14 2008 -0500
richedit: EM_GETLINE: honor CR and LF counters.
Add richedit 1.0 tests for EM_GETLINE.
---
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 4bf35ab..106cd65 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.