[RICHED20_WINETEST] Sync to Wine-6.10. (#7692)

ROSTESTS-398 and CORE-6727
This commit is contained in:
Doug Lyons 2025-02-08 13:04:04 -06:00 committed by GitHub
parent dd34ad7037
commit 364d6e0346
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 906 additions and 412 deletions

View file

@ -33,6 +33,8 @@
#include <ole2.h> #include <ole2.h>
#include <richedit.h> #include <richedit.h>
#include <richole.h> #include <richole.h>
#include <imm.h>
#include <textserv.h>
#include <commdlg.h> #include <commdlg.h>
#include <time.h> #include <time.h>
#include <wine/test.h> #include <wine/test.h>
@ -51,12 +53,38 @@ static CHAR string1[MAX_PATH], string2[MAX_PATH], string3[MAX_PATH];
static HMODULE hmoduleRichEdit; static HMODULE hmoduleRichEdit;
static BOOL is_lang_japanese; 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) { static HWND new_window(LPCSTR lpClassName, DWORD dwStyle, HWND parent) {
HWND hwnd; HWND hwnd;
hwnd = CreateWindowA(lpClassName, NULL, dwStyle|WS_POPUP|WS_HSCROLL|WS_VSCROLL hwnd = CreateWindowA(lpClassName, NULL, dwStyle|WS_POPUP|WS_HSCROLL|WS_VSCROLL
|WS_VISIBLE, 0, 0, 200, 60, parent, NULL, |WS_VISIBLE, 0, 0, 200, 60, parent, NULL,
hmoduleRichEdit, NULL); hmoduleRichEdit, NULL);
ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int) GetLastError()); ok(hwnd != NULL, "class: %s, error: %d\n", lpClassName, (int) GetLastError());
disable_beep( hwnd );
return 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, |WS_VISIBLE, 0, 0, 200, 60, parent, NULL,
hmoduleRichEdit, NULL); hmoduleRichEdit, NULL);
ok(hwnd != NULL, "class: %s, error: %d\n", wine_dbgstr_w(lpClassName), (int) GetLastError()); ok(hwnd != NULL, "class: %s, error: %d\n", wine_dbgstr_w(lpClassName), (int) GetLastError());
disable_beep( hwnd );
return hwnd; return hwnd;
} }
@ -615,7 +644,7 @@ static void test_EM_POSFROMCHAR(void)
"gg\n" "gg\n"
"hh\n"; "hh\n";
rtl = (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_FONTSIGNATURE, rtl = (GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_FONTSIGNATURE,
(LPSTR) &sig, sizeof(LOCALESIGNATURE)) && (LPSTR) &sig, sizeof(LOCALESIGNATURE)) &&
(sig.lsUsb[3] & 0x08000000) != 0); (sig.lsUsb[3] & 0x08000000) != 0);
@ -772,7 +801,7 @@ static void test_EM_SETCHARFORMAT(void)
BOOL rtl; BOOL rtl;
DWORD expect_effects; DWORD expect_effects;
rtl = (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_FONTSIGNATURE, rtl = (GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_FONTSIGNATURE,
(LPSTR) &sig, sizeof(LOCALESIGNATURE)) && (LPSTR) &sig, sizeof(LOCALESIGNATURE)) &&
(sig.lsUsb[3] & 0x08000000) != 0); (sig.lsUsb[3] & 0x08000000) != 0);
@ -1791,8 +1820,8 @@ static void test_EM_GETTEXTRANGE(void)
textRange.chrg.cpMin = 4; textRange.chrg.cpMin = 4;
textRange.chrg.cpMax = 8; textRange.chrg.cpMax = 8;
result = SendMessageA(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange); result = SendMessageA(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange);
todo_wine ok(result == 5, "EM_GETTEXTRANGE returned %ld\n", result); ok(result == 5, "EM_GETTEXTRANGE returned %ld\n", result);
todo_wine ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETTEXTRANGE filled %s\n", buffer); ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETTEXTRANGE filled %s\n", buffer);
} }
DestroyWindow(hwndRichEdit); DestroyWindow(hwndRichEdit);
@ -1829,8 +1858,8 @@ static void test_EM_GETSELTEXT(void)
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk"); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"abcdef\x8e\xf0ghijk");
SendMessageA(hwndRichEdit, EM_SETSEL, 4, 8); SendMessageA(hwndRichEdit, EM_SETSEL, 4, 8);
result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer); result = SendMessageA(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer);
todo_wine ok(result == 5, "EM_GETSELTEXT returned %ld\n", result); ok(result == 5, "EM_GETSELTEXT returned %ld\n", result);
todo_wine ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETSELTEXT filled %s\n", buffer); ok(!strcmp("ef\x8e\xf0g", buffer), "EM_GETSELTEXT filled %s\n", buffer);
} }
DestroyWindow(hwndRichEdit); DestroyWindow(hwndRichEdit);
@ -1863,6 +1892,7 @@ static void test_EM_SETOPTIONS(void)
hmoduleRichEdit, NULL); hmoduleRichEdit, NULL);
ok(hwndRichEdit != NULL, "class: %s, error: %d\n", ok(hwndRichEdit != NULL, "class: %s, error: %d\n",
RICHEDIT_CLASS20A, (int) GetLastError()); RICHEDIT_CLASS20A, (int) GetLastError());
disable_beep( hwndRichEdit );
options = SendMessageA(hwndRichEdit, EM_GETOPTIONS, 0, 0); options = SendMessageA(hwndRichEdit, EM_GETOPTIONS, 0, 0);
/* WS_[VH]SCROLL cause the ECO_AUTO[VH]SCROLL options to be set */ /* WS_[VH]SCROLL cause the ECO_AUTO[VH]SCROLL options to be set */
ok(options == (ECO_AUTOVSCROLL|ECO_AUTOHSCROLL), ok(options == (ECO_AUTOVSCROLL|ECO_AUTOHSCROLL),
@ -3110,11 +3140,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si); GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n"); "Vertical scrollbar is invisible, should be visible.\n");
todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n", "reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax); si.nPage, si.nMin, si.nMax);
}
/* Ditto, see above */ /* Ditto, see above */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
@ -3124,11 +3152,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si); GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n"); "Vertical scrollbar is invisible, should be visible.\n");
todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n", "reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax); si.nPage, si.nMin, si.nMax);
}
/* Ditto, see above */ /* Ditto, see above */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a"); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a");
@ -3138,11 +3164,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si); GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n"); "Vertical scrollbar is invisible, should be visible.\n");
todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n", "reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax); si.nPage, si.nMin, si.nMax);
}
/* Ditto, see above */ /* Ditto, see above */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a\na"); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"a\na");
@ -3152,11 +3176,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si); GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n"); "Vertical scrollbar is invisible, should be visible.\n");
todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n", "reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax); si.nPage, si.nMin, si.nMax);
}
/* Ditto, see above */ /* Ditto, see above */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0);
@ -3166,11 +3188,9 @@ static void test_scrollbar_visibility(void)
GetScrollInfo(hwndRichEdit, SB_VERT, &si); GetScrollInfo(hwndRichEdit, SB_VERT, &si);
ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0), ok (((GetWindowLongA(hwndRichEdit, GWL_STYLE) & WS_VSCROLL) != 0),
"Vertical scrollbar is invisible, should be visible.\n"); "Vertical scrollbar is invisible, should be visible.\n");
todo_wine {
ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100, ok(si.nPage == 0 && si.nMin == 0 && si.nMax == 100,
"reported page/range is %d (%d..%d) expected 0 (0..100)\n", "reported page/range is %d (%d..%d) expected 0 (0..100)\n",
si.nPage, si.nMin, si.nMax); si.nPage, si.nMin, si.nMax);
}
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text); SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text);
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, 0); 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} {"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) if (skip_non_english)
skip("Skipping some tests on non-English platform\n"); 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, hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP,
0, 0, 200, 60, 0, 0, 0, 0); 0, 0, 200, 60, 0, 0, 0, 0);
ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError()); ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
disable_beep( hwnd );
p = char_list; p = char_list;
while (*p != '\0') { while (*p != '\0') {
@ -6951,6 +6972,7 @@ static void test_undo_coalescing(void)
hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP|ES_MULTILINE, hwnd = CreateWindowExA(0, "RichEdit20W", NULL, WS_POPUP|ES_MULTILINE,
0, 0, 200, 60, 0, 0, 0, 0); 0, 0, 200, 60, 0, 0, 0, 0);
ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError()); ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError());
disable_beep( hwnd );
result = SendMessageA(hwnd, EM_CANUNDO, 0, 0); result = SendMessageA(hwnd, EM_CANUNDO, 0, 0);
ok (result == FALSE, "Can undo after window creation.\n"); 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), ok(EqualRect(&rc, &expected), "rect %s != %s\n", wine_dbgstr_rect(&rc),
wine_dbgstr_rect(&expected)); 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. */ /* Set the absolute value of the formatting rectangle. */
rc = clientRect; rc = clientRect;
SendMessageA(hwnd, EM_SETRECT, 0, (LPARAM)&rc); SendMessageA(hwnd, EM_SETRECT, 0, (LPARAM)&rc);
expected = clientRect; expected = clientRect;
SendMessageA(hwnd, EM_GETRECT, 0, (LPARAM)&rc); 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)); wine_dbgstr_rect(&expected));
/* MSDN documents the EM_SETRECT message as using the rectangle provided in /* 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. */ * RICHED20.DLL, so the linker doesn't actually link to it. */
hmoduleRichEdit = LoadLibraryA("riched20.dll"); hmoduleRichEdit = LoadLibraryA("riched20.dll");
ok(hmoduleRichEdit != NULL, "error: %d\n", (int) GetLastError()); 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_window_classes();
test_WM_CHAR(); test_WM_CHAR();

File diff suppressed because it is too large Load diff

View file

@ -48,7 +48,7 @@ static PCreateTextServices pCreateTextServices;
/* Use a special table for x86 machines to convert the thiscall /* Use a special table for x86 machines to convert the thiscall
* calling convention. This isn't needed on other platforms. */ * 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; static ITextServicesVtbl itextServicesStdcallVtbl;
#define TXTSERV_VTABLE(This) (&itextServicesStdcallVtbl) #define TXTSERV_VTABLE(This) (&itextServicesStdcallVtbl)
#else /* __i386__ */ #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_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_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_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_OnTxInPlaceActivate(This,a) TXTSERV_VTABLE(This)->OnTxInPlaceActivate(This,a)
#define ITextServices_OnTxInplaceDeactivate(This) TXTSERV_VTABLE(This)->OnTxInplaceDeactivate(This) #define ITextServices_OnTxInPlaceDeactivate(This) TXTSERV_VTABLE(This)->OnTxInPlaceDeactivate(This)
#define ITextServices_OnTxUIActivate(This) TXTSERV_VTABLE(This)->OnTxUIActivate(This) #define ITextServices_OnTxUIActivate(This) TXTSERV_VTABLE(This)->OnTxUIActivate(This)
#define ITextServices_OnTxUIDeactivate(This) TXTSERV_VTABLE(This)->OnTxUIDeactivate(This) #define ITextServices_OnTxUIDeactivate(This) TXTSERV_VTABLE(This)->OnTxUIDeactivate(This)
#define ITextServices_TxGetText(This,a) TXTSERV_VTABLE(This)->TxGetText(This,a) #define ITextServices_TxGetText(This,a) TXTSERV_VTABLE(This)->TxGetText(This,a)
@ -85,7 +85,10 @@ typedef struct ITextHostTestImpl
{ {
ITextHost ITextHost_iface; ITextHost ITextHost_iface;
LONG refCount; LONG refCount;
HWND window;
RECT client_rect;
CHARFORMAT2W char_format; CHARFORMAT2W char_format;
DWORD scrollbars, props;
} ITextHostTestImpl; } ITextHostTestImpl;
static inline ITextHostTestImpl *impl_from_ITextHost(ITextHost *iface) 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); 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, static HRESULT WINAPI ITextHostImpl_QueryInterface(ITextHost *iface,
REFIID riid, REFIID riid,
LPVOID *ppvObject) LPVOID *ppvObject)
@ -133,6 +141,7 @@ static HDC __thiscall ITextHostImpl_TxGetDC(ITextHost *iface)
{ {
ITextHostTestImpl *This = impl_from_ITextHost(iface); ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxGetDC(%p)\n", This); TRACECALL("Call to TxGetDC(%p)\n", This);
if (This->window) return GetDC( This->window );
return NULL; return NULL;
} }
@ -140,6 +149,7 @@ static INT __thiscall ITextHostImpl_TxReleaseDC(ITextHost *iface, HDC hdc)
{ {
ITextHostTestImpl *This = impl_from_ITextHost(iface); ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxReleaseDC(%p)\n", This); TRACECALL("Call to TxReleaseDC(%p)\n", This);
if (This->window) return ReleaseDC( This->window, hdc );
return 0; return 0;
} }
@ -287,7 +297,8 @@ static HRESULT __thiscall ITextHostImpl_TxGetClientRect(ITextHost *iface, LPRECT
{ {
ITextHostTestImpl *This = impl_from_ITextHost(iface); ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxGetClientRect(%p, prc=%p)\n", This, prc); 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) static HRESULT __thiscall ITextHostImpl_TxGetViewInset(ITextHost *iface, LPRECT prc)
@ -333,12 +344,12 @@ static HRESULT __thiscall ITextHostImpl_TxGetMaxLength(ITextHost *iface, DWORD *
return E_NOTIMPL; 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); ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxGetScrollBars(%p, pdwScrollBar=%p)\n", TRACECALL("Call to TxGetScrollBars(%p, scrollbars=%p)\n", This, scrollbars);
This, pdwScrollBar); *scrollbars = This->scrollbars;
return E_NOTIMPL; return S_OK;
} }
static HRESULT __thiscall ITextHostImpl_TxGetPasswordChar(ITextHost *iface, WCHAR *pch) 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); ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxGetPropertyBits(%p, dwMask=0x%08x, pdwBits=%p)\n", TRACECALL("Call to TxGetPropertyBits(%p, dwMask=0x%08x, pdwBits=%p)\n",
This, dwMask, pdwBits); This, dwMask, pdwBits);
*pdwBits = 0; *pdwBits = This->props & dwMask;
return S_OK; 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); ITextHostTestImpl *This = impl_from_ITextHost(iface);
TRACECALL("Call to TxNotify(%p, iNotify=%d, pv=%p)\n", This, iNotify, pv); TRACECALL( "Call to TxNotify(%p, code = %#x, data = %p)\n", This, code, data );
return E_NOTIMPL; 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) static HIMC __thiscall ITextHostImpl_TxImmGetContext(ITextHost *iface)
@ -492,7 +516,7 @@ typedef struct
static void setup_thiscall_wrappers(void) static void setup_thiscall_wrappers(void)
{ {
#if defined(__i386__) && !defined(__MINGW32__) #if defined(__i386__) && !defined(__MINGW32__) && (!defined(_MSC_VER) || !defined(__clang__))
void** pVtable; void** pVtable;
void** pVtableEnd; void** pVtableEnd;
THISCALL_TO_STDCALL_THUNK *thunk; THISCALL_TO_STDCALL_THUNK *thunk;
@ -591,9 +615,13 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
} }
dummyTextHost->ITextHost_iface.lpVtbl = &itextHostVtbl; dummyTextHost->ITextHost_iface.lpVtbl = &itextHostVtbl;
dummyTextHost->refCount = 1; dummyTextHost->refCount = 1;
dummyTextHost->window = NULL;
SetRectEmpty( &dummyTextHost->client_rect );
memset(&dummyTextHost->char_format, 0, sizeof(dummyTextHost->char_format)); memset(&dummyTextHost->char_format, 0, sizeof(dummyTextHost->char_format));
dummyTextHost->char_format.cbSize = sizeof(dummyTextHost->char_format); dummyTextHost->char_format.cbSize = sizeof(dummyTextHost->char_format);
dummyTextHost->char_format.dwMask = CFM_ALL2; dummyTextHost->char_format.dwMask = CFM_ALL2;
dummyTextHost->scrollbars = 0;
dummyTextHost->props = 0;
hf = GetStockObject(DEFAULT_GUI_FONT); hf = GetStockObject(DEFAULT_GUI_FONT);
hf_to_cf(hf, &dummyTextHost->char_format); hf_to_cf(hf, &dummyTextHost->char_format);
@ -602,6 +630,7 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
ITextServices object. */ 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); 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) { if (result != S_OK) {
CoTaskMemFree(dummyTextHost); CoTaskMemFree(dummyTextHost);
win_skip("CreateTextServices failed.\n"); win_skip("CreateTextServices failed.\n");
@ -621,9 +650,30 @@ static BOOL init_texthost(ITextServices **txtserv, ITextHost **ret)
return TRUE; 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) static void test_TxGetText(void)
{ {
const WCHAR *expected_string;
IOleClientSite *clientsite;
ITextServices *txtserv; ITextServices *txtserv;
IRichEditOle *reole;
REOBJECT reobject;
ITextHost *host; ITextHost *host;
HRESULT hres; HRESULT hres;
BSTR rettext; BSTR rettext;
@ -635,6 +685,24 @@ static void test_TxGetText(void)
ok(hres == S_OK, "ITextServices_TxGetText failed (result = %x)\n", hres); ok(hres == S_OK, "ITextServices_TxGetText failed (result = %x)\n", hres);
SysFreeString(rettext); 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); ITextServices_Release(txtserv);
ITextHost_Release(host); 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_width = expected_rect.right - expected_rect.left;
expected_height = expected_rect.bottom - expected_rect.top; expected_height = expected_rect.bottom - expected_rect.top;
ok_(__FILE__,line)(res == S_OK, "ITextServices_TxGetNaturalSize failed: 0x%08x.\n", res); 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); "got wrong width: %d, expected: %d {+1}.\n", width, expected_width);
ok_(__FILE__,line)(height == expected_height, "got wrong height: %d, expected: %d.\n", ok_(__FILE__,line)(height == expected_height, "got wrong height: %d, expected: %d.\n",
height, expected_height); height, expected_height);
@ -701,7 +769,7 @@ static void test_TxGetNaturalSize(void)
ITextHost *host; ITextHost *host;
HRESULT result; HRESULT result;
SIZEL extent; 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; LONG width, height;
HDC hdcDraw; HDC hdcDraw;
HWND hwnd; HWND hwnd;
@ -736,7 +804,7 @@ static void test_TxGetNaturalSize(void)
height = 0; height = 0;
result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT, hdcDraw, NULL, NULL, result = ITextServices_TxGetNaturalSize(txtserv, DVASPECT_CONTENT, hdcDraw, NULL, NULL,
TXTNS_FITTOCONTENT, &extent, &width, &height); 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); ReleaseDC(hwnd, hdcDraw);
DestroyWindow(hwnd); DestroyWindow(hwnd);
@ -748,26 +816,51 @@ static void test_TxDraw(void)
{ {
ITextServices *txtserv; ITextServices *txtserv;
ITextHost *host; ITextHost *host;
HDC tmphdc = GetDC(NULL); HRESULT hr;
DWORD dwAspect = DVASPECT_CONTENT; RECT client = {0, 0, 100, 100};
HDC hicTargetDev = NULL; /* Means "default" device */ ITextHostTestImpl *host_impl;
DVTARGETDEVICE *ptd = NULL; HDC hdc;
void *pvAspect = NULL;
HRESULT result;
RECTL client = {0,0,100,100};
if (!init_texthost(&txtserv, &host)) if (!init_texthost(&txtserv, &host))
return; return;
todo_wine { host_impl = impl_from_ITextHost( host );
result = ITextServices_TxDraw(txtserv, dwAspect, 0, pvAspect, ptd, host_impl->window = CreateWindowExA( 0, "static", NULL, WS_POPUP | WS_VISIBLE,
tmphdc, hicTargetDev, &client, NULL, 0, 0, 400, 400, 0, 0, 0, NULL );
NULL, NULL, 0, 0); host_impl->client_rect = client;
ok(result == S_OK, "TxDraw failed (result = %x)\n", result); 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); ITextServices_Release(txtserv);
DestroyWindow( host_impl->window );
ITextHost_Release(host); ITextHost_Release(host);
} }
@ -863,6 +956,7 @@ static void test_QueryInterface(void)
IRichEditOle *reole, *txtsrv_reole; IRichEditOle *reole, *txtsrv_reole;
ITextDocument *txtdoc, *txtsrv_txtdoc; ITextDocument *txtdoc, *txtsrv_txtdoc;
ITextDocument2Old *txtdoc2old, *txtsrv_txtdoc2old; ITextDocument2Old *txtdoc2old, *txtsrv_txtdoc2old;
IUnknown *unk, *unk2;
ULONG refcount; ULONG refcount;
if(!init_texthost(&txtserv, &host)) if(!init_texthost(&txtserv, &host))
@ -879,6 +973,14 @@ static void test_QueryInterface(void)
refcount = get_refcount((IUnknown *)txtsrv_reole); refcount = get_refcount((IUnknown *)txtsrv_reole);
ok(refcount == 2, "got wrong ref count: %d\n", refcount); 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); hres = IRichEditOle_QueryInterface(txtsrv_reole, &IID_ITextDocument, (void **)&txtdoc);
ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres); ok(hres == S_OK, "IRichEditOle_QueryInterface: 0x%08x\n", hres);
refcount = get_refcount((IUnknown *)txtserv); refcount = get_refcount((IUnknown *)txtserv);
@ -987,20 +1089,134 @@ static void test_TxGetScroll(void)
ITextServices *txtserv; ITextServices *txtserv;
ITextHost *host; ITextHost *host;
HRESULT ret; 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)) if (!init_texthost(&txtserv, &host))
return; return;
host_impl = impl_from_ITextHost( host );
ret = ITextServices_TxGetHScroll(txtserv, NULL, NULL, NULL, NULL, NULL); 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); 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); ITextServices_Release(txtserv);
ITextHost_Release(host); 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 ) START_TEST( txtsrv )
{ {
ITextServices *txtserv; ITextServices *txtserv;
@ -1033,6 +1249,7 @@ START_TEST( txtsrv )
test_QueryInterface(); test_QueryInterface();
test_default_format(); test_default_format();
test_TxGetScroll(); test_TxGetScroll();
test_notifications();
} }
if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE); if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE);
} }

View file

@ -33,9 +33,9 @@ extern "C" {
#define THISCALLMETHOD_(type,method) type (__thiscall *method) #define THISCALLMETHOD_(type,method) type (__thiscall *method)
#endif #endif
DEFINE_GUID(IID_ITextServices,0x8d33f740,0xcf58,0x11ce,0xa8,0x9d,0x00,0xaa,0x00,0x6c,0xad,0xc5); EXTERN_C const IID IID_ITextServices;
DEFINE_GUID(IID_ITextHost, 0xc5bdd8d0,0xd26e,0x11ce,0xa8,0x9e,0x00,0xaa,0x00,0x6c,0xad,0xc5); EXTERN_C const IID IID_ITextHost;
DEFINE_GUID(IID_ITextHost2, 0xc5bdd8d0,0xd26e,0x11ce,0xa8,0x9e,0x00,0xaa,0x00,0x6c,0xad,0xc5); EXTERN_C const IID IID_ITextHost2;
/***************************************************************************** /*****************************************************************************
* ITextServices interface * ITextServices interface
@ -108,10 +108,10 @@ DECLARE_INTERFACE_(ITextServices,IUnknown)
INT y, INT y,
DWORD* pHitResult) PURE; DWORD* pHitResult) PURE;
THISCALLMETHOD_(HRESULT,OnTxInplaceActivate)( THIS_ THISCALLMETHOD_(HRESULT,OnTxInPlaceActivate)( THIS_
LPCRECT prcClient) PURE; LPCRECT prcClient) PURE;
THISCALLMETHOD_(HRESULT,OnTxInplaceDeactivate)( THIS ) PURE; THISCALLMETHOD_(HRESULT,OnTxInPlaceDeactivate)( THIS ) PURE;
THISCALLMETHOD_(HRESULT,OnTxUIActivate)( THIS ) PURE; THISCALLMETHOD_(HRESULT,OnTxUIActivate)( THIS ) PURE;
@ -151,6 +151,7 @@ DECLARE_INTERFACE_(ITextServices,IUnknown)
DWORD* pdwHeight) PURE; DWORD* pdwHeight) PURE;
}; };
#undef INTERFACE
#ifdef COBJMACROS #ifdef COBJMACROS
/*** IUnknown methods ***/ /*** IUnknown methods ***/
@ -159,8 +160,6 @@ DECLARE_INTERFACE_(ITextServices,IUnknown)
#define ITextServices_Release(p) (p)->lpVtbl->Release(p) #define ITextServices_Release(p) (p)->lpVtbl->Release(p)
#endif #endif
#undef INTERFACE
typedef enum _TXTBACKSTYLE { typedef enum _TXTBACKSTYLE {
TXTBACK_TRANSPARENT = 0, TXTBACK_TRANSPARENT = 0,
TXTBACK_OPAQUE TXTBACK_OPAQUE
@ -180,7 +179,7 @@ enum TXTNATURALSIZE {
enum TXTVIEW { enum TXTVIEW {
TXTVIEW_ACTIVE = 0, TXTVIEW_ACTIVE = 0,
TXTVIEW_INACTIVE = 1 TXTVIEW_INACTIVE = -1
}; };
#define TXTBIT_RICHTEXT 0x000001 #define TXTBIT_RICHTEXT 0x000001
@ -361,6 +360,7 @@ DECLARE_INTERFACE_(ITextHost,IUnknown)
LONG* lSelBarWidth) PURE; LONG* lSelBarWidth) PURE;
}; };
#undef INTERFACE
#ifdef COBJMACROS #ifdef COBJMACROS
/*** IUnknown methods ***/ /*** IUnknown methods ***/
@ -369,8 +369,80 @@ DECLARE_INTERFACE_(ITextHost,IUnknown)
#define ITextHost_Release(p) (p)->lpVtbl->Release(p) #define ITextHost_Release(p) (p)->lpVtbl->Release(p)
#endif #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 #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**); HRESULT WINAPI CreateTextServices(IUnknown*,ITextHost*,IUnknown**);
typedef HRESULT (WINAPI *PCreateTextServices)(IUnknown*,ITextHost*,IUnknown**); typedef HRESULT (WINAPI *PCreateTextServices)(IUnknown*,ITextHost*,IUnknown**);