From b6bf232f1880c114f9debd4e902a1083c436a411 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 20 Jul 2015 22:53:56 +0000 Subject: [PATCH] [RICHED20_WINETEST] Sync with Wine Staging 1.7.47. CORE-9924 svn path=/trunk/; revision=68496 --- rostests/winetests/riched20/CMakeLists.txt | 4 + rostests/winetests/riched20/editor.c | 462 +++- rostests/winetests/riched20/richole.c | 2554 +++++++++++++++++++- rostests/winetests/riched20/txtsrv.c | 76 +- 4 files changed, 2875 insertions(+), 221 deletions(-) diff --git a/rostests/winetests/riched20/CMakeLists.txt b/rostests/winetests/riched20/CMakeLists.txt index 276d142aff0..305b2b23a78 100644 --- a/rostests/winetests/riched20/CMakeLists.txt +++ b/rostests/winetests/riched20/CMakeLists.txt @@ -7,6 +7,10 @@ list(APPEND SOURCE testlist.c txtsrv.c) +if(MSVC) + set_property(SOURCE editor.c APPEND_STRING PROPERTY COMPILE_FLAGS " /w14189") +endif() + add_executable(riched20_winetest ${SOURCE}) set_module_type(riched20_winetest win32cui) add_importlibs(riched20_winetest ole32 oleaut32 user32 gdi32 msvcrt kernel32) diff --git a/rostests/winetests/riched20/editor.c b/rostests/winetests/riched20/editor.c index 756cd6590c2..29af470824e 100644 --- a/rostests/winetests/riched20/editor.c +++ b/rostests/winetests/riched20/editor.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -194,7 +195,7 @@ static struct find_s find_tests2[] = { {10, -1, "winewine", FR_DOWN | FR_WHOLEWORD, 23}, {11, -1, "winewine", FR_WHOLEWORD, 0}, {31, -1, "winewine", FR_WHOLEWORD, 23}, - + /* Bad ranges */ {5, 200, "XXX", FR_DOWN, -1}, {-20, 20, "Wine", FR_DOWN, -1}, @@ -1327,7 +1328,7 @@ static void test_TM_PLAINTEXT(void) ok((cf2.dwMask == cf2test.dwMask) && (cf2.dwEffects == cf2test.dwEffects), "two selections' formats differ - cf2.dwMask: %x, cf2test.dwMask %x, cf2.dwEffects: %x, cf2test.dwEffects: %x\n", cf2.dwMask, cf2test.dwMask, cf2.dwEffects, cf2test.dwEffects); - + /*Fill the control with a "wine" string, which when inserted will be bold*/ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"wine"); @@ -1399,7 +1400,7 @@ static void test_WM_GETTEXT(void) "WM_GETTEXT returned %d, expected %d\n", result, lstrlenA(buffer)); SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); result = strcmp(buffer,text); - ok(result == 0, + ok(result == 0, "WM_GETTEXT: settext and gettext differ. strcmp: %d\n", result); /* Test for returned value of WM_GETTEXTLENGTH */ @@ -1586,7 +1587,7 @@ static void test_EM_SETOPTIONS(void) /* testing no readonly by sending 'a' to the control*/ SendMessageA(hwndRichEdit, WM_CHAR, 'a', 0x1E0001); SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); - ok(buffer[0]=='a', + ok(buffer[0]=='a', "EM_SETOPTIONS: Text not changed! s1:%s s2:%s\n", text, buffer); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); @@ -1595,8 +1596,8 @@ static void test_EM_SETOPTIONS(void) SendMessageA(hwndRichEdit, EM_SETOPTIONS, ECOOP_SET, ECO_READONLY); SendMessageA(hwndRichEdit, WM_CHAR, 'a', 0x1E0001); SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); - ok(buffer[0]==text[0], - "EM_SETOPTIONS: Text changed! s1:%s s2:%s\n", text, buffer); + ok(buffer[0]==text[0], + "EM_SETOPTIONS: Text changed! s1:%s s2:%s\n", text, buffer); /* EM_SETOPTIONS changes the window style, but changing the * window style does not change the options. */ @@ -1634,11 +1635,11 @@ static void check_CFE_LINK_rcvd(HWND hwnd, BOOL is_url, const char * url) BOOL link_present = FALSE; link_present = check_CFE_LINK_selection(hwnd, 0, 1); - if (is_url) + if (is_url) { /* control text is url; should get CFE_LINK */ ok(link_present, "URL Case: CFE_LINK not set for [%s].\n", url); } - else + else { ok(!link_present, "Non-URL Case: CFE_LINK set for [%s].\n", url); } @@ -2414,7 +2415,7 @@ static void test_EM_SCROLL(void) "(line %d scrolled to line %d\n", y_before, y_after); y_before = y_after; - + r = SendMessageA(hwndRichEdit, EM_SCROLL, SB_PAGEUP, 0); /* page up */ y_after = SendMessageA(hwndRichEdit, EM_GETFIRSTVISIBLELINE, 0, 0); ok(((r & 0xffffff00) == 0x0001ff00), @@ -2422,7 +2423,7 @@ static void test_EM_SCROLL(void) "(r == 0x%08x)\n", r); ok(y_after < y_before, "EM_SCROLL page up not functioning (line " "%d scrolled to line %d\n", y_before, y_after); - + y_before = y_after; r = SendMessageA(hwndRichEdit, EM_SCROLL, SB_LINEDOWN, 0); /* line down */ @@ -3220,16 +3221,16 @@ static void test_scrollbar_visibility(void) static void test_EM_SETUNDOLIMIT(void) { /* cases we test for: - * default behaviour - limiting at 100 undo's + * default behaviour - limiting at 100 undo's * undo disabled - setting a limit of 0 * undo limited - undo limit set to some to some number, like 2 * bad input - sending a negative number should default to 100 undo's */ - + HWND hwndRichEdit = new_richedit(NULL); CHARRANGE cr; int i; int result; - + SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"x"); cr.cpMin = 0; cr.cpMax = 1; @@ -3270,13 +3271,13 @@ static void test_EM_SETUNDOLIMIT(void) SendMessageA(hwndRichEdit, WM_UNDO, 0, 0); ok(!SendMessageA(hwndRichEdit, EM_CANUNDO, 0, 0), "EM_SETUNDOLIMIT allowed a third undo with UNDOLIMIT set to 2\n"); - + /* fourth case - setting negative numbers should default to 100 undos */ SendMessageA(hwndRichEdit,EM_EMPTYUNDOBUFFER, 0,0); result = SendMessageA(hwndRichEdit, EM_SETUNDOLIMIT, -1, 0); - ok (result == 100, + ok (result == 100, "EM_SETUNDOLIMIT returned %d when set to -1, instead of 100\n",result); - + DestroyWindow(hwndRichEdit); } @@ -3403,6 +3404,37 @@ static void test_WM_SETTEXT(void) #undef TEST_SETTEXTW } +/* Set *pcb to one to show that the remaining cb-1 bytes are not + resent to the callkack. */ +static DWORD CALLBACK test_esCallback_written_1(DWORD_PTR dwCookie, + LPBYTE pbBuff, + LONG cb, + LONG *pcb) +{ + char** str = (char**)dwCookie; + ok(*pcb == cb || *pcb == 0, "cb %d, *pcb %d\n", cb, *pcb); + *pcb = 0; + if (cb > 0) { + memcpy(*str, pbBuff, cb); + *str += cb; + *pcb = 1; + } + return 0; +} + +static int count_pars(const char *buf) +{ + const char *p = buf; + int count = 0; + while ((p = strstr( p, "\\par" )) != NULL) + { + if (!isalpha( p[4] )) + count++; + p++; + } + return count; +} + static void test_EM_STREAMOUT(void) { HWND hwndRichEdit = new_richedit(NULL); @@ -3427,6 +3459,19 @@ static void test_EM_STREAMOUT(void) ok(strcmp(buf, TestItem1) == 0, "streamed text different, got %s\n", buf); + /* RTF mode writes the final end of para \r if it's part of the selection */ + p = buf; + SendMessageA(hwndRichEdit, EM_STREAMOUT, SF_RTF, (LPARAM)&es); + ok (count_pars(buf) == 1, "got %s\n", buf); + p = buf; + SendMessageA(hwndRichEdit, EM_SETSEL, 0, 12); + SendMessageA(hwndRichEdit, EM_STREAMOUT, SF_RTF|SFF_SELECTION, (LPARAM)&es); + ok (count_pars(buf) == 0, "got %s\n", buf); + p = buf; + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + SendMessageA(hwndRichEdit, EM_STREAMOUT, SF_RTF|SFF_SELECTION, (LPARAM)&es); + ok (count_pars(buf) == 1, "got %s\n", buf); + SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)TestItem2); p = buf; es.dwCookie = (DWORD_PTR)&p; @@ -3439,6 +3484,20 @@ static void test_EM_STREAMOUT(void) ok(r == 14, "streamed text length is %d, expecting 14\n", r); ok(strcmp(buf, TestItem3) == 0, "streamed text different from, got %s\n", buf); + + /* And again RTF mode writes the final end of para \r if it's part of the selection */ + p = buf; + SendMessageA(hwndRichEdit, EM_STREAMOUT, SF_RTF, (LPARAM)&es); + ok (count_pars(buf) == 2, "got %s\n", buf); + p = buf; + SendMessageA(hwndRichEdit, EM_SETSEL, 0, 13); + SendMessageA(hwndRichEdit, EM_STREAMOUT, SF_RTF|SFF_SELECTION, (LPARAM)&es); + ok (count_pars(buf) == 1, "got %s\n", buf); + p = buf; + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); + SendMessageA(hwndRichEdit, EM_STREAMOUT, SF_RTF|SFF_SELECTION, (LPARAM)&es); + ok (count_pars(buf) == 2, "got %s\n", buf); + SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)TestItem3); p = buf; es.dwCookie = (DWORD_PTR)&p; @@ -3451,6 +3510,19 @@ static void test_EM_STREAMOUT(void) ok(strcmp(buf, TestItem3) == 0, "streamed text different, got %s\n", buf); + /* Use a callback that sets *pcb to one */ + p = buf; + es.dwCookie = (DWORD_PTR)&p; + es.dwError = 0; + es.pfnCallback = test_esCallback_written_1; + memset(buf, 0, sizeof(buf)); + SendMessageA(hwndRichEdit, EM_STREAMOUT, 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); } @@ -3515,9 +3587,9 @@ static void test_EM_SETTEXTEX(void) int sel_start, sel_end; SETTEXTEX setText; GETTEXTEX getText; - WCHAR TestItem1[] = {'T', 'e', 's', 't', - 'S', 'o', 'm', 'e', - 'T', 'e', 'x', 't', 0}; + WCHAR TestItem1[] = {'T', 'e', 's', 't', + 'S', 'o', 'm', 'e', + 'T', 'e', 'x', 't', 0}; WCHAR TestItem1alt[] = {'T', 'T', 'e', 's', 't', 'S', 'o', 'm', 'e', 'T', 'e', 'x', @@ -3732,8 +3804,8 @@ static void test_EM_SETTEXTEX(void) /* !ST_SELECTION && Unicode && !\rtf */ result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, 0); SendMessageA(hwndRichEdit, EM_GETTEXTEX, (WPARAM)&getText, (LPARAM)buf); - - ok (result == 1, + + ok (result == 1, "EM_SETTEXTEX returned %d, instead of 1\n",result); ok(!buf[0], "EM_SETTEXTEX with NULL lParam should clear rich edit.\n"); @@ -3751,7 +3823,7 @@ static void test_EM_SETTEXTEX(void) "EM_SETTEXTEX with NULL lParam to replace selection" " with no text should return 0. Got %i\n", result); - + /* put some text back: !ST_SELECTION && Unicode && !\rtf */ setText.flags = 0; SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1); @@ -3962,68 +4034,68 @@ static void test_EM_EXLIMITTEXT(void) char buffer[1024 + 1]; int textlimit = 0; /* multiple of 100 */ HWND hwndRichEdit = new_richedit(NULL); - + i = SendMessageA(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); ok(32767 == i, "EM_EXLIMITTEXT: expected: %d, actual: %d\n", 32767, i); /* default */ - + textlimit = 256000; SendMessageA(hwndRichEdit, EM_EXLIMITTEXT, 0, textlimit); i = SendMessageA(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); /* set higher */ ok(textlimit == i, "EM_EXLIMITTEXT: expected: %d, actual: %d\n", textlimit, i); - + textlimit = 1000; SendMessageA(hwndRichEdit, EM_EXLIMITTEXT, 0, textlimit); i = SendMessageA(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); /* set lower */ ok(textlimit == i, "EM_EXLIMITTEXT: expected: %d, actual: %d\n", textlimit, i); - + SendMessageA(hwndRichEdit, EM_EXLIMITTEXT, 0, 0); i = SendMessageA(hwndRichEdit, EM_GETLIMITTEXT, 0, 0); /* default for WParam = 0 */ ok(65536 == i, "EM_EXLIMITTEXT: expected: %d, actual: %d\n", 65536, i); - + textlimit = sizeof(text)-1; memset(text, 'W', textlimit); text[sizeof(text)-1] = 0; SendMessageA(hwndRichEdit, EM_EXLIMITTEXT, 0, textlimit); /* maxed out text */ SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); - + SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); /* select everything */ SendMessageA(hwndRichEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); len1 = selEnd - selBegin; - + SendMessageA(hwndRichEdit, WM_KEYDOWN, VK_BACK, 1); SendMessageA(hwndRichEdit, WM_CHAR, VK_BACK, 1); SendMessageA(hwndRichEdit, WM_KEYUP, VK_BACK, 1); SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); SendMessageA(hwndRichEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); len2 = selEnd - selBegin; - + ok(len1 != len2, "EM_EXLIMITTEXT: Change Expected\nOld Length: %d, New Length: %d, Limit: %d\n", len1,len2,i); - + SendMessageA(hwndRichEdit, WM_KEYDOWN, 'A', 1); SendMessageA(hwndRichEdit, WM_CHAR, 'A', 1); SendMessageA(hwndRichEdit, WM_KEYUP, 'A', 1); SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); SendMessageA(hwndRichEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); len1 = selEnd - selBegin; - + ok(len1 != len2, "EM_EXLIMITTEXT: Change Expected\nOld Length: %d, New Length: %d, Limit: %d\n", len1,len2,i); - + SendMessageA(hwndRichEdit, WM_KEYDOWN, 'A', 1); SendMessageA(hwndRichEdit, WM_CHAR, 'A', 1); SendMessageA(hwndRichEdit, WM_KEYUP, 'A', 1); /* full; should be no effect */ SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1); SendMessageA(hwndRichEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); len2 = selEnd - selBegin; - - ok(len1 == len2, + + ok(len1 == len2, "EM_EXLIMITTEXT: No Change Expected\nOld Length: %d, New Length: %d, Limit: %d\n", len1,len2,i); @@ -4103,26 +4175,26 @@ static void test_EM_GETLIMITTEXT(void) static void test_WM_SETFONT(void) { /* There is no invalid input or error conditions for this function. - * NULL wParam and lParam just fall back to their default values + * NULL wParam and lParam just fall back to their default values * It should be noted that even if you use a gibberish name for your fonts * here, it will still work because the name is stored. They will display as * System, but will report their name to be whatever they were created as */ - + HWND hwndRichEdit = new_richedit(NULL); - HFONT testFont1 = CreateFontA (0,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | + HFONT testFont1 = CreateFontA (0,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Marlett"); - HFONT testFont2 = CreateFontA (0,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, - OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | + HFONT testFont2 = CreateFontA (0,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, + OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "MS Sans Serif"); - HFONT testFont3 = CreateFontA (0,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | + HFONT testFont3 = CreateFontA (0,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier"); LOGFONTA sentLogFont; CHARFORMAT2A returnedCF2A; - + returnedCF2A.cbSize = sizeof(returnedCF2A); - + SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"x"); SendMessageA(hwndRichEdit, WM_SETFONT, (WPARAM)testFont1, MAKELPARAM(TRUE, 0)); SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&returnedCF2A); @@ -4138,26 +4210,26 @@ static void test_WM_SETFONT(void) ok (!strcmp(sentLogFont.lfFaceName,returnedCF2A.szFaceName), "EM_GETCHARFORMAT: Returned wrong font on test 2. Sent: %s, Returned: %s\n", sentLogFont.lfFaceName,returnedCF2A.szFaceName); - + SendMessageA(hwndRichEdit, WM_SETFONT, (WPARAM)testFont3, MAKELPARAM(TRUE, 0)); SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&returnedCF2A); GetObjectA(testFont3, sizeof(LOGFONTA), &sentLogFont); ok (!strcmp(sentLogFont.lfFaceName,returnedCF2A.szFaceName), "EM_GETCHARFORMAT: Returned wrong font on test 3. Sent: %s, Returned: %s\n", sentLogFont.lfFaceName,returnedCF2A.szFaceName); - + /* This last test is special since we send in NULL. We clear the variables * and just compare to "System" instead of the sent in font name. */ ZeroMemory(&returnedCF2A,sizeof(returnedCF2A)); ZeroMemory(&sentLogFont,sizeof(sentLogFont)); returnedCF2A.cbSize = sizeof(returnedCF2A); - + SendMessageA(hwndRichEdit, WM_SETFONT, 0, MAKELPARAM((WORD) TRUE, 0)); SendMessageA(hwndRichEdit, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM)&returnedCF2A); GetObjectA(NULL, sizeof(LOGFONTA), &sentLogFont); ok (!strcmp("System",returnedCF2A.szFaceName), "EM_GETCHARFORMAT: Returned wrong font on test 4. Sent: NULL, Returned: %s. Expected \"System\".\n",returnedCF2A.szFaceName); - + DestroyWindow(hwndRichEdit); } @@ -4187,43 +4259,43 @@ static void test_EM_GETMODIFY(void) HWND hwndRichEdit = new_richedit(NULL); LRESULT result; SETTEXTEX setText; - WCHAR TestItem1[] = {'T', 'e', 's', 't', - 'S', 'o', 'm', 'e', - 'T', 'e', 'x', 't', 0}; - WCHAR TestItem2[] = {'T', 'e', 's', 't', - 'S', 'o', 'm', 'e', + WCHAR TestItem1[] = {'T', 'e', 's', 't', + 'S', 'o', 'm', 'e', + 'T', 'e', 'x', 't', 0}; + WCHAR TestItem2[] = {'T', 'e', 's', 't', + 'S', 'o', 'm', 'e', 'O', 't', 'h', 'e', 'r', - 'T', 'e', 'x', 't', 0}; + 'T', 'e', 'x', 't', 0}; const char* streamText = "hello world"; CHARFORMAT2A cf2; PARAFORMAT2 pf2; EDITSTREAM es; - - HFONT testFont = CreateFontA (0,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, - OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | + + HFONT testFont = CreateFontA (0,0,0,0,FW_LIGHT, 0, 0, 0, ANSI_CHARSET, + OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier"); - + setText.codepage = 1200; /* no constant for unicode */ setText.flags = ST_KEEPUNDO; - + /* modify flag shouldn't be set when richedit is first created */ result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); - ok (result == 0, + ok (result == 0, "EM_GETMODIFY returned non-zero, instead of zero on create\n"); - + /* setting modify flag should actually set it */ SendMessageA(hwndRichEdit, EM_SETMODIFY, TRUE, 0); result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); - ok (result != 0, + ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero on EM_SETMODIFY\n"); - + /* clearing modify flag should actually clear it */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); - ok (result == 0, + ok (result == 0, "EM_GETMODIFY returned non-zero, instead of zero on EM_SETMODIFY\n"); - + /* setting font doesn't change modify flag */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); SendMessageA(hwndRichEdit, WM_SETFONT, (WPARAM)testFont, MAKELPARAM(TRUE, 0)); @@ -4237,13 +4309,13 @@ static void test_EM_GETMODIFY(void) result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero on setting text\n"); - + /* undo previous text doesn't reset modify flag */ SendMessageA(hwndRichEdit, WM_UNDO, 0, 0); result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero on undo after setting text\n"); - + /* set text with no flag to keep undo stack should not set modify flag */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); setText.flags = 0; @@ -4251,21 +4323,21 @@ static void test_EM_GETMODIFY(void) result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result == 0, "EM_GETMODIFY returned non-zero, instead of zero when setting text while not keeping undo stack\n"); - + /* WM_SETTEXT doesn't modify */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)TestItem2); result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result == 0, "EM_GETMODIFY returned non-zero for WM_SETTEXT\n"); - + /* clear the text */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); SendMessageA(hwndRichEdit, WM_CLEAR, 0, 0); result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result == 0, "EM_GETMODIFY returned non-zero, instead of zero for WM_CLEAR\n"); - + /* replace text */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)TestItem1); @@ -4274,7 +4346,7 @@ static void test_EM_GETMODIFY(void) result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero when replacing text\n"); - + /* copy/paste text 1 */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); SendMessageA(hwndRichEdit, EM_SETSEL, 0, 2); @@ -4283,7 +4355,7 @@ static void test_EM_GETMODIFY(void) result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero when pasting identical text\n"); - + /* copy/paste text 2 */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); SendMessageA(hwndRichEdit, EM_SETSEL, 0, 2); @@ -4293,7 +4365,7 @@ static void test_EM_GETMODIFY(void) result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero when pasting different text\n"); - + /* press char */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); SendMessageA(hwndRichEdit, EM_SETSEL, 0, 1); @@ -4309,7 +4381,7 @@ static void test_EM_GETMODIFY(void) result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero for backspace\n"); - + /* set char format */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); cf2.cbSize = sizeof(CHARFORMAT2A); @@ -4322,7 +4394,7 @@ static void test_EM_GETMODIFY(void) result = SendMessageA(hwndRichEdit, EM_GETMODIFY, 0, 0); ok (result != 0, "EM_GETMODIFY returned zero, instead of non-zero for EM_SETCHARFORMAT\n"); - + /* set para format */ SendMessageA(hwndRichEdit, EM_SETMODIFY, FALSE, 0); pf2.cbSize = sizeof(PARAFORMAT2); @@ -4353,33 +4425,36 @@ struct exsetsel_s { LRESULT expected_retval; int expected_getsel_start; int expected_getsel_end; - int _getsel_todo_wine; + BOOL todo; }; -const struct exsetsel_s exsetsel_tests[] = { +static const struct exsetsel_s exsetsel_tests[] = { /* sanity tests */ - {5, 10, 10, 5, 10, 0}, - {15, 17, 17, 15, 17, 0}, + {5, 10, 10, 5, 10 }, + {15, 17, 17, 15, 17 }, /* test cpMax > strlen() */ - {0, 100, 18, 0, 18, 0}, + {0, 100, 18, 0, 18 }, /* test cpMin < 0 && cpMax >= 0 after cpMax > strlen() */ - {-1, 1, 17, 17, 17, 0}, + {-1, 1, 17, 17, 17 }, /* test cpMin == cpMax */ - {5, 5, 5, 5, 5, 0}, + {5, 5, 5, 5, 5 }, /* test cpMin < 0 && cpMax >= 0 (bug 4462) */ - {-1, 0, 5, 5, 5, 0}, - {-1, 17, 5, 5, 5, 0}, - {-1, 18, 5, 5, 5, 0}, + {-1, 0, 5, 5, 5 }, + {-1, 17, 5, 5, 5 }, + {-1, 18, 5, 5, 5 }, /* test cpMin < 0 && cpMax < 0 */ - {-1, -1, 17, 17, 17, 0}, - {-4, -5, 17, 17, 17, 0}, + {-1, -1, 17, 17, 17 }, + {-4, -5, 17, 17, 17 }, /* test cpMin >=0 && cpMax < 0 (bug 6814) */ - {0, -1, 18, 0, 18, 0}, - {17, -5, 18, 17, 18, 0}, - {18, -3, 17, 17, 17, 0}, + {0, -1, 18, 0, 18 }, + {17, -5, 18, 17, 18 }, + {18, -3, 17, 17, 17 }, /* test if cpMin > cpMax */ - {15, 19, 18, 15, 18, 0}, - {19, 15, 18, 15, 18, 0}, + {15, 19, 18, 15, 18 }, + {19, 15, 18, 15, 18 }, + /* cpMin == strlen() && cpMax > cpMin */ + {17, 18, 18, 17, 18 }, + {17, 50, 18, 17, 18 }, }; static void check_EM_EXSETSEL(HWND hwnd, const struct exsetsel_s *setsel, int id) { @@ -4395,7 +4470,7 @@ static void check_EM_EXSETSEL(HWND hwnd, const struct exsetsel_s *setsel, int id SendMessageA(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end); - if (setsel->_getsel_todo_wine) { + if (setsel->todo) { todo_wine { ok(start == setsel->expected_getsel_start && end == setsel->expected_getsel_end, "EM_EXSETSEL(%d): expected (%d,%d) actual:(%d,%d)\n", id, setsel->expected_getsel_start, setsel->expected_getsel_end, start, end); } @@ -4432,7 +4507,7 @@ static void check_EM_SETSEL(HWND hwnd, const struct exsetsel_s *setsel, int id) SendMessageA(hwnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end); - if (setsel->_getsel_todo_wine) { + if (setsel->todo) { todo_wine { ok(start == setsel->expected_getsel_start && end == setsel->expected_getsel_end, "EM_SETSEL(%d): expected (%d,%d) actual:(%d,%d)\n", id, setsel->expected_getsel_start, setsel->expected_getsel_end, start, end); } @@ -4443,6 +4518,7 @@ static void check_EM_SETSEL(HWND hwnd, const struct exsetsel_s *setsel, int id) static void test_EM_SETSEL(void) { + char buffA[32]; HWND hwndRichEdit = new_richedit(NULL); int i; const int num_tests = sizeof(exsetsel_tests)/sizeof(struct exsetsel_s); @@ -4456,6 +4532,11 @@ static void test_EM_SETSEL(void) check_EM_SETSEL(hwndRichEdit, &exsetsel_tests[i], i); } + SendMessageA(hwndRichEdit, EM_SETSEL, 17, 18); + buffA[0] = 123; + SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffA); + ok(buffA[0] == 0, "selection text %s\n", buffA); + DestroyWindow(hwndRichEdit); } @@ -4872,7 +4953,7 @@ static void test_WM_PASTE(void) SendMessageA(hwndRichEdit, WM_PASTE, 0, 0); SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); result = strcmp(buffer,"cut\r\n"); - todo_wine ok(result == 0, + ok(result == 0, "test paste: strcmp = %i, actual = '%s'\n", result, buffer); /* Simulates undo (Ctrl-Z) */ hold_key(VK_CONTROL); @@ -4887,7 +4968,7 @@ static void test_WM_PASTE(void) (MapVirtualKeyA('Y', MAPVK_VK_TO_VSC) << 16) | 1); SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer); result = strcmp(buffer,"cut\r\n"); - todo_wine ok(result == 0, + ok(result == 0, "test paste: strcmp = %i, actual = '%s'\n", result, buffer); release_key(VK_CONTROL); @@ -5424,7 +5505,6 @@ static void test_unicode_conversions(void) do { \ SETTEXTEX stex = { ST_DEFAULT, CP_ACP }; \ WPARAM wparam = (wm_set_text == WM_SETTEXT) ? 0 : (WPARAM)&stex; \ - UNREFERENCED_LOCAL_VARIABLE(stex); \ assert(wm_set_text == WM_SETTEXT || wm_set_text == EM_SETTEXTEX); \ ret = SendMessageA(hwnd, wm_set_text, wparam, (LPARAM)txt); \ ok(ret, "SendMessageA(%02x) error %u\n", wm_set_text, GetLastError()); \ @@ -5433,7 +5513,6 @@ static void test_unicode_conversions(void) do { \ GETTEXTEX gtex = { 64, GT_DEFAULT, CP_ACP, NULL, NULL }; \ WPARAM wparam = (wm_get_text == WM_GETTEXT) ? 64 : (WPARAM)>ex; \ - UNREFERENCED_LOCAL_VARIABLE(gtex); \ assert(wm_get_text == WM_GETTEXT || wm_get_text == EM_GETTEXTEX); \ memset(bufA, 0xAA, sizeof(bufA)); \ ret = SendMessageA(hwnd, wm_get_text, wparam, (LPARAM)bufA); \ @@ -5446,7 +5525,6 @@ static void test_unicode_conversions(void) do { \ SETTEXTEX stex = { ST_DEFAULT, 1200 }; \ WPARAM wparam = (wm_set_text == WM_SETTEXT) ? 0 : (WPARAM)&stex; \ - UNREFERENCED_LOCAL_VARIABLE(stex); \ assert(wm_set_text == WM_SETTEXT || wm_set_text == EM_SETTEXTEX); \ ret = SendMessageW(hwnd, wm_set_text, wparam, (LPARAM)txt); \ ok(ret, "SendMessageW(%02x) error %u\n", wm_set_text, GetLastError()); \ @@ -5455,7 +5533,6 @@ static void test_unicode_conversions(void) do { \ GETTEXTEX gtex = { 64, GT_DEFAULT, 1200, NULL, NULL }; \ WPARAM wparam = (wm_get_text == WM_GETTEXT) ? 64 : (WPARAM)>ex; \ - UNREFERENCED_LOCAL_VARIABLE(gtex); \ assert(wm_get_text == WM_GETTEXT || wm_get_text == EM_GETTEXTEX); \ memset(bufW, 0xAA, sizeof(bufW)); \ ret = SendMessageW(hwnd, wm_get_text, wparam, (LPARAM)bufW); \ @@ -5467,7 +5544,6 @@ static void test_unicode_conversions(void) do { \ GETTEXTEX gtex = { 64, GT_DEFAULT, CP_ACP, NULL, NULL }; \ WPARAM wparam = (wm_get_text == WM_GETTEXT) ? 64 : (WPARAM)>ex; \ - UNREFERENCED_LOCAL_VARIABLE(gtex); \ assert(wm_get_text == WM_GETTEXT || wm_get_text == EM_GETTEXTEX); \ memset(bufA, 0xAA, sizeof(bufA)); \ ret = SendMessageA(hwnd, wm_get_text, wparam, (LPARAM)bufA); \ @@ -5977,26 +6053,153 @@ static void test_WM_NOTIFY(void) DestroyWindow(parent); } -static int cpMin_EN_LINK = -1; -static int cpMax_EN_LINK = -1; +static ENLINK enlink; +#define CURSOR_CLIENT_X 5 +#define CURSOR_CLIENT_Y 5 +#define WP_PARENT 1 +#define WP_CHILD 2 static LRESULT WINAPI EN_LINK_ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - ENLINK* enlink = (ENLINK*)lParam; - if(message == WM_NOTIFY && enlink->nmhdr.code == EN_LINK) + if(message == WM_NOTIFY && ((NMHDR*)lParam)->code == EN_LINK) { - cpMin_EN_LINK = enlink->chrg.cpMin; - cpMax_EN_LINK = enlink->chrg.cpMax; + enlink = *(ENLINK*)lParam; } return DefWindowProcA(hwnd, message, wParam, lParam); } +static void link_notify_test(const char *desc, int i, HWND hwnd, HWND parent, + UINT msg, WPARAM wParam, LPARAM lParam, BOOL notifies) +{ + ENLINK junk_enlink; + + switch (msg) + { + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MOUSEHOVER: + case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + lParam = MAKELPARAM(CURSOR_CLIENT_X, CURSOR_CLIENT_Y); + break; + case WM_SETCURSOR: + if (wParam == WP_PARENT) + wParam = (WPARAM)parent; + else if (wParam == WP_CHILD) + wParam = (WPARAM)hwnd; + break; + } + + memset(&junk_enlink, 0x23, sizeof(junk_enlink)); + enlink = junk_enlink; + + SendMessageA(hwnd, msg, wParam, lParam); + + if (notifies) + { + ok(enlink.nmhdr.hwndFrom == hwnd, + "%s test %i: Expected hwnd %p got %p\n", desc, i, hwnd, enlink.nmhdr.hwndFrom); + ok(enlink.nmhdr.idFrom == 0, + "%s test %i: Expected idFrom 0 got 0x%lx\n", desc, i, enlink.nmhdr.idFrom); + ok(enlink.msg == msg, + "%s test %i: Expected msg 0x%x got 0x%x\n", desc, i, msg, enlink.msg); + if (msg == WM_SETCURSOR) + { + ok(enlink.wParam == 0, + "%s test %i: Expected wParam 0 got 0x%lx\n", desc, i, enlink.wParam); + } + else + { + ok(enlink.wParam == wParam, + "%s test %i: Expected wParam 0x%lx got 0x%lx\n", desc, i, wParam, enlink.wParam); + } + ok(enlink.lParam == MAKELPARAM(CURSOR_CLIENT_X, CURSOR_CLIENT_Y), + "%s test %i: Expected lParam 0x%lx got 0x%lx\n", + desc, i, MAKELPARAM(CURSOR_CLIENT_X, CURSOR_CLIENT_Y), enlink.lParam); + ok(enlink.chrg.cpMin == 0 && enlink.chrg.cpMax == 31, + "%s test %i: Expected link range [0,31) got [%i,%i)\n", desc, i, enlink.chrg.cpMin, enlink.chrg.cpMax); + } + else + { + ok(memcmp(&enlink, &junk_enlink, sizeof(enlink)) == 0, + "%s test %i: Expected enlink to remain unmodified\n", desc, i); + } +} + static void test_EN_LINK(void) { - HWND parent; + HWND hwnd, parent; WNDCLASSA cls; - HWND hwndRichedit_EN_LINK; CHARFORMAT2A cf2; + POINT orig_cursor_pos; + POINT cursor_screen_pos = {CURSOR_CLIENT_X, CURSOR_CLIENT_Y}; + int i; + + static const struct + { + UINT msg; + WPARAM wParam; + LPARAM lParam; + BOOL notifies; + } + link_notify_tests[] = + { + /* hold down the left button and try some messages */ + { WM_LBUTTONDOWN, 0, 0, TRUE }, /* 0 */ + { EM_LINESCROLL, 0, 1, FALSE }, + { EM_SCROLL, SB_BOTTOM, 0, FALSE }, + { WM_LBUTTONDBLCLK, 0, 0, TRUE }, + { WM_MOUSEHOVER, 0, 0, FALSE }, + { WM_MOUSEMOVE, 0, 0, FALSE }, + { WM_MOUSEWHEEL, 0, 0, FALSE }, + { WM_RBUTTONDBLCLK, 0, 0, TRUE }, + { WM_RBUTTONDOWN, 0, 0, TRUE }, + { WM_RBUTTONUP, 0, 0, TRUE }, + { WM_SETCURSOR, 0, 0, FALSE }, + { WM_SETCURSOR, WP_PARENT, 0, FALSE }, + { WM_SETCURSOR, WP_CHILD, 0, TRUE }, + { WM_SETCURSOR, WP_CHILD, 1, TRUE }, + { WM_VSCROLL, SB_BOTTOM, 0, FALSE }, + { WM_LBUTTONUP, 0, 0, TRUE }, + /* hold down the right button and try some messages */ + { WM_RBUTTONDOWN, 0, 0, TRUE }, /* 16 */ + { EM_LINESCROLL, 0, 1, FALSE }, + { EM_SCROLL, SB_BOTTOM, 0, FALSE }, + { WM_LBUTTONDBLCLK, 0, 0, TRUE }, + { WM_LBUTTONDOWN, 0, 0, TRUE }, + { WM_LBUTTONUP, 0, 0, TRUE }, + { WM_MOUSEHOVER, 0, 0, FALSE }, + { WM_MOUSEMOVE, 0, 0, TRUE }, + { WM_MOUSEWHEEL, 0, 0, FALSE }, + { WM_RBUTTONDBLCLK, 0, 0, TRUE }, + { WM_SETCURSOR, 0, 0, FALSE }, + { WM_SETCURSOR, WP_PARENT, 0, FALSE }, + { WM_SETCURSOR, WP_CHILD, 0, TRUE }, + { WM_SETCURSOR, WP_CHILD, 1, TRUE }, + { WM_VSCROLL, SB_BOTTOM, 0, FALSE }, + { WM_RBUTTONUP, 0, 0, TRUE }, + /* try the messages with both buttons released */ + { EM_LINESCROLL, 0, 1, FALSE }, /* 32 */ + { EM_SCROLL, SB_BOTTOM, 0, FALSE }, + { WM_LBUTTONDBLCLK, 0, 0, TRUE }, + { WM_LBUTTONDOWN, 0, 0, TRUE }, + { WM_LBUTTONUP, 0, 0, TRUE }, + { WM_MOUSEHOVER, 0, 0, FALSE }, + { WM_MOUSEMOVE, 0, 0, TRUE }, + { WM_MOUSEWHEEL, 0, 0, FALSE }, + { WM_RBUTTONDBLCLK, 0, 0, TRUE }, + { WM_RBUTTONDOWN, 0, 0, TRUE }, + { WM_RBUTTONUP, 0, 0, TRUE }, + { WM_SETCURSOR, 0, 0, FALSE }, + { WM_SETCURSOR, WP_CHILD, 0, TRUE }, + { WM_SETCURSOR, WP_CHILD, 1, TRUE }, + { WM_SETCURSOR, WP_PARENT, 0, FALSE }, + { WM_VSCROLL, SB_BOTTOM, 0, FALSE } + }; /* register class to capture WM_NOTIFY */ cls.style = 0; @@ -6015,21 +6218,40 @@ static void test_EN_LINK(void) 0, 0, 200, 60, NULL, NULL, NULL, NULL); ok(parent != 0, "Failed to create parent window\n"); - hwndRichedit_EN_LINK = new_richedit(parent); - ok(hwndRichedit_EN_LINK != 0, "Failed to create edit window\n"); + hwnd = new_richedit(parent); + ok(hwnd != 0, "Failed to create edit window\n"); - SendMessageA(hwndRichedit_EN_LINK, EM_SETEVENTMASK, 0, ENM_LINK); + SendMessageA(hwnd, EM_SETEVENTMASK, 0, ENM_LINK); cf2.cbSize = sizeof(CHARFORMAT2A); cf2.dwMask = CFM_LINK; cf2.dwEffects = CFE_LINK; - SendMessageA(hwndRichedit_EN_LINK, EM_SETCHARFORMAT, 0, (LPARAM)&cf2); + SendMessageA(hwnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf2); /* mixing letters and numbers causes runs to be split */ - SendMessageA(hwndRichedit_EN_LINK, WM_SETTEXT, 0, (LPARAM)"link text with at least 2 runs"); - SendMessageA(hwndRichedit_EN_LINK, WM_LBUTTONDOWN, 0, MAKELPARAM(5, 5)); - ok(cpMin_EN_LINK == 0 && cpMax_EN_LINK == 31, "Expected link range [0,31) got [%i,%i)\n", cpMin_EN_LINK, cpMax_EN_LINK); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"link text with at least 2 runs"); - DestroyWindow(hwndRichedit_EN_LINK); + GetCursorPos(&orig_cursor_pos); + SetCursorPos(0, 0); + + for (i = 0; i < sizeof(link_notify_tests)/sizeof(link_notify_tests[0]); 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, + link_notify_tests[i].msg == WM_SETCURSOR ? FALSE : link_notify_tests[i].notifies); + } + + 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++) + { + link_notify_test("cursor position set", i, hwnd, parent, + link_notify_tests[i].msg, link_notify_tests[i].wParam, link_notify_tests[i].lParam, + link_notify_tests[i].notifies); + } + + SetCursorPos(orig_cursor_pos.x, orig_cursor_pos.y); + DestroyWindow(hwnd); DestroyWindow(parent); } @@ -7625,12 +7847,12 @@ static void test_EM_SETREADONLY(void) res = SendMessageA(richedit, EM_SETREADONLY, TRUE, 0); ok(res == 1, "EM_SETREADONLY\n"); dwStyle = GetWindowLongA(richedit, GWL_STYLE); - ok(dwStyle & ES_READONLY, "got wrong value: 0x%x\n", dwStyle & ES_READONLY); + ok(dwStyle & ES_READONLY, "got wrong value: 0x%x\n", dwStyle); res = SendMessageA(richedit, EM_SETREADONLY, FALSE, 0); ok(res == 1, "EM_SETREADONLY\n"); dwStyle = GetWindowLongA(richedit, GWL_STYLE); - ok(!(dwStyle & ES_READONLY), "got wrong value: 0x%x\n", dwStyle & ES_READONLY); + ok(!(dwStyle & ES_READONLY), "got wrong value: 0x%x\n", dwStyle); DestroyWindow(richedit); } diff --git a/rostests/winetests/riched20/richole.c b/rostests/winetests/riched20/richole.c index baed1f7dc35..392cb5c981b 100644 --- a/rostests/winetests/riched20/richole.c +++ b/rostests/winetests/riched20/richole.c @@ -35,6 +35,19 @@ static HMODULE hmoduleRichEdit; +DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +static const WCHAR sysW[] = {'S','y','s','t','e','m',0}; + +#define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__) +static void _expect_ref(IUnknown* obj, ULONG ref, int line) +{ + ULONG rc; + IUnknown_AddRef(obj); + rc = IUnknown_Release(obj); + ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); +} + static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent) { HWND hwnd = CreateWindowA(lpClassName, NULL, @@ -103,7 +116,7 @@ static void test_Interfaces(void) { IRichEditOle *reOle = NULL, *reOle1 = NULL; ITextDocument *txtDoc = NULL; - ITextSelection *txtSel = NULL; + ITextSelection *txtSel = NULL, *txtSel2; IUnknown *punk; HRESULT hres; LRESULT res; @@ -119,14 +132,12 @@ static void test_Interfaces(void) res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle); ok(res, "SendMessage\n"); ok(reOle != NULL, "EM_GETOLEINTERFACE\n"); - refcount = get_refcount((IUnknown *)reOle); - ok(refcount == 2, "got wrong ref count: %d\n", refcount); + EXPECT_REF(reOle, 2); res = SendMessageA(w, EM_GETOLEINTERFACE, 0, (LPARAM)&reOle1); ok(res == 1, "SendMessage\n"); ok(reOle1 == reOle, "Should not return a new IRichEditOle interface\n"); - refcount = get_refcount((IUnknown *)reOle); - ok(refcount == 3, "got wrong ref count: %d\n", refcount); + EXPECT_REF(reOle, 3); hres = IRichEditOle_QueryInterface(reOle, &IID_ITextDocument, (void **) &txtDoc); @@ -136,7 +147,22 @@ static void test_Interfaces(void) hres = ITextDocument_GetSelection(txtDoc, NULL); ok(hres == E_INVALIDARG, "ITextDocument_GetSelection: 0x%x\n", hres); - ITextDocument_GetSelection(txtDoc, &txtSel); + EXPECT_REF(txtDoc, 4); + + hres = ITextDocument_GetSelection(txtDoc, &txtSel); + ok(hres == S_OK, "got 0x%08x\n", hres); + + EXPECT_REF(txtDoc, 4); + EXPECT_REF(txtSel, 2); + + hres = ITextDocument_GetSelection(txtDoc, &txtSel2); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(txtSel2 == txtSel, "got %p, %p\n", txtSel, txtSel2); + + EXPECT_REF(txtDoc, 4); + EXPECT_REF(txtSel, 3); + + ITextSelection_Release(txtSel2); punk = NULL; hres = ITextSelection_QueryInterface(txtSel, &IID_ITextSelection, (void **) &punk); @@ -156,6 +182,18 @@ static void test_Interfaces(void) ok(punk != NULL, "ITextSelection_QueryInterface\n"); IUnknown_Release(punk); + punk = NULL; + hres = IRichEditOle_QueryInterface(reOle, &IID_IOleClientSite, (void **) &punk); + ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n"); + + punk = NULL; + hres = IRichEditOle_QueryInterface(reOle, &IID_IOleWindow, (void **) &punk); + ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n"); + + punk = NULL; + hres = IRichEditOle_QueryInterface(reOle, &IID_IOleInPlaceSite, (void **) &punk); + ok(hres == E_NOINTERFACE, "IRichEditOle_QueryInterface\n"); + ITextDocument_Release(txtDoc); IRichEditOle_Release(reOle); refcount = IRichEditOle_Release(reOle); @@ -321,15 +359,20 @@ static void test_ITextDocument_Open(void) create_interfaces(&w, &reOle, &txtDoc, &txtSel); DeleteFileW(filename); - ITextDocument_Open(txtDoc, &testfile, tomText, CP_ACP); - todo_wine ok(is_existing_file(filename) == TRUE, "a file should be created default\n"); + hres = ITextDocument_Open(txtDoc, &testfile, tomText, CP_ACP); +todo_wine { + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(is_existing_file(filename) == TRUE, "a file should be created default\n"); +} release_interfaces(&w, &reOle, &txtDoc, &txtSel); DeleteFileW(filename); /* test of share mode */ touch_file(filename); create_interfaces(&w, &reOle, &txtDoc, &txtSel); - ITextDocument_Open(txtDoc, &testfile, tomShareDenyRead, CP_ACP); + hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyRead, CP_ACP); +todo_wine + ok(hres == S_OK, "got 0x%08x\n", hres); SetLastError(0xdeadbeef); hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -340,7 +383,9 @@ static void test_ITextDocument_Open(void) touch_file(filename); create_interfaces(&w, &reOle, &txtDoc, &txtSel); - ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite, CP_ACP); + hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite, CP_ACP); +todo_wine + ok(hres == S_OK, "got 0x%08x\n", hres); SetLastError(0xdeadbeef); hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -352,7 +397,9 @@ static void test_ITextDocument_Open(void) touch_file(filename); create_interfaces(&w, &reOle, &txtDoc, &txtSel); SetLastError(0xdeadbeef); - ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite|tomShareDenyRead, CP_ACP); + hres = ITextDocument_Open(txtDoc, &testfile, tomShareDenyWrite|tomShareDenyRead, CP_ACP); +todo_wine + ok(hres == S_OK, "got 0x%08x\n", hres); hFile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); todo_wine ok(GetLastError() == ERROR_SHARING_VIOLATION, "ITextDocument_Open should fail\n"); @@ -366,7 +413,9 @@ static void test_ITextDocument_Open(void) WriteFile(hFile, chACP, sizeof(chACP)-sizeof(CHAR), &dw, NULL); CloseHandle(hFile); create_interfaces(&w, &reOle, &txtDoc, &txtSel); - ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_ACP); + hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_ACP); +todo_wine + ok(hres == S_OK, "got 0x%08x\n", hres); result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP); todo_wine ok(result == 12, "ITextDocument_Open: Test ASCII returned %d, expected 12\n", result); result = strcmp(bufACP, chACP); @@ -379,7 +428,9 @@ static void test_ITextDocument_Open(void) WriteFile(hFile, chUTF8, sizeof(chUTF8)-sizeof(CHAR), &dw, NULL); CloseHandle(hFile); create_interfaces(&w, &reOle, &txtDoc, &txtSel); - ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_UTF8); + hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, CP_UTF8); +todo_wine + ok(hres == S_OK, "got 0x%08x\n", hres); result = SendMessageA(w, WM_GETTEXT, 1024, (LPARAM)bufACP); todo_wine ok(result == 15, "ITextDocument_Open: Test UTF-8 returned %d, expected 15\n", result); result = strcmp(bufACP, &chUTF8[3]); @@ -392,7 +443,9 @@ static void test_ITextDocument_Open(void) WriteFile(hFile, chUTF16, sizeof(chUTF16)-sizeof(WCHAR), &dw, NULL); CloseHandle(hFile); create_interfaces(&w, &reOle, &txtDoc, &txtSel); - ITextDocument_Open(txtDoc, &testfile, tomReadOnly, 1200); + hres = ITextDocument_Open(txtDoc, &testfile, tomReadOnly, 1200); +todo_wine + ok(hres == S_OK, "got 0x%08x\n", hres); result = SendMessageW(w, WM_GETTEXT, 1024, (LPARAM)bufUnicode); todo_wine ok(result == 12, "ITextDocument_Open: Test UTF-16 returned %d, expected 12\n", result); result = lstrcmpW(bufUnicode, &chUTF16[1]); @@ -403,7 +456,7 @@ static void test_ITextDocument_Open(void) VariantClear(&testfile); } -static void test_ITextSelection_GetText(void) +static void test_GetText(void) { HWND w; IRichEditOle *reOle = NULL; @@ -419,11 +472,14 @@ static void test_ITextSelection_GetText(void) static const WCHAR bufW4[] = {'T', 'e', 's', 't', 'S', 'o', 'm', 'e', 'T', 'e', 'x', 't', '\r', 0}; static const WCHAR bufW5[] = {'\r', 0}; + static const WCHAR bufW6[] = {'T','e','s','t','S','o','m','e','T',0}; BOOL is64bit = sizeof(void *) > sizeof(int); + ITextRange *range; create_interfaces(&w, &reOle, &txtDoc, &txtSel); SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + /* ITextSelection */ first = 0, lim = 4; SendMessageA(w, EM_SETSEL, first, lim); hres = ITextSelection_GetText(txtSel, &bstr); @@ -484,34 +540,143 @@ static void test_ITextSelection_GetText(void) ok(hres == S_OK, "ITextSelection_GetText\n"); ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr)); - release_interfaces(&w, &reOle, &txtDoc, &txtSel); + /* ITextRange */ + hres = ITextDocument_Range(txtDoc, 0, 4, &range); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_GetText(range, &bstr); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr)); + + SysFreeString(bstr); + ITextRange_Release(range); + + hres = ITextDocument_Range(txtDoc, 4, 0, &range); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_GetText(range, &bstr); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(!lstrcmpW(bstr, bufW1), "got wrong text: %s\n", wine_dbgstr_w(bstr)); + + SysFreeString(bstr); + ITextRange_Release(range); + + hres = ITextDocument_Range(txtDoc, 1, 1, &range); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_GetText(range, &bstr); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr)); + if (!is64bit) + { + hres = ITextRange_GetText(range, NULL); + ok(hres == E_INVALIDARG, "got 0x%08x\n", hres); + } + ITextRange_Release(range); + + hres = ITextDocument_Range(txtDoc, 8, 12, &range); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_GetText(range, &bstr); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(!lstrcmpW(bstr, bufW3), "got wrong text: %s\n", wine_dbgstr_w(bstr)); + + SysFreeString(bstr); + ITextRange_Release(range); + + hres = ITextDocument_Range(txtDoc, 8, 13, &range); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_GetText(range, &bstr); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(!lstrcmpW(bstr, bufW2), "got wrong text: %s\n", wine_dbgstr_w(bstr)); + + SysFreeString(bstr); + ITextRange_Release(range); + + hres = ITextDocument_Range(txtDoc, 12, 13, &range); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_GetText(range, &bstr); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(!lstrcmpW(bstr, bufW5), "got wrong text: %s\n", wine_dbgstr_w(bstr)); + + SysFreeString(bstr); + ITextRange_Release(range); + + hres = ITextDocument_Range(txtDoc, 0, -1, &range); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_GetText(range, &bstr); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(!bstr, "got wrong text: %s\n", wine_dbgstr_w(bstr)); + ITextRange_Release(range); + + hres = ITextDocument_Range(txtDoc, -1, 9, &range); + ok(hres == S_OK, "got 0x%08x\n", hres); + hres = ITextRange_GetText(range, &bstr); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(!lstrcmpW(bstr, bufW6), "got wrong text: %s\n", wine_dbgstr_w(bstr)); + + SysFreeString(bstr); + + release_interfaces(&w, &reOle, &txtDoc, NULL); + + /* detached selection/range */ + if (is64bit) { + bstr = (void*)0xdeadbeef; + hres = ITextSelection_GetText(txtSel, &bstr); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); +todo_wine + ok(bstr == NULL, "got %p\n", bstr); + + bstr = (void*)0xdeadbeef; + hres = ITextRange_GetText(range, &bstr); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); +todo_wine + ok(bstr == NULL, "got %p\n", bstr); + } + else { + hres = ITextSelection_GetText(txtSel, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetText(range, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + } + + ITextRange_Release(range); + ITextSelection_Release(txtSel); } static void test_ITextDocument_Range(void) { + static const CHAR test_text1[] = "TestSomeText"; HWND w; IRichEditOle *reOle = NULL; ITextDocument *txtDoc = NULL; - ITextRange *txtRge = NULL; - ITextRange *pointer = NULL; + ITextRange *txtRge, *range2; HRESULT hres; - ULONG refcount; + LONG value; create_interfaces(&w, &reOle, &txtDoc, NULL); hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge); ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres); - refcount = get_refcount((IUnknown *)txtRge); - ok(refcount == 1, "get wrong refcount: returned %d expected 1\n", refcount); + EXPECT_REF(txtRge, 1); - pointer = txtRge; - hres = ITextDocument_Range(txtDoc, 0, 0, &txtRge); + hres = ITextDocument_Range(txtDoc, 0, 0, &range2); ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres); - ok(pointer != txtRge, "A new pointer should be returned\n"); - ITextRange_Release(pointer); + ok(range2 != txtRge, "A new pointer should be returned\n"); + ITextRange_Release(range2); hres = ITextDocument_Range(txtDoc, 0, 0, NULL); ok(hres == E_INVALIDARG, "ITextDocument_Range should fail 0x%x.\n", hres); + SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); + + hres = ITextDocument_Range(txtDoc, 8, 30, &range2); + ok(hres == S_OK, "ITextDocument_Range fails 0x%x.\n", hres); + hres = ITextRange_GetStart(range2, &value); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(value == 8, "got %d\n", value); + + hres = ITextRange_GetEnd(range2, &value); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(value == 13, "got %d\n", value); + ITextRange_Release(range2); + release_interfaces(&w, &reOle, &txtDoc, NULL); hres = ITextRange_CanEdit(txtRge, NULL); ok(hres == CO_E_RELEASED, "ITextRange after ITextDocument destroyed\n"); @@ -525,14 +690,15 @@ static void test_ITextRange_GetChar(void) ITextDocument *txtDoc = NULL; ITextRange *txtRge = NULL; HRESULT hres; - LONG pch = 0xdeadbeef; + LONG pch; int first, lim; static const CHAR test_text1[] = "TestSomeText"; first = 0, lim = 4; create_interfaces(&w, &reOle, &txtDoc, NULL); SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); pch = 0xdeadbeef; hres = ITextRange_GetChar(txtRge, &pch); ok(hres == S_OK, "ITextRange_GetChar\n"); @@ -543,7 +709,8 @@ static void test_ITextRange_GetChar(void) first = 0, lim = 0; create_interfaces(&w, &reOle, &txtDoc, NULL); SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); pch = 0xdeadbeef; hres = ITextRange_GetChar(txtRge, &pch); ok(hres == S_OK, "ITextRange_GetChar\n"); @@ -554,7 +721,8 @@ static void test_ITextRange_GetChar(void) first = 12, lim = 12; create_interfaces(&w, &reOle, &txtDoc, NULL); SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); pch = 0xdeadbeef; hres = ITextRange_GetChar(txtRge, &pch); ok(hres == S_OK, "ITextRange_GetChar\n"); @@ -565,7 +733,8 @@ static void test_ITextRange_GetChar(void) first = 13, lim = 13; create_interfaces(&w, &reOle, &txtDoc, NULL); SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); pch = 0xdeadbeef; hres = ITextRange_GetChar(txtRge, &pch); ok(hres == S_OK, "ITextRange_GetChar\n"); @@ -576,11 +745,20 @@ static void test_ITextRange_GetChar(void) create_interfaces(&w, &reOle, &txtDoc, NULL); SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); first = 12, lim = 12; - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); hres = ITextRange_GetChar(txtRge, NULL); ok(hres == E_INVALIDARG, "ITextRange_GetChar\n"); - ITextRange_Release(txtRge); + release_interfaces(&w, &reOle, &txtDoc, NULL); + + hres = ITextRange_GetChar(txtRge, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetChar(txtRge, &pch); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextRange_Release(txtRge); } static void test_ITextSelection_GetChar(void) @@ -590,7 +768,7 @@ static void test_ITextSelection_GetChar(void) ITextDocument *txtDoc = NULL; ITextSelection *txtSel = NULL; HRESULT hres; - LONG pch = 0xdeadbeef; + LONG pch; int first, lim; static const CHAR test_text1[] = "TestSomeText"; @@ -628,7 +806,15 @@ static void test_ITextSelection_GetChar(void) hres = ITextSelection_GetChar(txtSel, NULL); ok(hres == E_INVALIDARG, "ITextSelection_GetChar\n"); - release_interfaces(&w, &reOle, &txtDoc, &txtSel); + release_interfaces(&w, &reOle, &txtDoc, NULL); + + hres = ITextSelection_GetChar(txtSel, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextSelection_GetChar(txtSel, &pch); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextSelection_Release(txtSel); } static void test_ITextRange_GetStart_GetEnd(void) @@ -645,7 +831,8 @@ static void test_ITextRange_GetStart_GetEnd(void) SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); first = 1, lim = 6; - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); start = 0xdeadbeef; hres = ITextRange_GetStart(txtRge, &start); ok(hres == S_OK, "ITextRange_GetStart\n"); @@ -657,7 +844,8 @@ static void test_ITextRange_GetStart_GetEnd(void) ITextRange_Release(txtRge); first = 6, lim = 1; - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); start = 0xdeadbeef; hres = ITextRange_GetStart(txtRge, &start); ok(hres == S_OK, "ITextRange_GetStart\n"); @@ -669,7 +857,8 @@ static void test_ITextRange_GetStart_GetEnd(void) ITextRange_Release(txtRge); first = -1, lim = 13; - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); start = 0xdeadbeef; hres = ITextRange_GetStart(txtRge, &start); ok(hres == S_OK, "ITextRange_GetStart\n"); @@ -681,7 +870,8 @@ static void test_ITextRange_GetStart_GetEnd(void) ITextRange_Release(txtRge); first = 13, lim = 13; - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); start = 0xdeadbeef; hres = ITextRange_GetStart(txtRge, &start); ok(hres == S_OK, "ITextRange_GetStart\n"); @@ -690,9 +880,160 @@ static void test_ITextRange_GetStart_GetEnd(void) hres = ITextRange_GetEnd(txtRge, &end); ok(hres == S_OK, "ITextRange_GetEnd\n"); ok(end == 12, "got wrong end value: %d\n", end); - ITextRange_Release(txtRge); + + /* SetStart */ + hres = ITextRange_SetStart(txtRge, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* same value */ + hres = ITextRange_SetStart(txtRge, 0); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + hres = ITextRange_SetStart(txtRge, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* negative resets to 0, return value is S_FALSE when + position wasn't changed */ + hres = ITextRange_SetStart(txtRge, -1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextRange_SetStart(txtRge, -1); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + hres = ITextRange_SetStart(txtRge, 0); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + start = -1; + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + /* greater than initial end, but less than total char count */ + hres = ITextRange_SetStart(txtRge, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextRange_SetEnd(txtRge, 3); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextRange_SetStart(txtRge, 10); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 10, "got %d\n", start); + + end = 0; + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 10, "got %d\n", end); + + /* more that total text length */ + hres = ITextRange_SetStart(txtRge, 50); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 12, "got %d\n", start); + + end = 0; + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 12, "got %d\n", end); + + /* SetEnd */ + hres = ITextRange_SetStart(txtRge, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* same value */ + hres = ITextRange_SetEnd(txtRge, 5); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextRange_SetEnd(txtRge, 5); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + /* negative resets to 0 */ + hres = ITextRange_SetEnd(txtRge, -1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + end = -1; + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 0, "got %d\n", end); + + start = -1; + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + /* greater than initial end, but less than total char count */ + hres = ITextRange_SetStart(txtRge, 3); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextRange_SetEnd(txtRge, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 1, "got %d\n", start); + + end = 0; + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 1, "got %d\n", end); + + /* more than total count */ + hres = ITextRange_SetEnd(txtRge, 50); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 1, "got %d\n", start); + + end = 0; + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 13, "got %d\n", end); + + /* zero */ + hres = ITextRange_SetEnd(txtRge, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + end = 0; + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 0, "got %d\n", end); release_interfaces(&w, &reOle, &txtDoc, NULL); + + /* detached range */ + hres = ITextRange_SetStart(txtRge, 0); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_SetEnd(txtRge, 3); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetStart(txtRge, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetEnd(txtRge, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextRange_Release(txtRge); } static void test_ITextSelection_GetStart_GetEnd(void) @@ -752,7 +1093,153 @@ static void test_ITextSelection_GetStart_GetEnd(void) ok(hres == S_OK, "ITextSelection_GetEnd\n"); ok(end == 12, "got wrong end value: %d\n", end); - release_interfaces(&w, &reOle, &txtDoc, &txtSel); + /* SetStart/SetEnd */ + hres = ITextSelection_SetStart(txtSel, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* same value */ + hres = ITextSelection_SetStart(txtSel, 0); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + hres = ITextSelection_SetStart(txtSel, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* negative resets to 0, return value is S_FALSE when + position wasn't changed */ + hres = ITextSelection_SetStart(txtSel, -1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetStart(txtSel, -1); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + hres = ITextSelection_SetStart(txtSel, 0); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + start = -1; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + /* greater than initial end, but less than total char count */ + hres = ITextSelection_SetStart(txtSel, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetEnd(txtSel, 3); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetStart(txtSel, 10); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 10, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 10, "got %d\n", end); + + /* more that total text length */ + hres = ITextSelection_SetStart(txtSel, 50); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 12, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 12, "got %d\n", end); + + /* SetEnd */ + hres = ITextSelection_SetStart(txtSel, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + /* same value */ + hres = ITextSelection_SetEnd(txtSel, 5); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetEnd(txtSel, 5); + ok(hres == S_FALSE, "got 0x%08x\n", hres); + + /* negative resets to 0 */ + hres = ITextSelection_SetEnd(txtSel, -1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + end = -1; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 0, "got %d\n", end); + + start = -1; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + /* greater than initial end, but less than total char count */ + hres = ITextSelection_SetStart(txtSel, 3); + ok(hres == S_OK, "got 0x%08x\n", hres); + + hres = ITextSelection_SetEnd(txtSel, 1); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 1, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 1, "got %d\n", end); + + /* more than total count */ + hres = ITextSelection_SetEnd(txtSel, 50); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 1, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 13, "got %d\n", end); + + /* zero */ + hres = ITextSelection_SetEnd(txtSel, 0); + ok(hres == S_OK, "got 0x%08x\n", hres); + + start = 0; + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(start == 0, "got %d\n", start); + + end = 0; + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(end == 0, "got %d\n", end); + + release_interfaces(&w, &reOle, &txtDoc, NULL); + + /* detached selection */ + hres = ITextSelection_GetStart(txtSel, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextSelection_GetStart(txtSel, &start); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextSelection_GetEnd(txtSel, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextSelection_GetEnd(txtSel, &end); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextSelection_Release(txtSel); } static void test_ITextRange_GetDuplicate(void) @@ -775,9 +1262,11 @@ static void test_ITextRange_GetDuplicate(void) hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup); ok(hres == S_OK, "ITextRange_GetDuplicate\n"); ok(txtRgeDup != txtRge, "A new pointer should be returned\n"); - ITextRange_GetStart(txtRgeDup, &start); + hres = ITextRange_GetStart(txtRgeDup, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == first, "got wrong value: %d\n", start); - ITextRange_GetEnd(txtRgeDup, &end); + hres = ITextRange_GetEnd(txtRgeDup, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == lim, "got wrong value: %d\n", end); ITextRange_Release(txtRgeDup); @@ -785,8 +1274,15 @@ static void test_ITextRange_GetDuplicate(void) hres = ITextRange_GetDuplicate(txtRge, NULL); ok(hres == E_INVALIDARG, "ITextRange_GetDuplicate\n"); - ITextRange_Release(txtRge); release_interfaces(&w, &reOle, &txtDoc, NULL); + + hres = ITextRange_GetDuplicate(txtRge, NULL); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_GetDuplicate(txtRge, &txtRgeDup); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextRange_Release(txtRge); } static void test_ITextRange_Collapse(void) @@ -803,73 +1299,101 @@ static void test_ITextRange_Collapse(void) SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1); first = 4, lim = 8; - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); hres = ITextRange_Collapse(txtRge, tomTrue); ok(hres == S_OK, "ITextRange_Collapse\n"); - ITextRange_GetStart(txtRge, &start); + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == 4, "got wrong start value: %d\n", start); - ITextRange_GetEnd(txtRge, &end); + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == 4, "got wrong end value: %d\n", end); ITextRange_Release(txtRge); - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); hres = ITextRange_Collapse(txtRge, tomStart); ok(hres == S_OK, "ITextRange_Collapse\n"); - ITextRange_GetStart(txtRge, &start); + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == 4, "got wrong start value: %d\n", start); - ITextRange_GetEnd(txtRge, &end); + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == 4, "got wrong end value: %d\n", end); ITextRange_Release(txtRge); - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); hres = ITextRange_Collapse(txtRge, tomFalse); ok(hres == S_OK, "ITextRange_Collapse\n"); - ITextRange_GetStart(txtRge, &start); + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == 8, "got wrong start value: %d\n", start); - ITextRange_GetEnd(txtRge, &end); + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == 8, "got wrong end value: %d\n", end); ITextRange_Release(txtRge); - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); hres = ITextRange_Collapse(txtRge, tomEnd); ok(hres == S_OK, "ITextRange_Collapse\n"); - ITextRange_GetStart(txtRge, &start); + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == 8, "got wrong start value: %d\n", start); - ITextRange_GetEnd(txtRge, &end); + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == 8, "got wrong end value: %d\n", end); ITextRange_Release(txtRge); /* tomStart is the default */ - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); hres = ITextRange_Collapse(txtRge, 256); ok(hres == S_OK, "ITextRange_Collapse\n"); - ITextRange_GetStart(txtRge, &start); + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == 4, "got wrong start value: %d\n", start); - ITextRange_GetEnd(txtRge, &end); + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == 4, "got wrong end value: %d\n", end); ITextRange_Release(txtRge); first = 6, lim = 6; - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); hres = ITextRange_Collapse(txtRge, tomEnd); ok(hres == S_FALSE, "ITextRange_Collapse\n"); - ITextRange_GetStart(txtRge, &start); + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == 6, "got wrong start value: %d\n", start); - ITextRange_GetEnd(txtRge, &end); + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == 6, "got wrong end value: %d\n", end); ITextRange_Release(txtRge); first = 8, lim = 8; - ITextDocument_Range(txtDoc, first, lim, &txtRge); + hres = ITextDocument_Range(txtDoc, first, lim, &txtRge); + ok(hres == S_OK, "got 0x%08x\n", hres); hres = ITextRange_Collapse(txtRge, tomStart); ok(hres == S_FALSE, "ITextRange_Collapse\n"); - ITextRange_GetStart(txtRge, &start); + hres = ITextRange_GetStart(txtRge, &start); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(start == 8, "got wrong start value: %d\n", start); - ITextRange_GetEnd(txtRge, &end); + hres = ITextRange_GetEnd(txtRge, &end); + ok(hres == S_OK, "got 0x%08x\n", hres); ok(end == 8, "got wrong end value: %d\n", end); - ITextRange_Release(txtRge); release_interfaces(&w, &reOle, &txtDoc, NULL); + + hres = ITextRange_Collapse(txtRge, tomStart); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextRange_Collapse(txtRge, tomUndefined); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextRange_Release(txtRge); } static void test_ITextSelection_Collapse(void) @@ -938,7 +1462,1879 @@ static void test_ITextSelection_Collapse(void) ok(start == 8, "got wrong start value: %d\n", start); ok(end == 8, "got wrong end value: %d\n", end); - release_interfaces(&w, &reOle, &txtDoc, &txtSel); + release_interfaces(&w, &reOle, &txtDoc, NULL); + + hres = ITextSelection_Collapse(txtSel, tomStart); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + hres = ITextSelection_Collapse(txtSel, tomUndefined); + ok(hres == CO_E_RELEASED, "got 0x%08x\n", hres); + + ITextSelection_Release(txtSel); +} + +static void test_GetClientSite(void) +{ + HWND w; + IRichEditOle *reOle = NULL, *reOle1 = NULL; + ITextDocument *txtDoc = NULL; + IOleClientSite *clientSite = NULL, *clientSite1 = NULL, *clientSite2 = NULL; + IOleWindow *oleWin = NULL, *oleWin1 = NULL; + IOleInPlaceSite *olePlace = NULL, *olePlace1 = NULL; + HRESULT hres; + LONG refcount1, refcount2; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + hres = IRichEditOle_GetClientSite(reOle, &clientSite); + ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres); + EXPECT_REF(clientSite, 1); + + hres = IOleClientSite_QueryInterface(clientSite, &IID_IRichEditOle, (void **)&reOle1); + ok(hres == E_NOINTERFACE, "IOleClientSite_QueryInterface: %x\n", hres); + + hres = IRichEditOle_GetClientSite(reOle, &clientSite1); + ok(hres == S_OK, "got 0x%08x\n", hres); + ok(clientSite != clientSite1, "got %p, %p\n", clientSite, clientSite1); + IOleClientSite_Release(clientSite1); + + hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleClientSite, (void **)&clientSite1); + ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres); + ok(clientSite == clientSite1, "Should not return a new pointer.\n"); + EXPECT_REF(clientSite, 2); + + /* IOleWindow interface */ + hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin); + ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres); + refcount1 = get_refcount((IUnknown *)clientSite); + refcount2 = get_refcount((IUnknown *)oleWin); + ok(refcount1 == refcount2, "got wrong ref count.\n"); + + hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin1); + ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres); + ok(oleWin == oleWin1, "Should not return a new pointer.\n"); + refcount1 = get_refcount((IUnknown *)clientSite); + refcount2 = get_refcount((IUnknown *)oleWin); + ok(refcount1 == refcount2, "got wrong ref count.\n"); + + hres = IOleWindow_QueryInterface(oleWin, &IID_IOleClientSite, (void **)&clientSite2); + ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres); + ok(clientSite2 == clientSite1, "got wrong pointer\n"); + + /* IOleInPlaceSite interface */ + hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace); + ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres); + refcount1 = get_refcount((IUnknown *)olePlace); + refcount2 = get_refcount((IUnknown *)clientSite); + ok(refcount1 == refcount2, "got wrong ref count.\n"); + + hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace1); + ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres); + ok(olePlace == olePlace1, "Should not return a new pointer.\n"); + IOleInPlaceSite_Release(olePlace1); + + hres = IOleWindow_QueryInterface(oleWin, &IID_IOleInPlaceSite, (void **)&olePlace1); + ok(hres == S_OK, "IOleWindow_QueryInterface: 0x%08x\n", hres); + refcount1 = get_refcount((IUnknown *)olePlace1); + refcount2 = get_refcount((IUnknown *)oleWin); + ok(refcount1 == refcount2, "got wrong ref count.\n"); + + IOleInPlaceSite_Release(olePlace1); + IOleInPlaceSite_Release(olePlace); + IOleWindow_Release(oleWin1); + IOleWindow_Release(oleWin); + IOleClientSite_Release(clientSite2); + IOleClientSite_Release(clientSite1); + IOleClientSite_Release(clientSite); + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + +static void test_IOleWindow_GetWindow(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + IOleClientSite *clientSite = NULL; + IOleWindow *oleWin = NULL; + HRESULT hres; + HWND hwnd; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + hres = IRichEditOle_GetClientSite(reOle, &clientSite); + ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres); + + hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleWindow, (void **)&oleWin); + ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres); + hres = IOleWindow_GetWindow(oleWin, &hwnd); + ok(hres == S_OK, "IOleClientSite_GetWindow: 0x%08x\n", hres); + ok(w == hwnd, "got wrong pointer\n"); + + hres = IOleWindow_GetWindow(oleWin, NULL); + ok(hres == E_INVALIDARG, "IOleClientSite_GetWindow: 0x%08x\n", hres); + + IOleWindow_Release(oleWin); + IOleClientSite_Release(clientSite); + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + +static void test_IOleInPlaceSite_GetWindow(void) +{ + HWND w; + IRichEditOle *reOle = NULL; + ITextDocument *txtDoc = NULL; + IOleClientSite *clientSite = NULL; + IOleInPlaceSite *olePlace = NULL; + HRESULT hres; + HWND hwnd; + + create_interfaces(&w, &reOle, &txtDoc, NULL); + hres = IRichEditOle_GetClientSite(reOle, &clientSite); + ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres); + + hres = IOleClientSite_QueryInterface(clientSite, &IID_IOleInPlaceSite, (void **)&olePlace); + ok(hres == S_OK, "IOleClientSite_QueryInterface: 0x%08x\n", hres); + hres = IOleInPlaceSite_GetWindow(olePlace, &hwnd); + ok(hres == S_OK, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres); + ok(w == hwnd, "got wrong pointer.\n"); + + hres = IOleInPlaceSite_GetWindow(olePlace, NULL); + ok(hres == E_INVALIDARG, "IOleInPlaceSite_GetWindow: 0x%08x\n", hres); + + IOleInPlaceSite_Release(olePlace); + IOleClientSite_Release(clientSite); + release_interfaces(&w, &reOle, &txtDoc, NULL); +} + +static void test_GetFont(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextRange *range = NULL; + ITextSelection *selection; + ITextFont *font, *font2; + CHARFORMAT2A cf; + LONG value; + float size; + HRESULT hr; + HWND hwnd; + BOOL ret; + + create_interfaces(&hwnd, &reOle, &doc, NULL); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + + hr = ITextDocument_GetSelection(doc, &selection); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = ITextSelection_GetFont(selection, &font); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = ITextSelection_GetFont(selection, &font2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(font != font2, "got %p, %p\n", font, font2); + ITextFont_Release(font2); + ITextFont_Release(font); + ITextSelection_Release(selection); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + EXPECT_REF(range, 1); + + hr = ITextRange_GetFont(range, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextRange_GetFont(range, &font); + ok(hr == S_OK, "got 0x%08x\n", hr); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + EXPECT_REF(range, 2); + EXPECT_REF(font, 1); + + hr = ITextRange_GetFont(range, &font2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(font != font2, "got %p, %p\n", font, font2); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + EXPECT_REF(range, 3); + EXPECT_REF(font, 1); + EXPECT_REF(font2, 1); + + ITextFont_Release(font2); + + /* set different font style within a range */ + hr = ITextFont_GetItalic(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetSize(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + size = 0.0; + hr = ITextFont_GetSize(font, &size); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(size > 0.0, "size %.2f\n", size); + + value = 0; + hr = ITextFont_GetLanguageID(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine + ok(value == GetSystemDefaultLCID(), "got lcid %x, user lcid %x\n", value, + GetSystemDefaultLCID()); + + /* range is non-italic */ + value = tomTrue; + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + cf.cbSize = sizeof(CHARFORMAT2A); + cf.dwMask = CFM_ITALIC|CFM_SIZE; + cf.dwEffects = CFE_ITALIC; + cf.yHeight = 24.0; + + SendMessageA(hwnd, EM_SETSEL, 2, 3); + ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + + /* now range is partially italicized */ + value = tomFalse; + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + size = 0.0; + hr = ITextFont_GetSize(font, &size); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(size == tomUndefined, "size %.2f\n", size); + + ITextFont_Release(font); + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_GetFont(range, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextRange_GetFont(range, &font2); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + ITextRange_Release(range); +} + +static void test_GetPara(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + ITextRange *range = NULL; + ITextPara *para, *para2; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + EXPECT_REF(range, 1); + + hr = ITextRange_GetPara(range, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextRange_GetPara(range, ¶); + ok(hr == S_OK, "got 0x%08x\n", hr); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + EXPECT_REF(range, 2); + EXPECT_REF(para, 1); + + hr = ITextRange_GetPara(range, ¶2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(para != para2, "got %p, %p\n", para, para2); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + EXPECT_REF(range, 3); + EXPECT_REF(para, 1); + EXPECT_REF(para2, 1); + + ITextPara_Release(para); + ITextPara_Release(para2); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + EXPECT_REF(selection, 2); + + hr = ITextSelection_GetPara(selection, ¶); + ok(hr == S_OK, "got 0x%08x\n", hr); + + EXPECT_REF(reOle, 3); + EXPECT_REF(doc, 3); + EXPECT_REF(selection, 3); + EXPECT_REF(para, 1); + + hr = ITextSelection_GetPara(selection, ¶2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(para != para2, "got %p, %p\n", para, para2); + + ITextPara_Release(para); + ITextPara_Release(para2); + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_GetPara(range, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextRange_GetPara(range, ¶); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_GetPara(selection, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_GetPara(selection, ¶); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + ITextSelection_Release(selection); + ITextRange_Release(range); +} + +static void test_dispatch(void) +{ + static const WCHAR testnameW[] = {'G','e','t','T','e','x','t',0}; + static const WCHAR testname2W[] = {'T','e','x','t',0}; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextRange *range = NULL; + WCHAR *nameW; + DISPID dispid; + HRESULT hr; + UINT count; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, NULL); + + range = NULL; + hr = ITextDocument_Range(doc, 0, 0, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(range != NULL, "got %p\n", range); + + dispid = 123; + nameW = (WCHAR*)testnameW; + hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid); + ok(hr == DISP_E_UNKNOWNNAME, "got 0x%08x\n", hr); + ok(dispid == DISPID_UNKNOWN, "got %d\n", dispid); + + dispid = 123; + nameW = (WCHAR*)testname2W; + hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(dispid == DISPID_VALUE, "got %d\n", dispid); + + release_interfaces(&hwnd, &reOle, &doc, NULL); + + /* try dispatch methods on detached range */ + hr = ITextRange_GetTypeInfoCount(range, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + + dispid = 123; + nameW = (WCHAR*)testname2W; + hr = ITextRange_GetIDsOfNames(range, &IID_NULL, &nameW, 1, LOCALE_USER_DEFAULT, &dispid); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(dispid == DISPID_VALUE, "got %d\n", dispid); + + ITextRange_Release(range); +} + +static void test_detached_font_getters(ITextFont *font, BOOL duplicate) +{ + HRESULT hr, hrexp = duplicate ? S_OK : CO_E_RELEASED; + LONG value; + float size; + BSTR str; + + hr = ITextFont_GetBold(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetBold(font, &value); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetForeColor(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetForeColor(font, &value); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, &value); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetLanguageID(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetLanguageID(font, &value); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetName(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetName(font, &str); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetSize(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetSize(font, &size); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetStrikeThrough(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetStrikeThrough(font, &value); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetSubscript(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetSubscript(font, &value); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetSuperscript(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetSuperscript(font, &value); + ok(hr == hrexp, "got 0x%08x\n", hr); + + hr = ITextFont_GetUnderline(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetUnderline(font, &value); + ok(hr == hrexp, "got 0x%08x\n", hr); +} + +static void test_textfont_global_defaults(ITextFont *font) +{ + float valuef; + LONG value; + HRESULT hr; + BSTR str; + + value = tomUndefined; + hr = ITextFont_GetAllCaps(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetAnimation(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetBackColor(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomAutoColor, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetBold(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse || value == tomTrue, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetEmboss(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetForeColor(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomAutoColor, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetHidden(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetEngrave(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + valuef = 1.0; + hr = ITextFont_GetKerning(font, &valuef); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(valuef == 0.0, "got %.2f\n", valuef); + + value = tomUndefined; + hr = ITextFont_GetLanguageID(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == GetSystemDefaultLCID(), "got %d\n", value); + + str = NULL; + hr = ITextFont_GetName(font, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(sysW, str), "%s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + value = tomUndefined; + hr = ITextFont_GetOutline(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + valuef = 1.0; + hr = ITextFont_GetPosition(font, &valuef); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(valuef == 0.0, "got %.2f\n", valuef); + + value = tomUndefined; + hr = ITextFont_GetProtected(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetShadow(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + valuef = 0.0; + hr = ITextFont_GetSize(font, &valuef); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(valuef >= 0.0, "got %.2f\n", valuef); + + value = tomUndefined; + hr = ITextFont_GetSmallCaps(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + valuef = 1.0; + hr = ITextFont_GetSpacing(font, &valuef); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(valuef == 0.0, "got %.2f\n", valuef); + + value = tomUndefined; + hr = ITextFont_GetStrikeThrough(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetSubscript(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetSuperscript(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetUnderline(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomUndefined; + hr = ITextFont_GetWeight(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == FW_NORMAL || value == FW_BOLD, "got %d\n", value); +} + +static void test_textfont_undefined(ITextFont *font) +{ + float valuef; + LONG value; + HRESULT hr; + + value = tomFalse; + hr = ITextFont_GetAllCaps(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetAnimation(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetBackColor(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetBold(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetEmboss(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetForeColor(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetHidden(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetEngrave(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + valuef = 0.0; + hr = ITextFont_GetKerning(font, &valuef); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(valuef == tomUndefined, "got %.2f\n", valuef); + + value = tomFalse; + hr = ITextFont_GetLanguageID(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetOutline(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + valuef = 0.0; + hr = ITextFont_GetPosition(font, &valuef); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(valuef == tomUndefined, "got %.2f\n", valuef); + + value = tomFalse; + hr = ITextFont_GetProtected(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetShadow(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + valuef = 0.0; + hr = ITextFont_GetSize(font, &valuef); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(valuef == tomUndefined, "got %.2f\n", valuef); + + value = tomFalse; + hr = ITextFont_GetSmallCaps(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + valuef = 0.0; + hr = ITextFont_GetSpacing(font, &valuef); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(valuef == tomUndefined, "got %.2f\n", valuef); + + value = tomFalse; + hr = ITextFont_GetStrikeThrough(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetSubscript(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetSuperscript(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetUnderline(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); + + value = tomFalse; + hr = ITextFont_GetWeight(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUndefined, "got %d\n", value); +} + +static inline FLOAT twips_to_points(LONG value) +{ + return value * 72.0 / 1440; +} + +static void test_ITextFont(void) +{ + static const WCHAR arialW[] = {'A','r','i','a','l',0}; + static const CHAR test_text1[] = "TestSomeText"; + ITextFont *font, *font2, *font3; + FLOAT size, position, kerning; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextRange *range = NULL; + CHARFORMAT2A cf; + LONG value; + HRESULT hr; + HWND hwnd; + BOOL ret; + BSTR str; + + create_interfaces(&hwnd, &reOle, &doc, NULL); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + + hr = ITextDocument_Range(doc, 0, 10, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_GetFont(range, &font); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_Reset(font, tomUseTwips); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_Reset(font, tomUsePoints); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetName(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + /* default font size unit is point */ + size = 0.0; + hr = ITextFont_GetSize(font, &size); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* set to some non-zero values */ + hr = ITextFont_SetPosition(font, 20.0); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_SetKerning(font, 10.0); + ok(hr == S_OK, "got 0x%08x\n", hr); + + position = 0.0; + hr = ITextFont_GetPosition(font, &position); + ok(hr == S_OK, "got 0x%08x\n", hr); + + kerning = 0.0; + hr = ITextFont_GetKerning(font, &kerning); + ok(hr == S_OK, "got 0x%08x\n", hr); + + memset(&cf, 0, sizeof(cf)); + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_SIZE|CFM_OFFSET|CFM_KERNING; + + /* CHARFORMAT members are in twips */ + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + ok(size == twips_to_points(cf.yHeight), "got yHeight %d, size %.2f\n", cf.yHeight, size); + ok(position == twips_to_points(cf.yOffset), "got yOffset %d, position %.2f\n", cf.yOffset, position); + ok(kerning == twips_to_points(cf.wKerning), "got wKerning %d, kerning %.2f\n", cf.wKerning, kerning); + + hr = ITextFont_Reset(font, tomUseTwips); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_Reset(font, tomUsePoints); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_GetDuplicate(font, &font2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_Reset(font2, tomUseTwips); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextFont_Reset(font2, tomUsePoints); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + ITextFont_Release(font2); + + /* default font name */ + str = NULL; + hr = ITextFont_GetName(font, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + /* change font name for an inner subrange */ + memset(&cf, 0, sizeof(cf)); + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_FACE; + strcpy(cf.szFaceName, "Arial"); + + SendMessageA(hwnd, EM_SETSEL, 3, 4); + ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + + /* still original name */ + str = NULL; + hr = ITextFont_GetName(font, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + SendMessageA(hwnd, EM_SETSEL, 1, 2); + ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + + str = NULL; + hr = ITextFont_GetName(font, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, sysW), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + /* name is returned for first position within a range */ + SendMessageA(hwnd, EM_SETSEL, 0, 1); + ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + + str = NULL; + hr = ITextFont_GetName(font, &str); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(str, arialW), "got %s\n", wine_dbgstr_w(str)); + SysFreeString(str); + + /* GetDuplicate() */ + hr = ITextFont_GetDuplicate(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + EXPECT_REF(range, 2); + font2 = NULL; + hr = ITextFont_GetDuplicate(font, &font2); + ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(range, 2); + + /* set whole range to italic */ + cf.cbSize = sizeof(CHARFORMAT2A); + cf.dwMask = CFM_ITALIC; + cf.dwEffects = CFE_ITALIC; + + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + + value = tomFalse; + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomTrue, "got %d\n", value); + + /* duplicate retains original value */ + value = tomTrue; + hr = ITextFont_GetItalic(font2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + /* get a duplicate from a cloned font */ + hr = ITextFont_GetDuplicate(font2, &font3); + ok(hr == S_OK, "got 0x%08x\n", hr); + ITextFont_Release(font3); + + ITextRange_Release(range); + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextFont_GetDuplicate(font, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + test_detached_font_getters(font, FALSE); + test_detached_font_getters(font2, TRUE); + + /* get a duplicate of detached font */ + hr = ITextFont_GetDuplicate(font2, &font3); + ok(hr == S_OK, "got 0x%08x\n", hr); + ITextFont_Release(font3); + + /* reset detached font to undefined */ + value = tomUndefined; + hr = ITextFont_GetBold(font2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value != tomUndefined, "got %d\n", value); + + /* reset to undefined for deatached font */ + hr = ITextFont_Reset(font2, tomUndefined); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_undefined(font2); + + /* font is detached, default means global TOM defaults */ + hr = ITextFont_Reset(font2, tomDefault); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + hr = ITextFont_GetDuplicate(font2, &font3); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + hr = ITextFont_Reset(font2, tomApplyNow); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + hr = ITextFont_Reset(font2, tomApplyLater); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + hr = ITextFont_Reset(font2, tomTrackParms); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + hr = ITextFont_SetItalic(font2, tomUndefined); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextFont_Reset(font2, tomCacheParms); + ok(hr == S_OK, "got 0x%08x\n", hr); + test_textfont_global_defaults(font2); + + ITextFont_Release(font3); + ITextFont_Release(font2); + + font2 = (void*)0xdeadbeef; + hr = ITextFont_GetDuplicate(font, &font2); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(font2 == NULL, "got %p\n", font2); + + hr = ITextFont_Reset(font, tomDefault); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + ITextFont_Release(font); + + /* Reset() */ + create_interfaces(&hwnd, &reOle, &doc, NULL); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + + hr = ITextDocument_Range(doc, 0, 10, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_GetFont(range, &font); + ok(hr == S_OK, "got 0x%08x\n", hr); + + value = tomUndefined; + hr = ITextFont_GetBold(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value != tomUndefined, "got %d\n", value); + + /* reset to undefined for attached font */ + hr = ITextFont_Reset(font, tomUndefined); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + value = tomUndefined; + hr = ITextFont_GetBold(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value != tomUndefined, "got %d\n", value); + + /* tomCacheParms/tomTrackParms */ + hr = ITextFont_Reset(font, tomCacheParms); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + memset(&cf, 0, sizeof(cf)); + cf.cbSize = sizeof(CHARFORMAT2A); + cf.dwMask = CFM_ITALIC; + + cf.dwEffects = CFE_ITALIC; + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + + /* still cached value */ + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextFont_Reset(font, tomTrackParms); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomTrue, "got %d\n", value); + + /* switch back to cache - value retained */ + hr = ITextFont_Reset(font, tomCacheParms); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomTrue, "got %d\n", value); + + /* tomApplyLater */ + hr = ITextFont_Reset(font, tomApplyLater); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_SetItalic(font, tomFalse); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + cf.dwEffects = 0; + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + ok((cf.dwEffects & CFE_ITALIC) == CFE_ITALIC, "got 0x%08x\n", cf.dwEffects); + + hr = ITextFont_Reset(font, tomApplyNow); + ok(hr == S_OK, "got 0x%08x\n", hr); + + cf.dwEffects = 0; + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects); + + hr = ITextFont_SetItalic(font, tomUndefined); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextFont_SetItalic(font, tomAutoColor); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + cf.dwEffects = 0; + SendMessageA(hwnd, EM_SETSEL, 0, 10); + ret = SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + ok(ret, "got %d\n", ret); + ok((cf.dwEffects & CFE_ITALIC) == 0, "got 0x%08x\n", cf.dwEffects); + + ITextRange_Release(range); + ITextFont_Release(font); + release_interfaces(&hwnd, &reOle, &doc, NULL); +} + +static void test_Delete(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextRange *range, *range2; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, NULL); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextDocument_Range(doc, 1, 2, &range2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_GetEnd(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 4, "got %d\n", value); + + /* unit type doesn't matter is count is 0 */ + value = 0; + hr = ITextRange_Delete(range2, tomSentence, 0, &value); +todo_wine { + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 1, "got %d\n", value); +} + value = 1; + hr = ITextRange_Delete(range2, tomCharacter, 0, &value); +todo_wine { + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); +} + hr = ITextRange_GetEnd(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine + ok(value == 3, "got %d\n", value); + + hr = ITextRange_GetStart(range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 1, "got %d\n", value); + + hr = ITextRange_GetEnd(range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); +todo_wine + ok(value == 1, "got %d\n", value); + + ITextRange_Release(range); + ITextRange_Release(range2); + release_interfaces(&hwnd, &reOle, &doc, NULL); +} + +static void test_SetText(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + static const WCHAR textW[] = {'a','b','c','d','e','f','g','h','i',0}; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextRange *range, *range2; + LONG value; + HRESULT hr; + HWND hwnd; + BSTR str; + + create_interfaces(&hwnd, &reOle, &doc, NULL); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextDocument_Range(doc, 0, 4, &range2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + value = 1; + hr = ITextRange_GetStart(range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + + value = 0; + hr = ITextRange_GetEnd(range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 4, "got %d\n", value); + + hr = ITextRange_SetText(range, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + value = 1; + hr = ITextRange_GetEnd(range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + + str = SysAllocString(textW); + hr = ITextRange_SetText(range, str); + ok(hr == S_OK, "got 0x%08x\n", hr); + SysFreeString(str); + + value = 1; + hr = ITextRange_GetStart(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + + value = 0; + hr = ITextRange_GetEnd(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 9, "got %d\n", value); + + value = 1; + hr = ITextRange_GetStart(range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + + value = 0; + hr = ITextRange_GetEnd(range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + + str = SysAllocStringLen(NULL, 0); + hr = ITextRange_SetText(range, str); + ok(hr == S_OK, "got 0x%08x\n", hr); + value = 1; + hr = ITextRange_GetEnd(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + SysFreeString(str); + + ITextRange_Release(range2); + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_SetText(range, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + str = SysAllocStringLen(NULL, 0); + hr = ITextRange_SetText(range, str); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + SysFreeString(str); + + ITextRange_Release(range); +} + +static void test_InRange(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + ITextRange *range, *range2, *range3; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextDocument_Range(doc, 0, 4, &range2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* matches selection */ + hr = ITextDocument_Range(doc, 1, 2, &range3); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_InRange(range, NULL, NULL); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextRange_InRange(range, NULL, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextRange_InRange(range, range2, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + value = tomFalse; + hr = ITextRange_InRange(range, range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomTrue, "got %d\n", value); + + /* selection */ + hr = ITextSelection_InRange(selection, NULL, NULL); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextSelection_InRange(selection, NULL, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextSelection_InRange(selection, range2, NULL); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextSelection_InRange(selection, range2, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomTrue; + hr = ITextSelection_InRange(selection, range3, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + /* seems to work on ITextSelection ranges only */ + value = tomFalse; + hr = ITextSelection_InRange(selection, (ITextRange*)selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomTrue, "got %d\n", value); + + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_InRange(range, NULL, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextRange_InRange(range, NULL, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextRange_InRange(range, range2, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextRange_InRange(range, range2, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + /* selection */ + hr = ITextSelection_InRange(selection, NULL, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextSelection_InRange(selection, NULL, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextSelection_InRange(selection, range2, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextSelection_InRange(selection, range2, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + ITextRange_Release(range); + ITextRange_Release(range2); + ITextRange_Release(range3); + ITextSelection_Release(selection); +} + +static void test_ITextRange_IsEqual(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + ITextRange *range, *range2, *range3; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextDocument_Range(doc, 0, 4, &range2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* matches selection */ + hr = ITextDocument_Range(doc, 1, 2, &range3); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_IsEqual(range, NULL, NULL); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextRange_IsEqual(range, NULL, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextRange_IsEqual(range, range2, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + value = tomFalse; + hr = ITextRange_IsEqual(range, range2, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomTrue, "got %d\n", value); + + value = tomTrue; + hr = ITextRange_IsEqual(range, range3, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + /* selection */ + hr = ITextSelection_IsEqual(selection, NULL, NULL); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextSelection_IsEqual(selection, NULL, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextSelection_IsEqual(selection, range2, NULL); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextSelection_IsEqual(selection, range2, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + value = tomTrue; + hr = ITextSelection_IsEqual(selection, range3, &value); + ok(hr == S_FALSE, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + /* seems to work on ITextSelection ranges only */ + value = tomFalse; + hr = ITextSelection_IsEqual(selection, (ITextRange*)selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomTrue, "got %d\n", value); + + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_IsEqual(range, NULL, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextRange_IsEqual(range, NULL, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextRange_IsEqual(range, range2, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextRange_IsEqual(range, range2, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + /* selection */ + hr = ITextSelection_IsEqual(selection, NULL, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextSelection_IsEqual(selection, NULL, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + hr = ITextSelection_IsEqual(selection, range2, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = tomTrue; + hr = ITextSelection_IsEqual(selection, range2, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + ITextRange_Release(range); + ITextRange_Release(range2); + ITextRange_Release(range3); + ITextSelection_Release(selection); +} + +static void test_Select(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + ITextRange *range; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_Select(range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + value = 1; + hr = ITextSelection_GetStart(selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + + hr = ITextRange_Select(range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextSelection_Select(selection); + ok(hr == S_OK, "got 0x%08x\n", hr); + + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_Select(range); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_Select(selection); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + ITextRange_Release(range); + ITextSelection_Release(selection); +} + +static void test_GetStoryType(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + ITextRange *range; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_GetStoryType(range, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + value = tomTextFrameStory; + hr = ITextRange_GetStoryType(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUnknownStory, "got %d\n", value); + + hr = ITextSelection_GetStoryType(selection, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + value = tomTextFrameStory; + hr = ITextSelection_GetStoryType(selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomUnknownStory, "got %d\n", value); + + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_GetStoryType(range, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = 123; + hr = ITextRange_GetStoryType(range, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == 123, "got %d\n", value); + + hr = ITextSelection_GetStoryType(selection, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = 123; + hr = ITextSelection_GetStoryType(selection, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == 123, "got %d\n", value); + + ITextRange_Release(range); + ITextSelection_Release(selection); +} + +static void test_SetFont(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + ITextRange *range, *range2; + ITextFont *font, *font2; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextDocument_Range(doc, 5, 2, &range2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + EXPECT_REF(range, 1); + hr = ITextRange_GetFont(range, &font); + ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(range, 2); + + EXPECT_REF(range2, 1); + hr = ITextRange_GetFont(range2, &font2); + ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(range2, 2); + + hr = ITextRange_SetFont(range, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + /* setting same font, no-op */ + EXPECT_REF(range, 2); + hr = ITextRange_SetFont(range, font); + ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(range, 2); + + EXPECT_REF(range2, 2); + EXPECT_REF(range, 2); + hr = ITextRange_SetFont(range, font2); + ok(hr == S_OK, "got 0x%08x\n", hr); + EXPECT_REF(range2, 2); + EXPECT_REF(range, 2); + + /* originaly range 0-4 is non-italic */ + value = tomTrue; + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomFalse, "got %d\n", value); + + /* set range 5-2 to italic, then set this font to range 0-4 */ + hr = ITextFont_SetItalic(font2, tomTrue); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_SetFont(range, font2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + value = tomFalse; + hr = ITextFont_GetItalic(font, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == tomTrue, "got %d\n", value); + + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_SetFont(range, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextRange_SetFont(range, font); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_SetFont(selection, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ITextSelection_SetFont(selection, font); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + ITextFont_Release(font); + ITextFont_Release(font2); + ITextRange_Release(range); + ITextRange_Release(range2); + ITextSelection_Release(selection); +} + +static void test_InsertObject(void) +{ + IRichEditOle *reole = NULL; + ITextDocument *doc = NULL; + IOleClientSite *clientsite; + REOBJECT reo; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reole, &doc, NULL); + + hr = IRichEditOle_InsertObject(reole, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = IRichEditOle_GetClientSite(reole, &clientsite); + ok(hr == S_OK, "got 0x%08x\n", hr); + + reo.cbStruct = sizeof(reo); + reo.cp = 0; + memset(&reo.clsid, 0, sizeof(reo.clsid)); + reo.poleobj = NULL; + reo.pstg = NULL; + reo.polesite = clientsite; + reo.sizel.cx = 10; + reo.sizel.cy = 10; + reo.dvaspect = DVASPECT_CONTENT; + reo.dwFlags = 0; + reo.dwUser = 0; + + hr = IRichEditOle_InsertObject(reole, &reo); + ok(hr == S_OK, "got 0x%08x\n", hr); + + IOleClientSite_Release(clientsite); + release_interfaces(&hwnd, &reole, &doc, NULL); +} + +static void test_GetStoryLength(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + ITextRange *range; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_GetStoryLength(range, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + value = 0; + hr = ITextRange_GetStoryLength(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 13, "got %d\n", value); + + hr = ITextSelection_GetStoryLength(selection, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + value = 0; + hr = ITextSelection_GetStoryLength(selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 13, "got %d\n", value); + + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)""); + + value = 0; + hr = ITextRange_GetStoryLength(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 1, "got %d\n", value); + + value = 0; + hr = ITextSelection_GetStoryLength(selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 1, "got %d\n", value); + + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextRange_GetStoryLength(range, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = 100; + hr = ITextRange_GetStoryLength(range, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == 100, "got %d\n", value); + + hr = ITextSelection_GetStoryLength(selection, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + value = 100; + hr = ITextSelection_GetStoryLength(selection, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + ok(value == 100, "got %d\n", value); + + ITextSelection_Release(selection); + ITextRange_Release(range); +} + +static void test_ITextSelection_GetDuplicate(void) +{ + static const CHAR test_text1[] = "TestSomeText"; + IRichEditOle *reOle = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection, *sel2; + ITextRange *range, *range2; + ITextFont *font; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reOle, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextSelection_GetDuplicate(selection, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + EXPECT_REF(selection, 2); + + hr = ITextSelection_GetDuplicate(selection, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextSelection_GetDuplicate(selection, &range2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(range != range2, "got %p, %p\n", range, range2); + + EXPECT_REF(selection, 2); + EXPECT_REF(range, 1); + EXPECT_REF(range2, 1); + + ITextRange_Release(range2); + + value = 0; + hr = ITextRange_GetStart(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 1, "got %d\n", value); + + value = 0; + hr = ITextRange_GetEnd(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 2, "got %d\n", value); + + SendMessageA(hwnd, EM_SETSEL, 2, 3); + + value = 0; + hr = ITextRange_GetStart(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 1, "got %d\n", value); + + value = 0; + hr = ITextRange_GetEnd(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 2, "got %d\n", value); + + hr = ITextRange_QueryInterface(range, &IID_ITextSelection, (void**)&sel2); + ok(hr == E_NOINTERFACE, "got 0x%08x\n", hr); + + release_interfaces(&hwnd, &reOle, &doc, NULL); + + hr = ITextSelection_GetDuplicate(selection, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_GetDuplicate(selection, &range); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextRange_GetFont(range, &font); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + ITextSelection_Release(selection); + ITextRange_Release(range); +} + +static void test_Expand(void) +{ + static const char test_text1[] = "TestSomeText"; + IRichEditOle *reole = NULL; + ITextDocument *doc = NULL; + ITextSelection *selection; + ITextRange *range; + LONG value; + HRESULT hr; + HWND hwnd; + + create_interfaces(&hwnd, &reole, &doc, &selection); + SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1); + SendMessageA(hwnd, EM_SETSEL, 1, 2); + + hr = ITextDocument_Range(doc, 0, 4, &range); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextRange_Expand(range, tomStory, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = ITextRange_GetStart(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + hr = ITextRange_GetEnd(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 13, "got %d\n", value); + + hr = ITextSelection_Expand(selection, tomStory, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = ITextSelection_GetStart(selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + hr = ITextSelection_GetEnd(selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 13, "got %d\n", value); + + hr = ITextRange_SetStart(range, 1); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = ITextRange_SetEnd(range, 2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ITextSelection_SetStart(selection, 1); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = ITextSelection_SetEnd(selection, 2); + ok(hr == S_OK, "got 0x%08x\n", hr); + + value = 0; + hr = ITextRange_Expand(range, tomStory, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 12, "got %d\n", value); + hr = ITextRange_GetStart(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + hr = ITextRange_GetEnd(range, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 13, "got %d\n", value); + + value = 0; + hr = ITextSelection_Expand(selection, tomStory, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 12, "got %d\n", value); + hr = ITextSelection_GetStart(selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 0, "got %d\n", value); + hr = ITextSelection_GetEnd(selection, &value); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(value == 13, "got %d\n", value); + + release_interfaces(&hwnd, &reole, &doc, NULL); + + hr = ITextRange_Expand(range, tomStory, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextRange_Expand(range, tomStory, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_Expand(selection, tomStory, NULL); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + hr = ITextSelection_Expand(selection, tomStory, &value); + ok(hr == CO_E_RELEASED, "got 0x%08x\n", hr); + + ITextSelection_Release(selection); + ITextRange_Release(range); } static void test_ITextRange_SetStart(void) @@ -1280,7 +3676,7 @@ static void test_ITextRange_SetRange(void) release_interfaces(&w, &reOle, &txtDoc, NULL); } -static void test_ITextRange_IsEqual(void) +static void test_ITextRange_IsEqual2(void) { HWND w; IRichEditOle *reOle = NULL; @@ -1395,7 +3791,7 @@ START_TEST(richole) test_Interfaces(); test_ITextDocument_Open(); - test_ITextSelection_GetText(); + test_GetText(); test_ITextSelection_GetChar(); test_ITextSelection_GetStart_GetEnd(); test_ITextSelection_SetStart(); @@ -1407,13 +3803,31 @@ START_TEST(richole) test_ITextRange_GetChar(); test_ITextRange_GetStart_GetEnd(); test_ITextRange_GetDuplicate(); - test_ITextRange_Collapse(); test_ITextRange_SetStart(); test_ITextRange_SetEnd(); + test_ITextRange_Collapse(); test_ITextRange_GetFont(); test_ITextRange_GetPara(); test_ITextRange_GetText(); test_ITextRange_SetRange(); - test_ITextRange_IsEqual(); + test_ITextRange_IsEqual2(); test_ITextRange_GetStoryLength(); + test_GetClientSite(); + test_IOleWindow_GetWindow(); + test_IOleInPlaceSite_GetWindow(); + test_GetFont(); + test_GetPara(); + test_dispatch(); + test_ITextFont(); + test_Delete(); + test_SetText(); + test_InRange(); + test_ITextRange_IsEqual(); + test_Select(); + test_GetStoryType(); + test_SetFont(); + test_InsertObject(); + test_GetStoryLength(); + test_ITextSelection_GetDuplicate(); + test_Expand(); } diff --git a/rostests/winetests/riched20/txtsrv.c b/rostests/winetests/riched20/txtsrv.c index 50797b1e015..1a6ca61052d 100644 --- a/rostests/winetests/riched20/txtsrv.c +++ b/rostests/winetests/riched20/txtsrv.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -505,8 +506,6 @@ static ITextHostVtbl itextHostVtbl = { ITextHostImpl_TxGetSelectionBarWidth }; -static ITextServices *txtserv = NULL; -static ITextHostTestImpl *dummyTextHost; static void *wrapperCodeMem = NULL; #include "pshpack1.h" @@ -605,14 +604,15 @@ static void setup_thiscall_wrappers(void) /* Conformance test functions. */ /* Initialize the test texthost structure */ -static BOOL init_texthost(void) +static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret) { + ITextHostTestImpl *dummyTextHost; IUnknown *init; HRESULT result; dummyTextHost = CoTaskMemAlloc(sizeof(*dummyTextHost)); if (dummyTextHost == NULL) { - skip("Insufficient memory to create ITextHost interface\n"); + win_skip("Insufficient memory to create ITextHost interface\n"); return FALSE; } dummyTextHost->ITextHost_iface.lpVtbl = &itextHostVtbl; @@ -621,54 +621,53 @@ static BOOL init_texthost(void) /* MSDN states that an IUnknown object is returned by CreateTextServices which is then queried to obtain a ITextServices object. */ - result = (*pCreateTextServices)(NULL, &dummyTextHost->ITextHost_iface, &init); + result = pCreateTextServices(NULL, &dummyTextHost->ITextHost_iface, &init); ok(result == S_OK, "Did not return S_OK when created (result = %x)\n", result); if (result != S_OK) { CoTaskMemFree(dummyTextHost); - skip("CreateTextServices failed.\n"); + win_skip("CreateTextServices failed.\n"); return FALSE; } - result = IUnknown_QueryInterface(init, pIID_ITextServices, - (void **)&txtserv); - ok((result == S_OK) && (txtserv != NULL), "Querying interface failed (result = %x, txtserv = %p)\n", result, txtserv); + result = IUnknown_QueryInterface(init, pIID_ITextServices, (void**)txtserv); + ok((result == S_OK) && (*txtserv != NULL), "Querying interface failed (result = %x, txtserv = %p)\n", result, *txtserv); IUnknown_Release(init); - if (!((result == S_OK) && (txtserv != NULL))) { + if (!((result == S_OK) && (*txtserv != NULL))) { CoTaskMemFree(dummyTextHost); - skip("Could not retrieve ITextServices interface\n"); + win_skip("Could not retrieve ITextServices interface\n"); return FALSE; } + *ret = &dummyTextHost->ITextHost_iface; return TRUE; } -static void free_texthost(void) -{ - ITextServices_Release(txtserv); - CoTaskMemFree(dummyTextHost); -} - static void test_TxGetText(void) { + ITextServices *txtserv; + ITextHost *host; HRESULT hres; BSTR rettext; - if (!init_texthost()) + if (!init_texthost(&txtserv, &host)) return; hres = ITextServices_TxGetText(txtserv, &rettext); ok(hres == S_OK, "ITextServices_TxGetText failed (result = %x)\n", hres); - free_texthost(); + ITextServices_Release(txtserv); + ITextHost_Release(host); } static void test_TxSetText(void) { + ITextServices *txtserv; + ITextHost *host; HRESULT hres; BSTR rettext; WCHAR settext[] = {'T','e','s','t',0}; - if (!init_texthost()) + if (!init_texthost(&txtserv, &host)) return; hres = ITextServices_TxSetText(txtserv, settext); @@ -683,10 +682,14 @@ static void test_TxSetText(void) "String returned differs\n"); SysFreeString(rettext); - free_texthost(); + ITextServices_Release(txtserv); + ITextHost_Release(host); } -static void test_TxGetNaturalSize(void) { +static void test_TxGetNaturalSize(void) +{ + ITextServices *txtserv; + ITextHost *host; HRESULT result; BOOL ret; @@ -709,7 +712,7 @@ static void test_TxGetNaturalSize(void) { INT charwidth_caps_text[26]; TEXTMETRICA tmInfo_text; - if (!init_texthost()) + if (!init_texthost(&txtserv, &host)) return; hdcDraw = GetDC(NULL); @@ -758,11 +761,14 @@ static void test_TxGetNaturalSize(void) { cleanup: RestoreDC(hdcDraw,1); ReleaseDC(NULL,hdcDraw); - free_texthost(); + ITextServices_Release(txtserv); + ITextHost_Release(host); } static void test_TxDraw(void) { + ITextServices *txtserv; + ITextHost *host; HDC tmphdc = GetDC(NULL); DWORD dwAspect = DVASPECT_CONTENT; HDC hicTargetDev = NULL; /* Means "default" device */ @@ -771,7 +777,8 @@ static void test_TxDraw(void) HRESULT result; RECTL client = {0,0,100,100}; - if (!init_texthost()) + + if (!init_texthost(&txtserv, &host)) return; todo_wine { @@ -781,8 +788,8 @@ static void test_TxDraw(void) ok(result == S_OK, "TxDraw failed (result = %x)\n", result); } - free_texthost(); - + ITextServices_Release(txtserv); + ITextHost_Release(host); } DEFINE_GUID(expected_iid_itextservices, 0x8d33f740, 0xcf58, 0x11ce, 0xa8, 0x9d, 0x00, 0xaa, 0x00, 0x6c, 0xad, 0xc5); @@ -871,12 +878,14 @@ static ULONG get_refcount(IUnknown *iface) static void test_QueryInterface(void) { + ITextServices *txtserv; + ITextHost *host; HRESULT hres; IRichEditOle *reole, *txtsrv_reole; ITextDocument *txtdoc, *txtsrv_txtdoc; ULONG refcount; - if(!init_texthost()) + if(!init_texthost(&txtserv, &host)) return; refcount = get_refcount((IUnknown *)txtserv); @@ -926,11 +935,15 @@ static void test_QueryInterface(void) refcount = get_refcount((IUnknown *)txtserv); ok(refcount == 1, "got wrong ref count: %d\n", refcount); - free_texthost(); + ITextServices_Release(txtserv); + ITextHost_Release(host); } START_TEST( txtsrv ) { + ITextServices *txtserv; + ITextHost *host; + setup_thiscall_wrappers(); /* Must explicitly LoadLibrary(). The test has no references to functions in @@ -946,9 +959,10 @@ START_TEST( txtsrv ) test_IIDs(); test_COM(); - if (init_texthost()) + if (init_texthost(&txtserv, &host)) { - free_texthost(); + ITextServices_Release(txtserv); + ITextHost_Release(host); test_TxGetText(); test_TxSetText();