[RICHED20_WINETEST] Sync with Wine Staging 4.18. CORE-16441

This commit is contained in:
Amine Khaldi 2019-11-23 12:11:20 +01:00
parent 661b8a2a05
commit 76cf09cfea
3 changed files with 481 additions and 344 deletions

View file

@ -340,14 +340,12 @@ static void test_EM_FINDTEXT(BOOL unicode)
hwndRichEdit = new_richedit(NULL);
/* Empty rich edit control */
run_tests_EM_FINDTEXT(hwndRichEdit, "1", find_tests,
sizeof(find_tests)/sizeof(struct find_s), unicode);
run_tests_EM_FINDTEXT(hwndRichEdit, "1", find_tests, ARRAY_SIZE(find_tests), unicode);
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)haystack);
/* Haystack text */
run_tests_EM_FINDTEXT(hwndRichEdit, "2", find_tests2,
sizeof(find_tests2)/sizeof(struct find_s), unicode);
run_tests_EM_FINDTEXT(hwndRichEdit, "2", find_tests2, ARRAY_SIZE(find_tests2), unicode);
/* Setting a format on an arbitrary range should have no effect in search
results. This tests correct offset reporting across runs. */
@ -359,8 +357,7 @@ static void test_EM_FINDTEXT(BOOL unicode)
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
/* Haystack text, again */
run_tests_EM_FINDTEXT(hwndRichEdit, "2-bis", find_tests2,
sizeof(find_tests2)/sizeof(struct find_s), unicode);
run_tests_EM_FINDTEXT(hwndRichEdit, "2-bis", find_tests2, ARRAY_SIZE(find_tests2), unicode);
/* Yet another range */
cf2.dwMask = CFM_BOLD | cf2.dwMask;
@ -369,8 +366,7 @@ static void test_EM_FINDTEXT(BOOL unicode)
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf2);
/* Haystack text, again */
run_tests_EM_FINDTEXT(hwndRichEdit, "2-bisbis", find_tests2,
sizeof(find_tests2)/sizeof(struct find_s), unicode);
run_tests_EM_FINDTEXT(hwndRichEdit, "2-bisbis", find_tests2, ARRAY_SIZE(find_tests2), unicode);
DestroyWindow(hwndRichEdit);
}
@ -404,7 +400,7 @@ static void test_EM_GETLINE(void)
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text);
memset(origdest, 0xBB, nBuf);
for (i = 0; i < sizeof(gl)/sizeof(struct getline_s); i++)
for (i = 0; i < ARRAY_SIZE(gl); i++)
{
int nCopied;
int expected_nCopied = min(gl[i].buffer_len, strlen(gl[i].text));
@ -509,7 +505,7 @@ static void test_EM_LINELENGTH(void)
{15, 4}, /* Line 3: |wine */
};
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text1);
for (i = 0; i < sizeof(offset_test1)/sizeof(offset_test1[0]); i++) {
for (i = 0; i < ARRAY_SIZE(offset_test1); i++) {
result = SendMessageA(hwndRichEdit, EM_LINELENGTH, offset_test1[i][0], 0);
ok(result == offset_test1[i][1], "Length of line at offset %d is %ld, expected %d\n",
offset_test1[i][0], result, offset_test1[i][1]);
@ -755,6 +751,8 @@ static void test_EM_SETCHARFORMAT(void)
HWND hwndRichEdit = new_richedit(NULL);
CHARFORMAT2A cf2;
CHARFORMAT2W cfW;
CHARFORMATA cf1a;
CHARFORMATW cf1w;
int rc = 0;
int tested_effects[] = {
CFE_BOLD,
@ -1342,6 +1340,23 @@ static void test_EM_SETCHARFORMAT(void)
ok(cf2.dwEffects & CFE_UNDERLINE, "got %08x\n", cf2.dwEffects);
ok(cf2.bUnderlineType == CFU_UNDERLINEDOUBLE, "got %x\n", cf2.bUnderlineType);
/* Check setting CFM_ALL2/CFM_EFFECTS2 in CHARFORMAT(A/W). */
memset(&cf1a, 0, sizeof(CHARFORMATA));
memset(&cf1w, 0, sizeof(CHARFORMATW));
cf1a.cbSize = sizeof(CHARFORMATA);
cf1w.cbSize = sizeof(CHARFORMATW);
cf1a.dwMask = cf1w.dwMask = CFM_ALL2;
cf1a.dwEffects = cf1w.dwEffects = CFM_EFFECTS2;
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf1a);
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf1a);
/* flags only valid for CHARFORMAT2 should be masked out */
ok((cf1a.dwMask & (CFM_ALL2 & ~CFM_ALL)) == 0, "flags were not masked out\n");
ok((cf1a.dwEffects & (CFM_EFFECTS2 & ~CFM_EFFECTS)) == 0, "flags were not masked out\n");
SendMessageA(hwndRichEdit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf1w);
SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf1w);
ok((cf1w.dwMask & (CFM_ALL2 & ~CFM_ALL)) == 0, "flags were not masked out\n");
ok((cf1w.dwEffects & (CFM_EFFECTS2 & ~CFM_EFFECTS)) == 0, "flags were not masked out\n");
DestroyWindow(hwndRichEdit);
}
@ -2049,7 +2064,7 @@ static void test_EM_AUTOURLDETECT(void)
urlRet=SendMessageA(hwndRichEdit, EM_AUTOURLDETECT, (WPARAM)"h", (LPARAM)"h");
ok(urlRet==E_INVALIDARG, "Bad wParam2: urlRet is: %d\n", urlRet);
/* for each url, check the text to see if CFE_LINK effect is present */
for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
for (i = 0; i < ARRAY_SIZE(urls); i++) {
SendMessageA(hwndRichEdit, EM_AUTOURLDETECT, FALSE, 0);
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)urls[i].text);
@ -2063,10 +2078,10 @@ static void test_EM_AUTOURLDETECT(void)
DestroyWindow(hwndRichEdit);
/* Test detection of URLs within normal text - WM_SETTEXT case. */
for (i = 0; i < sizeof(urls)/sizeof(struct urls_s); i++) {
for (i = 0; i < ARRAY_SIZE(urls); i++) {
hwndRichEdit = new_richedit(parent);
for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
char * at_pos;
int at_offset;
int end_offset;
@ -2117,7 +2132,7 @@ static void test_EM_AUTOURLDETECT(void)
}
}
for (j = 0; j < sizeof(templates_non_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_non_delim); j++) {
char * at_pos;
int at_offset;
int end_offset;
@ -2158,7 +2173,7 @@ static void test_EM_AUTOURLDETECT(void)
}
}
for (j = 0; j < sizeof(templates_xten_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_xten_delim); j++) {
char * at_pos;
int at_offset;
int end_offset;
@ -2213,7 +2228,7 @@ static void test_EM_AUTOURLDETECT(void)
}
}
for (j = 0; j < sizeof(templates_neutral_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_neutral_delim); j++) {
char * at_pos, * end_pos;
int at_offset;
int end_offset;
@ -2421,7 +2436,7 @@ static void test_EM_AUTOURLDETECT(void)
*/
/* Set entire text in one go, like WM_SETTEXT */
for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
char * at_pos;
int at_offset;
int end_offset;
@ -2476,7 +2491,7 @@ static void test_EM_AUTOURLDETECT(void)
}
/* Set selection with X to the URL */
for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
char * at_pos;
int at_offset;
int end_offset;
@ -2530,7 +2545,7 @@ static void test_EM_AUTOURLDETECT(void)
}
/* Set selection with X to the first character of the URL, then the rest */
for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
char * at_pos;
int at_offset;
int end_offset;
@ -2598,7 +2613,7 @@ static void test_EM_AUTOURLDETECT(void)
hwndRichEdit = new_richedit(parent);
/* Set selection with X to the URL */
for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
char * at_pos;
int at_offset;
int end_offset;
@ -2649,7 +2664,7 @@ static void test_EM_AUTOURLDETECT(void)
}
/* Set selection with X to the first character of the URL, then the rest */
for (j = 0; j < sizeof(templates_delim) / sizeof(const char *); j++) {
for (j = 0; j < ARRAY_SIZE(templates_delim); j++) {
char * at_pos;
int at_offset;
int end_offset;
@ -4933,7 +4948,7 @@ static void test_EM_EXSETSEL(void)
{
HWND hwndRichEdit = new_richedit(NULL);
int i;
const int num_tests = sizeof(exsetsel_tests)/sizeof(struct exsetsel_s);
const int num_tests = ARRAY_SIZE(exsetsel_tests);
/* sending some text to the window */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"testing selection");
@ -4955,7 +4970,7 @@ static void test_EM_EXSETSEL(void)
/* Test with multibyte character */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk");
/* 012345 6 78901 */
cr.cpMin = 4, cr.cpMax = 8;
cr.cpMin = 4; cr.cpMax = 8;
result = SendMessageA(hwndRichEdit, EM_EXSETSEL, 0, (LPARAM)&cr);
ok(result == 8, "EM_EXSETSEL return %ld expected 8\n", result);
result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, sizeof(bufA), (LPARAM)bufA);
@ -4988,7 +5003,7 @@ static void test_EM_SETSEL(void)
char buffA[32] = {0};
HWND hwndRichEdit = new_richedit(NULL);
int i;
const int num_tests = sizeof(exsetsel_tests)/sizeof(struct exsetsel_s);
const int num_tests = ARRAY_SIZE(exsetsel_tests);
/* sending some text to the window */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"testing selection");
@ -5623,7 +5638,7 @@ static void test_EM_FORMATRANGE(void)
SendMessageA(hwndRichEdit, EM_FORMATRANGE, FALSE, 0);
for (i = 0; i < sizeof(fmtstrings)/sizeof(fmtstrings[0]); i++)
for (i = 0; i < ARRAY_SIZE(fmtstrings); i++)
{
GETTEXTLENGTHEX gtl;
SIZE stringsize;
@ -5758,6 +5773,30 @@ static DWORD CALLBACK test_EM_STREAMIN_esCallback_UTF8Split(DWORD_PTR dwCookie,
return 0;
}
static DWORD CALLBACK test_EM_STREAMIN_null_bytes(DWORD_PTR cookie, BYTE *buf, LONG size, LONG *written)
{
DWORD *phase = (DWORD *)cookie;
if (*phase == 0)
{
static const char first[] = "{\\rtf1\\ansi{Th\0is";
*written = sizeof(first);
memcpy(buf, first, *written);
}
else if (*phase == 1)
{
static const char second[] = " is a test}}";
*written = sizeof(second);
memcpy(buf, second, *written);
}
else
*written = 0;
++*phase;
return 0;
}
struct StringWithLength {
int length;
char *buffer;
@ -5831,7 +5870,7 @@ static void test_EM_STREAMIN(void)
};
const WCHAR streamText5[] = { 'T', 'e', 's', 't', 'S', 'o', 'm', 'e', 'T', 'e', 'x', 't' };
int length5 = sizeof(streamText5) / sizeof(WCHAR);
int length5 = ARRAY_SIZE(streamText5);
struct StringWithLength cookieForStream5 = {
sizeof(streamText5),
(char *)streamText5,
@ -6044,6 +6083,17 @@ static void test_EM_STREAMIN(void)
result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
ok (!strcmp(buffer, "line1"),
"EM_STREAMIN: Unexpected text '%s'\n", buffer);
/* Test 0-bytes inside text */
hwndRichEdit = new_richedit_with_style(NULL, 0);
phase = 0;
es.dwCookie = (DWORD_PTR)&phase;
es.dwError = 0;
es.pfnCallback = test_EM_STREAMIN_null_bytes;
result = SendMessageA(hwndRichEdit, EM_STREAMIN, SF_RTF, (LPARAM)&es);
ok(result == 16, "got %ld, expected %d\n", result, 16);
result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
ok (!strcmp(buffer, "Th is is a test"), "EM_STREAMIN: Unexpected text '%s'\n", buffer);
}
static void test_EM_StreamIn_Undo(void)
@ -6868,7 +6918,7 @@ static void test_EN_LINK(void)
GetCursorPos(&orig_cursor_pos);
SetCursorPos(0, 0);
for (i = 0; i < sizeof(link_notify_tests)/sizeof(link_notify_tests[0]); i++)
for (i = 0; i < ARRAY_SIZE(link_notify_tests); i++)
{
link_notify_test("cursor position simulated", i, hwnd, parent,
link_notify_tests[i].msg, link_notify_tests[i].wParam, link_notify_tests[i].lParam,
@ -6878,7 +6928,7 @@ static void test_EN_LINK(void)
ClientToScreen(hwnd, &cursor_screen_pos);
SetCursorPos(cursor_screen_pos.x, cursor_screen_pos.y);
for (i = 0; i < sizeof(link_notify_tests)/sizeof(link_notify_tests[0]); i++)
for (i = 0; i < ARRAY_SIZE(link_notify_tests); i++)
{
link_notify_test("cursor position set", i, hwnd, parent,
link_notify_tests[i].msg, link_notify_tests[i].wParam, link_notify_tests[i].lParam,
@ -8178,7 +8228,7 @@ static void test_EM_FINDWORDBREAK_W(void)
int i;
HWND hwndRichEdit = new_richeditW(NULL);
ok(IsWindowUnicode(hwndRichEdit), "window should be unicode\n");
for (i = 0; i < sizeof(delimiter_tests)/sizeof(delimiter_tests[0]); i++)
for (i = 0; i < ARRAY_SIZE(delimiter_tests); i++)
{
WCHAR wbuf[2];
int result;
@ -8212,7 +8262,7 @@ static void test_EM_FINDWORDBREAK_A(void)
HWND hwndRichEdit = new_richedit(NULL);
ok(!IsWindowUnicode(hwndRichEdit), "window should not be unicode\n");
for (i = 0; i < sizeof(delimiter_tests)/sizeof(delimiter_tests[0]); i++)
for (i = 0; i < ARRAY_SIZE(delimiter_tests); i++)
{
int result;
char buf[2];
@ -8228,12 +8278,21 @@ static void test_EM_FINDWORDBREAK_A(void)
DestroyWindow(hwndRichEdit);
}
static void format_test_result(char *target, const char *src)
{
int i;
for (i = 0; i < strlen(src); i++)
sprintf(target + 2*i, "%02x", src[i] & 0xFF);
target[2*i] = 0;
}
/*
* 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.
* Also shows the difference between WM_CHAR/WM_KEYDOWN in v1.0 and higher versions
*/
static void test_enter(void)
{
@ -8254,15 +8313,14 @@ static void test_enter(void)
char expectedbuf[1024];
char resultbuf[1024];
HWND hwndRichEdit = new_richedit(NULL);
UINT i,j;
for (i = 0; i < sizeof(testenteritems)/sizeof(testenteritems[0]); i++) {
UINT i;
char buf[1024] = {0};
GETTEXTEX getText = {sizeof(buf)};
LRESULT result;
GETTEXTEX getText;
const char *expected;
for (i = 0; i < ARRAY_SIZE(testenteritems); i++)
{
/* 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);
@ -8276,12 +8334,8 @@ static void test_enter(void)
result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buf);
expected = testenteritems[i].expectedwmtext;
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);
format_test_result(resultbuf, buf);
format_test_result(expectedbuf, expected);
result = strcmp(expected, buf);
ok (result == 0,
@ -8289,21 +8343,14 @@ static void test_enter(void)
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].expectedemtext;
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);
format_test_result(resultbuf, buf);
format_test_result(expectedbuf, expected);
result = strcmp(expected, buf);
ok (result == 0,
@ -8311,21 +8358,14 @@ static void test_enter(void)
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].expectedemtextcrlf;
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);
format_test_result(resultbuf, buf);
format_test_result(expectedbuf, expected);
result = strcmp(expected, buf);
ok (result == 0,
@ -8333,6 +8373,34 @@ static void test_enter(void)
i, resultbuf, expectedbuf);
}
/* Show that WM_CHAR is handled differently from WM_KEYDOWN */
getText.flags = GT_DEFAULT;
getText.codepage = CP_ACP;
result = SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"");
ok (result == 1, "[%d] WM_SETTEXT returned %ld instead of 1\n", i, result);
SendMessageW(hwndRichEdit, WM_CHAR, 'T', 0);
SendMessageW(hwndRichEdit, WM_KEYDOWN, VK_RETURN, 0);
result = SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
ok(result == 2, "Got %d\n", (int)result);
format_test_result(resultbuf, buf);
format_test_result(expectedbuf, "T\r");
result = strcmp(resultbuf, expectedbuf);
ok (result == 0, "[%d] EM_GETTEXTEX, GT_DEFAULT unexpected '%s', expected '%s'\n", i, resultbuf, expectedbuf);
result = SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"");
ok (result == 1, "[%d] WM_SETTEXT returned %ld instead of 1\n", i, result);
SendMessageW(hwndRichEdit, WM_CHAR, 'T', 0);
SendMessageW(hwndRichEdit, WM_CHAR, '\r', 0);
result = SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf);
ok(result == 1, "Got %d\n", (int)result);
format_test_result(resultbuf, buf);
format_test_result(expectedbuf, "T");
result = strcmp(resultbuf, expectedbuf);
ok (result == 0, "[%d] EM_GETTEXTEX, GT_DEFAULT unexpected '%s', expected '%s'\n", i, resultbuf, expectedbuf);
DestroyWindow(hwndRichEdit);
}
@ -8538,7 +8606,7 @@ static void test_alignment_style(void)
EDITSTREAM es;
int i;
for (i = 0; i < sizeof(align_style) / sizeof(align_style[0]); i++)
for (i = 0; i < ARRAY_SIZE(align_style); i++)
{
DWORD dwStyle, new_align;
@ -8646,8 +8714,8 @@ static void test_rtf(void)
result = SendMessageA( edit, EM_STREAMIN, SF_RTF, (LPARAM)&es );
ok( result == 11, "got %ld\n", result );
result = SendMessageW( edit, WM_GETTEXT, sizeof(buf)/sizeof(buf[0]), (LPARAM)buf );
ok( result == sizeof(expect_specials)/sizeof(expect_specials[0]), "got %ld\n", result );
result = SendMessageW( edit, WM_GETTEXT, ARRAY_SIZE(buf), (LPARAM)buf );
ok( result == ARRAY_SIZE(expect_specials), "got %ld\n", result );
ok( !memcmp( buf, expect_specials, sizeof(expect_specials) ), "got %s\n", wine_dbgstr_w(buf) );
/* Show that \rtlpar propagates to the second paragraph and is

View file

@ -113,10 +113,36 @@ static ULONG get_refcount(IUnknown *iface)
return IUnknown_Release(iface);
}
#define CHECK_TYPEINFO(disp,expected_riid) _check_typeinfo((IDispatch *)disp, expected_riid, __LINE__)
static void _check_typeinfo(IDispatch* disp, REFIID expected_riid, int line)
{
ITypeInfo *typeinfo;
TYPEATTR *typeattr;
UINT count;
HRESULT hr;
count = 10;
hr = IDispatch_GetTypeInfoCount(disp, &count);
ok_(__FILE__,line)(hr == S_OK, "IDispatch_GetTypeInfoCount failed: 0x%08x.\n", hr);
ok_(__FILE__,line)(count == 1, "got wrong count: %u.\n", count);
hr = IDispatch_GetTypeInfo(disp, 0, LOCALE_SYSTEM_DEFAULT, &typeinfo);
ok_(__FILE__,line)(hr == S_OK, "IDispatch_GetTypeInfo failed: 0x%08x.\n", hr);
hr = ITypeInfo_GetTypeAttr(typeinfo, &typeattr);
ok_(__FILE__,line)(hr == S_OK, "ITypeInfo_GetTypeAttr failed: 0x%08x.\n", hr);
ok_(__FILE__,line)(IsEqualGUID(&typeattr->guid, expected_riid),
"Unexpected type guid: %s.\n", wine_dbgstr_guid(&typeattr->guid));
ITypeInfo_ReleaseTypeAttr(typeinfo, typeattr);
ITypeInfo_Release(typeinfo);
}
static void test_Interfaces(void)
{
IRichEditOle *reOle = NULL, *reOle1 = NULL;
ITextDocument *txtDoc = NULL;
ITextDocument2Old *txtDoc2Old = NULL;
ITextSelection *txtSel = NULL, *txtSel2;
IUnknown *punk;
HRESULT hres;
@ -144,6 +170,7 @@ static void test_Interfaces(void)
(void **) &txtDoc);
ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
ok(txtDoc != NULL, "IRichEditOle_QueryInterface\n");
CHECK_TYPEINFO(txtDoc, &IID_ITextDocument);
hres = ITextDocument_GetSelection(txtDoc, NULL);
ok(hres == E_INVALIDARG, "ITextDocument_GetSelection: 0x%x\n", hres);
@ -195,6 +222,16 @@ static void test_Interfaces(void)
hres = IRichEditOle_QueryInterface(reOle, &IID_IOleInPlaceSite, (void **) &punk);
ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n");
hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument2Old, (void **)&txtDoc2Old);
ok(hres == S_OK, "IRichEditOle_QueryInterface\n");
ok(txtDoc2Old != NULL, "IRichEditOle_QueryInterface\n");
ok((ITextDocument *)txtDoc2Old == txtDoc, "interface pointer isn't equal.\n");
EXPECT_REF(txtDoc2Old, 5);
EXPECT_REF(reOle, 5);
CHECK_TYPEINFO(txtDoc2Old, &IID_ITextDocument);
ITextDocument2Old_Release(txtDoc2Old);
ITextDocument_Release(txtDoc);
IRichEditOle_Release(reOle);
refcount = IRichEditOle_Release(reOle);
@ -207,6 +244,19 @@ static void test_Interfaces(void)
ok(hres == CO_E_RELEASED, "ITextSelection after ITextDocument destroyed\n");
ITextSelection_Release(txtSel);
w = new_richedit(NULL);
res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle);
ok(res, "SendMessage\n");
ok(reOle != NULL, "EM_GETOLEINTERFACE\n");
hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument2Old, (void **)&txtDoc2Old);
ok(hres == S_OK, "IRichEditOle_QueryInterface failed: 0x%08x.\n", hres);
ok(txtDoc2Old != NULL, "IRichEditOle_QueryInterface\n");
CHECK_TYPEINFO(txtDoc2Old, &IID_ITextDocument);
ITextDocument2Old_Release(txtDoc2Old);
IRichEditOle_Release(reOle);
DestroyWindow(w);
}
static void test_ITextDocument_Open(void)
@ -247,8 +297,8 @@ static void test_ITextDocument_Open(void)
tomReadOnly|tomShareDenyWrite, tomReadOnly|tomShareDenyRead
};
int tomNumSingle = sizeof(tomConstantsSingle)/sizeof(tomConstantsSingle[0]);
int tomNumMulti = sizeof(tomConstantsMulti)/sizeof(tomConstantsMulti[0]);
int tomNumSingle = ARRAY_SIZE(tomConstantsSingle);
int tomNumMulti = ARRAY_SIZE(tomConstantsMulti);
int i;
V_VT(&testfile) = VT_BSTR;
@ -481,21 +531,21 @@ static void test_GetText(void)
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
/* ITextSelection */
first = 0, lim = 4;
first = 0; lim = 4;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 4, lim = 0;
first = 4; lim = 0;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 1, lim = 1;
first = 1; lim = 1;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
@ -507,35 +557,35 @@ static void test_GetText(void)
ok(hres == E_INVALIDARG, "ITextSelection_GetText\n");
}
first = 8, lim = 12;
first = 8; lim = 12;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 8, lim = 13;
first = 8; lim = 13;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 12, lim = 13;
first = 12; lim = 13;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = 0, lim = -1;
first = 0; lim = -1;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
ok(!lstrcmpW(bstr, bufW4), "got wrong text: %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
first = -1, lim = 9;
first = -1; lim = 9;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_GetText(txtSel, &bstr);
ok(hres == S_OK, "ITextSelection_GetText\n");
@ -707,7 +757,7 @@ static void test_ITextRange_GetChar(void)
ITextRange_Release(txtRge);
release_interfaces(&w, &reOle, &txtDoc, NULL);
first = 0, lim = 0;
first = 0; lim = 0;
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
@ -719,7 +769,7 @@ static void test_ITextRange_GetChar(void)
ITextRange_Release(txtRge);
release_interfaces(&w, &reOle, &txtDoc, NULL);
first = 12, lim = 12;
first = 12; lim = 12;
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
@ -731,7 +781,7 @@ static void test_ITextRange_GetChar(void)
ITextRange_Release(txtRge);
release_interfaces(&w, &reOle, &txtDoc, NULL);
first = 13, lim = 13;
first = 13; lim = 13;
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
@ -745,7 +795,7 @@ static void test_ITextRange_GetChar(void)
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
first = 12, lim = 12;
first = 12; lim = 12;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
hres = ITextRange_GetChar(txtRge, NULL);
@ -803,15 +853,19 @@ static void test_ITextRange_ScrollIntoView(void)
/* Scroll to the top. */
check_range(w, txtDoc, 0, 1, tomStart, 0);
check_range(w, txtDoc, 0, 1, tomEnd, 0);
/* Scroll to the bottom. */
check_range(w, txtDoc, 19, 20, tomStart, 1);
check_range(w, txtDoc, 19, 20, tomEnd, 1);
/* Back up to the top. */
check_range(w, txtDoc, 0, 1, tomStart, 0);
check_range(w, txtDoc, 0, 1, tomEnd, 0);
/* Large range */
check_range(w, txtDoc, 0, 20, tomStart, 0);
check_range(w, txtDoc, 0, 20, tomEnd, 1);
hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
@ -835,28 +889,28 @@ static void test_ITextSelection_GetChar(void)
create_interfaces(&w, &reOle, &txtDoc, &txtSel);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
first = 0, lim = 4;
first = 0; lim = 4;
SendMessageA(w, EM_SETSEL, first, lim);
pch = 0xdeadbeef;
hres = ITextSelection_GetChar(txtSel, &pch);
ok(hres == S_OK, "ITextSelection_GetChar\n");
ok(pch == 'T', "got wrong char: %c\n", pch);
first = 0, lim = 0;
first = 0; lim = 0;
SendMessageA(w, EM_SETSEL, first, lim);
pch = 0xdeadbeef;
hres = ITextSelection_GetChar(txtSel, &pch);
ok(hres == S_OK, "ITextSelection_GetChar\n");
ok(pch == 'T', "got wrong char: %c\n", pch);
first = 12, lim = 12;
first = 12; lim = 12;
SendMessageA(w, EM_SETSEL, first, lim);
pch = 0xdeadbeef;
hres = ITextSelection_GetChar(txtSel, &pch);
ok(hres == S_OK, "ITextSelection_GetChar\n");
ok(pch == '\r', "got wrong char: %c\n", pch);
first = 13, lim = 13;
first = 13; lim = 13;
SendMessageA(w, EM_SETSEL, first, lim);
pch = 0xdeadbeef;
hres = ITextSelection_GetChar(txtSel, &pch);
@ -890,7 +944,7 @@ static void test_ITextRange_GetStart_GetEnd(void)
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
first = 1, lim = 6;
first = 1; lim = 6;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
start = 0xdeadbeef;
@ -903,7 +957,7 @@ static void test_ITextRange_GetStart_GetEnd(void)
ok(end == 6, "got wrong end value: %d\n", end);
ITextRange_Release(txtRge);
first = 6, lim = 1;
first = 6; lim = 1;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
start = 0xdeadbeef;
@ -916,7 +970,7 @@ static void test_ITextRange_GetStart_GetEnd(void)
ok(end == 6, "got wrong end value: %d\n", end);
ITextRange_Release(txtRge);
first = -1, lim = 13;
first = -1; lim = 13;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
start = 0xdeadbeef;
@ -929,7 +983,7 @@ static void test_ITextRange_GetStart_GetEnd(void)
ok(end == 13, "got wrong end value: %d\n", end);
ITextRange_Release(txtRge);
first = 13, lim = 13;
first = 13; lim = 13;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
start = 0xdeadbeef;
@ -1109,7 +1163,7 @@ static void test_ITextSelection_GetStart_GetEnd(void)
create_interfaces(&w, &reOle, &txtDoc, &txtSel);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
first = 2, lim = 5;
first = 2; lim = 5;
SendMessageA(w, EM_SETSEL, first, lim);
start = 0xdeadbeef;
hres = ITextSelection_GetStart(txtSel, &start);
@ -1120,7 +1174,7 @@ static void test_ITextSelection_GetStart_GetEnd(void)
ok(hres == S_OK, "ITextSelection_GetEnd\n");
ok(end == 5, "got wrong end value: %d\n", end);
first = 5, lim = 2;
first = 5; lim = 2;
SendMessageA(w, EM_SETSEL, first, lim);
start = 0xdeadbeef;
hres = ITextSelection_GetStart(txtSel, &start);
@ -1131,7 +1185,7 @@ static void test_ITextSelection_GetStart_GetEnd(void)
ok(hres == S_OK, "ITextSelection_GetEnd\n");
ok(end == 5, "got wrong end value: %d\n", end);
first = 0, lim = -1;
first = 0; lim = -1;
SendMessageA(w, EM_SETSEL, first, lim);
start = 0xdeadbeef;
hres = ITextSelection_GetStart(txtSel, &start);
@ -1142,7 +1196,7 @@ static void test_ITextSelection_GetStart_GetEnd(void)
ok(hres == S_OK, "ITextSelection_GetEnd\n");
ok(end == 13, "got wrong end value: %d\n", end);
first = 13, lim = 13;
first = 13; lim = 13;
SendMessageA(w, EM_SETSEL, first, lim);
start = 0xdeadbeef;
hres = ITextSelection_GetStart(txtSel, &start);
@ -1315,7 +1369,7 @@ static void test_ITextRange_GetDuplicate(void)
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
first = 0, lim = 4;
first = 0; lim = 4;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres);
@ -1358,7 +1412,7 @@ static void test_ITextRange_Collapse(void)
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
first = 4, lim = 8;
first = 4; lim = 8;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
hres = ITextRange_Collapse(txtRge, tomTrue);
@ -1420,7 +1474,7 @@ static void test_ITextRange_Collapse(void)
ok(end == 4, "got wrong end value: %d\n", end);
ITextRange_Release(txtRge);
first = 6, lim = 6;
first = 6; lim = 6;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
hres = ITextRange_Collapse(txtRge, tomEnd);
@ -1433,7 +1487,7 @@ static void test_ITextRange_Collapse(void)
ok(end == 6, "got wrong end value: %d\n", end);
ITextRange_Release(txtRge);
first = 8, lim = 8;
first = 8; lim = 8;
hres = ITextDocument_Range(txtDoc, first, lim, &txtRge);
ok(hres == S_OK, "got 0x%08x\n", hres);
hres = ITextRange_Collapse(txtRge, tomStart);
@ -1469,7 +1523,7 @@ static void test_ITextSelection_Collapse(void)
create_interfaces(&w, &reOle, &txtDoc, &txtSel);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
first = 4, lim = 8;
first = 4; lim = 8;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_Collapse(txtSel, tomTrue);
ok(hres == S_OK, "ITextSelection_Collapse\n");
@ -1506,7 +1560,7 @@ static void test_ITextSelection_Collapse(void)
ok(start == 4, "got wrong start value: %d\n", start);
ok(end == 4, "got wrong end value: %d\n", end);
first = 6, lim = 6;
first = 6; lim = 6;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_Collapse(txtSel, tomEnd);
ok(hres == S_FALSE, "ITextSelection_Collapse\n");
@ -1514,7 +1568,7 @@ static void test_ITextSelection_Collapse(void)
ok(start == 6, "got wrong start value: %d\n", start);
ok(end == 6, "got wrong end value: %d\n", end);
first = 8, lim = 8;
first = 8; lim = 8;
SendMessageA(w, EM_SETSEL, first, lim);
hres = ITextSelection_Collapse(txtSel, tomStart);
ok(hres == S_FALSE, "ITextSelection_Collapse\n");
@ -3278,6 +3332,61 @@ static void test_InsertObject(void)
/* received_reo4 didn't be zeroed in E_INVALIDARG case */
CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
SendMessageA(hwnd, EM_SETSEL, 0, 1);
received_reo4.cbStruct = sizeof(received_reo4);
received_reo4.cp = 1;
hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
SendMessageA(hwnd, EM_SETSEL, 1, 2);
received_reo4.cbStruct = sizeof(received_reo4);
received_reo4.cp = 0;
hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
SendMessageA(hwnd, EM_SETSEL, 2, 3);
received_reo4.cbStruct = sizeof(received_reo4);
received_reo4.cp = 0;
hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
SendMessageA(hwnd, EM_SETSEL, 0, 2);
received_reo4.cbStruct = sizeof(received_reo4);
received_reo4.cp = 0;
hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
SendMessageA(hwnd, EM_SETSEL, 1, 3);
received_reo4.cbStruct = sizeof(received_reo4);
received_reo4.cp = 0;
hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
SendMessageA(hwnd, EM_SETSEL, 2, 0);
received_reo4.cbStruct = sizeof(received_reo4);
received_reo4.cp = 0;
hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
SendMessageA(hwnd, EM_SETSEL, 0, 6);
received_reo4.cbStruct = sizeof(received_reo4);
received_reo4.cp = 0;
hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
SendMessageA(hwnd, EM_SETSEL, 4, 5);
received_reo4.cbStruct = sizeof(received_reo4);
received_reo4.cp = 0;
hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
release_interfaces(&hwnd, &reole, &doc, NULL);
}
@ -3481,6 +3590,51 @@ static void _check_selection(ITextSelection *selection, LONG expected_start, LON
expected_end, value);
}
static void test_ITextRange_SetRange(void)
{
static const CHAR test_text1[] = "TestSomeText";
ITextDocument *txtDoc = NULL;
IRichEditOle *reOle = NULL;
ITextRange *txtRge = NULL;
HRESULT hr;
HWND w;
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
ITextDocument_Range(txtDoc, 0, 0, &txtRge);
hr = ITextRange_SetRange(txtRge, 2, 4);
ok(hr == S_OK, "got 0x%08x.\n", hr);
CHECK_RANGE(txtRge, 2, 4);
hr = ITextRange_SetRange(txtRge, 2, 4);
ok(hr == S_FALSE, "got 0x%08x.\n", hr);
CHECK_RANGE(txtRge, 2, 4);
hr = ITextRange_SetRange(txtRge, 4, 2);
ok(hr == S_FALSE, "got 0x%08x.\n", hr);
CHECK_RANGE(txtRge, 2, 4);
hr = ITextRange_SetRange(txtRge, 14, 14);
ok(hr == S_OK, "got 0x%08x.\n", hr);
CHECK_RANGE(txtRge, 12, 12);
hr = ITextRange_SetRange(txtRge, 15, 15);
ok(hr == S_FALSE, "got 0x%08x.\n", hr);
CHECK_RANGE(txtRge, 12, 12);
hr = ITextRange_SetRange(txtRge, 14, 1);
ok(hr == S_OK, "got 0x%08x.\n", hr);
CHECK_RANGE(txtRge, 1, 13);
hr = ITextRange_SetRange(txtRge, -1, 4);
ok(hr == S_OK, "got 0x%08x.\n", hr);
CHECK_RANGE(txtRge, 0, 4);
ITextRange_Release(txtRge);
release_interfaces(&w, &reOle, &txtDoc, NULL);
}
static void test_Expand(void)
{
static const char test_text1[] = "TestSomeText";
@ -3922,183 +4076,6 @@ static void test_ITextRange_GetPara(void)
ITextPara_Release(txtPara);
}
static void test_ITextRange_GetText(void)
{
HWND w;
IRichEditOle *reOle = NULL;
ITextDocument *txtDoc = NULL;
ITextRange *txtRge = NULL;
HRESULT hres;
BSTR bstr = NULL;
static const CHAR test_text1[] = "TestSomeText";
static const WCHAR bufW1[] = {'T', 'e', 's', 't', 0};
static const WCHAR bufW2[] = {'T', 'e', 'x', 't', '\r', 0};
static const WCHAR bufW3[] = {'T', 'e', 'x', 't', 0};
static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm',
'e', 'T', 'e', 'x', 't', '\r', 0};
static const WCHAR bufW5[] = {'\r', 0};
#define TEST_TXTRGE_GETTEXT(first, lim, expected_string) \
create_interfaces(&w, &reOle, &txtDoc, NULL); \
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); \
ITextDocument_Range(txtDoc, first, lim, &txtRge); \
hres = ITextRange_GetText(txtRge, &bstr); \
ok(hres == S_OK, "ITextRange_GetText\n"); \
ok(!lstrcmpW(bstr, expected_string), "got wrong text: %s\n", wine_dbgstr_w(bstr)); \
SysFreeString(bstr); \
ITextRange_Release(txtRge); \
release_interfaces(&w, &reOle, &txtDoc, NULL);
TEST_TXTRGE_GETTEXT(0, 4, bufW1)
TEST_TXTRGE_GETTEXT(4, 0, bufW1)
TEST_TXTRGE_GETTEXT(8, 12, bufW3)
TEST_TXTRGE_GETTEXT(8, 13, bufW2)
TEST_TXTRGE_GETTEXT(12, 13, bufW5)
TEST_TXTRGE_GETTEXT(0, 13, bufW4)
TEST_TXTRGE_GETTEXT(1, 1, NULL)
}
static void test_ITextRange_SetRange(void)
{
HWND w;
IRichEditOle *reOle = NULL;
ITextDocument *txtDoc = NULL;
ITextRange *txtRge = NULL;
HRESULT hres;
int start, end;
static const CHAR test_text1[] = "TestSomeText";
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
ITextDocument_Range(txtDoc, 0, 0, &txtRge);
#define TEST_TXTRGE_SETRANGE(first, lim, expected_start, expected_end, expected_return) \
hres = ITextRange_SetRange(txtRge, first, lim); \
ok(hres == expected_return, "ITextRange_SetRange\n"); \
ITextRange_GetStart(txtRge, &start); \
ITextRange_GetEnd(txtRge, &end); \
ok(start == expected_start, "got wrong start value: %d\n", start); \
ok(end == expected_end, "got wrong end value: %d\n", end);
TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_OK)
TEST_TXTRGE_SETRANGE(2, 4, 2, 4, S_FALSE)
TEST_TXTRGE_SETRANGE(4, 2, 2, 4, S_FALSE)
TEST_TXTRGE_SETRANGE(14, 14, 12, 12, S_OK)
TEST_TXTRGE_SETRANGE(15, 15, 12, 12, S_FALSE)
TEST_TXTRGE_SETRANGE(14, 1, 1, 13, S_OK)
TEST_TXTRGE_SETRANGE(-1, 4, 0, 4, S_OK)
ITextRange_Release(txtRge);
release_interfaces(&w, &reOle, &txtDoc, NULL);
}
static void test_ITextRange_IsEqual2(void)
{
HWND w;
IRichEditOle *reOle = NULL;
ITextDocument *txtDoc = NULL;
ITextRange *txtRge1 = NULL, *txtRge2 = NULL;
HRESULT hres;
static const CHAR test_text1[] = "TestSomeText";
LONG res;
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
ITextDocument_Range(txtDoc, 2, 4, &txtRge1);
ITextDocument_Range(txtDoc, 2, 4, &txtRge2);
#define TEST_TXTRGE_ISEQUAL(expected_hres, expected_res) \
hres = ITextRange_IsEqual(txtRge1, txtRge2, &res); \
ok(hres == expected_hres, "ITextRange_IsEqual\n"); \
ok(res == expected_res, "got wrong return value: %d\n", res);
TEST_TXTRGE_ISEQUAL(S_OK, tomTrue)
ITextRange_SetRange(txtRge2, 1, 2);
TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse)
ITextRange_SetRange(txtRge1, 1, 1);
ITextRange_SetRange(txtRge2, 2, 2);
TEST_TXTRGE_ISEQUAL(S_FALSE, tomFalse)
ITextRange_SetRange(txtRge2, 1, 1);
TEST_TXTRGE_ISEQUAL(S_OK, tomTrue)
hres = ITextRange_IsEqual(txtRge1, txtRge1, &res);
ok(hres == S_OK, "ITextRange_IsEqual\n");
ok(res == tomTrue, "got wrong return value: %d\n", res);
hres = ITextRange_IsEqual(txtRge1, txtRge2, NULL);
ok(hres == S_OK, "ITextRange_IsEqual\n");
hres = ITextRange_IsEqual(txtRge1, NULL, NULL);
ok(hres == S_FALSE, "ITextRange_IsEqual\n");
ITextRange_Release(txtRge1);
ITextRange_Release(txtRge2);
release_interfaces(&w, &reOle, &txtDoc, NULL);
}
static void test_ITextRange_GetStoryLength(void)
{
HWND w;
IRichEditOle *reOle = NULL;
ITextDocument *txtDoc = NULL;
ITextRange *txtRge = NULL;
HRESULT hres;
LONG count;
static const CHAR test_text1[] = "TestSomeText";
int len = strlen(test_text1) + 1;
create_interfaces(&w, &reOle, &txtDoc, NULL);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
ITextDocument_Range(txtDoc, 0, 0, &txtRge);
hres = ITextRange_GetStoryLength(txtRge, &count);
ok(hres == S_OK, "ITextRange_GetStoryLength\n");
ok(count == len, "got wrong length: %d\n", count);
ITextRange_SetRange(txtRge, 1, 2);
hres = ITextRange_GetStoryLength(txtRge, &count);
ok(hres == S_OK, "ITextRange_GetStoryLength\n");
ok(count == len, "got wrong length: %d\n", count);
hres = ITextRange_GetStoryLength(txtRge, NULL);
ok(hres == E_INVALIDARG, "ITextRange_GetStoryLength\n");
ITextRange_Release(txtRge);
release_interfaces(&w, &reOle, &txtDoc, NULL);
}
static void test_ITextSelection_GetStoryLength(void)
{
HWND w;
IRichEditOle *reOle = NULL;
ITextDocument *txtDoc = NULL;
ITextSelection *txtSel = NULL;
HRESULT hres;
LONG count;
static const CHAR test_text1[] = "TestSomeText";
int len = strlen(test_text1) + 1;
create_interfaces(&w, &reOle, &txtDoc, &txtSel);
SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
hres = ITextSelection_GetStoryLength(txtSel, &count);
ok(hres == S_OK, "ITextSelection_GetStoryLength\n");
ok(count == len, "got wrong length: %d\n", count);
SendMessageA(w, EM_SETSEL, 1, 2);
hres = ITextSelection_GetStoryLength(txtSel, &count);
ok(hres == S_OK, "ITextSelection_GetStoryLength\n");
ok(count == len, "got wrong length: %d\n", count);
hres = ITextSelection_GetStoryLength(txtSel, NULL);
ok(hres == E_INVALIDARG, "ITextSelection_GetStoryLength\n");
release_interfaces(&w, &reOle, &txtDoc, &txtSel);
}
START_TEST(richole)
{
/* Must explicitly LoadLibrary(). The test has no references to functions in
@ -4115,21 +4092,17 @@ START_TEST(richole)
test_ITextSelection_SetEnd();
test_ITextSelection_Collapse();
test_ITextSelection_GetFont();
test_ITextSelection_GetStoryLength();
test_ITextDocument_Range();
test_ITextRange_GetChar();
test_ITextRange_ScrollIntoView();
test_ITextRange_GetStart_GetEnd();
test_ITextRange_SetRange();
test_ITextRange_GetDuplicate();
test_ITextRange_SetStart();
test_ITextRange_SetEnd();
test_ITextRange_Collapse();
test_ITextRange_GetFont();
test_ITextRange_GetPara();
test_ITextRange_GetText();
test_ITextRange_SetRange();
test_ITextRange_IsEqual2();
test_ITextRange_GetStoryLength();
test_GetClientSite();
test_IOleWindow_GetWindow();
test_IOleInPlaceSite_GetWindow();

View file

@ -48,7 +48,7 @@ static PCreateTextServices pCreateTextServices;
/* Use a special table for x86 machines to convert the thiscall
* calling convention. This isn't needed on other platforms. */
#ifdef __i386__
#if defined(__i386__) && !defined(__MINGW32__)
static ITextServicesVtbl itextServicesStdcallVtbl;
#define TXTSERV_VTABLE(This) (&itextServicesStdcallVtbl)
#else /* __i386__ */
@ -85,6 +85,7 @@ typedef struct ITextHostTestImpl
{
ITextHost ITextHost_iface;
LONG refCount;
CHARFORMAT2W char_format;
} ITextHostTestImpl;
static inline ITextHostTestImpl *impl_from_ITextHost(ITextHost *iface)
@ -534,7 +535,7 @@ typedef struct
static void setup_thiscall_wrappers(void)
{
#ifdef __i386__
#if defined(__i386__) && !defined(__MINGW32__)
void** pVtable;
void** pVtableEnd;
THISCALL_TO_STDCALL_THUNK *thunk;
@ -600,6 +601,21 @@ static void setup_thiscall_wrappers(void)
#endif /* __i386__ */
}
static void hf_to_cf(HFONT hf, CHARFORMAT2W *cf)
{
LOGFONTW lf;
GetObjectW(hf, sizeof(lf), &lf);
lstrcpyW(cf->szFaceName, lf.lfFaceName);
cf->yHeight = MulDiv(abs(lf.lfHeight), 1440, GetDeviceCaps(GetDC(NULL), LOGPIXELSY));
if (lf.lfWeight > FW_NORMAL) cf->dwEffects |= CFE_BOLD;
if (lf.lfItalic) cf->dwEffects |= CFE_ITALIC;
if (lf.lfUnderline) cf->dwEffects |= CFE_UNDERLINE;
if (lf.lfStrikeOut) cf->dwEffects |= CFE_SUBSCRIPT;
cf->bPitchAndFamily = lf.lfPitchAndFamily;
cf->bCharSet = lf.lfCharSet;
}
/*************************************************************************/
/* Conformance test functions. */
@ -609,6 +625,7 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
ITextHostTestImpl *dummyTextHost;
IUnknown *init;
HRESULT result;
HFONT hf;
dummyTextHost = CoTaskMemAlloc(sizeof(*dummyTextHost));
if (dummyTextHost == NULL) {
@ -617,6 +634,11 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
}
dummyTextHost->ITextHost_iface.lpVtbl = &itextHostVtbl;
dummyTextHost->refCount = 1;
memset(&dummyTextHost->char_format, 0, sizeof(dummyTextHost->char_format));
dummyTextHost->char_format.cbSize = sizeof(dummyTextHost->char_format);
dummyTextHost->char_format.dwMask = CFM_ALL2;
hf = GetStockObject(DEFAULT_GUI_FONT);
hf_to_cf(hf, &dummyTextHost->char_format);
/* MSDN states that an IUnknown object is returned by
CreateTextServices which is then queried to obtain a
@ -682,6 +704,8 @@ static void test_TxSetText(void)
ok(memcmp(rettext,settext,SysStringByteLen(rettext)) == 0,
"String returned differs\n");
SysFreeString(rettext);
/* Null-pointer should behave the same as empty-string */
hres = ITextServices_TxSetText(txtserv, 0);
@ -697,81 +721,68 @@ static void test_TxSetText(void)
ITextHost_Release(host);
}
#define CHECK_TXGETNATURALSIZE(res,width,height,hdc,rect,string) \
_check_txgetnaturalsize(res, width, height, hdc, rect, string, __LINE__)
static void _check_txgetnaturalsize(HRESULT res, LONG width, LONG height, HDC hdc, RECT rect, LPCWSTR string, int line)
{
RECT expected_rect = rect;
LONG expected_width, expected_height;
DrawTextW(hdc, string, -1, &expected_rect, DT_LEFT | DT_CALCRECT | DT_NOCLIP | DT_EDITCONTROL | DT_WORDBREAK);
expected_width = expected_rect.right - expected_rect.left;
expected_height = expected_rect.bottom - expected_rect.top;
ok_(__FILE__,line)(res == S_OK, "ITextServices_TxGetNaturalSize failed: 0x%08x.\n", res);
ok_(__FILE__,line)(width >= expected_width && width <= expected_width + 1,
"got wrong width: %d, expected: %d {+1}.\n", width, expected_width);
ok_(__FILE__,line)(height == expected_height, "got wrong height: %d, expected: %d.\n",
height, expected_height);
}
static void test_TxGetNaturalSize(void)
{
ITextServices *txtserv;
ITextHost *host;
HRESULT result;
BOOL ret;
/* This value is used when calling TxGetNaturalSize. MSDN says
that this is not supported however a null pointer cannot be
used as it will cause a segmentation violation. The values in
the structure being pointed to are required to be INT_MAX
otherwise calculations can give wrong values. */
const SIZEL psizelExtent = {INT_MAX,INT_MAX};
static const WCHAR oneA[] = {'A',0};
/* Results of measurements */
LONG xdim, ydim;
/* The device context to do the tests in */
SIZEL extent;
static const WCHAR test_text[] = {'T','e','s','t','S','o','m','e','T','e','x','t',0};
LONG width, height;
HDC hdcDraw;
/* Variables with the text metric information */
INT charwidth_caps_text[26];
TEXTMETRICA tmInfo_text;
HWND hwnd;
RECT rect;
CHARFORMAT2W cf;
LRESULT lresult;
HFONT hf;
if (!init_texthost(&txtserv, &host))
return;
hdcDraw = GetDC(NULL);
SaveDC(hdcDraw);
/* Populate the metric strucs */
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
0, 0, 100, 100, 0, 0, 0, NULL);
hdcDraw = GetDC(hwnd);
SetMapMode(hdcDraw,MM_TEXT);
GetTextMetricsA(hdcDraw, &tmInfo_text);
SetLastError(0xdeadbeef);
ret = GetCharWidth32A(hdcDraw,'A','Z',charwidth_caps_text);
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) {
win_skip("GetCharWidth32 is not available\n");
goto cleanup;
}
GetClientRect(hwnd, &rect);
/* Make measurements in MM_TEXT */
SetMapMode(hdcDraw,MM_TEXT);
xdim = 0; ydim = 0;
memset(&cf, 0, sizeof(cf));
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_ALL2;
hf = GetStockObject(DEFAULT_GUI_FONT);
hf_to_cf(hf, &cf);
result = ITextServices_TxSendMessage(txtserv, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM)&cf, &lresult);
ok(result == S_OK, "ITextServices_TxSendMessage failed: 0x%08x.\n", result);
SelectObject(hdcDraw, hf);
result = ITextServices_TxSetText(txtserv, oneA);
ok(result == S_OK, "ITextServices_TxSetText failed (result = %x)\n", result);
if (result != S_OK) {
skip("Could not set text\n");
goto cleanup;
}
result = ITextServices_TxSetText(txtserv, test_text);
ok(result == S_OK, "ITextServices_TxSetText failed: 0x%08x.\n", result);
SetLastError(0xdeadbeef);
result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT,
hdcDraw, NULL, NULL,
TXTNS_FITTOCONTENT, &psizelExtent,
&xdim, &ydim);
todo_wine ok(result == S_OK || broken(result == E_FAIL), /* WINXP Arabic Language */
"TxGetNaturalSize gave unexpected return value (result = %x)\n", result);
if (result == S_OK) {
todo_wine ok(ydim == tmInfo_text.tmHeight,
"Height calculated incorrectly (expected %d, got %d)\n",
tmInfo_text.tmHeight, ydim);
/* The native DLL adds one pixel extra when calculating widths. */
todo_wine ok(xdim >= charwidth_caps_text[0] && xdim <= charwidth_caps_text[0] + 1,
"Width calculated incorrectly (expected %d {+1}, got %d)\n",
charwidth_caps_text[0], xdim);
} else
skip("TxGetNaturalSize measurements not performed (xdim = %d, ydim = %d, result = %x, error = %x)\n",
xdim, ydim, result, GetLastError());
extent.cx = -1; extent.cy = -1;
width = rect.right - rect.left;
height = 0;
result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT, hdcDraw, NULL, NULL,
TXTNS_FITTOCONTENT, &extent, &width, &height);
todo_wine CHECK_TXGETNATURALSIZE(result, width, height, hdcDraw, rect, test_text);
cleanup:
RestoreDC(hdcDraw,1);
ReleaseDC(NULL,hdcDraw);
ReleaseDC(hwnd, hdcDraw);
DestroyWindow(hwnd);
ITextServices_Release(txtserv);
ITextHost_Release(host);
}
@ -894,6 +905,7 @@ static void test_QueryInterface(void)
HRESULT hres;
IRichEditOle *reole, *txtsrv_reole;
ITextDocument *txtdoc, *txtsrv_txtdoc;
ITextDocument2Old *txtdoc2old, *txtsrv_txtdoc2old;
ULONG refcount;
if(!init_texthost(&txtserv, &host))
@ -920,6 +932,17 @@ static void test_QueryInterface(void)
ITextDocument_Release(txtdoc);
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 2, "got wrong ref count: %d\n", refcount);
hres = IRichEditOle_QueryInterface(txtsrv_reole, &IID_ITextDocument2Old, (void **)&txtdoc2old);
ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 3, "got wrong ref count: %d\n", refcount);
refcount = get_refcount((IUnknown *)txtsrv_reole);
ok(refcount == 3, "got wrong ref count: %d\n", refcount);
ITextDocument2Old_Release(txtdoc2old);
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 2, "got wrong ref count: %d\n", refcount);
IRichEditOle_Release(txtsrv_reole);
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 1, "got wrong ref count: %d\n", refcount);
@ -946,6 +969,77 @@ static void test_QueryInterface(void)
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 1, "got wrong ref count: %d\n", refcount);
/* ITextDocument2Old */
hres = ITextServices_QueryInterface(txtserv, &IID_ITextDocument2Old, (void **)&txtsrv_txtdoc2old);
ok(hres == S_OK, "ITextServices_QueryInterface: 0x%08x\n", hres);
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 2, "got wrong ref count: %d\n", refcount);
refcount = get_refcount((IUnknown *)txtsrv_txtdoc2old);
ok(refcount == 2, "got wrong ref count: %d\n", refcount);
hres = ITextDocument2Old_QueryInterface(txtsrv_txtdoc2old, &IID_IRichEditOle, (void **)&reole);
ok(hres == S_OK, "ITextDocument2Old_QueryInterface: 0x%08x\n", hres);
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 3, "got wrong ref count: %d\n", refcount);
refcount = get_refcount((IUnknown *)txtsrv_txtdoc2old);
ok(refcount == 3, "got wrong ref count: %d\n", refcount);
IRichEditOle_Release(reole);
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 2, "got wrong ref count: %d\n", refcount);
ITextDocument2Old_Release(txtsrv_txtdoc2old);
refcount = get_refcount((IUnknown *)txtserv);
ok(refcount == 1, "got wrong ref count: %d\n", refcount);
ITextServices_Release(txtserv);
ITextHost_Release(host);
}
static void test_default_format(void)
{
ITextServices *txtserv;
ITextHost *host;
HRESULT result;
LRESULT lresult;
CHARFORMAT2W cf2;
const CHARFORMATW *host_cf;
DWORD expected_effects;
if (!init_texthost(&txtserv, &host))
return;
cf2.cbSize = sizeof(CHARFORMAT2W);
result = ITextServices_TxSendMessage(txtserv, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&cf2, &lresult);
ok(result == S_OK, "ITextServices_TxSendMessage failed: 0x%08x.\n", result);
ITextHostImpl_TxGetCharFormat(host, &host_cf);
ok(!lstrcmpW(host_cf->szFaceName, cf2.szFaceName), "got wrong font name: %s.\n", wine_dbgstr_w(cf2.szFaceName));
ok(cf2.yHeight == host_cf->yHeight, "got wrong yHeight: %d, expected %d.\n", cf2.yHeight, host_cf->yHeight);
expected_effects = (cf2.dwEffects & ~(CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR));
ok(host_cf->dwEffects == expected_effects, "got wrong dwEffects: %x, expected %x.\n", cf2.dwEffects, expected_effects);
ok(cf2.bPitchAndFamily == host_cf->bPitchAndFamily, "got wrong bPitchAndFamily: %x, expected %x.\n",
cf2.bPitchAndFamily, host_cf->bPitchAndFamily);
ok(cf2.bCharSet == host_cf->bCharSet, "got wrong bCharSet: %x, expected %x.\n", cf2.bCharSet, host_cf->bCharSet);
ITextServices_Release(txtserv);
ITextHost_Release(host);
}
static void test_TxGetScroll(void)
{
ITextServices *txtserv;
ITextHost *host;
HRESULT ret;
if (!init_texthost(&txtserv, &host))
return;
ret = ITextServices_TxGetHScroll(txtserv, NULL, NULL, NULL, NULL, NULL);
ok(ret == S_OK, "ITextSerHices_GetVScroll failed: 0x%08x.\n", ret);
ret = ITextServices_TxGetVScroll(txtserv, NULL, NULL, NULL, NULL, NULL);
ok(ret == S_OK, "ITextServices_GetVScroll failed: 0x%08x.\n", ret);
ITextServices_Release(txtserv);
ITextHost_Release(host);
}
@ -980,6 +1074,8 @@ START_TEST( txtsrv )
test_TxGetNaturalSize();
test_TxDraw();
test_QueryInterface();
test_default_format();
test_TxGetScroll();
}
if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE);
}