https://git.reactos.org/?p=reactos.git;a=commitdiff;h=364d6e0346e62d6e9ece7…
commit 364d6e0346e62d6e9ece700be1adac76be763d68
Author: Doug Lyons <douglyons(a)douglyons.com>
AuthorDate: Sat Feb 8 13:04:04 2025 -0600
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Feb 8 13:04:04 2025 -0600
[RICHED20_WINETEST] Sync to Wine-6.10. (#7692)
ROSTESTS-398 and CORE-6727
---
modules/rostests/winetests/riched20/editor.c | 73 ++-
modules/rostests/winetests/riched20/richole.c | 890 +++++++++++++++-----------
modules/rostests/winetests/riched20/txtsrv.c | 285 ++++++++-
sdk/include/psdk/textserv.h | 88 ++-
4 files changed, 915 insertions(+), 421 deletions(-)
diff --git a/modules/rostests/winetests/riched20/editor.c
b/modules/rostests/winetests/riched20/editor.c
index 791f471dee2..6bac7e0a89b 100644
--- a/modules/rostests/winetests/riched20/editor.c
+++ b/modules/rostests/winetests/riched20/editor.c
@@ -33,6 +33,8 @@
#include <ole2.h>
#include <richedit.h>
#include <richole.h>
+#include <imm.h>
+#include <textserv.h>
#include <commdlg.h>
#include <time.h>
#include <wine/test.h>
@@ -51,12 +53,38 @@ static CHAR string1[MAX_PATH], string2[MAX_PATH], string3[MAX_PATH];
static HMODULE hmoduleRichEdit;
static BOOL is_lang_japanese;
+#if defined(__i386__) && !defined(__MINGW32__) && (!defined(_MSC_VER) ||
!defined(__clang__))
+static void disable_beep( HWND hwnd )
+{
+ /* don't attempt to disable beep if we don't have thiscall compiler support
*/
+}
+#else
+#define ITextServices_OnTxPropertyBitsChange(This,a,b)
(This)->lpVtbl->OnTxPropertyBitsChange(This,a,b)
+static void disable_beep( HWND hwnd )
+{
+ IRichEditOle *richole;
+ ITextServices *services;
+ IID *pIID_ITextServices = (IID *)GetProcAddress( hmoduleRichEdit,
"IID_ITextServices" );
+
+ if (SendMessageW( hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&richole ))
+ {
+ if (SUCCEEDED( IRichEditOle_QueryInterface( richole, pIID_ITextServices, (void
**)&services ) ))
+ {
+ ITextServices_OnTxPropertyBitsChange( services, TXTBIT_ALLOWBEEP, 0 );
+ ITextServices_Release( services );
+ }
+ IRichEditOle_Release( richole );
+ }
+}
+#endif
+
static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent) {
HWND hwnd;
hwnd = CreateWindowA(lpClassName, NULL, dwStyle|WS_POPUP|WS_HSCROLL|WS_VSCROLL
|WS_VISIBLE, 0, 0, 200, 60, parent, NULL,
hmoduleRichEdit, NULL);
ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int)
GetLastError());
+ disable_beep( hwnd );
return hwnd;
}
@@ -66,6 +94,7 @@ static HWND new_windowW(LPCWSTR lpClassName, DWORD dwStyle, HWND parent)
{
|WS_VISIBLE, 0, 0, 200, 60, parent, NULL,
hmoduleRichEdit, NULL);
ok(hwnd != NULL, "class: %s, error: %d\n", wine_dbgstr_w(lpClassName), (int)
GetLastError());
+ disable_beep( hwnd );
return hwnd;
}
@@ -615,7 +644,7 @@ static void test_EM_POSFROMCHAR(void)
"gg\n"
"hh\n";
- rtl = (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_FONTSIGNATURE,
+ rtl = (GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_FONTSIGNATURE,
(LPSTR) &sig, sizeof(LOCALESIGNATURE)) &&
(sig.lsUsb[3] & 0x08000000) != 0);
@@ -772,7 +801,7 @@ static void test_EM_SETCHARFORMAT(void)
BOOL rtl;
DWORD expect_effects;
- rtl = (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_FONTSIGNATURE,
+ rtl = (GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_FONTSIGNATURE,
(LPSTR) &sig, sizeof(LOCALESIGNATURE)) &&
(sig.lsUsb[3] & 0x08000000) != 0);
@@ -1791,8 +1820,8 @@ static void test_EM_GETTEXTRANGE(void)
textRange.chrg.cpMin = 4;
textRange.chrg.cpMax = 8;
result = SendMessageA(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange);
- todo_wine ok(result == 5, "EM_GETTEXTRANGE returned %ld\n", result);
- todo_wine ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETTEXTRANGE
filled %s\n", buffer);
+ ok(result == 5, "EM_GETTEXTRANGE returned %ld\n", result);
+ ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETTEXTRANGE filled
%s\n", buffer);
}
DestroyWindow(hwndRichEdit);
@@ -1829,8 +1858,8 @@ static void test_EM_GETSELTEXT(void)
SendMessageA(hwndRichEdit, WM_SETTEXT, 0,
(LPARAM)"abcdef\x8e\xf0ghijk");
SendMessageA(hwndRichEdit, EM_SETSEL, 4, 8);
result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer);
- todo_wine ok(result == 5, "EM_GETSELTEXT returned %ld\n", result);
- todo_wine ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETSELTEXT filled
%s\n", buffer);
+ ok(result == 5, "EM_GETSELTEXT returned %ld\n", result);
+ ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETSELTEXT filled
%s\n", buffer);
}
DestroyWindow(hwndRichEdit);
@@ -1863,6 +1892,7 @@ static void test_EM_SETOPTIONS(void)
hmoduleRichEdit, NULL);
ok(hwndRichEdit != NULL, "class: %s, error: %d\n",
RICHEDIT_CLASS20A, (int) GetLastError());
+ disable_beep( hwndRichEdit );
options = SendMessageA(hwndRichEdit, EM_GETOPTIONS, 0, 0);
/* WS_[VH]SCROLL cause the ECO_AUTO[VH]SCROLL options to be set */
ok(options == (ECO_AUTOVSCROLL|ECO_AUTOHSCROLL),
@@ -3110,11 +3140,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n");
- todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax);
- }
/* Ditto, see above */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
@@ -3124,11 +3152,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n");
- todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax);
- }
/* Ditto, see above */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a");
@@ -3138,11 +3164,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n");
- todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax);
- }
/* Ditto, see above */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a\na");
@@ -3152,11 +3176,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n");
- todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax);
- }
/* Ditto, see above */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
@@ -3166,11 +3188,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n");
- todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax);
- }
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text);
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
@@ -5610,7 +5630,7 @@ static void test_EM_FORMATRANGE(void)
{"WINE\r\n\r\nwine\r\nwine", 5, 6}
};
- skip_non_english = (PRIMARYLANGID(GetUserDefaultLangID()) != LANG_ENGLISH);
+ skip_non_english = (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH);
if (skip_non_english)
skip("Skipping some tests on non-English platform\n");
@@ -6348,6 +6368,7 @@ static void test_WM_CHAR(void)
hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP,
0, 0, 200, 60, 0, 0, 0, 0);
ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
+ disable_beep( hwnd );
p = char_list;
while (*p != '\0') {
@@ -6951,6 +6972,7 @@ static void test_undo_coalescing(void)
hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP|ES_MULTILINE,
0, 0, 200, 60, 0, 0, 0, 0);
ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
+ disable_beep( hwnd );
result = SendMessageA(hwnd, EM_CANUNDO, 0, 0);
ok (result == FALSE, "Can undo after window creation.\n");
@@ -7461,12 +7483,25 @@ static void test_format_rect(void)
ok(EqualRect(&rc, &expected), "rect %s != %s\n",
wine_dbgstr_rect(&rc),
wine_dbgstr_rect(&expected));
+ /* reset back to client rect and now try adding selection bar */
+ SendMessageA(hwnd, EM_SETRECT, 0, 0);
+ expected = clientRect;
+ InflateRect(&expected, -1, 0);
+ SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc);
+ ok(EqualRect(&rc, &expected), "rect %s != %s\n",
wine_dbgstr_rect(&rc),
+ wine_dbgstr_rect(&expected));
+ SendMessageA(hwnd, EM_SETOPTIONS, ECOOP_OR, ECO_SELECTIONBAR);
+ SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc);
+ ok(EqualRect(&rc, &expected), "rect %s != %s\n",
wine_dbgstr_rect(&rc),
+ wine_dbgstr_rect(&expected));
+ SendMessageA(hwnd, EM_SETOPTIONS, ECOOP_AND, ~ECO_SELECTIONBAR);
+
/* Set the absolute value of the formatting rectangle. */
rc = clientRect;
SendMessageA(hwnd, EM_SETRECT, 0, (LPARAM)&rc);
expected = clientRect;
SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc);
- ok(EqualRect(&rc, &expected), "[n=%d] rect %s != %s\n", n,
wine_dbgstr_rect(&rc),
+ ok(EqualRect(&rc, &expected), "rect %s != %s\n",
wine_dbgstr_rect(&rc),
wine_dbgstr_rect(&expected));
/* MSDN documents the EM_SETRECT message as using the rectangle provided in
@@ -9026,7 +9061,7 @@ START_TEST( editor )
* RICHED20.DLL, so the linker doesn't actually link to it. */
hmoduleRichEdit = LoadLibraryA("riched20.dll");
ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError());
- is_lang_japanese = (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_JAPANESE);
+ is_lang_japanese = (PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_JAPANESE);
test_window_classes();
test_WM_CHAR();
diff --git a/modules/rostests/winetests/riched20/richole.c
b/modules/rostests/winetests/riched20/richole.c
index 492bdc3fa9a..3885eb527fc 100644
--- a/modules/rostests/winetests/riched20/richole.c
+++ b/modules/rostests/winetests/riched20/richole.c
@@ -149,6 +149,7 @@ static void test_Interfaces(void)
LRESULT res;
HWND w;
ULONG refcount;
+ IUnknown *unk, *unk2;
w = new_richedit(NULL);
if (!w) {
@@ -180,6 +181,14 @@ static void test_Interfaces(void)
hres = ITextDocument_GetSelection(txtDoc, &txtSel);
ok(hres == S_OK, "got 0x%08x\n", hres);
+ hres = ITextDocument_QueryInterface(txtDoc, &IID_IUnknown, (void **)&unk);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+ hres = ITextSelection_QueryInterface(txtSel, &IID_IUnknown, (void **)&unk2);
+ ok(hres == S_OK, "got 0x%08x\n", hres);
+ ok(unk != unk2, "unknowns are the same\n");
+ IUnknown_Release(unk2);
+ IUnknown_Release(unk);
+
EXPECT_REF(txtDoc, 4);
EXPECT_REF(txtSel, 2);
@@ -3203,29 +3212,62 @@ static void fill_reobject_struct(REOBJECT *reobj, LONG cp,
LPOLEOBJECT poleobj,
reobj->dwUser = user;
}
-#define CHECK_REOBJECT_STRUCT(reobj,poleobj,pstg,polesite,user) \
- _check_reobject_struct(reobj, poleobj, pstg, polesite, user, __LINE__)
-static void _check_reobject_struct(REOBJECT reobj, LPOLEOBJECT poleobj, LPSTORAGE pstg,
- LPOLECLIENTSITE polesite, DWORD user, int line)
+#define CHECK_REOBJECT_STRUCT(reole,index,flags,cp,poleobj,pstg,polesite,user) \
+ _check_reobject_struct(reole, index, flags, cp, poleobj, pstg, polesite, user,
__LINE__)
+static void _check_reobject_struct(IRichEditOle *reole, LONG index, DWORD flags, LONG
cp,
+ LPOLEOBJECT poleobj, LPSTORAGE pstg, LPOLECLIENTSITE polesite, DWORD user, int line)
{
+ REOBJECT reobj;
+ HRESULT hr;
+
+ reobj.cbStruct = sizeof(reobj);
+ reobj.cp = cp;
+ hr = IRichEditOle_GetObject(reole, index, &reobj, flags);
+ ok(hr == S_OK, "IRichEditOle_GetObject failed: %#x.\n", hr);
ok_(__FILE__,line)(reobj.poleobj == poleobj, "got wrong object
interface.\n");
ok_(__FILE__,line)(reobj.pstg == pstg, "got wrong storage interface.\n");
ok_(__FILE__,line)(reobj.polesite == polesite, "got wrong site
interface.\n");
ok_(__FILE__,line)(reobj.dwUser == user, "got wrong user-defined value.\n");
}
+#define INSERT_REOBJECT(reole,reobj,cp,user) \
+ _insert_reobject(reole, reobj, cp, user, __LINE__)
+static void _insert_reobject(IRichEditOle *reole, REOBJECT *reobj, LONG cp, DWORD user,
int line)
+{
+ IOleClientSite *clientsite;
+ HRESULT hr;
+ hr = IRichEditOle_GetClientSite(reole, &clientsite);
+ ok_(__FILE__,line)(hr == S_OK, "IRichEditOle_GetClientSite got hr %#x.\n",
hr);
+ fill_reobject_struct(reobj, cp, NULL, NULL, clientsite, 10, 10, DVASPECT_CONTENT, 0,
user);
+ hr = IRichEditOle_InsertObject(reole, reobj);
+ ok_(__FILE__,line)(hr == S_OK, "IRichEditOle_InsertObject got hr %#x.\n",
hr);
+ IOleClientSite_Release(clientsite);
+}
+
static void test_InsertObject(void)
{
static CHAR test_text1[] = "abcdefg";
IRichEditOle *reole = NULL;
ITextDocument *doc = NULL;
- IOleClientSite *clientsite;
- REOBJECT reo1, reo2, reo3, received_reo1, received_reo2, received_reo3, received_reo4;
+ REOBJECT reo1, reo2, reo3, received_reo;
HRESULT hr;
HWND hwnd;
- LONG count;
+ const WCHAR *expected_string;
+ const CHAR *expected_stringA;
+ ITextSelection *selection;
+ IDataObject *dataobject;
+ TEXTRANGEA textrange;
+ FORMATETC formatetc;
+ CHARRANGE charrange;
+ GETTEXTEX gettextex;
+ STGMEDIUM stgmedium;
+ WCHAR buffer[1024];
+ CHAR bufferA[1024];
+ LONG count, result;
+ ITextRange *range;
+ BSTR bstr;
- create_interfaces(&hwnd, &reole, &doc, NULL);
+ create_interfaces(&hwnd, &reole, &doc, &selection);
SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
hr = IRichEditOle_InsertObject(reole, NULL);
@@ -3233,161 +3275,278 @@ static void test_InsertObject(void)
/* insert object1 in (0, 1)*/
SendMessageA(hwnd, EM_SETSEL, 0, 1);
- hr = IRichEditOle_GetClientSite(reole, &clientsite);
- ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
- fill_reobject_struct(&reo1, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
DVASPECT_CONTENT, 0, 1);
- hr = IRichEditOle_InsertObject(reole, &reo1);
- ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+ INSERT_REOBJECT(reole, &reo1, REO_CP_SELECTION, 1);
count = IRichEditOle_GetObjectCount(reole);
ok(count == 1, "got wrong object count: %d\n", count);
- IOleClientSite_Release(clientsite);
/* insert object2 in (2, 3)*/
SendMessageA(hwnd, EM_SETSEL, 2, 3);
- hr = IRichEditOle_GetClientSite(reole, &clientsite);
- ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
- fill_reobject_struct(&reo2, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
DVASPECT_CONTENT, 0, 2);
- hr = IRichEditOle_InsertObject(reole, &reo2);
- ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+ INSERT_REOBJECT(reole, &reo2, REO_CP_SELECTION, 2);
count = IRichEditOle_GetObjectCount(reole);
ok(count == 2, "got wrong object count: %d\n", count);
- IOleClientSite_Release(clientsite);
/* insert object3 in (1, 2)*/
SendMessageA(hwnd, EM_SETSEL, 1, 2);
- hr = IRichEditOle_GetClientSite(reole, &clientsite);
- ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
- fill_reobject_struct(&reo3, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
DVASPECT_CONTENT, 0, 3);
- hr = IRichEditOle_InsertObject(reole, &reo3);
- ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+ INSERT_REOBJECT(reole, &reo3, REO_CP_SELECTION, 3);
count = IRichEditOle_GetObjectCount(reole);
ok(count == 3, "got wrong object count: %d\n", count);
- IOleClientSite_Release(clientsite);
/* tests below show that order of rebject (from 0 to 2) is: reo1,reo3,reo2 */
- received_reo1.cbStruct = sizeof(received_reo1);
- hr = IRichEditOle_GetObject(reole, 0, &received_reo1, REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo1, NULL, NULL, reo1.polesite, 1);
-
- received_reo2.cbStruct = sizeof(received_reo2);
- hr = IRichEditOle_GetObject(reole, 1, &received_reo2, REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo2, NULL, NULL, reo3.polesite, 3);
-
- received_reo3.cbStruct = sizeof(received_reo3);
- hr = IRichEditOle_GetObject(reole, 2, &received_reo3, REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo3, NULL, NULL, reo2.polesite, 2);
+ CHECK_REOBJECT_STRUCT(reole, 0, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL,
reo1.polesite, 1);
+ CHECK_REOBJECT_STRUCT(reole, 1, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL,
reo3.polesite, 3);
+ CHECK_REOBJECT_STRUCT(reole, 2, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL,
reo2.polesite, 2);
hr = IRichEditOle_GetObject(reole, 2, NULL, REO_GETOBJ_ALL_INTERFACES);
ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
- received_reo4.cbStruct = 0;
- hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_ALL_INTERFACES);
+ received_reo.cbStruct = 0;
+ hr = IRichEditOle_GetObject(reole, 2, &received_reo, REO_GETOBJ_ALL_INTERFACES);
ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
- received_reo4.cbStruct = sizeof(received_reo4);
- hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_PSTG);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2);
-
- hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_POLESITE);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
+ CHECK_REOBJECT_STRUCT(reole, 2, REO_GETOBJ_PSTG, 0, NULL, NULL, NULL, 2);
+ CHECK_REOBJECT_STRUCT(reole, 2, REO_GETOBJ_POLESITE, 0, NULL, NULL, reo2.polesite, 2);
- hr = IRichEditOle_GetObject(reole, 4, &received_reo4, REO_GETOBJ_POLESITE);
+ hr = IRichEditOle_GetObject(reole, 3, &received_reo, REO_GETOBJ_POLESITE);
ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
- hr = IRichEditOle_GetObject(reole, 1024, &received_reo4, REO_GETOBJ_POLESITE);
+ hr = IRichEditOle_GetObject(reole, 4, &received_reo, REO_GETOBJ_POLESITE);
ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
- /* received_reo4 will be zeroed before be used */
- hr = IRichEditOle_GetObject(reole, 2, &received_reo4, REO_GETOBJ_NO_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, NULL, 2);
+ hr = IRichEditOle_GetObject(reole, 1024, &received_reo, REO_GETOBJ_POLESITE);
+ ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 0;
- hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
+ hr = IRichEditOle_GetObject(reole, -10, &received_reo, REO_GETOBJ_POLESITE);
+ ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 1;
- hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
+ /* received_reo will be zeroed before be used */
+ received_reo.cbStruct = sizeof(received_reo);
+ received_reo.polesite = (IOleClientSite *)0xdeadbeef;
+ hr = IRichEditOle_GetObject(reole, 2, &received_reo, REO_GETOBJ_NO_INTERFACES);
ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
+ ok(received_reo.polesite == (IOleClientSite *)NULL, "Got wrong site
interface.\n");
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 2;
- hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_USE_CP, REO_GETOBJ_ALL_INTERFACES, 0, NULL, NULL,
reo1.polesite, 1);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_USE_CP, REO_GETOBJ_ALL_INTERFACES, 1, NULL, NULL,
reo3.polesite, 3);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_USE_CP, REO_GETOBJ_ALL_INTERFACES, 2, NULL, NULL,
reo2.polesite, 2);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 4;
- hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
+ received_reo.cbStruct = sizeof(received_reo);
+ received_reo.polesite = (IOleClientSite *)0xdeadbeef;
+ received_reo.dwUser = 4;
+ received_reo.cp = 4;
+ hr = IRichEditOle_GetObject(reole, REO_IOB_USE_CP, &received_reo,
REO_GETOBJ_ALL_INTERFACES);
ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
- /* received_reo4 didn't be zeroed in E_INVALIDARG case */
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
+ ok(received_reo.polesite == (IOleClientSite *)0xdeadbeef, "Got wrong site
interface.\n");
+ ok(received_reo.dwUser == 4, "Got wrong user-defined value: %d.\n",
received_reo.dwUser);
SendMessageA(hwnd, EM_SETSEL, 0, 1);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 1;
- hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL,
NULL, reo1.polesite, 1);
SendMessageA(hwnd, EM_SETSEL, 1, 2);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 0;
- hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL,
NULL, reo3.polesite, 3);
SendMessageA(hwnd, EM_SETSEL, 2, 3);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 0;
- hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo2.polesite, 2);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL,
NULL, reo2.polesite, 2);
SendMessageA(hwnd, EM_SETSEL, 0, 2);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 0;
- hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL,
NULL, reo1.polesite, 1);
SendMessageA(hwnd, EM_SETSEL, 1, 3);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 0;
- hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo3.polesite, 3);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL,
NULL, reo3.polesite, 3);
SendMessageA(hwnd, EM_SETSEL, 2, 0);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 0;
- hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL,
NULL, reo1.polesite, 1);
SendMessageA(hwnd, EM_SETSEL, 0, 6);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 0;
- hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
- ok(hr == S_OK, "IRichEditOle_GetObject failed: 0x%08x\n", hr);
- CHECK_REOBJECT_STRUCT(received_reo4, NULL, NULL, reo1.polesite, 1);
+ CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 0, NULL,
NULL, reo1.polesite, 1);
SendMessageA(hwnd, EM_SETSEL, 4, 5);
- received_reo4.cbStruct = sizeof(received_reo4);
- received_reo4.cp = 0;
- hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo4,
REO_GETOBJ_ALL_INTERFACES);
+ received_reo.cbStruct = sizeof(received_reo);
+ received_reo.cp = 0;
+ hr = IRichEditOle_GetObject(reole, REO_IOB_SELECTION, &received_reo,
REO_GETOBJ_ALL_INTERFACES);
ok(hr == E_INVALIDARG, "IRichEditOle_GetObject should fail: 0x%08x\n", hr);
- release_interfaces(&hwnd, &reole, &doc, NULL);
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
+
+ /* "abc|d|efg" */
+ INSERT_REOBJECT(reole, &reo1, 3, 1);
+ INSERT_REOBJECT(reole, &reo2, 5, 2);
+
+ SendMessageW(hwnd, EM_SETSEL, 2, 3);
+ result = SendMessageW(hwnd, EM_SELECTIONTYPE, 0, 0);
+ ok(result == SEL_TEXT, "Got selection type: %x.\n", result);
+
+ SendMessageW(hwnd, EM_SETSEL, 3, 4);
+ result = SendMessageW(hwnd, EM_SELECTIONTYPE, 0, 0);
+ todo_wine ok(result == SEL_OBJECT, "Got selection type: %x.\n", result);
+ todo_wine CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 1,
NULL, NULL, reo1.polesite, 1);
+
+ SendMessageW(hwnd, EM_SETSEL, 2, 4);
+ result = SendMessageW(hwnd, EM_SELECTIONTYPE, 0, 0);
+ todo_wine ok(result == (SEL_TEXT | SEL_OBJECT), "Got selection type: %x.\n",
result);
+
+ SendMessageW(hwnd, EM_SETSEL, 5, 6);
+ todo_wine CHECK_REOBJECT_STRUCT(reole, REO_IOB_SELECTION, REO_GETOBJ_ALL_INTERFACES, 1,
NULL, NULL, reo2.polesite, 2);
+
+#ifdef __REACTOS__
+ expected_string = L"abc\xfffc"L"d\xfffc"L"efg";
+#else
+ expected_string = L"abc\xfffc""d\xfffc""efg";
+#endif
+
+ gettextex.cb = sizeof(buffer);
+ gettextex.flags = GT_DEFAULT;
+ gettextex.codepage = 1200;
+ gettextex.lpDefaultChar = NULL;
+ gettextex.lpUsedDefChar = NULL;
+ result = SendMessageW(hwnd, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)buffer);
+ ok(result == lstrlenW(expected_string), "Got wrong length: %d.\n", result);
+ todo_wine ok(!lstrcmpW(buffer, expected_string), "Got wrong content: %s.\n",
debugstr_w(buffer));
+
+ gettextex.flags = GT_RAWTEXT;
+ memset(buffer, 0, sizeof(buffer));
+ result = SendMessageW(hwnd, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)buffer);
+ ok(result == lstrlenW(expected_string), "Got wrong length: %d.\n", result);
+ todo_wine ok(!lstrcmpW(buffer, expected_string), "Got wrong content: %s.\n",
debugstr_w(buffer));
+
+ expected_stringA = "abc d efg";
+ memset(bufferA, 0, sizeof(bufferA));
+ SendMessageA(hwnd, EM_SETSEL, 0, -1);
+ result = SendMessageA(hwnd, EM_GETSELTEXT, (WPARAM)sizeof(bufferA), (LPARAM)bufferA);
+ ok(result == strlen(expected_stringA), "Got wrong length: %d.\n", result);
+ todo_wine ok(!strcmp(bufferA, expected_stringA), "Got wrong content: %s.\n",
bufferA);
+
+ memset(bufferA, 0, sizeof(bufferA));
+ textrange.lpstrText = bufferA;
+ textrange.chrg.cpMin = 0;
+ textrange.chrg.cpMax = 11;
+ result = SendMessageA(hwnd, EM_GETTEXTRANGE, 0, (LPARAM)&textrange);
+ ok(result == strlen(expected_stringA), "Got wrong length: %d.\n", result);
+ todo_wine ok(!strcmp(bufferA, expected_stringA), "Got wrong content: %s.\n",
bufferA);
+
+#ifdef __REACTOS__
+ expected_string = L"abc\xfffc"L"d\xfffc"L"efg\r";
+#else
+ expected_string = L"abc\xfffc""d\xfffc""efg\r";
+#endif
+
+ hr = ITextDocument_Range(doc, 0, 11, &range);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = ITextRange_GetText(range, &bstr);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(lstrlenW(bstr) == lstrlenW(expected_string), "Got wrong length: %d.\n",
lstrlenW(bstr));
+ todo_wine ok(!lstrcmpW(bstr, expected_string), "Got text: %s.\n",
wine_dbgstr_w(bstr));
+ SysFreeString(bstr);
+ hr = ITextRange_SetRange(range, 3, 4);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = ITextRange_GetChar(range, &result);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(result == 0xfffc, "Got char: %c\n", result);
+ ITextRange_Release(range);
+
+ SendMessageW(hwnd, EM_SETSEL, 0, -1);
+ hr = ITextSelection_GetText(selection, &bstr);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(lstrlenW(bstr) == lstrlenW(expected_string), "Got wrong length: %d.\n",
lstrlenW(bstr));
+ todo_wine ok(!lstrcmpW(bstr, expected_string), "Got text: %s.\n",
wine_dbgstr_w(bstr));
+ SysFreeString(bstr);
+ SendMessageW(hwnd, EM_SETSEL, 3, 4);
+ result = 0;
+ hr = ITextSelection_GetChar(selection, &result);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(result == 0xfffc, "Got char: %c\n", result);
+
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"");
+ result = SendMessageW(hwnd, EM_SETTEXTMODE, (WPARAM)TM_PLAINTEXT, 0);
+ ok(!result, "Got result %x.\n", result);
+ /* "abc|d|efg" */
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
+ INSERT_REOBJECT(reole, &reo1, 3, 1);
+ INSERT_REOBJECT(reole, &reo2, 5, 2);
+
+ expected_string = L"abc d efg";
+ charrange.cpMin = 0;
+ charrange.cpMax = 11;
+ hr = IRichEditOle_GetClipboardData(reole, &charrange, 1, &dataobject);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ formatetc.cfFormat = CF_UNICODETEXT;
+ formatetc.dwAspect = DVASPECT_CONTENT;
+ formatetc.ptd = NULL;
+ formatetc.tymed = TYMED_HGLOBAL;
+ formatetc.lindex = -1;
+ hr = IDataObject_GetData(dataobject, &formatetc, &stgmedium);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(lstrlenW(stgmedium.hGlobal) == lstrlenW(expected_string), "Got wrong
length: %d.\n", result);
+ todo_wine ok(!lstrcmpW(stgmedium.hGlobal, expected_string), "Got wrong content:
%s.\n", debugstr_w(stgmedium.hGlobal));
+
+#ifdef __REACTOS__
+ expected_string = L"abc\xfffc"L"d\xfffc"L"efg";
+#else
+ expected_string = L"abc\xfffc""d\xfffc""efg";
+#endif
+
+ gettextex.cb = sizeof(buffer);
+ gettextex.flags = GT_DEFAULT;
+ gettextex.codepage = 1200;
+ gettextex.lpDefaultChar = NULL;
+ gettextex.lpUsedDefChar = NULL;
+ result = SendMessageW(hwnd, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)buffer);
+ ok(result == lstrlenW(expected_string), "Got wrong length: %d.\n", result);
+ todo_wine ok(!lstrcmpW(buffer, expected_string), "Got wrong content: %s.\n",
debugstr_w(buffer));
+
+ gettextex.flags = GT_RAWTEXT;
+ memset(buffer, 0, sizeof(buffer));
+ result = SendMessageW(hwnd, EM_GETTEXTEX, (WPARAM)&gettextex, (LPARAM)buffer);
+ ok(result == lstrlenW(expected_string), "Got wrong length: %d.\n", result);
+ todo_wine ok(!lstrcmpW(buffer, expected_string), "Got wrong content: %s.\n",
debugstr_w(buffer));
+
+ expected_stringA = "abc d efg";
+ memset(bufferA, 0, sizeof(bufferA));
+ SendMessageA(hwnd, EM_SETSEL, 0, -1);
+ result = SendMessageA(hwnd, EM_GETSELTEXT, (WPARAM)sizeof(bufferA), (LPARAM)bufferA);
+ ok(result == strlen(expected_stringA), "Got wrong length: %d.\n", result);
+ todo_wine ok(!strcmp(bufferA, expected_stringA), "Got wrong content: %s.\n",
bufferA);
+
+ memset(bufferA, 0, sizeof(bufferA));
+ textrange.lpstrText = bufferA;
+ textrange.chrg.cpMin = 0;
+ textrange.chrg.cpMax = 11;
+ result = SendMessageA(hwnd, EM_GETTEXTRANGE, 0, (LPARAM)&textrange);
+ ok(result == strlen(expected_stringA), "Got wrong length: %d.\n", result);
+ todo_wine ok(!strcmp(bufferA, expected_stringA), "Got wrong content: %s.\n",
bufferA);
+
+#ifdef __REACTOS__
+ expected_string = L"abc\xfffc"L"d\xfffc"L"efg";
+#else
+ expected_string = L"abc\xfffc""d\xfffc""efg";
+#endif
+
+ hr = ITextDocument_Range(doc, 0, 11, &range);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = ITextRange_GetText(range, &bstr);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(lstrlenW(bstr) == lstrlenW(expected_string), "Got wrong length:
%d.\n", lstrlenW(bstr));
+ todo_wine ok(!lstrcmpW(bstr, expected_string), "Got text: %s.\n",
wine_dbgstr_w(bstr));
+ SysFreeString(bstr);
+ hr = ITextRange_SetRange(range, 3, 4);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = ITextRange_GetChar(range, &result);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(result == 0xfffc, "Got char: %c\n", result);
+ ITextRange_Release(range);
+
+ SendMessageW(hwnd, EM_SETSEL, 0, -1);
+ hr = ITextSelection_GetText(selection, &bstr);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(lstrlenW(bstr) == lstrlenW(expected_string), "Got wrong length:
%d.\n", lstrlenW(bstr));
+ todo_wine ok(!lstrcmpW(bstr, expected_string), "Got text: %s.\n",
wine_dbgstr_w(bstr));
+ SysFreeString(bstr);
+ SendMessageW(hwnd, EM_SETSEL, 3, 4);
+ result = 0;
+ hr = ITextSelection_GetChar(selection, &result);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ todo_wine ok(result == 0xfffc, "Got char: %c\n", result);
+
+ release_interfaces(&hwnd, &reole, &doc, &selection);
}
static void test_GetStoryLength(void)
@@ -3694,7 +3853,7 @@ static void test_Expand(void)
ITextRange_Release(range);
}
-static void test_MoveEnd(void)
+static void test_MoveEnd_story(void)
{
static const char test_text1[] = "Word1 Word2";
IRichEditOle *reole = NULL;
@@ -3808,272 +3967,288 @@ static void test_MoveEnd(void)
ITextRange_Release(range);
}
-static void test_ITextRange_SetStart(void)
+static void test_character_movestart(ITextRange *range, int textlen, int i, int j, LONG
target)
{
- HWND w;
- IRichEditOle *reOle = NULL;
- ITextDocument *txtDoc = NULL;
- ITextRange *txtRge = NULL;
- HRESULT hres;
- LONG first, lim, start, end;
- static const CHAR test_text1[] = "TestSomeText";
-
- create_interfaces(&w, &reOle, &txtDoc, NULL);
- SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-
- first = 4, lim = 8;
- ITextDocument_Range(txtDoc, first, lim, &txtRge);
- hres = ITextRange_SetStart(txtRge, first);
- ok(hres == S_FALSE, "ITextRange_SetStart\n");
-
-#define TEST_TXTRGE_SETSTART(cp, expected_start, expected_end) \
- hres = ITextRange_SetStart(txtRge, cp); \
- ok(hres == S_OK, "ITextRange_SetStart\n"); \
- ITextRange_GetStart(txtRge, &start); \
- ITextRange_GetEnd(txtRge, &end); \
- ok(start == expected_start, "got wrong start value: %d\n", start); \
- ok(end == expected_end, "got wrong end value: %d\n", end);
-
- TEST_TXTRGE_SETSTART(2, 2, 8)
- TEST_TXTRGE_SETSTART(-1, 0, 8)
- TEST_TXTRGE_SETSTART(13, 12, 12)
-
- release_interfaces(&w, &reOle, &txtDoc, NULL);
+ HRESULT hr;
+ LONG delta = 0;
+ LONG expected_delta;
+ LONG expected_start = target;
+
+ if (expected_start < 0)
+ expected_start = 0;
+ else if (expected_start > textlen)
+ expected_start = textlen;
+ expected_delta = expected_start - i;
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_MoveStart(range, tomCharacter, target - i, &delta);
+ if (expected_start == i) {
+ ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target -
i, hr);
+ ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, target - i,
delta);
+ CHECK_RANGE(range, i, j);
+ } else {
+ ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - i,
hr);
+ ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j,
target - i, delta);
+ if (expected_start <= j)
+ CHECK_RANGE(range, expected_start, j);
+ else
+ CHECK_RANGE(range, expected_start, expected_start);
+ }
}
-static void test_ITextRange_SetEnd(void)
+static void test_character_moveend(ITextRange *range, int textlen, int i, int j, LONG
target)
{
- HWND w;
- IRichEditOle *reOle = NULL;
- ITextDocument *txtDoc = NULL;
- ITextRange *txtRge = NULL;
- HRESULT hres;
- LONG first, lim, start, end;
- static const CHAR test_text1[] = "TestSomeText";
-
- create_interfaces(&w, &reOle, &txtDoc, NULL);
- SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-
- first = 4, lim = 8;
- ITextDocument_Range(txtDoc, first, lim, &txtRge);
- hres = ITextRange_SetEnd(txtRge, lim);
- ok(hres == S_FALSE, "ITextRange_SetEnd\n");
-
-#define TEST_TXTRGE_SETEND(cp, expected_start, expected_end) \
- hres = ITextRange_SetEnd(txtRge, cp); \
- ok(hres == S_OK, "ITextRange_SetEnd\n"); \
- ITextRange_GetStart(txtRge, &start); \
- ITextRange_GetEnd(txtRge, &end); \
- ok(start == expected_start, "got wrong start value: %d\n", start); \
- ok(end == expected_end, "got wrong end value: %d\n", end);
-
- TEST_TXTRGE_SETEND(6, 4, 6)
- TEST_TXTRGE_SETEND(14, 4, 13)
- TEST_TXTRGE_SETEND(-1, 0, 0)
-
- ITextRange_Release(txtRge);
- release_interfaces(&w, &reOle, &txtDoc, NULL);
+ HRESULT hr;
+ LONG delta;
+ LONG expected_delta;
+ LONG expected_end = target;
+
+ if (expected_end < 0)
+ expected_end = 0;
+ else if (expected_end > textlen + 1)
+ expected_end = textlen + 1;
+ expected_delta = expected_end - j;
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_MoveEnd(range, tomCharacter, target - j, &delta);
+ if (expected_end == j) {
+ ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target -
j, hr);
+ ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, target - j,
delta);
+ CHECK_RANGE(range, i, j);
+ } else {
+ ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, target - j,
hr);
+ ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j,
target - j, delta);
+ if (i <= expected_end)
+ CHECK_RANGE(range, i, expected_end);
+ else
+ CHECK_RANGE(range, expected_end, expected_end);
+ }
}
-static void test_ITextSelection_SetStart(void)
+static void test_character_move(ITextRange *range, int textlen, int i, int j, LONG
target)
{
- HWND w;
- IRichEditOle *reOle = NULL;
- ITextDocument *txtDoc = NULL;
- ITextSelection *txtSel = NULL;
- HRESULT hres;
- LONG first, lim, start, end;
- static const CHAR test_text1[] = "TestSomeText";
-
- create_interfaces(&w, &reOle, &txtDoc, &txtSel);
- SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-
- first = 4, lim = 8;
- SendMessageA(w, EM_SETSEL, first, lim);
- hres = ITextSelection_SetStart(txtSel, first);
- ok(hres == S_FALSE, "ITextSelection_SetStart\n");
-
-#define TEST_TXTSEL_SETSTART(cp, expected_start, expected_end) \
- hres = ITextSelection_SetStart(txtSel, cp); \
- ok(hres == S_OK, "ITextSelection_SetStart\n"); \
- SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end); \
- ok(start == expected_start, "got wrong start value: %d\n", start); \
- ok(end == expected_end, "got wrong end value: %d\n", end);
-
- TEST_TXTSEL_SETSTART(2, 2, 8)
- TEST_TXTSEL_SETSTART(-1, 0, 8)
- TEST_TXTSEL_SETSTART(13, 12, 12)
+ HRESULT hr;
+ LONG move_by;
+ LONG delta = 0;
+ LONG expected_delta;
+ LONG expected_location = target;
+
+ if (expected_location < 0)
+ expected_location = 0;
+ else if (expected_location > textlen)
+ expected_location = textlen;
+
+ if (target <= i) {
+ move_by = target - i;
+ expected_delta = expected_location - i;
+ if (i != j) {
+ --move_by;
+ --expected_delta;
+ }
+ } else if (j <= target) {
+ move_by = target - j;
+ expected_delta = expected_location - j;
+ if (i != j) {
+ ++move_by;
+ ++expected_delta;
+ }
+ } else {
+ /* There's no way to move to a point between start and end: */
+ return;
+ }
- release_interfaces(&w, &reOle, &txtDoc, &txtSel);
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_Move(range, tomCharacter, move_by, &delta);
+ if (expected_delta == 0) {
+ ok(hr == S_FALSE, "(%d,%d) move by %d got hr=0x%08x\n", i, j, move_by,
hr);
+ ok(delta == 0, "(%d,%d) move by %d got delta %d\n", i, j, move_by,
delta);
+ CHECK_RANGE(range, expected_location, expected_location);
+ } else {
+ ok(hr == S_OK, "(%d,%d) move by %d got hr=0x%08x\n", i, j, move_by,
hr);
+ ok(delta == expected_delta, "(%d,%d) move by %d got delta %d\n", i, j,
move_by, delta);
+ CHECK_RANGE(range, expected_location, expected_location);
+ }
}
-static void test_ITextSelection_SetEnd(void)
+static void test_character_startof(ITextRange *range, int textlen, int i, int j)
{
- HWND w;
- IRichEditOle *reOle = NULL;
- ITextDocument *txtDoc = NULL;
- ITextSelection *txtSel = NULL;
- HRESULT hres;
- LONG first, lim, start, end;
- static const CHAR test_text1[] = "TestSomeText";
-
- create_interfaces(&w, &reOle, &txtDoc, &txtSel);
- SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-
- first = 4, lim = 8;
- SendMessageA(w, EM_SETSEL, first, lim);
- hres = ITextSelection_SetEnd(txtSel, lim);
- ok(hres == S_FALSE, "ITextSelection_SetEnd\n");
-
-#define TEST_TXTSEL_SETEND(cp, expected_start, expected_end) \
- hres = ITextSelection_SetEnd(txtSel, cp); \
- ok(hres == S_OK, "ITextSelection_SetEnd\n"); \
- SendMessageA(w, EM_GETSEL, (LPARAM)&start, (WPARAM)&end); \
- ok(start == expected_start, "got wrong start value: %d\n", start); \
- ok(end == expected_end, "got wrong end value: %d\n", end);
-
- TEST_TXTSEL_SETEND(6, 4, 6)
- TEST_TXTSEL_SETEND(14, 4, 13)
- TEST_TXTSEL_SETEND(-1, 0, 0)
-
- release_interfaces(&w, &reOle, &txtDoc, &txtSel);
+ HRESULT hr;
+ LONG delta;
+
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_StartOf(range, tomCharacter, tomMove, &delta);
+ if (i == j) {
+ ok(hr == S_FALSE, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
+ ok(delta == 0, "(%d,%d) tomMove got delta %d\n", i, j, delta);
+ } else {
+ ok(hr == S_OK, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
+ ok(delta == -1, "(%d,%d) tomMove got delta %d\n", i, j, delta);
+ }
+ CHECK_RANGE(range, i, i);
+
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_StartOf(range, tomCharacter, tomExtend, &delta);
+ ok(hr == S_FALSE, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
+ ok(delta == 0, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
+ CHECK_RANGE(range, i, j);
}
-static void test_ITextRange_GetFont(void)
+static void test_character_endof(ITextRange *range, int textlen, int i, int j)
{
- HWND w;
- IRichEditOle *reOle = NULL;
- ITextDocument *txtDoc = NULL;
- ITextRange *txtRge = NULL;
- ITextFont *txtFont = NULL, *txtFont1 = NULL;
- HRESULT hres;
- int first, lim;
- int refcount;
- static const CHAR test_text1[] = "TestSomeText";
- LONG value;
-
- create_interfaces(&w, &reOle, &txtDoc, NULL);
- SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-
- first = 4, lim = 4;
- ITextDocument_Range(txtDoc, first, lim, &txtRge);
- refcount = get_refcount((IUnknown *)txtRge);
- ok(refcount == 1, "got wrong ref count: %d\n", refcount);
-
- hres = ITextRange_GetFont(txtRge, &txtFont);
- ok(hres == S_OK, "ITextRange_GetFont\n");
- refcount = get_refcount((IUnknown *)txtFont);
- ok(refcount == 1, "got wrong ref count: %d\n", refcount);
- refcount = get_refcount((IUnknown *)txtRge);
- ok(refcount == 2, "got wrong ref count: %d\n", refcount);
-
- hres = ITextRange_GetFont(txtRge, &txtFont1);
- ok(hres == S_OK, "ITextRange_GetFont\n");
- ok(txtFont1 != txtFont, "A new pointer should be return\n");
- refcount = get_refcount((IUnknown *)txtFont1);
- ok(refcount == 1, "got wrong ref count: %d\n", refcount);
- ITextFont_Release(txtFont1);
- refcount = get_refcount((IUnknown *)txtRge);
- ok(refcount == 2, "got wrong ref count: %d\n", refcount);
-
- ITextRange_Release(txtRge);
- release_interfaces(&w, &reOle, &txtDoc, NULL);
-
- hres = ITextFont_GetOutline(txtFont, &value);
- ok(hres == CO_E_RELEASED, "ITextFont after ITextDocument destroyed\n");
-
- ITextFont_Release(txtFont);
+ HRESULT hr;
+ LONG end;
+ LONG delta;
+
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_EndOf(range, tomCharacter, tomMove, &delta);
+
+ /* A character "end", apparently cannot be before the very first character
*/
+ end = j;
+ if (j == 0)
+ ++end;
+
+ if (i == end) {
+ ok(hr == S_FALSE, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
+ ok(delta == 0, "(%d,%d) tomMove got delta %d\n", i, j, delta);
+ } else {
+ ok(hr == S_OK, "(%d,%d) tomMove got hr=0x%08x\n", i, j, hr);
+ ok(delta == 1, "(%d,%d) tomMove got delta %d\n", i, j, delta);
+ }
+ CHECK_RANGE(range, end, end);
+
+ hr = ITextRange_SetRange(range, i, j);
+ ok(SUCCEEDED(hr), "got 0x%08x\n", hr);
+ hr = ITextRange_EndOf(range, tomCharacter, tomExtend, &delta);
+ if (0 < j) {
+ ok(hr == S_FALSE, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
+ ok(delta == 0, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
+ } else {
+ ok(hr == S_OK, "(%d,%d) tomExtend got hr=0x%08x\n", i, j, hr);
+ ok(delta == 1, "(%d,%d) tomExtend got delta %d\n", i, j, delta);
+ }
+ CHECK_RANGE(range, i, end);
}
-static void test_ITextSelection_GetFont(void)
+static void test_character_movement(void)
{
- HWND w;
- IRichEditOle *reOle = NULL;
- ITextDocument *txtDoc = NULL;
- ITextSelection *txtSel = NULL;
- ITextFont *txtFont = NULL, *txtFont1 = NULL;
- HRESULT hres;
- int first, lim;
- int refcount;
- static const CHAR test_text1[] = "TestSomeText";
- LONG value;
-
- create_interfaces(&w, &reOle, &txtDoc, &txtSel);
- SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-
- first = 4, lim = 4;
- SendMessageA(w, EM_SETSEL, first, lim);
- refcount = get_refcount((IUnknown *)txtSel);
- ok(refcount == 2, "got wrong ref count: %d\n", refcount);
-
- hres = ITextSelection_GetFont(txtSel, &txtFont);
- ok(hres == S_OK, "ITextSelection_GetFont\n");
- refcount = get_refcount((IUnknown *)txtFont);
- ok(refcount == 1, "got wrong ref count: %d\n", refcount);
- refcount = get_refcount((IUnknown *)txtSel);
- ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+ static const char test_text1[] = "ab\n c";
+ IRichEditOle *reole = NULL;
+ ITextDocument *doc = NULL;
+ ITextRange *range;
+ ITextSelection *selection;
+ HRESULT hr;
+ HWND hwnd;
+ int i, j;
+ const int textlen = strlen(test_text1);
- hres = ITextSelection_GetFont(txtSel, &txtFont1);
- ok(hres == S_OK, "ITextSelection_GetFont\n");
- ok(txtFont1 != txtFont, "A new pointer should be return\n");
- refcount = get_refcount((IUnknown *)txtFont1);
- ok(refcount == 1, "got wrong ref count: %d\n", refcount);
- ITextFont_Release(txtFont1);
- refcount = get_refcount((IUnknown *)txtSel);
- ok(refcount == 3, "got wrong ref count: %d\n", refcount);
+ create_interfaces(&hwnd, &reole, &doc, &selection);
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)test_text1);
- release_interfaces(&w, &reOle, &txtDoc, &txtSel);
+ hr = ITextDocument_Range(doc, 0, 0, &range);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
- hres = ITextFont_GetOutline(txtFont, &value);
- ok(hres == CO_E_RELEASED, "ITextFont after ITextDocument destroyed\n");
+ /* Exhaustive test of every possible combination of (start,end) locations,
+ * against every possible target location to move to. */
+ for (i = 0; i <= textlen; i++) {
+ for (j = i; j <= textlen; j++) {
+ LONG target;
+ for (target = -2; target <= textlen + 3; target++) {
+ test_character_moveend(range, textlen, i, j, target);
+ test_character_movestart(range, textlen, i, j, target);
+ test_character_move(range, textlen, i, j, target);
+ }
+ test_character_startof(range, textlen, i, j);
+ test_character_endof(range, textlen, i, j);
+ }
+ }
- ITextFont_Release(txtFont);
+ release_interfaces(&hwnd, &reole, &doc, NULL);
+ ITextSelection_Release(selection);
+ ITextRange_Release(range);
}
-static void test_ITextRange_GetPara(void)
+#define CLIPBOARD_RANGE_CONTAINS(range, start, end, expected)
_clipboard_range_contains(range, start, end, expected, __LINE__, 0);
+#define TODO_CLIPBOARD_RANGE_CONTAINS(range, start, end, expected)
_clipboard_range_contains(range, start, end, expected, __LINE__, 1);
+static void _clipboard_range_contains(ITextRange *range, LONG start, LONG end, const char
*expected, int line, int todo)
{
- HWND w;
- IRichEditOle *reOle = NULL;
- ITextDocument *txtDoc = NULL;
- ITextRange *txtRge = NULL;
- ITextPara *txtPara = NULL, *txtPara1 = NULL;
- HRESULT hres;
- int first, lim;
- int refcount;
- static const CHAR test_text1[] = "TestSomeText";
- LONG value;
-
- create_interfaces(&w, &reOle, &txtDoc, NULL);
- SendMessageA(w, WM_SETTEXT, 0, (LPARAM)test_text1);
-
- first = 4, lim = 4;
- ITextDocument_Range(txtDoc, first, lim, &txtRge);
- refcount = get_refcount((IUnknown *)txtRge);
- ok(refcount == 1, "got wrong ref count: %d\n", refcount);
+ HRESULT hr;
+ BOOL clipboard_open;
+ HGLOBAL global;
+ const char *clipboard_text;
+
+ hr = ITextRange_SetRange(range, start, end);
+ ok_(__FILE__,line)(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr);
+ hr = ITextRange_Copy(range, NULL);
+ ok_(__FILE__,line)(hr == S_OK, "Copy failed: 0x%08x\n", hr);
+
+ clipboard_open = OpenClipboard(NULL);
+ ok_(__FILE__,line)(clipboard_open, "OpenClipboard failed: %d\n",
GetLastError());
+ global = GetClipboardData(CF_TEXT);
+ ok_(__FILE__,line)(global != NULL, "GetClipboardData failed: %p\n", global);
+ clipboard_text = GlobalLock(global);
+ ok_(__FILE__,line)(clipboard_text != NULL, "GlobalLock failed: %p\n",
clipboard_text);
+#ifdef __REACTOS__
+ if (expected != NULL && clipboard_text != NULL)
+ todo_wine_if(todo) ok_(__FILE__,line)(!strcmp(expected, clipboard_text),
"unexpected contents: %s\n", wine_dbgstr_a(clipboard_text));
+ else
+ todo_wine_if(todo) ok_(__FILE__,line)(FALSE, "Either 'expected' or
'clipboard_text' was NULL\n");
+#else
+ todo_wine_if(todo) ok_(__FILE__,line)(!strcmp(expected, clipboard_text),
"unexpected contents: %s\n", wine_dbgstr_a(clipboard_text));
+#endif
+ GlobalUnlock(global);
+ CloseClipboard();
+}
- hres = ITextRange_GetPara(txtRge, &txtPara);
- ok(hres == S_OK, "ITextRange_GetPara\n");
- refcount = get_refcount((IUnknown *)txtPara);
- ok(refcount == 1, "got wrong ref count: %d\n", refcount);
- refcount = get_refcount((IUnknown *)txtRge);
- ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+static void test_clipboard(void)
+{
+ static const char text_in[] = "ab\n c";
+ IRichEditOle *reole = NULL;
+ ITextDocument *doc = NULL;
+ ITextRange *range;
+ ITextSelection *selection;
+ HRESULT hr;
+ HWND hwnd;
- hres = ITextRange_GetPara(txtRge, &txtPara1);
- ok(hres == S_OK, "ITextRange_GetPara\n");
- ok(txtPara1 != txtPara, "A new pointer should be return\n");
- refcount = get_refcount((IUnknown *)txtPara1);
- ok(refcount == 1, "got wrong ref count: %d\n", refcount);
- ITextPara_Release(txtPara1);
- refcount = get_refcount((IUnknown *)txtRge);
- ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+ create_interfaces(&hwnd, &reole, &doc, &selection);
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)text_in);
- ITextRange_Release(txtRge);
- release_interfaces(&w, &reOle, &txtDoc, NULL);
+ hr = ITextDocument_Range(doc, 0, 0, &range);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
- hres = ITextPara_GetStyle(txtPara, &value);
- ok(hres == CO_E_RELEASED, "ITextPara after ITextDocument destroyed\n");
+ CLIPBOARD_RANGE_CONTAINS(range, 0, 5, "ab\r\n c")
+ CLIPBOARD_RANGE_CONTAINS(range, 0, 0, "ab\r\n c")
+ CLIPBOARD_RANGE_CONTAINS(range, 1, 1, "ab\r\n c")
+ CLIPBOARD_RANGE_CONTAINS(range, 0, 1, "a")
+ CLIPBOARD_RANGE_CONTAINS(range, 5, 6, "")
+
+ /* Setting password char does not stop Copy */
+ SendMessageA(hwnd, EM_SETPASSWORDCHAR, '*', 0);
+ CLIPBOARD_RANGE_CONTAINS(range, 0, 1, "a")
+
+ /* Cut can be undone */
+ hr = ITextRange_SetRange(range, 0, 1);
+ ok(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr);
+ hr = ITextRange_Cut(range, NULL);
+ ok(hr == S_OK, "Cut failed: 0x%08x\n", hr);
+ CLIPBOARD_RANGE_CONTAINS(range, 0, 4, "b\r\n c");
+ hr = ITextDocument_Undo(doc, 1, NULL);
+ todo_wine ok(hr == S_OK, "Undo failed: 0x%08x\n", hr);
+ TODO_CLIPBOARD_RANGE_CONTAINS(range, 0, 5, "ab\r\n c");
+
+ /* Cannot cut when read-only */
+ SendMessageA(hwnd, EM_SETREADONLY, TRUE, 0);
+ hr = ITextRange_SetRange(range, 0, 1);
+ ok(SUCCEEDED(hr), "SetRange failed: 0x%08x\n", hr);
+ hr = ITextRange_Cut(range, NULL);
+ ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr);
- ITextPara_Release(txtPara);
+ release_interfaces(&hwnd, &reole, &doc, NULL);
+ ITextSelection_Release(selection);
+ ITextRange_Release(range);
}
START_TEST(richole)
@@ -4088,21 +4263,14 @@ START_TEST(richole)
test_GetText();
test_ITextSelection_GetChar();
test_ITextSelection_GetStart_GetEnd();
- test_ITextSelection_SetStart();
- test_ITextSelection_SetEnd();
test_ITextSelection_Collapse();
- test_ITextSelection_GetFont();
test_ITextDocument_Range();
test_ITextRange_GetChar();
test_ITextRange_ScrollIntoView();
test_ITextRange_GetStart_GetEnd();
test_ITextRange_SetRange();
test_ITextRange_GetDuplicate();
- test_ITextRange_SetStart();
- test_ITextRange_SetEnd();
test_ITextRange_Collapse();
- test_ITextRange_GetFont();
- test_ITextRange_GetPara();
test_GetClientSite();
test_IOleWindow_GetWindow();
test_IOleInPlaceSite_GetWindow();
@@ -4121,5 +4289,7 @@ START_TEST(richole)
test_GetStoryLength();
test_ITextSelection_GetDuplicate();
test_Expand();
- test_MoveEnd();
+ test_MoveEnd_story();
+ test_character_movement();
+ test_clipboard();
}
diff --git a/modules/rostests/winetests/riched20/txtsrv.c
b/modules/rostests/winetests/riched20/txtsrv.c
index dd290e3fb2f..1f789da8a37 100644
--- a/modules/rostests/winetests/riched20/txtsrv.c
+++ b/modules/rostests/winetests/riched20/txtsrv.c
@@ -48,7 +48,7 @@ static PCreateTextServices pCreateTextServices;
/* Use a special table for x86 machines to convert the thiscall
* calling convention. This isn't needed on other platforms. */
-#if defined(__i386__) && !defined(__MINGW32__)
+#if defined(__i386__) && !defined(__MINGW32__) && (!defined(_MSC_VER) ||
!defined(__clang__))
static ITextServicesVtbl itextServicesStdcallVtbl;
#define TXTSERV_VTABLE(This) (&itextServicesStdcallVtbl)
#else /* __i386__ */
@@ -61,8 +61,8 @@ static ITextServicesVtbl itextServicesStdcallVtbl;
#define ITextServices_TxGetVScroll(This,a,b,c,d,e)
TXTSERV_VTABLE(This)->TxGetVScroll(This,a,b,c,d,e)
#define ITextServices_OnTxSetCursor(This,a,b,c,d,e,f,g,h,i)
TXTSERV_VTABLE(This)->OnTxSetCursor(This,a,b,c,d,e,f,g,h,i)
#define ITextServices_TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j)
TXTSERV_VTABLE(This)->TxQueryHitPoint(This,a,b,c,d,e,f,g,h,i,j)
-#define ITextServices_OnTxInplaceActivate(This,a)
TXTSERV_VTABLE(This)->OnTxInplaceActivate(This,a)
-#define ITextServices_OnTxInplaceDeactivate(This)
TXTSERV_VTABLE(This)->OnTxInplaceDeactivate(This)
+#define ITextServices_OnTxInPlaceActivate(This,a)
TXTSERV_VTABLE(This)->OnTxInPlaceActivate(This,a)
+#define ITextServices_OnTxInPlaceDeactivate(This)
TXTSERV_VTABLE(This)->OnTxInPlaceDeactivate(This)
#define ITextServices_OnTxUIActivate(This) TXTSERV_VTABLE(This)->OnTxUIActivate(This)
#define ITextServices_OnTxUIDeactivate(This)
TXTSERV_VTABLE(This)->OnTxUIDeactivate(This)
#define ITextServices_TxGetText(This,a) TXTSERV_VTABLE(This)->TxGetText(This,a)
@@ -85,7 +85,10 @@ typedef struct ITextHostTestImpl
{
ITextHost ITextHost_iface;
LONG refCount;
+ HWND window;
+ RECT client_rect;
CHARFORMAT2W char_format;
+ DWORD scrollbars, props;
} ITextHostTestImpl;
static inline ITextHostTestImpl *impl_from_ITextHost(ITextHost *iface)
@@ -93,6 +96,11 @@ static inline ITextHostTestImpl *impl_from_ITextHost(ITextHost *iface)
return CONTAINING_RECORD(iface, ITextHostTestImpl, ITextHost_iface);
}
+static const WCHAR lorem[] = L"Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
+ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. "
+ "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. "
+ "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.";
+
static HRESULT WINAPI ITextHostImpl_QueryInterface(ITextHost *iface,
REFIID riid,
LPVOID *ppvObject)
@@ -133,6 +141,7 @@ static HDC __thiscall ITextHostImpl_TxGetDC(ITextHost *iface)
{
ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxGetDC(%p)\n", This);
+ if (This->window) return GetDC( This->window );
return NULL;
}
@@ -140,6 +149,7 @@ static INT __thiscall ITextHostImpl_TxReleaseDC(ITextHost *iface, HDC
hdc)
{
ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxReleaseDC(%p)\n", This);
+ if (This->window) return ReleaseDC( This->window, hdc );
return 0;
}
@@ -287,7 +297,8 @@ static HRESULT __thiscall ITextHostImpl_TxGetClientRect(ITextHost
*iface, LPRECT
{
ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxGetClientRect(%p, prc=%p)\n", This, prc);
- return E_NOTIMPL;
+ *prc = This->client_rect;
+ return S_OK;
}
static HRESULT __thiscall ITextHostImpl_TxGetViewInset(ITextHost *iface, LPRECT prc)
@@ -333,12 +344,12 @@ static HRESULT __thiscall ITextHostImpl_TxGetMaxLength(ITextHost
*iface, DWORD *
return E_NOTIMPL;
}
-static HRESULT __thiscall ITextHostImpl_TxGetScrollBars(ITextHost *iface, DWORD
*pdwScrollBar)
+static HRESULT __thiscall ITextHostImpl_TxGetScrollBars(ITextHost *iface, DWORD
*scrollbars)
{
ITextHostTestImpl *This = impl_from_ITextHost(iface);
- TRACECALL("Call to TxGetScrollBars(%p, pdwScrollBar=%p)\n",
- This, pdwScrollBar);
- return E_NOTIMPL;
+ TRACECALL("Call to TxGetScrollBars(%p, scrollbars=%p)\n", This,
scrollbars);
+ *scrollbars = This->scrollbars;
+ return S_OK;
}
static HRESULT __thiscall ITextHostImpl_TxGetPasswordChar(ITextHost *iface, WCHAR *pch)
@@ -383,15 +394,28 @@ static HRESULT __thiscall ITextHostImpl_TxGetPropertyBits(ITextHost
*iface, DWOR
ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxGetPropertyBits(%p, dwMask=0x%08x, pdwBits=%p)\n",
This, dwMask, pdwBits);
- *pdwBits = 0;
+ *pdwBits = This->props & dwMask;
return S_OK;
}
-static HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, void
*pv)
+static int en_vscroll_sent;
+static int en_update_sent;
+static HRESULT __thiscall ITextHostImpl_TxNotify( ITextHost *iface, DWORD code, void
*data )
{
ITextHostTestImpl *This = impl_from_ITextHost(iface);
- TRACECALL("Call to TxNotify(%p, iNotify=%d, pv=%p)\n", This, iNotify, pv);
- return E_NOTIMPL;
+ TRACECALL( "Call to TxNotify(%p, code = %#x, data = %p)\n", This, code,
data );
+ switch (code)
+ {
+ case EN_VSCROLL:
+ en_vscroll_sent++;
+ ok( !data, "got %p\n", data );
+ break;
+ case EN_UPDATE:
+ en_update_sent++;
+ ok( !data, "got %p\n", data );
+ break;
+ }
+ return S_OK;
}
static HIMC __thiscall ITextHostImpl_TxImmGetContext(ITextHost *iface)
@@ -492,7 +516,7 @@ typedef struct
static void setup_thiscall_wrappers(void)
{
-#if defined(__i386__) && !defined(__MINGW32__)
+#if defined(__i386__) && !defined(__MINGW32__) && (!defined(_MSC_VER) ||
!defined(__clang__))
void** pVtable;
void** pVtableEnd;
THISCALL_TO_STDCALL_THUNK *thunk;
@@ -591,9 +615,13 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
}
dummyTextHost->ITextHost_iface.lpVtbl = &itextHostVtbl;
dummyTextHost->refCount = 1;
+ dummyTextHost->window = NULL;
+ SetRectEmpty( &dummyTextHost->client_rect );
memset(&dummyTextHost->char_format, 0,
sizeof(dummyTextHost->char_format));
dummyTextHost->char_format.cbSize = sizeof(dummyTextHost->char_format);
dummyTextHost->char_format.dwMask = CFM_ALL2;
+ dummyTextHost->scrollbars = 0;
+ dummyTextHost->props = 0;
hf = GetStockObject(DEFAULT_GUI_FONT);
hf_to_cf(hf, &dummyTextHost->char_format);
@@ -602,6 +630,7 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
ITextServices object. */
result = pCreateTextServices(NULL, &dummyTextHost->ITextHost_iface,
&init);
ok(result == S_OK, "Did not return S_OK when created (result = %x)\n",
result);
+ ok(dummyTextHost->refCount == 1, "host ref %d\n",
dummyTextHost->refCount);
if (result != S_OK) {
CoTaskMemFree(dummyTextHost);
win_skip("CreateTextServices failed.\n");
@@ -621,9 +650,30 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
return TRUE;
}
+static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj,
+ LPSTORAGE pstg, LPOLECLIENTSITE polesite, LONG sizel_cx,
+ LONG sizel_cy, DWORD aspect, DWORD flags, DWORD user)
+{
+ reobj->cbStruct = sizeof(*reobj);
+ reobj->clsid = CLSID_NULL;
+ reobj->cp = cp;
+ reobj->poleobj = poleobj;
+ reobj->pstg = pstg;
+ reobj->polesite = polesite;
+ reobj->sizel.cx = sizel_cx;
+ reobj->sizel.cy = sizel_cy;
+ reobj->dvaspect = aspect;
+ reobj->dwFlags = flags;
+ reobj->dwUser = user;
+}
+
static void test_TxGetText(void)
{
+ const WCHAR *expected_string;
+ IOleClientSite *clientsite;
ITextServices *txtserv;
+ IRichEditOle *reole;
+ REOBJECT reobject;
ITextHost *host;
HRESULT hres;
BSTR rettext;
@@ -635,6 +685,24 @@ static void test_TxGetText(void)
ok(hres == S_OK, "ITextServices_TxGetText failed (result = %x)\n", hres);
SysFreeString(rettext);
+ hres = ITextServices_TxSetText(txtserv, L"abcdefg");
+ ok(hres == S_OK, "Got hres: %#x.\n", hres);
+ hres = ITextServices_QueryInterface(txtserv, &IID_IRichEditOle, (void
**)&reole);
+ ok(hres == S_OK, "Got hres: %#x.\n", hres);
+ hres = IRichEditOle_GetClientSite(reole, &clientsite);
+ ok(hres == S_OK, "Got hres: %#x.\n", hres);
+ expected_string = L"abc\xfffc""defg";
+ fill_reobject_struct(&reobject, 3, NULL, NULL, clientsite, 10, 10,
DVASPECT_CONTENT, 0, 1);
+ hres = IRichEditOle_InsertObject(reole, &reobject);
+ ok(hres == S_OK, "Got hres: %#x.\n", hres);
+ hres = ITextServices_TxGetText(txtserv, &rettext);
+ ok(hres == S_OK, "Got hres: %#x.\n", hres);
+ ok(lstrlenW(rettext) == lstrlenW(expected_string), "Got wrong length:
%d.\n", lstrlenW(rettext));
+ todo_wine ok(!lstrcmpW(rettext, expected_string), "Got wrong content:
%s.\n", debugstr_w(rettext));
+ SysFreeString(rettext);
+ IOleClientSite_Release(clientsite);
+ IRichEditOle_Release(reole);
+
ITextServices_Release(txtserv);
ITextHost_Release(host);
}
@@ -689,7 +757,7 @@ static void _check_txgetnaturalsize(HRESULT res, LONG width, LONG
height, HDC hd
expected_width = expected_rect.right - expected_rect.left;
expected_height = expected_rect.bottom - expected_rect.top;
ok_(__FILE__,line)(res == S_OK, "ITextServices_TxGetNaturalSize failed:
0x%08x.\n", res);
- ok_(__FILE__,line)(width >= expected_width && width <= expected_width +
1,
+ todo_wine ok_(__FILE__,line)(width >= expected_width && width <=
expected_width + 1,
"got wrong width: %d, expected: %d {+1}.\n", width,
expected_width);
ok_(__FILE__,line)(height == expected_height, "got wrong height: %d, expected:
%d.\n",
height, expected_height);
@@ -701,7 +769,7 @@ static void test_TxGetNaturalSize(void)
ITextHost *host;
HRESULT result;
SIZEL extent;
- static const WCHAR test_text[] =
{'T','e','s','t','S','o','m','e','T','e','x','t',0};
+ static const WCHAR test_text[] = L"TestSomeText";
LONG width, height;
HDC hdcDraw;
HWND hwnd;
@@ -736,7 +804,7 @@ static void test_TxGetNaturalSize(void)
height = 0;
result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT, hdcDraw, NULL,
NULL,
TXTNS_FITTOCONTENT, &extent, &width,
&height);
- todo_wine CHECK_TXGETNATURALSIZE(result, width, height, hdcDraw, rect, test_text);
+ CHECK_TXGETNATURALSIZE(result, width, height, hdcDraw, rect, test_text);
ReleaseDC(hwnd, hdcDraw);
DestroyWindow(hwnd);
@@ -748,26 +816,51 @@ static void test_TxDraw(void)
{
ITextServices *txtserv;
ITextHost *host;
- HDC tmphdc = GetDC(NULL);
- DWORD dwAspect = DVASPECT_CONTENT;
- HDC hicTargetDev = NULL; /* Means "default" device */
- DVTARGETDEVICE *ptd = NULL;
- void *pvAspect = NULL;
- HRESULT result;
- RECTL client = {0,0,100,100};
-
+ HRESULT hr;
+ RECT client = {0, 0, 100, 100};
+ ITextHostTestImpl *host_impl;
+ HDC hdc;
if (!init_texthost(&txtserv, &host))
return;
- todo_wine {
- result = ITextServices_TxDraw(txtserv, dwAspect, 0, pvAspect, ptd,
- tmphdc, hicTargetDev, &client, NULL,
- NULL, NULL, 0, 0);
- ok(result == S_OK, "TxDraw failed (result = %x)\n", result);
- }
-
+ host_impl = impl_from_ITextHost( host );
+ host_impl->window = CreateWindowExA( 0, "static", NULL, WS_POPUP |
WS_VISIBLE,
+ 0, 0, 400, 400, 0, 0, 0, NULL );
+ host_impl->client_rect = client;
+ host_impl->props = TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP;
+ ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_CLIENTRECTCHANGE |
TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP,
+ host_impl->props );
+ hdc = GetDC( host_impl->window );
+
+ hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL,
NULL, NULL,
+ NULL, NULL, 0, TXTVIEW_INACTIVE );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+ hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL, NULL,
NULL,
+ NULL, NULL, 0, TXTVIEW_INACTIVE );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+ hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL,
(RECTL *)&client, NULL,
+ NULL, NULL, 0, TXTVIEW_INACTIVE );
+ ok( hr == E_FAIL, "got %08x\n", hr );
+ hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL,
(RECTL *)&client, NULL,
+ NULL, NULL, 0, TXTVIEW_INACTIVE );
+ ok( hr == S_OK, "got %08x\n", hr );
+ hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, hdc, NULL,
(RECTL *)&client, NULL,
+ NULL, NULL, 0, TXTVIEW_ACTIVE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = ITextServices_OnTxInPlaceActivate( txtserv, &client );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL,
NULL, NULL,
+ NULL, NULL, 0, TXTVIEW_INACTIVE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = ITextServices_OnTxInPlaceDeactivate( txtserv );
+
+ ReleaseDC( host_impl->window, hdc );
ITextServices_Release(txtserv);
+ DestroyWindow( host_impl->window );
ITextHost_Release(host);
}
@@ -863,6 +956,7 @@ static void test_QueryInterface(void)
IRichEditOle *reole, *txtsrv_reole;
ITextDocument *txtdoc, *txtsrv_txtdoc;
ITextDocument2Old *txtdoc2old, *txtsrv_txtdoc2old;
+ IUnknown *unk, *unk2;
ULONG refcount;
if(!init_texthost(&txtserv, &host))
@@ -879,6 +973,14 @@ static void test_QueryInterface(void)
refcount = get_refcount((IUnknown *)txtsrv_reole);
ok(refcount == 2, "got wrong ref count: %d\n", refcount);
+ hres = ITextServices_QueryInterface( txtserv, &IID_IUnknown, (void **)&unk
);
+ ok( hres == S_OK, "got 0x%08x\n", hres );
+ hres = IRichEditOle_QueryInterface( txtsrv_reole, &IID_IUnknown, (void
**)&unk2 );
+ ok( hres == S_OK, "got 0x%08x\n", hres );
+ ok( unk == unk2, "unknowns differ\n" );
+ IUnknown_Release( unk2 );
+ IUnknown_Release( unk );
+
hres = IRichEditOle_QueryInterface(txtsrv_reole, &IID_ITextDocument, (void
**)&txtdoc);
ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
refcount = get_refcount((IUnknown *)txtserv);
@@ -987,20 +1089,134 @@ static void test_TxGetScroll(void)
ITextServices *txtserv;
ITextHost *host;
HRESULT ret;
+ LONG min_pos, max_pos, pos, page;
+ BOOL enabled;
+ ITextHostTestImpl *host_impl;
+ RECT client = {0, 0, 100, 100};
if (!init_texthost(&txtserv, &host))
return;
+ host_impl = impl_from_ITextHost( host );
+
ret = ITextServices_TxGetHScroll(txtserv, NULL, NULL, NULL, NULL, NULL);
- ok(ret == S_OK, "ITextSerHices_GetVScroll failed: 0x%08x.\n", ret);
+ ok(ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret);
ret = ITextServices_TxGetVScroll(txtserv, NULL, NULL, NULL, NULL, NULL);
- ok(ret == S_OK, "ITextServices_GetVScroll failed: 0x%08x.\n", ret);
-
+ ok(ret == S_OK, "ITextServices_TxGetVScroll failed: 0x%08x.\n", ret);
+
+ ret = ITextServices_TxGetVScroll( txtserv, &min_pos, &max_pos, &pos,
&page, &enabled );
+ ok( ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret );
+ ok( min_pos == 0, "got %d\n", min_pos );
+ ok( max_pos == 0, "got %d\n", max_pos );
+ ok( pos == 0, "got %d\n", pos );
+ ok( page == 0, "got %d\n", page );
+ ok( !enabled, "got %d\n", enabled );
+
+ host_impl->scrollbars = WS_VSCROLL;
+ host_impl->props = TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP;
+ ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_SCROLLBARCHANGE |
TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP, host_impl->props );
+
+ host_impl->window = CreateWindowExA( 0, "static", NULL, WS_POPUP |
WS_VISIBLE,
+ 0, 0, 400, 400, 0, 0, 0, NULL );
+ host_impl->client_rect = client;
+ ret = ITextServices_OnTxInPlaceActivate( txtserv, &client );
+ ok( ret == S_OK, "got 0x%08x.\n", ret );
+
+ ret = ITextServices_TxGetVScroll( txtserv, &min_pos, &max_pos, &pos,
&page, &enabled );
+ ok( ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret );
+ ok( min_pos == 0, "got %d\n", min_pos );
+todo_wine
+ ok( max_pos == 0, "got %d\n", max_pos );
+ ok( pos == 0, "got %d\n", pos );
+ ok( page == client.bottom, "got %d\n", page );
+ ok( !enabled, "got %d\n", enabled );
+
+ ret = ITextServices_TxSetText( txtserv, lorem );
+ ok( ret == S_OK, "got 0x%08x.\n", ret );
+
+ ret = ITextServices_TxGetVScroll( txtserv, &min_pos, &max_pos, &pos,
&page, &enabled );
+ ok( ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret );
+ ok( min_pos == 0, "got %d\n", min_pos );
+ ok( max_pos > client.bottom, "got %d\n", max_pos );
+ ok( pos == 0, "got %d\n", pos );
+ ok( page == client.bottom, "got %d\n", page );
+ ok( enabled, "got %d\n", enabled );
+
+ host_impl->scrollbars = WS_VSCROLL | ES_DISABLENOSCROLL;
+ ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_SCROLLBARCHANGE,
host_impl->props );
+ ITextServices_TxSetText( txtserv, L"short" );
+
+ ret = ITextServices_TxGetVScroll( txtserv, &min_pos, &max_pos, &pos,
&page, &enabled );
+ ok( ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret );
+ ok( min_pos == 0, "got %d\n", min_pos );
+todo_wine
+ ok( max_pos == 0, "got %d\n", max_pos );
+ ok( pos == 0, "got %d\n", pos );
+ ok( page == client.bottom, "got %d\n", page );
+ ok( !enabled, "got %d\n", enabled );
+
+ DestroyWindow( host_impl->window );
ITextServices_Release(txtserv);
ITextHost_Release(host);
}
+static void test_notifications( void )
+{
+ ITextServices *txtserv;
+ ITextHost *host;
+ LRESULT res;
+ HRESULT hr;
+ RECT client = { 0, 0, 100, 100 };
+ ITextHostTestImpl *host_impl;
+
+ init_texthost( &txtserv, &host );
+ host_impl = impl_from_ITextHost( host );
+
+ host_impl->scrollbars = WS_VSCROLL;
+ host_impl->props = TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP;
+ ITextServices_OnTxPropertyBitsChange( txtserv, TXTBIT_SCROLLBARCHANGE |
TXTBIT_MULTILINE | TXTBIT_RICHTEXT | TXTBIT_WORDWRAP, host_impl->props );
+
+ ITextServices_TxSetText( txtserv, lorem );
+
+ host_impl->window = CreateWindowExA( 0, "static", NULL, WS_POPUP |
WS_VISIBLE,
+ 0, 0, 400, 400, 0, 0, 0, NULL );
+ host_impl->client_rect = client;
+ hr = ITextServices_OnTxInPlaceActivate( txtserv, &client );
+ ok( hr == S_OK, "got 0x%08x.\n", hr );
+
+ hr = ITextServices_TxSendMessage( txtserv, EM_SETEVENTMASK, 0, ENM_SCROLL, &res
);
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ /* check EN_VSCROLL notification is sent */
+ en_vscroll_sent = 0;
+ hr = ITextServices_TxSendMessage( txtserv, WM_VSCROLL, SB_LINEDOWN, 0, &res );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( en_vscroll_sent == 1, "got %d\n", en_vscroll_sent );
+
+ hr = ITextServices_TxSendMessage( txtserv, WM_VSCROLL, SB_BOTTOM, 0, &res );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( en_vscroll_sent == 2, "got %d\n", en_vscroll_sent );
+
+ /* but not when the thumb is moved */
+ hr = ITextServices_TxSendMessage( txtserv, WM_VSCROLL, MAKEWPARAM( SB_THUMBTRACK, 0
), 0, &res );
+ ok( hr == S_OK, "got %08x\n", hr );
+ hr = ITextServices_TxSendMessage( txtserv, WM_VSCROLL, MAKEWPARAM( SB_THUMBPOSITION,
0 ), 0, &res );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( en_vscroll_sent == 2, "got %d\n", en_vscroll_sent );
+
+ /* EN_UPDATE is sent by TxDraw() */
+ en_update_sent = 0;
+ hr = ITextServices_TxDraw( txtserv, DVASPECT_CONTENT, 0, NULL, NULL, NULL, NULL,
NULL, NULL,
+ NULL, NULL, 0, TXTVIEW_ACTIVE );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( en_update_sent == 1, "got %d\n", en_update_sent );
+
+ DestroyWindow( host_impl->window );
+ ITextServices_Release( txtserv );
+ ITextHost_Release( host );
+}
+
START_TEST( txtsrv )
{
ITextServices *txtserv;
@@ -1033,6 +1249,7 @@ START_TEST( txtsrv )
test_QueryInterface();
test_default_format();
test_TxGetScroll();
+ test_notifications();
}
if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE);
}
diff --git a/sdk/include/psdk/textserv.h b/sdk/include/psdk/textserv.h
index 455e88c5581..26278cc85c8 100644
--- a/sdk/include/psdk/textserv.h
+++ b/sdk/include/psdk/textserv.h
@@ -33,9 +33,9 @@ extern "C" {
#define THISCALLMETHOD_(type,method) type (__thiscall *method)
#endif
-DEFINE_GUID(IID_ITextServices,0x8d33f740,0xcf58,0x11ce,0xa8,0x9d,0x00,0xaa,0x00,0x6c,0xad,0xc5);
-DEFINE_GUID(IID_ITextHost,
0xc5bdd8d0,0xd26e,0x11ce,0xa8,0x9e,0x00,0xaa,0x00,0x6c,0xad,0xc5);
-DEFINE_GUID(IID_ITextHost2,
0xc5bdd8d0,0xd26e,0x11ce,0xa8,0x9e,0x00,0xaa,0x00,0x6c,0xad,0xc5);
+EXTERN_C const IID IID_ITextServices;
+EXTERN_C const IID IID_ITextHost;
+EXTERN_C const IID IID_ITextHost2;
/*****************************************************************************
* ITextServices interface
@@ -108,10 +108,10 @@ DECLARE_INTERFACE_(ITextServices,IUnknown)
INT y,
DWORD* pHitResult) PURE;
- THISCALLMETHOD_(HRESULT,OnTxInplaceActivate)( THIS_
+ THISCALLMETHOD_(HRESULT,OnTxInPlaceActivate)( THIS_
LPCRECT prcClient) PURE;
- THISCALLMETHOD_(HRESULT,OnTxInplaceDeactivate)( THIS ) PURE;
+ THISCALLMETHOD_(HRESULT,OnTxInPlaceDeactivate)( THIS ) PURE;
THISCALLMETHOD_(HRESULT,OnTxUIActivate)( THIS ) PURE;
@@ -151,6 +151,7 @@ DECLARE_INTERFACE_(ITextServices,IUnknown)
DWORD* pdwHeight) PURE;
};
+#undef INTERFACE
#ifdef COBJMACROS
/*** IUnknown methods ***/
@@ -159,8 +160,6 @@ DECLARE_INTERFACE_(ITextServices,IUnknown)
#define ITextServices_Release(p) (p)->lpVtbl->Release(p)
#endif
-#undef INTERFACE
-
typedef enum _TXTBACKSTYLE {
TXTBACK_TRANSPARENT = 0,
TXTBACK_OPAQUE
@@ -180,7 +179,7 @@ enum TXTNATURALSIZE {
enum TXTVIEW {
TXTVIEW_ACTIVE = 0,
- TXTVIEW_INACTIVE = 1
+ TXTVIEW_INACTIVE = -1
};
#define TXTBIT_RICHTEXT 0x000001
@@ -361,6 +360,7 @@ DECLARE_INTERFACE_(ITextHost,IUnknown)
LONG* lSelBarWidth) PURE;
};
+#undef INTERFACE
#ifdef COBJMACROS
/*** IUnknown methods ***/
@@ -369,8 +369,80 @@ DECLARE_INTERFACE_(ITextHost,IUnknown)
#define ITextHost_Release(p) (p)->lpVtbl->Release(p)
#endif
+/*****************************************************************************
+ * ITextHost2 interface
+ */
+#define INTERFACE ITextHost2
+DECLARE_INTERFACE_(ITextHost2,ITextHost)
+{
+ /*** IUnknown methods ***/
+ STDMETHOD(QueryInterface)( THIS_ REFIID riid, void** ppvObject ) PURE;
+ STDMETHOD_(ULONG,AddRef)( THIS ) PURE;
+ STDMETHOD_(ULONG,Release)( THIS ) PURE;
+ /*** ITextHost methods ***/
+ THISCALLMETHOD_(HDC,TxGetDC)( THIS ) PURE;
+ THISCALLMETHOD_(INT,TxReleaseDC)( THIS_ HDC hdc ) PURE;
+ THISCALLMETHOD_(BOOL,TxShowScrollBar)( THIS_ INT fnBar, BOOL fShow ) PURE;
+ THISCALLMETHOD_(BOOL,TxEnableScrollBar)( THIS_ INT fuSBFlags, INT fuArrowflags )
PURE;
+ THISCALLMETHOD_(BOOL,TxSetScrollRange)( THIS_ INT fnBar, LONG nMinPos, INT nMaxPos,
BOOL fRedraw ) PURE;
+ THISCALLMETHOD_(BOOL,TxSetScrollPos)( THIS_ INT fnBar, INT nPos, BOOL fRedraw )
PURE;
+ THISCALLMETHOD_(void,TxInvalidateRect)( THIS_ LPCRECT prc, BOOL fMode ) PURE;
+ THISCALLMETHOD_(void,TxViewChange)( THIS_ BOOL fUpdate ) PURE;
+ THISCALLMETHOD_(BOOL,TxCreateCaret)( THIS_ HBITMAP hbmp, INT xWidth, INT yHeight )
PURE;
+ THISCALLMETHOD_(BOOL,TxShowCaret)( THIS_ BOOL fShow ) PURE;
+ THISCALLMETHOD_(BOOL,TxSetCaretPos)( THIS_ INT x, INT y ) PURE;
+ THISCALLMETHOD_(BOOL,TxSetTimer)( THIS_ UINT idTimer, UINT uTimeout ) PURE;
+ THISCALLMETHOD_(void,TxKillTimer)( THIS_ UINT idTimer ) PURE;
+ THISCALLMETHOD_(void,TxScrollWindowEx)( THIS_ INT dx, INT dy, LPCRECT lprcScroll,
LPCRECT lprcClip,
+ HRGN hRgnUpdate, LPRECT lprcUpdate, UINT
fuScroll ) PURE;
+ THISCALLMETHOD_(void,TxSetCapture)( THIS_ BOOL fCapture ) PURE;
+ THISCALLMETHOD_(void,TxSetFocus)( THIS ) PURE;
+ THISCALLMETHOD_(void,TxSetCursor)( THIS_ HCURSOR hcur, BOOL fText ) PURE;
+ THISCALLMETHOD_(BOOL,TxScreenToClient)( THIS_ LPPOINT lppt ) PURE;
+ THISCALLMETHOD_(BOOL,TxClientToScreen)( THIS_ LPPOINT lppt ) PURE;
+ THISCALLMETHOD_(HRESULT,TxActivate)( THIS_ LONG* plOldState ) PURE;
+ THISCALLMETHOD_(HRESULT,TxDeactivate)( THIS_ LONG lNewState ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetClientRect)( THIS_ LPRECT prc ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetViewInset)( THIS_ LPRECT prc ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetCharFormat)( THIS_ const CHARFORMATW** ppCF ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetParaFormat)( THIS_ const PARAFORMAT** ppPF ) PURE;
+ THISCALLMETHOD_(COLORREF,TxGetSysColor)( THIS_ int nIndex ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetBackStyle)( THIS_ TXTBACKSTYLE* pStyle ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetMaxLength)( THIS_ DWORD* plength ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetScrollBars)( THIS_ DWORD* pdwScrollBar ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetPasswordChar)( THIS_ WCHAR* pch ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetAcceleratorPos)( THIS_ LONG* pch ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetExtent)( THIS_ LPSIZEL lpExtent ) PURE;
+ THISCALLMETHOD_(HRESULT,OnTxCharFormatChange)( THIS_ const CHARFORMATW* pcf ) PURE;
+ THISCALLMETHOD_(HRESULT,OnTxParaFormatChange)( THIS_ const PARAFORMAT* ppf ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetPropertyBits)( THIS_ DWORD dwMask, DWORD* pdwBits )
PURE;
+ THISCALLMETHOD_(HRESULT,TxNotify)( THIS_ DWORD iNotify, void* pv ) PURE;
+ THISCALLMETHOD_(HIMC,TxImmGetContext)( THIS ) PURE;
+ THISCALLMETHOD_(void,TxImmReleaseContext)( THIS_ HIMC himc ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetSelectionBarWidth)( THIS_ LONG* lSelBarWidth ) PURE;
+ /* ITextHost2 methods */
+ THISCALLMETHOD_(BOOL,TxIsDoubleClickPending)( THIS ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetWindow)( THIS_ HWND *hwnd ) PURE;
+ THISCALLMETHOD_(HRESULT,TxSetForegroundWindow)( THIS ) PURE;
+ THISCALLMETHOD_(HPALETTE,TxGetPalette)( THIS ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetEastAsianFlags)( THIS_ LONG *flags ) PURE;
+ THISCALLMETHOD_(HCURSOR,TxSetCursor2)( THIS_ HCURSOR cursor, BOOL text ) PURE;
+ THISCALLMETHOD_(void,TxFreeTextServicesNotification)( THIS ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetEditStyle)( THIS_ DWORD item, DWORD *data ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetWindowStyles)( THIS_ DWORD *style, DWORD *ex_style )
PURE;
+ THISCALLMETHOD_(HRESULT,TxShowDropCaret)( THIS_ BOOL show, HDC hdc, const RECT *rect
) PURE;
+ THISCALLMETHOD_(HRESULT,TxDestroyCaret)( THIS ) PURE;
+ THISCALLMETHOD_(HRESULT,TxGetHorzExtent)( THIS_ LONG *horz_extent ) PURE;
+};
#undef INTERFACE
+#ifdef COBJMACROS
+/*** IUnknown methods ***/
+#define ITextHost2_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b)
+#define ITextHost2_AddRef(p) (p)->lpVtbl->AddRef(p)
+#define ITextHost2_Release(p) (p)->lpVtbl->Release(p)
+#endif
+
HRESULT WINAPI CreateTextServices(IUnknown*,ITextHost*,IUnknown**);
typedef HRESULT (WINAPI *PCreateTextServices)(IUnknown*,ITextHost*,IUnknown**);