[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