static void test_EM_GETSELTEXT(void) { HWND hwndRichEdit = new_richedit(NULL); const char * text1 = "foo bar\r\nfoo bar"; const char * text2 = "foo bar\rfoo bar"; const char * expect1 = "bar\r\nfoo"; const char * expect2 = "bar\rfoo"; char buffer[1024] = {0}; LRESULT result; SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text1); SendMessage(hwndRichEdit, EM_SETSEL, 4, 12); result = SendMessage(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer); ok(result == 8, "EM_GETTEXTRANGE returned %ld\n", result); ok(!strcmp(expect1, buffer), "EM_GETTEXTRANGE filled %s\n", buffer); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text2); SendMessage(hwndRichEdit, EM_SETSEL, 4, 11); result = SendMessage(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer); ok(result == 7, "EM_GETTEXTRANGE returned %ld\n", result); ok(!strcmp(expect2, buffer), "EM_GETTEXTRANGE filled %s\n", buffer); DestroyWindow(hwndRichEdit); }
static void create_interfaces(HWND *w, IRichEditOle **reOle, ITextDocument **txtDoc, ITextSelection **txtSel) { *w = new_richedit(NULL); SendMessageA(*w, EM_GETOLEINTERFACE, 0, (LPARAM)reOle); IRichEditOle_QueryInterface(*reOle, &IID_ITextDocument, (void **) txtDoc); ITextDocument_GetSelection(*txtDoc, txtSel); }
static void test_Interfaces(void) { IRichEditOle *reOle = NULL; ITextDocument *txtDoc = NULL; ITextSelection *txtSel = NULL; IUnknown *punk; HRESULT hres; LRESULT res; HWND w; w = new_richedit(NULL); if (!w) { skip("Couldn't create window\n"); return; } res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle); ok(res, "SendMessage\n"); ok(reOle != NULL, "EM_GETOLEINTERFACE\n"); hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument, (void **) &txtDoc); ok(hres == S_OK, "IRichEditOle_QueryInterface\n"); ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n"); ITextDocument_GetSelection(txtDoc, &txtSel); punk = NULL; hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **) &punk); ok(hres == S_OK, "ITextSelection_QueryInterface\n"); ok(punk != NULL, "ITextSelection_QueryInterface\n"); IUnknown_Release(punk); punk = NULL; hres = ITextSelection_QueryInterface(txtSel, &IID_ITextRange, (void **) &punk); ok(hres == S_OK, "ITextSelection_QueryInterface\n"); ok(punk != NULL, "ITextSelection_QueryInterface\n"); IUnknown_Release(punk); punk = NULL; hres = ITextSelection_QueryInterface(txtSel, &IID_IDispatch, (void **) &punk); ok(hres == S_OK, "ITextSelection_QueryInterface\n"); ok(punk != NULL, "ITextSelection_QueryInterface\n"); IUnknown_Release(punk); ITextDocument_Release(txtDoc); IRichEditOle_Release(reOle); DestroyWindow(w); /* Methods should return CO_E_RELEASED if the backing document has been released. One test should suffice. */ hres = ITextSelection_CanEdit(txtSel, NULL); ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n"); ITextSelection_Release(txtSel); }
static void test_EM_STREAMOUT(void) { HWND hwndRichEdit = new_richedit(NULL); int r; EDITSTREAM es; char buf[1024] = {0}; char * p; const char * TestItem1 = "TestSomeText"; const char * TestItem2 = "TestSomeText\r"; const char * TestItem3 = "TestSomeText\r\n"; SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) TestItem1); p = buf; es.dwCookie = (DWORD_PTR)&p; es.dwError = 0; es.pfnCallback = test_WM_SETTEXT_esCallback; memset(buf, 0, sizeof(buf)); SendMessage(hwndRichEdit, EM_STREAMOUT, (WPARAM)(SF_TEXT), (LPARAM)&es); r = strlen(buf); ok(r == 12, "streamed text length is %d, expecting 12\n", r); ok(strcmp(buf, TestItem1) == 0, "streamed text different, got %s\n", buf); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) TestItem2); p = buf; es.dwCookie = (DWORD_PTR)&p; es.dwError = 0; es.pfnCallback = test_WM_SETTEXT_esCallback; memset(buf, 0, sizeof(buf)); SendMessage(hwndRichEdit, EM_STREAMOUT, (WPARAM)(SF_TEXT), (LPARAM)&es); r = strlen(buf); ok(r == 13, "streamed text length is %d, expecting 13\n", r); ok(strcmp(buf, TestItem2) == 0, "streamed text different, got %s\n", buf); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) TestItem3); p = buf; es.dwCookie = (DWORD_PTR)&p; es.dwError = 0; es.pfnCallback = test_WM_SETTEXT_esCallback; memset(buf, 0, sizeof(buf)); SendMessage(hwndRichEdit, EM_STREAMOUT, (WPARAM)(SF_TEXT), (LPARAM)&es); r = strlen(buf); ok(r == 14, "streamed text length is %d, expecting 14\n", r); ok(strcmp(buf, TestItem3) == 0, "streamed text different, got %s\n", buf); DestroyWindow(hwndRichEdit); }
static void test_EM_LINELENGTH(void) { HWND hwndRichEdit = new_richedit(NULL); const char * text = "richedit1\r" "richedit1\n" "richedit1\r\n" "short\r" "richedit1\r" "\r" "\r" "\r\r\n"; int offset_test[16][2] = { {0, 9}, /* Line 1: |richedit1\r */ {5, 9}, /* Line 1: riche|dit1\r */ {10, 9}, /* Line 2: |richedit1\n */ {15, 9}, /* Line 2: riche|dit1\n */ {20, 9}, /* Line 3: |richedit1\r\n */ {25, 9}, /* Line 3: riche|dit1\r\n */ {30, 9}, /* Line 3: richedit1\r|\n */ {31, 5}, /* Line 4: |short\r */ {42, 9}, /* Line 5: riche|dit1\r */ {46, 9}, /* Line 5: richedit1|\r */ {47, 0}, /* Line 6: |\r */ {48, 0}, /* Line 7: |\r */ {49, 0}, /* Line 8: |\r\r\n */ {50, 0}, /* Line 8: \r|\r\n */ {51, 0}, /* Line 8: \r\r|\n */ {52, 0}, /* Line 9: \r\r\n| */ }; int i; LRESULT result; SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text); result = SendMessage(hwndRichEdit, EM_GETLINECOUNT, 0, 0); if (result == 4) { win_skip("Win9x, WinME and NT4 don't handle '\\r only' correctly\n"); return; } ok(result == 9, "Incorrect line count of %ld\n", result); for (i = 0; i < sizeof(offset_test)/sizeof(offset_test[0]); i++) { result = SendMessage(hwndRichEdit, EM_LINELENGTH, offset_test[i][0], 0); ok(result == offset_test[i][1], "Length of line at offset %d is %ld, expected %d\n", offset_test[i][0], result, offset_test[i][1]); } DestroyWindow(hwndRichEdit); }
static void test_EM_GETTEXTRANGE(void) { HWND hwndRichEdit = new_richedit(NULL); const char * text1 = "foo bar\r\nfoo bar"; const char * text3 = "foo bar\rfoo bar"; const char * expect1 = "bar\r\nfoo"; const char * expect2 = "\nfoo"; const char * expect3 = "bar\rfoo"; char buffer[1024] = {0}; LRESULT result; TEXTRANGEA textRange; SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text1); textRange.lpstrText = buffer; textRange.chrg.cpMin = 4; textRange.chrg.cpMax = 12; result = SendMessage(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange); ok(result == 8, "EM_GETTEXTRANGE returned %ld\n", result); ok(!strcmp(expect1, buffer), "EM_GETTEXTRANGE filled %s\n", buffer); textRange.lpstrText = buffer; textRange.chrg.cpMin = 8; textRange.chrg.cpMax = 12; result = SendMessage(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange); ok(result == 4, "EM_GETTEXTRANGE returned %ld\n", result); ok(!strcmp(expect2, buffer), "EM_GETTEXTRANGE filled %s\n", buffer); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text3); textRange.lpstrText = buffer; textRange.chrg.cpMin = 4; textRange.chrg.cpMax = 11; result = SendMessage(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange); ok(result == 7, "EM_GETTEXTRANGE returned %ld\n", result); ok(!strcmp(expect3, buffer), "EM_GETTEXTRANGE filled %s\n", buffer); DestroyWindow(hwndRichEdit); }
static void test_EM_FINDTEXT(void) { HWND hwndRichEdit = new_richedit(NULL); /* Empty rich edit control */ run_tests_EM_FINDTEXT(hwndRichEdit, "1", find_tests, sizeof(find_tests)/sizeof(struct find_s)); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) haystack); /* Haystack text */ run_tests_EM_FINDTEXT(hwndRichEdit, "2", find_tests2, sizeof(find_tests2)/sizeof(struct find_s)); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) haystack2); /* Haystack text 2 (with EOL characters) */ run_tests_EM_FINDTEXT(hwndRichEdit, "3", find_tests3, sizeof(find_tests3)/sizeof(struct find_s)); DestroyWindow(hwndRichEdit); }
static void test_WM_GETTEXTLENGTH(void) { HWND hwndRichEdit = new_richedit(NULL); static const char text3[] = "aaa\r\nbbb\r\nccc\r\nddd\r\neee"; static const char text4[] = "aaa\r\nbbb\r\nccc\r\nddd\r\neee\r\n"; int result; /* Test for WM_GETTEXTLENGTH */ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text3); result = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0); ok(result == lstrlen(text3), "WM_GETTEXTLENGTH reports incorrect length %d, expected %d\n", result, lstrlen(text3)); SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text4); result = SendMessage(hwndRichEdit, WM_GETTEXTLENGTH, 0, 0); ok(result == lstrlen(text4), "WM_GETTEXTLENGTH reports incorrect length %d, expected %d\n", result, lstrlen(text4)); DestroyWindow(hwndRichEdit); }
static void test_EM_POSFROMCHAR(void) { HWND hwndRichEdit = new_richedit(NULL); int i; POINTL pl; LRESULT result; unsigned int height = 0; int xpos = 0; static const char text[] = "aa\n" "this is a long line of text that should be longer than the " "control's width\n" "cc\n" "dd\n" "ee\n" "ff\n" "gg\n" "hh\n"; /* Fill the control to lines to ensure that most of them are offscreen */ for (i = 0; i < 50; i++) { /* Do not modify the string; it is exactly 16 characters long. */ SendMessage(hwndRichEdit, EM_SETSEL, 0, 0); SendMessage(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"0123456789ABCD\r\n"); } /* Richedit 1.0 receives a POINTL* on wParam and character offset on lParam, returns void. Richedit 2.0 receives character offset on wParam, ignores lParam, returns MAKELONG(x,y) Richedit 3.0 accepts either of the above API conventions. */ /* Testing Richedit 1.0 API format */ /* Testing start of lines. X-offset should be constant on all cases (native is 1). Since all lines are identical and drawn with the same font, they should have the same height... right? */ for (i = 0; i < 50; i++) { /* All the lines are 16 characters long */ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, i * 16); ok(result == 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result); if (i == 0) { ok(pl.y == 0, "EM_POSFROMCHAR reports y=%d, expected 0\n", pl.y); ok(pl.x == 1 || broken(pl.x == 0), /* Win9x, WinME and NT4 */ "EM_POSFROMCHAR reports x=%d, expected 1\n", pl.x); xpos = pl.x; } else if (i == 1) { ok(pl.y > 0, "EM_POSFROMCHAR reports y=%d, expected > 0\n", pl.y); ok(pl.x == xpos, "EM_POSFROMCHAR reports x=%d, expected %d\n", pl.x, xpos); height = pl.y; } else { ok(pl.y == i * height, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl.y, i * height); ok(pl.x == xpos, "EM_POSFROMCHAR reports x=%d, expected %d\n", pl.x, xpos); } } /* Testing position at end of text */ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, 50 * 16); ok(result == 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result); ok(pl.y == 50 * height, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl.y, 50 * height); ok(pl.x == xpos, "EM_POSFROMCHAR reports x=%d, expected %d\n", pl.x, xpos); /* Testing position way past end of text */ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, 55 * 16); ok(result == 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result); ok(pl.y == 50 * height, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl.y, 50 * height); ok(pl.x == xpos, "EM_POSFROMCHAR reports x=%d, expected %d\n", pl.x, xpos); /* Testing that vertical scrolling does, in fact, have an effect on EM_POSFROMCHAR */ SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEDOWN, 0); /* line down */ for (i = 0; i < 50; i++) { /* All the lines are 16 characters long */ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, i * 16); ok(result == 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result); ok(pl.y == (i - 1) * height, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl.y, (i - 1) * height); ok(pl.x == xpos, "EM_POSFROMCHAR reports x=%d, expected %d\n", pl.x, xpos); } /* Testing position at end of text */ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, 50 * 16); ok(result == 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result); ok(pl.y == (50 - 1) * height, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl.y, (50 - 1) * height); ok(pl.x == xpos, "EM_POSFROMCHAR reports x=%d, expected %d\n", pl.x, xpos); /* Testing position way past end of text */ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, 55 * 16); ok(result == 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result); ok(pl.y == (50 - 1) * height, "EM_POSFROMCHAR reports y=%d, expected %d\n", pl.y, (50 - 1) * height); ok(pl.x == xpos, "EM_POSFROMCHAR reports x=%d, expected %d\n", pl.x, xpos); /* Testing that horizontal scrolling does, in fact, have an effect on EM_POSFROMCHAR */ SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text); SendMessage(hwndRichEdit, EM_SCROLL, SB_LINEUP, 0); /* line up */ result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, 0); ok(result == 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result); ok(pl.y == 0, "EM_POSFROMCHAR reports y=%d, expected 0\n", pl.y); ok(pl.x == 1 || broken(pl.x == 0), /* Win9x, WinME and NT4 */ "EM_POSFROMCHAR reports x=%d, expected 1\n", pl.x); xpos = pl.x; SendMessage(hwndRichEdit, WM_HSCROLL, SB_LINERIGHT, 0); result = SendMessage(hwndRichEdit, EM_POSFROMCHAR, (WPARAM)&pl, 0); ok(result == 0, "EM_POSFROMCHAR returned %ld, expected 0\n", result); ok(pl.y == 0, "EM_POSFROMCHAR reports y=%d, expected 0\n", pl.y); todo_wine { /* Fails on builtin because horizontal scrollbar is not being shown */ ok(pl.x < xpos || broken(pl.x == xpos), /* Win9x, WinME and NT4 */ "EM_POSFROMCHAR reports x=%d, expected value less than %d\n", pl.x, xpos); } DestroyWindow(hwndRichEdit); }
static void test_WM_SETTEXT(void) { static const struct { const char *itemtext; DWORD lines; DWORD lines_broken; } testitems[] = { { "TestSomeText", 1}, { "TestSomeText\r", 1}, { "TestSomeText\rSomeMoreText\r", 2, 1}, /* NT4 and below */ { "TestSomeText\n\nTestSomeText", 3}, { "TestSomeText\r\r\nTestSomeText", 2}, { "TestSomeText\r\r\n\rTestSomeText", 3, 2}, /* NT4 and below */ { "TestSomeText\r\n\r\r\n\rTestSomeText", 4, 3}, /* NT4 and below */ { "TestSomeText\r\n" ,2}, { "TestSomeText\r\nSomeMoreText\r\n", 3}, { "TestSomeText\r\n\r\nTestSomeText", 3}, { "TestSomeText TestSomeText" ,1}, { "TestSomeText \r\nTestSomeText", 2}, { "TestSomeText\r\n \r\nTestSomeText", 3}, { "TestSomeText\n", 2}, { "TestSomeText\r\r\r", 3, 1}, /* NT4 and below */ { "TestSomeText\r\r\rSomeMoreText", 4, 2} /* NT4 and below */ }; HWND hwndRichEdit = new_richedit(NULL); int i; /* This test attempts to show that WM_SETTEXT on a riched32 control does not * attempt to modify the text that is pasted into the control, and should * return it as is. In particular, \r\r\n is NOT converted, unlike riched20. * * For riched32, the rules for breaking lines seem to be the following: * - \r\n is one line break. This is the normal case. * - \r{0,2}\n is one line break. In particular, \n by itself is a line break. * - \r{0,N-1}\r\r\n is N line breaks. * - \n{1,N} are that many line breaks. * - \r with text or other characters (except \n) past it, is a line break. That * is, a run of \r{N} without a terminating \n is considered N line breaks * - \r at the end of the text is NOT a line break. This differs from riched20, * where \r at the end of the text is a proper line break. */ for (i = 0; i < sizeof(testitems)/sizeof(testitems[0]); i++) { char buf[1024] = {0}; LRESULT result; result = SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) testitems[i].itemtext); ok (result == 1, "[%d] WM_SETTEXT returned %ld instead of 1\n", i, result); result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buf); ok (result == lstrlen(buf), "[%d] WM_GETTEXT returned %ld instead of expected %u\n", i, result, lstrlen(buf)); result = strcmp(testitems[i].itemtext, buf); ok (result == 0, "[%d] WM_SETTEXT round trip: strcmp = %ld\n", i, result); result = SendMessage(hwndRichEdit, EM_GETLINECOUNT, 0, 0); ok (result == testitems[i].lines || broken(testitems[i].lines_broken && result == testitems[i].lines_broken), "[%d] EM_GETLINECOUNT returned %ld, expected %d\n", i, result, testitems[i].lines); } DestroyWindow(hwndRichEdit); }
static void test_EM_GETLINE(void) { int i; HWND hwndRichEdit = new_richedit(NULL); static const int nBuf = 1024; char dest[1024], origdest[1024]; LRESULT linecount; const char text[] = "foo bar\r\n" "\r" "\r\r\n" "bar\n"; BOOL broken_os = FALSE; SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) text); linecount = SendMessage(hwndRichEdit, EM_GETLINECOUNT, 0, 0); if (linecount == 4) { broken_os = TRUE; win_skip("Win9x, WinME and NT4 handle '\\r only' differently\n"); } memset(origdest, 0xBB, nBuf); for (i = 0; i < sizeof(gl)/sizeof(struct getline_s); i++) { int nCopied, expected_nCopied, expected_bytes_written; char gl_text[1024]; if (gl[i].line >= linecount) continue; /* Win9x, WinME and NT4 */ if (broken_os && gl[i].broken_text) /* Win9x, WinME and NT4 */ strcpy(gl_text, gl[i].broken_text); else strcpy(gl_text, gl[i].text); expected_nCopied = min(gl[i].buffer_len, strlen(gl_text)); /* Cater for the fact that Win9x, WinME and NT4 don't append the '\0' */ expected_bytes_written = min(gl[i].buffer_len, strlen(gl_text) + (broken_os ? 0 : 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_text[0] && !dest[1] && !strncmp(dest+2, origdest+2, nBuf-2), "buffer_len=1\n"); else { ok(!strncmp(dest, gl_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 void test_EM_STREAMIN(void) { HWND hwndRichEdit = new_richedit(NULL); LRESULT result; EDITSTREAM es; char buffer[1024] = {0}; const char * streamText0 = "{\\rtf1 TestSomeText}"; const char * streamText0a = "{\\rtf1 TestSomeText\\par}"; const char * streamText0b = "{\\rtf1 TestSomeText\\par\\par}"; const char * streamText1 = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang12298{\\fonttbl{\\f0\\fswiss\\fprq2\\fcharset0 System;}}\r\n" "\\viewkind4\\uc1\\pard\\f0\\fs17 TestSomeText\\par\r\n" "}\r\n"; /* This should be accepted in richedit 1.0 emulation. See bug #8326 */ const char * streamText2 = "{{\\colortbl;\\red0\\green255\\blue102;\\red255\\green255\\blue255;" "\\red170\\green255\\blue255;\\red255\\green238\\blue0;\\red51\\green255" "\\blue221;\\red238\\green238\\blue238;}\\tx0 \\tx424 \\tx848 \\tx1272 " "\\tx1696 \\tx2120 \\tx2544 \\tx2968 \\tx3392 \\tx3816 \\tx4240 \\tx4664 " "\\tx5088 \\tx5512 \\tx5936 \\tx6360 \\tx6784 \\tx7208 \\tx7632 \\tx8056 " "\\tx8480 \\tx8904 \\tx9328 \\tx9752 \\tx10176 \\tx10600 \\tx11024 " "\\tx11448 \\tx11872 \\tx12296 \\tx12720 \\tx13144 \\cf2 RichEdit1\\line }"; const char * streamText3 = "RichEdit1"; /* Minimal test without \par at the end */ es.dwCookie = (DWORD_PTR)&streamText0; es.dwError = 0; es.pfnCallback = test_EM_STREAMIN_esCallback; SendMessage(hwndRichEdit, EM_STREAMIN, (WPARAM)(SF_RTF), (LPARAM)&es); result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); ok (result == 12, "EM_STREAMIN: Test 0 returned %ld, expected 12\n", result); result = strcmp (buffer,"TestSomeText"); ok (result == 0, "EM_STREAMIN: Test 0 set wrong text: Result: %s\n",buffer); ok(es.dwError == 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es.dwError, 0); /* Native richedit 2.0 ignores last \par */ es.dwCookie = (DWORD_PTR)&streamText0a; es.dwError = 0; es.pfnCallback = test_EM_STREAMIN_esCallback; SendMessage(hwndRichEdit, EM_STREAMIN, (WPARAM)(SF_RTF), (LPARAM)&es); result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); ok (result == 12, "EM_STREAMIN: Test 0-a returned %ld, expected 12\n", result); result = strcmp (buffer,"TestSomeText"); ok (result == 0, "EM_STREAMIN: Test 0-a set wrong text: Result: %s\n",buffer); ok(es.dwError == 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es.dwError, 0); /* Native richedit 2.0 ignores last \par, next-to-last \par appears */ es.dwCookie = (DWORD_PTR)&streamText0b; es.dwError = 0; es.pfnCallback = test_EM_STREAMIN_esCallback; SendMessage(hwndRichEdit, EM_STREAMIN, (WPARAM)(SF_RTF), (LPARAM)&es); result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); ok (result == 14, "EM_STREAMIN: Test 0-b returned %ld, expected 14\n", result); result = strcmp (buffer,"TestSomeText\r\n"); ok (result == 0, "EM_STREAMIN: Test 0-b set wrong text: Result: %s\n",buffer); ok(es.dwError == 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es.dwError, 0); es.dwCookie = (DWORD_PTR)&streamText1; es.dwError = 0; es.pfnCallback = test_EM_STREAMIN_esCallback; SendMessage(hwndRichEdit, EM_STREAMIN, (WPARAM)(SF_RTF), (LPARAM)&es); result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); ok (result == 12, "EM_STREAMIN: Test 1 returned %ld, expected 12\n", result); result = strcmp (buffer,"TestSomeText"); ok (result == 0, "EM_STREAMIN: Test 1 set wrong text: Result: %s\n",buffer); ok(es.dwError == 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es.dwError, 0); es.dwCookie = (DWORD_PTR)&streamText2; es.dwError = 0; SendMessage(hwndRichEdit, EM_STREAMIN, (WPARAM)(SF_RTF), (LPARAM)&es); result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); todo_wine { ok (result == 9, "EM_STREAMIN: Test 2 returned %ld, expected 9\n", result); } result = strcmp (buffer,"RichEdit1"); todo_wine { ok (result == 0, "EM_STREAMIN: Test 2 set wrong text: Result: %s\n",buffer); } ok(es.dwError == 0, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es.dwError, 0); es.dwCookie = (DWORD_PTR)&streamText3; es.dwError = 0; SendMessage(hwndRichEdit, EM_STREAMIN, (WPARAM)(SF_RTF), (LPARAM)&es); result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buffer); ok (result == 0, "EM_STREAMIN: Test 3 returned %ld, expected 0\n", result); ok (strlen(buffer) == 0, "EM_STREAMIN: Test 3 set wrong text: Result: %s\n",buffer); ok(es.dwError == -16, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es.dwError, -16); DestroyWindow(hwndRichEdit); }
static void test_WM_SETTEXT() { HWND hwndRichEdit = new_richedit(NULL); const char * TestItem1 = "TestSomeText"; const char * TestItem2 = "TestSomeText\r"; const char * TestItem3 = "TestSomeText\rSomeMoreText\r"; const char * TestItem4 = "TestSomeText\n\nTestSomeText"; const char * TestItem5 = "TestSomeText\r\r\nTestSomeText"; const char * TestItem6 = "TestSomeText\r\r\n\rTestSomeText"; const char * TestItem7 = "TestSomeText\r\n\r\r\n\rTestSomeText"; const char * TestItem8 = "TestSomeText\r\n"; const char * TestItem9 = "TestSomeText\r\nSomeMoreText\r\n"; const char * TestItem10 = "TestSomeText\r\n\r\nTestSomeText"; const char * TestItem11 = "TestSomeText TestSomeText"; const char * TestItem12 = "TestSomeText \r\nTestSomeText"; const char * TestItem13 = "TestSomeText\r\n \r\nTestSomeText"; const char * TestItem14 = "TestSomeText\n"; const char * TestItem15 = "TestSomeText\r\r\r"; const char * TestItem16 = "TestSomeText\r\r\rSomeMoreText"; char buf[1024] = {0}; LRESULT result; /* This test attempts to show that WM_SETTEXT on a riched32 control does not attempt to modify the text that is pasted into the control, and should return it as is. In particular, \r\r\n is NOT converted, unlike riched20. Currently, builtin riched32 mangles solitary \r or \n when not part of a \r\n pair. For riched32, the rules for breaking lines seem to be the following: - \r\n is one line break. This is the normal case. - \r{0,N}\n is one line break. In particular, \n by itself is a line break. - \n{1,N} are that many line breaks. - \r with text or other characters (except \n) past it, is a line break. That is, a run of \r{N} without a terminating \n is considered N line breaks - \r at the end of the text is NOT a line break. This differs from riched20, where \r at the end of the text is a proper line break. This causes TestItem2 to fail its test. */ #define TEST_SETTEXT(a, b, nlines, is_todo, is_todo2) \ result = SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) a); \ ok (result == 1, "WM_SETTEXT returned %ld instead of 1\n", result); \ result = SendMessage(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM) buf); \ ok (result == lstrlen(buf), \ "WM_GETTEXT returned %ld instead of expected %u\n", \ result, lstrlen(buf)); \ result = strcmp(b, buf); \ if (is_todo) todo_wine { \ ok(result == 0, \ "WM_SETTEXT round trip: strcmp = %ld\n", result); \ } else { \ ok(result == 0, \ "WM_SETTEXT round trip: strcmp = %ld\n", result); \ } \ result = SendMessage(hwndRichEdit, EM_GETLINECOUNT, 0, 0); \ if (is_todo2) todo_wine { \ ok(result == nlines, "EM_GETLINECOUNT returned %ld, expected %d\n", result, nlines); \ } else { \ ok(result == nlines, "EM_GETLINECOUNT returned %ld, expected %d\n", result, nlines); \ } TEST_SETTEXT(TestItem1, TestItem1, 1, 0, 0) TEST_SETTEXT(TestItem2, TestItem2, 1, 0, 0) TEST_SETTEXT(TestItem3, TestItem3, 2, 0, 0) TEST_SETTEXT(TestItem4, TestItem4, 3, 0, 0) TEST_SETTEXT(TestItem5, TestItem5, 2, 0, 0) TEST_SETTEXT(TestItem6, TestItem6, 3, 0, 0) TEST_SETTEXT(TestItem7, TestItem7, 4, 0, 0) TEST_SETTEXT(TestItem8, TestItem8, 2, 0, 0) TEST_SETTEXT(TestItem9, TestItem9, 3, 0, 0) TEST_SETTEXT(TestItem10, TestItem10, 3, 0, 0) TEST_SETTEXT(TestItem11, TestItem11, 1, 0, 0) TEST_SETTEXT(TestItem12, TestItem12, 2, 0, 0) TEST_SETTEXT(TestItem13, TestItem13, 3, 0, 0) TEST_SETTEXT(TestItem14, TestItem14, 2, 0, 0) TEST_SETTEXT(TestItem15, TestItem15, 3, 0, 0) TEST_SETTEXT(TestItem16, TestItem16, 4, 0, 0) #undef TEST_SETTEXT DestroyWindow(hwndRichEdit); }
/* * This test attempts to show the effect of enter on a richedit * control v1.0 inserts CRLF whereas for higher versions it only * inserts CR. If shows that EM_GETTEXTEX with GT_USECRLF == WM_GETTEXT * and also shows that GT_USECRLF has no effect in richedit 1.0, but * does for higher. The same test is cloned in riched32 and riched20. */ static void test_enter(void) { static const struct { const char *initialtext; const int cursor; const char *expectedtext; } testenteritems[] = { { "aaabbb\r\n", 3, "aaa\r\nbbb\r\n"}, { "aaabbb\r\n", 6, "aaabbb\r\n\r\n"}, { "aa\rabbb\r\n", 7, "aa\rabbb\r\n\r\n"}, { "aa\rabbb\r\n", 3, "aa\r\r\nabbb\r\n"}, { "aa\rabbb\r\n", 2, "aa\r\n\rabbb\r\n"} }; char expectedbuf[1024]; char resultbuf[1024]; HWND hwndRichEdit = new_richedit(NULL); UINT i,j; for (i = 0; i < sizeof(testenteritems)/sizeof(testenteritems[0]); i++) { char buf[1024] = {0}; LRESULT result; GETTEXTEX getText; const char *expected; /* Set the text to the initial text */ result = SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)testenteritems[i].initialtext); ok (result == 1, "[%d] WM_SETTEXT returned %ld instead of 1\n", i, result); /* Send Enter */ SendMessageA(hwndRichEdit, EM_SETSEL, testenteritems[i].cursor, testenteritems[i].cursor); simulate_typing_characters(hwndRichEdit, "\r"); /* 1. Retrieve with WM_GETTEXT */ buf[0] = 0x00; result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buf); expected = testenteritems[i].expectedtext; resultbuf[0]=0x00; for (j = 0; j < (UINT)result; j++) sprintf(resultbuf+strlen(resultbuf), "%02x", buf[j] & 0xFF); expectedbuf[0] = '\0'; for (j = 0; j < strlen(expected); j++) sprintf(expectedbuf+strlen(expectedbuf), "%02x", expected[j] & 0xFF); result = strcmp(expected, buf); ok (result == 0, "[%d] WM_GETTEXT unexpected '%s' expected '%s'\n", i, resultbuf, expectedbuf); /* 2. Retrieve with EM_GETTEXTEX, GT_DEFAULT */ getText.cb = sizeof(buf); getText.flags = GT_DEFAULT; getText.codepage = CP_ACP; getText.lpDefaultChar = NULL; getText.lpUsedDefChar = NULL; buf[0] = 0x00; result = SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf); expected = testenteritems[i].expectedtext; resultbuf[0]=0x00; for (j = 0; j < (UINT)result; j++) sprintf(resultbuf+strlen(resultbuf), "%02x", buf[j] & 0xFF); expectedbuf[0] = '\0'; for (j = 0; j < strlen(expected); j++) sprintf(expectedbuf+strlen(expectedbuf), "%02x", expected[j] & 0xFF); result = strcmp(expected, buf); ok (result == 0 || broken(buf[0]==0x00 /* WinNT4 */), "[%d] EM_GETTEXTEX, GT_DEFAULT unexpected '%s', expected '%s'\n", i, resultbuf, expectedbuf); /* 3. Retrieve with EM_GETTEXTEX, GT_USECRLF */ getText.cb = sizeof(buf); getText.flags = GT_USECRLF; getText.codepage = CP_ACP; getText.lpDefaultChar = NULL; getText.lpUsedDefChar = NULL; buf[0] = 0x00; result = SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf); expected = testenteritems[i].expectedtext; resultbuf[0]=0x00; for (j = 0; j < (UINT)result; j++) sprintf(resultbuf+strlen(resultbuf), "%02x", buf[j] & 0xFF); expectedbuf[0] = '\0'; for (j = 0; j < strlen(expected); j++) sprintf(expectedbuf+strlen(expectedbuf), "%02x", expected[j] & 0xFF); result = strcmp(expected, buf); ok (result == 0 || broken(buf[0]==0x00 /* WinNT4 */), "[%d] EM_GETTEXTEX, GT_USECRLF unexpected '%s', expected '%s'\n", i, resultbuf, expectedbuf); } DestroyWindow(hwndRichEdit); }