[PATCH 1/4] riched20: Add support for EN_[HV]SCROLL notifications.
Huw Davies
huw at codeweavers.com
Tue Mar 30 06:36:47 CDT 2021
Signed-off-by: Huw Davies <huw at codeweavers.com>
---
dlls/riched20/editor.c | 20 +++++------
dlls/riched20/editor.h | 6 ++--
dlls/riched20/paint.c | 47 +++++++++++++-------------
dlls/riched20/richole.c | 2 +-
dlls/riched20/tests/txtsrv.c | 64 ++++++++++++++++++++++++++++++++++--
5 files changed, 99 insertions(+), 40 deletions(-)
diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 28b5cb1512d..dccc431f041 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -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;
}
}
diff --git a/dlls/riched20/editor.h b/dlls/riched20/editor.h
index 7a79df83c99..fa1e22f9b48 100644
--- a/dlls/riched20/editor.h
+++ b/dlls/riched20/editor.h
@@ -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;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index ad9f504db8e..550c3c97045 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -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 );
}
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index b652d5a753a..2bb15bb4504 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -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;
}
diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c
index 3cfd5e63753..45e48a734fa 100644
--- a/dlls/riched20/tests/txtsrv.c
+++ b/dlls/riched20/tests/txtsrv.c
@@ -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);
}
--
2.23.0
More information about the wine-devel
mailing list