riched20: EM_GETLINE implementation and test (update 2)
Thomas Kho
tkho at ucla.edu
Wed Jun 28 15:44:27 CDT 2006
Hi,
The following patch implements EM_GETLINE with Alexandre's suggestions and
Krzysztof Foltman's changes to bring it to cvs-current.
This feature was requested in bug #4305
<http://bugs.winehq.org/show_bug.cgi?id=4305> and also mentioned at
<http://groups.google.com/group/comp.emulators.ms-windows.wine/msg/f897626539d4701c>
Regards,
Thomas Kho
Index: dlls/riched20/editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.c,v
retrieving revision 1.111
diff -u -r1.111 editor.c
--- dlls/riched20/editor.c 22 Jun 2006 11:19:36 -0000 1.111
+++ dlls/riched20/editor.c 28 Jun 2006 20:23:16 -0000
@@ -52,7 +52,7 @@
- EM_GETIMESTATUS
- EM_GETLANGOPTIONS 2.0
- EM_GETLIMITTEXT
- - EM_GETLINE
+ + EM_GETLINE
+ EM_GETLINECOUNT returns number of rows, not of paragraphs
+ EM_GETMODIFY
- EM_GETOLEINTERFACE
@@ -1411,7 +1411,6 @@
/* UNSUPPORTED_MSG(EM_GETIMESTATUS) missing in Wine headers */
UNSUPPORTED_MSG(EM_GETLANGOPTIONS)
UNSUPPORTED_MSG(EM_GETLIMITTEXT)
- UNSUPPORTED_MSG(EM_GETLINE)
/* UNSUPPORTED_MSG(EM_GETOLEINTERFACE) separate stub */
UNSUPPORTED_MSG(EM_GETPASSWORDCHAR)
UNSUPPORTED_MSG(EM_GETREDONAME)
@@ -2016,6 +2015,58 @@
return nChars;
}
}
+ case EM_GETLINE:
+ {
+ ME_DisplayItem *run;
+ const BOOL bUnicode = IsWindowUnicode(hWnd);
+ const unsigned int nMaxChars = (unsigned int) *(WORD *) lParam;
+ unsigned int nEndChars, nCharsLeft = nMaxChars;
+ char *dest = (char *) lParam;
+
+ TRACE("EM_GETLINE: row=%d, nMaxChars=%d (%s)\n", (int) wParam, nMaxChars,
+ bUnicode ? "Unicode" : "Ansi");
+
+ run = ME_FindRowWithNumber(editor, (int) wParam);
+ if (run == NULL)
+ return 0;
+
+ while (nCharsLeft && (run = ME_FindItemFwd(run, diRunOrStartRow))
+ && !(run->member.run.nFlags & MERF_ENDPARA))
+ {
+ unsigned int nCopy;
+ ME_String *strText;
+ if (run->type != diRun)
+ break;
+ strText = run->member.run.strText;
+ nCopy = min(nCharsLeft, strText->nLen);
+
+ if (bUnicode)
+ lstrcpynW((LPWSTR) dest, strText->szData, nCopy);
+ else
+ nCopy = WideCharToMultiByte(CP_ACP, 0, strText->szData, nCopy, dest,
+ nCharsLeft, NULL, NULL);
+ dest += nCopy * (bUnicode ? sizeof(WCHAR) : 1);
+ nCharsLeft -= nCopy;
+ }
+
+ /* append \r\0, space allowing */
+ nEndChars = min(nCharsLeft, 2);
+ nCharsLeft -= nEndChars;
+ if (bUnicode)
+ {
+ const WCHAR src[] = {'\r', '\0'};
+ lstrcpynW((LPWSTR) dest, src, nEndChars);
+ }
+ else
+ lstrcpynA(dest, "\r", nEndChars);
+
+ TRACE("EM_GETLINE: got %u bytes\n", nMaxChars - nCharsLeft);
+
+ if (nEndChars == 2)
+ return nMaxChars - nCharsLeft - 1; /* don't count \0 */
+ else
+ return nMaxChars - nCharsLeft;
+ }
case EM_GETLINECOUNT:
{
ME_DisplayItem *item = editor->pBuffer->pFirst->next;
Index: dlls/riched20/tests/editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/tests/editor.c,v
retrieving revision 1.18
diff -u -r1.18 editor.c
--- dlls/riched20/tests/editor.c 16 Jun 2006 13:20:20 -0000 1.18
+++ dlls/riched20/tests/editor.c 28 Jun 2006 20:23:16 -0000
@@ -189,6 +189,68 @@
DestroyWindow(hwndRichEdit);
}
+struct getline_s {
+ int line;
+ size_t buffer_len;
+ char *text;
+} gl[] = {
+ {0, 10, "foo bar\r"},
+ {1, 10, "\r"},
+ {2, 10, "bar\r"},
+ {3, 10, "\r"},
+
+ /* Buffer smaller than line length */
+ {0, 2, "foo bar\r"},
+ {0, 1, "foo bar\r"},
+ {0, 0, "foo bar\r"}
+};
+
+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\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);
+ 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
+ {
+ 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);
+}
+
static int get_scroll_pos_y(HWND hwnd)
{
POINT p = {-1, -1};
@@ -822,6 +884,7 @@
hmoduleRichEdit = LoadLibrary("RICHED20.DLL");
ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
test_EM_FINDTEXT();
+ test_EM_GETLINE();
test_EM_SCROLLCARET();
test_EM_SCROLL();
test_EM_SETTEXTMODE();
More information about the wine-patches
mailing list