Module: wine Branch: refs/heads/master Commit: 3f19ffe809aa68a2936ae6a3b0df677932fd0ef7 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=3f19ffe809aa68a2936ae6a3...
Author: Thomas Kho tkho@ucla.edu Date: Mon Jul 31 07:59:43 2006 +0200
riched20: Implement EM_GETLINE.
---
dlls/riched20/editor.c | 55 +++++++++++++++++++++++++++++++++++-- dlls/riched20/tests/editor.c | 63 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 0bdfcd6..390ac3b 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -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 @@ LRESULT WINAPI RichEditANSIWndProc(HWND /* 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) @@ -2036,6 +2035,58 @@ LRESULT WINAPI RichEditANSIWndProc(HWND return nChars; } } + case EM_GETLINE: + { + ME_DisplayItem *run; + const BOOL bUnicode = IsWindowUnicode(hWnd); + const unsigned int nMaxChars = *(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, 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; diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 7aa5a5f..dd4f2dd 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -189,6 +189,68 @@ static void test_EM_FINDTEXT(void) DestroyWindow(hwndRichEdit); }
+static const struct getline_s { + int line; + size_t buffer_len; + const 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 @@ START_TEST( editor ) 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();