Alex Villacís Lasso : richedit: EM_GETLINE: honor CR and LF counters.
Alexandre Julliard
julliard at winehq.org
Tue Apr 29 08:54:44 CDT 2008
Module: wine
Branch: master
Commit: 3968a67eb9faa428365c5a2ca42d15e0f14d4d9c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3968a67eb9faa428365c5a2ca42d15e0f14d4d9c
Author: Alex Villacís Lasso <a_villacis at 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.
More information about the wine-cvs
mailing list