riched20: Add support for EN_[HV]SCROLL notifications.

Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Huw Davies 2021-03-30 12:36:47 +01:00 committed by Alexandre Julliard
parent db516804cc
commit 08c4de06a1
5 changed files with 99 additions and 40 deletions

View File

@ -3377,7 +3377,7 @@ LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam,
case EM_SETSCROLLPOS:
{
POINT *point = (POINT *)lParam;
ME_ScrollAbs(editor, point->x, point->y);
scroll_abs( editor, point->x, point->y, TRUE );
return 0;
}
case EM_AUTOURLDETECT:
@ -3986,12 +3986,11 @@ LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam,
switch(LOWORD(wParam))
{
case SB_LEFT:
ME_ScrollAbs(editor, 0, 0);
scroll_abs( editor, 0, 0, TRUE );
break;
case SB_RIGHT:
ME_ScrollAbs(editor,
editor->horz_si.nMax - (int)editor->horz_si.nPage,
editor->vert_si.nMax - (int)editor->vert_si.nPage);
scroll_abs( editor, editor->horz_si.nMax - (int)editor->horz_si.nPage,
editor->vert_si.nMax - (int)editor->vert_si.nPage, TRUE );
break;
case SB_LINELEFT:
ME_ScrollLeft(editor, scrollUnit);
@ -4011,7 +4010,7 @@ LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam,
int pos = HIWORD(wParam);
if (editor->horz_si.nMax > 0xffff)
pos = MulDiv(pos, editor->horz_si.nMax, 0xffff);
ME_HScrollAbs(editor, pos);
scroll_h_abs( editor, pos, FALSE );
break;
}
}
@ -4028,12 +4027,11 @@ LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam,
switch(LOWORD(wParam))
{
case SB_TOP:
ME_ScrollAbs(editor, 0, 0);
scroll_abs( editor, 0, 0, TRUE );
break;
case SB_BOTTOM:
ME_ScrollAbs(editor,
editor->horz_si.nMax - (int)editor->horz_si.nPage,
editor->vert_si.nMax - (int)editor->vert_si.nPage);
scroll_abs( editor, editor->horz_si.nMax - (int)editor->horz_si.nPage,
editor->vert_si.nMax - (int)editor->vert_si.nPage, TRUE );
break;
case SB_LINEUP:
ME_ScrollUp(editor,lineHeight);
@ -4053,7 +4051,7 @@ LRESULT editor_handle_message( ME_TextEditor *editor, UINT msg, WPARAM wParam,
int pos = HIWORD(wParam);
if (editor->vert_si.nMax > 0xffff)
pos = MulDiv(pos, editor->vert_si.nMax, 0xffff);
ME_VScrollAbs(editor, pos);
scroll_v_abs( editor, pos, FALSE );
break;
}
}

View File

@ -250,9 +250,9 @@ int ME_twips2pointsY(const ME_Context *c, int y) DECLSPEC_HIDDEN;
/* scroll functions in paint.c */
void ME_ScrollAbs(ME_TextEditor *editor, int x, int y) DECLSPEC_HIDDEN;
void ME_HScrollAbs(ME_TextEditor *editor, int x) DECLSPEC_HIDDEN;
void ME_VScrollAbs(ME_TextEditor *editor, int y) DECLSPEC_HIDDEN;
void scroll_abs( ME_TextEditor *editor, int x, int y, BOOL notify ) DECLSPEC_HIDDEN;
void scroll_h_abs( ME_TextEditor *editor, int x, BOOL notify ) DECLSPEC_HIDDEN;
void scroll_v_abs( ME_TextEditor *editor, int y, BOOL notify ) DECLSPEC_HIDDEN;
void ME_ScrollUp(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN;
void ME_ScrollDown(ME_TextEditor *editor, int cy) DECLSPEC_HIDDEN;
void ME_ScrollLeft(ME_TextEditor *editor, int cx) DECLSPEC_HIDDEN;

View File

@ -1070,7 +1070,7 @@ static void enable_show_scrollbar( ME_TextEditor *editor, INT bar, BOOL enable )
ITextHost_TxShowScrollBar( editor->texthost, bar, enable );
}
static void set_scroll_range_pos( ITextHost2 *host, INT bar, SCROLLINFO *info, BOOL set_range )
static void set_scroll_range_pos( ME_TextEditor *editor, INT bar, SCROLLINFO *info, BOOL set_range, BOOL notify )
{
LONG max_pos = info->nMax, pos = info->nPos;
@ -1080,11 +1080,14 @@ static void set_scroll_range_pos( ITextHost2 *host, INT bar, SCROLLINFO *info, B
pos = MulDiv( pos, 0xffff, max_pos );
max_pos = 0xffff;
}
if (set_range) ITextHost_TxSetScrollRange( host, bar, 0, max_pos, FALSE );
ITextHost_TxSetScrollPos( host, bar, pos, TRUE );
if (set_range) ITextHost_TxSetScrollRange( editor->texthost, bar, 0, max_pos, FALSE );
ITextHost_TxSetScrollPos( editor->texthost, bar, pos, TRUE );
if (notify && editor->nEventMask & ENM_SCROLL)
ITextHost_TxNotify( editor->texthost, bar == SB_VERT ? EN_VSCROLL : EN_HSCROLL, NULL );
}
void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
void scroll_abs( ME_TextEditor *editor, int x, int y, BOOL notify )
{
int scrollX = 0, scrollY = 0;
@ -1093,7 +1096,7 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
x = max(x, editor->horz_si.nMin);
scrollX = editor->horz_si.nPos - x;
editor->horz_si.nPos = x;
set_scroll_range_pos( editor->texthost, SB_HORZ, &editor->horz_si, FALSE );
set_scroll_range_pos( editor, SB_HORZ, &editor->horz_si, FALSE, notify );
}
if (editor->vert_si.nPos != y) {
@ -1101,7 +1104,7 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
y = max(y, editor->vert_si.nMin);
scrollY = editor->vert_si.nPos - y;
editor->vert_si.nPos = y;
set_scroll_range_pos( editor->texthost, SB_VERT, &editor->vert_si, FALSE );
set_scroll_range_pos( editor, SB_VERT, &editor->vert_si, FALSE, notify );
}
if (abs(scrollX) > editor->sizeWindow.cx || abs(scrollY) > editor->sizeWindow.cy)
@ -1114,34 +1117,34 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
ME_Repaint(editor);
}
void ME_HScrollAbs(ME_TextEditor *editor, int x)
void scroll_h_abs( ME_TextEditor *editor, int x, BOOL notify )
{
ME_ScrollAbs(editor, x, editor->vert_si.nPos);
scroll_abs( editor, x, editor->vert_si.nPos, notify );
}
void ME_VScrollAbs(ME_TextEditor *editor, int y)
void scroll_v_abs( ME_TextEditor *editor, int y, BOOL notify )
{
ME_ScrollAbs(editor, editor->horz_si.nPos, y);
scroll_abs( editor, editor->horz_si.nPos, y, notify );
}
void ME_ScrollUp(ME_TextEditor *editor, int cy)
{
ME_VScrollAbs(editor, editor->vert_si.nPos - cy);
scroll_v_abs( editor, editor->vert_si.nPos - cy, TRUE );
}
void ME_ScrollDown(ME_TextEditor *editor, int cy)
{
ME_VScrollAbs(editor, editor->vert_si.nPos + cy);
scroll_v_abs( editor, editor->vert_si.nPos + cy, TRUE );
}
void ME_ScrollLeft(ME_TextEditor *editor, int cx)
{
ME_HScrollAbs(editor, editor->horz_si.nPos - cx);
scroll_h_abs( editor, editor->horz_si.nPos - cx, TRUE );
}
void ME_ScrollRight(ME_TextEditor *editor, int cx)
{
ME_HScrollAbs(editor, editor->horz_si.nPos + cx);
scroll_h_abs( editor, editor->horz_si.nPos + cx, TRUE );
}
void ME_UpdateScrollBar(ME_TextEditor *editor)
@ -1157,7 +1160,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
enable = editor->nTotalWidth > editor->sizeWindow.cx;
if (editor->horz_si.nPos && !enable)
{
ME_HScrollAbs(editor, 0);
scroll_h_abs( editor, 0, TRUE );
/* ME_HScrollAbs will call this function, so nothing else needs to be done here. */
return;
}
@ -1174,7 +1177,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
editor->horz_si.nPage = editor->sizeWindow.cx;
TRACE( "min = %d max = %d page = %d\n", editor->horz_si.nMin, editor->horz_si.nMax, editor->horz_si.nPage );
if ((enable || editor->horz_sb_enabled) && editor->scrollbars & WS_HSCROLL)
set_scroll_range_pos( editor->texthost, SB_HORZ, &editor->horz_si, TRUE );
set_scroll_range_pos( editor, SB_HORZ, &editor->horz_si, TRUE, TRUE );
}
/* Update vertical scrollbar */
@ -1182,7 +1185,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
if (editor->vert_si.nPos && !enable)
{
ME_VScrollAbs(editor, 0);
scroll_v_abs( editor, 0, TRUE );
/* ME_VScrollAbs will call this function, so nothing else needs to be done here. */
return;
}
@ -1199,7 +1202,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
editor->vert_si.nPage = editor->sizeWindow.cy;
TRACE( "min = %d max = %d page = %d\n", editor->vert_si.nMin, editor->vert_si.nMax, editor->vert_si.nPage );
if ((enable || editor->vert_sb_enabled) && editor->scrollbars & WS_VSCROLL)
set_scroll_range_pos( editor->texthost, SB_VERT, &editor->vert_si, TRUE );
set_scroll_range_pos( editor, SB_VERT, &editor->vert_si, TRUE, TRUE );
}
}
@ -1221,7 +1224,7 @@ void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
if (~editor->scrollbars & ES_AUTOVSCROLL)
{
ME_HScrollAbs(editor, x);
scroll_h_abs( editor, x, TRUE );
return;
}
}
@ -1235,11 +1238,11 @@ void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
yheight = row->nHeight;
if (y < editor->vert_si.nPos)
ME_ScrollAbs(editor, x, y);
scroll_abs( editor, x, y, TRUE );
else if (y + yheight > editor->vert_si.nPos + editor->sizeWindow.cy)
ME_ScrollAbs(editor, x, y + yheight - editor->sizeWindow.cy);
scroll_abs( editor, x, y + yheight - editor->sizeWindow.cy, TRUE );
else if (x != editor->horz_si.nPos)
ME_ScrollAbs(editor, x, editor->vert_si.nPos);
scroll_abs( editor, x, editor->vert_si.nPos, TRUE );
}

View File

@ -2743,7 +2743,7 @@ static HRESULT WINAPI ITextRange_fnScrollIntoView(ITextRange *me, LONG value)
FIXME("bStart value %d not handled\n", value);
return E_NOTIMPL;
}
ME_ScrollAbs(editor, x, y);
scroll_abs( editor, x, y, TRUE );
return S_OK;
}

View File

@ -398,11 +398,19 @@ static HRESULT __thiscall ITextHostImpl_TxGetPropertyBits(ITextHost *iface, DWOR
return S_OK;
}
static HRESULT __thiscall ITextHostImpl_TxNotify(ITextHost *iface, DWORD iNotify, void *pv)
static int en_vscroll_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;
}
return S_OK;
}
static HIMC __thiscall ITextHostImpl_TxImmGetContext(ITextHost *iface)
@ -1100,6 +1108,55 @@ todo_wine
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 );
DestroyWindow( host_impl->window );
ITextServices_Release( txtserv );
ITextHost_Release( host );
}
START_TEST( txtsrv )
{
ITextServices *txtserv;
@ -1132,6 +1189,7 @@ START_TEST( txtsrv )
test_QueryInterface();
test_default_format();
test_TxGetScroll();
test_notifications();
}
if (wrapperCodeMem) VirtualFree(wrapperCodeMem, 0, MEM_RELEASE);
}