[PATCH 2/5] riched20: Handle scrollbar changes in the host.

Huw Davies huw at codeweavers.com
Tue Mar 16 03:22:46 CDT 2021


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/riched20/editor.c  | 57 +++++---------------------------
 dlls/riched20/editstr.h |  1 +
 dlls/riched20/paint.c   | 32 +++++++++---------
 dlls/riched20/txthost.c | 73 ++++++++++++++++++++++++++---------------
 dlls/riched20/txtsrv.c  | 21 ++++++++++--
 5 files changed, 92 insertions(+), 92 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 3d1eb458419..cf723d66cf6 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -3049,9 +3049,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
                                TXTBIT_USEPASSWORD | TXTBIT_HIDESELECTION | TXTBIT_SAVESELECTION |
                                TXTBIT_AUTOWORDSEL | TXTBIT_VERTICAL | TXTBIT_WORDWRAP | TXTBIT_DISABLEDRAG,
                                &ed->props );
-  ITextHost_TxGetScrollBars(texthost, &ed->styleFlags);
-  ed->styleFlags &= (WS_VSCROLL|WS_HSCROLL|ES_AUTOVSCROLL|
-                     ES_AUTOHSCROLL|ES_DISABLENOSCROLL);
+  ITextHost_TxGetScrollBars( texthost, &ed->scrollbars );
   ed->pBuffer = ME_MakeText();
   ed->nZoomNumerator = ed->nZoomDenominator = 0;
   ed->nAvailWidth = 0; /* wrap to client area */
@@ -3307,21 +3305,21 @@ static LRESULT ME_WmCreate(ME_TextEditor *editor, LPARAM lParam, BOOL unicode)
 
   ME_SetDefaultFormatRect(editor);
 
-  max = (editor->styleFlags & ES_DISABLENOSCROLL) ? 1 : 0;
-  if (~editor->styleFlags & ES_DISABLENOSCROLL || editor->styleFlags & WS_VSCROLL)
+  max = (editor->scrollbars & ES_DISABLENOSCROLL) ? 1 : 0;
+  if (~editor->scrollbars & ES_DISABLENOSCROLL || editor->scrollbars & WS_VSCROLL)
     ITextHost_TxSetScrollRange(editor->texthost, SB_VERT, 0, max, TRUE);
 
-  if (~editor->styleFlags & ES_DISABLENOSCROLL || editor->styleFlags & WS_HSCROLL)
+  if (~editor->scrollbars & ES_DISABLENOSCROLL || editor->scrollbars & WS_HSCROLL)
     ITextHost_TxSetScrollRange(editor->texthost, SB_HORZ, 0, max, TRUE);
 
-  if (editor->styleFlags & ES_DISABLENOSCROLL)
+  if (editor->scrollbars & ES_DISABLENOSCROLL)
   {
-    if (editor->styleFlags & WS_VSCROLL)
+    if (editor->scrollbars & WS_VSCROLL)
     {
       ITextHost_TxEnableScrollBar(editor->texthost, SB_VERT, ESB_DISABLE_BOTH);
       ITextHost_TxShowScrollBar(editor->texthost, SB_VERT, TRUE);
     }
-    if (editor->styleFlags & WS_HSCROLL)
+    if (editor->scrollbars & WS_HSCROLL)
     {
       ITextHost_TxEnableScrollBar(editor->texthost, SB_HORZ, ESB_DISABLE_BOTH);
       ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ, TRUE);
@@ -3494,7 +3492,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
   case EM_GETOPTIONS:
   {
     /* these flags are equivalent to the ES_* counterparts */
-    DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
+    DWORD mask = ECO_VERTICAL |
                  ECO_NOHIDESEL | ECO_WANTRETURN | ECO_SELECTIONBAR;
     DWORD settings = editor->styleFlags & mask;
 
@@ -3546,7 +3544,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     /* these flags are equivalent to ES_* counterparts, except for
      * ECO_AUTOWORDSELECTION that doesn't have an ES_* counterpart,
      * but is still stored in editor->styleFlags. */
-    const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
+    const DWORD mask = ECO_VERTICAL |
                        ECO_NOHIDESEL | ECO_WANTRETURN |
                        ECO_SELECTIONBAR | ECO_AUTOWORDSELECTION;
     DWORD settings = mask & editor->styleFlags;
@@ -3592,10 +3590,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
       if (changedSettings & settings & ECO_VERTICAL)
         FIXME("ECO_VERTICAL not implemented yet!\n");
       if (changedSettings & settings & ECO_AUTOHSCROLL)
-        FIXME("ECO_AUTOHSCROLL not implemented yet!\n");
-      if (changedSettings & settings & ECO_AUTOVSCROLL)
-        FIXME("ECO_AUTOVSCROLL not implemented yet!\n");
-      if (changedSettings & settings & ECO_WANTRETURN)
         FIXME("ECO_WANTRETURN not implemented yet!\n");
       if (changedSettings & settings & ECO_AUTOWORDSELECTION)
         FIXME("ECO_AUTOWORDSELECTION not implemented yet!\n");
@@ -3632,39 +3626,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
 
     return set_selection( editor, range.cpMin, range.cpMax );
   }
-  case EM_SHOWSCROLLBAR:
-  {
-    DWORD flags;
-
-    switch (wParam)
-    {
-      case SB_HORZ:
-        flags = WS_HSCROLL;
-        break;
-      case SB_VERT:
-        flags = WS_VSCROLL;
-        break;
-      case SB_BOTH:
-        flags = WS_HSCROLL|WS_VSCROLL;
-        break;
-      default:
-        return 0;
-    }
-
-    if (lParam) {
-      editor->styleFlags |= flags;
-      if (flags & WS_HSCROLL)
-        ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
-                          editor->nTotalWidth > editor->sizeWindow.cx);
-      if (flags & WS_VSCROLL)
-        ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
-                          editor->nTotalLength > editor->sizeWindow.cy);
-    } else {
-      editor->styleFlags &= ~flags;
-      ITextHost_TxShowScrollBar(editor->texthost, wParam, FALSE);
-    }
-    return 0;
-  }
   case EM_SETTEXTEX:
   {
     LPWSTR wszText;
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 7b78e5dccbe..f689194901c 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -386,6 +386,7 @@ typedef struct tagME_TextEditor
   DWORD styleFlags;
   DWORD exStyleFlags;
   DWORD props;
+  DWORD scrollbars;
   int nCursors;
   SIZE sizeWindow;
   int nTotalLength, nLastTotalLength;
diff --git a/dlls/riched20/paint.c b/dlls/riched20/paint.c
index 2db3a4ea2c1..e22dc64ebdb 100644
--- a/dlls/riched20/paint.c
+++ b/dlls/riched20/paint.c
@@ -1070,24 +1070,24 @@ void ME_ScrollAbs(ME_TextEditor *editor, int x, int y)
   if (editor->hWnd)
   {
     LONG winStyle = GetWindowLongW(editor->hWnd, GWL_STYLE);
-    if (editor->styleFlags & WS_HSCROLL)
+    if (editor->scrollbars & WS_HSCROLL)
     {
       bScrollBarIsVisible = (winStyle & WS_HSCROLL) != 0;
       bScrollBarWillBeVisible = (editor->nTotalWidth > editor->sizeWindow.cx
-                                 && (editor->styleFlags & WS_HSCROLL))
-                                || (editor->styleFlags & ES_DISABLENOSCROLL);
+                                 && (editor->scrollbars & WS_HSCROLL))
+                                || (editor->scrollbars & ES_DISABLENOSCROLL);
       if (bScrollBarIsVisible != bScrollBarWillBeVisible)
         ITextHost_TxShowScrollBar(editor->texthost, SB_HORZ,
                                   bScrollBarWillBeVisible);
     }
 
-    if (editor->styleFlags & WS_VSCROLL)
+    if (editor->scrollbars & WS_VSCROLL)
     {
       bScrollBarIsVisible = (winStyle & WS_VSCROLL) != 0;
       bScrollBarWillBeVisible = (editor->nTotalLength > editor->sizeWindow.cy
-                                 && (editor->styleFlags & WS_VSCROLL)
+                                 && (editor->scrollbars & WS_VSCROLL)
                                  && (editor->styleFlags & ES_MULTILINE))
-                                || (editor->styleFlags & ES_DISABLENOSCROLL);
+                                || (editor->scrollbars & ES_DISABLENOSCROLL);
       if (bScrollBarIsVisible != bScrollBarWillBeVisible)
         ITextHost_TxShowScrollBar(editor->texthost, SB_VERT,
                                   bScrollBarWillBeVisible);
@@ -1152,7 +1152,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
   si.cbSize = sizeof(si);
   si.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
   si.nMin = 0;
-  if (editor->styleFlags & ES_DISABLENOSCROLL)
+  if (editor->scrollbars & ES_DISABLENOSCROLL)
     si.fMask |= SIF_DISABLENOSCROLL;
 
   /* Update horizontal scrollbar */
@@ -1177,7 +1177,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
     editor->horz_si.nMax = si.nMax;
     editor->horz_si.nPage = si.nPage;
     if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
-        editor->styleFlags & WS_HSCROLL)
+        editor->scrollbars & WS_HSCROLL)
     {
       if (si.nMax > 0xFFFF)
       {
@@ -1196,11 +1196,11 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
     }
   }
 
-  if (editor->styleFlags & WS_HSCROLL)
+  if (editor->scrollbars & WS_HSCROLL)
   {
     if (si.fMask & SIF_DISABLENOSCROLL) {
       bScrollBarWillBeVisible = TRUE;
-    } else if (!(editor->styleFlags & WS_HSCROLL)) {
+    } else if (!(editor->scrollbars & WS_HSCROLL)) {
       bScrollBarWillBeVisible = FALSE;
     }
 
@@ -1232,7 +1232,7 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
     editor->vert_si.nMax = si.nMax;
     editor->vert_si.nPage = si.nPage;
     if ((bScrollBarWillBeVisible || bScrollBarWasVisible) &&
-        editor->styleFlags & WS_VSCROLL)
+        editor->scrollbars & WS_VSCROLL)
     {
       if (si.nMax > 0xFFFF)
       {
@@ -1251,11 +1251,11 @@ void ME_UpdateScrollBar(ME_TextEditor *editor)
     }
   }
 
-  if (editor->styleFlags & WS_VSCROLL)
+  if (editor->scrollbars & WS_VSCROLL)
   {
     if (si.fMask & SIF_DISABLENOSCROLL) {
       bScrollBarWillBeVisible = TRUE;
-    } else if (!(editor->styleFlags & WS_VSCROLL)) {
+    } else if (!(editor->scrollbars & WS_VSCROLL)) {
       bScrollBarWillBeVisible = FALSE;
     }
 
@@ -1273,7 +1273,7 @@ void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
   int x, y, yheight;
 
 
-  if (editor->styleFlags & ES_AUTOHSCROLL)
+  if (editor->scrollbars & ES_AUTOHSCROLL)
   {
     x = run->pt.x + ME_PointFromChar( editor, run, cursor->nOffset, TRUE );
     if (x > editor->horz_si.nPos + editor->sizeWindow.cx)
@@ -1281,7 +1281,7 @@ void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
     else if (x > editor->horz_si.nPos)
       x = editor->horz_si.nPos;
 
-    if (~editor->styleFlags & ES_AUTOVSCROLL)
+    if (~editor->scrollbars & ES_AUTOVSCROLL)
     {
       ME_HScrollAbs(editor, x);
       return;
@@ -1289,7 +1289,7 @@ void editor_ensure_visible( ME_TextEditor *editor, ME_Cursor *cursor )
   }
   else
   {
-    if (~editor->styleFlags & ES_AUTOVSCROLL) return;
+    if (~editor->scrollbars & ES_AUTOVSCROLL) return;
     x = editor->horz_si.nPos;
   }
 
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c
index 79cc79daa9a..027b079d654 100644
--- a/dlls/riched20/txthost.c
+++ b/dlls/riched20/txthost.c
@@ -41,7 +41,7 @@ struct host
     HWND window;
     BOOL emulate_10;
     PARAFORMAT2 para_fmt;
-    DWORD props;
+    DWORD props, scrollbars;
 };
 
 static const ITextHostVtbl textHostVtbl;
@@ -51,12 +51,16 @@ static BOOL combobox_registered;
 
 static void host_init_props( struct host *host )
 {
-    DWORD style, scrollbar;
-
-    host->props = TXTBIT_RICHTEXT | TXTBIT_AUTOWORDSEL | TXTBIT_ALLOWBEEP;
+    DWORD style;
 
     style = GetWindowLongW( host->window, GWL_STYLE );
 
+    host->scrollbars = style & (WS_VSCROLL | WS_HSCROLL | ES_AUTOVSCROLL |
+                                ES_AUTOHSCROLL | ES_DISABLENOSCROLL);
+    if (style & WS_VSCROLL) host->scrollbars |= ES_AUTOVSCROLL;
+    if ((style & WS_HSCROLL) && !host->emulate_10) host->scrollbars |= ES_AUTOHSCROLL;
+
+    host->props = TXTBIT_RICHTEXT | TXTBIT_AUTOWORDSEL | TXTBIT_ALLOWBEEP;
     if (style & ES_MULTILINE)     host->props |= TXTBIT_MULTILINE;
     if (style & ES_READONLY)      host->props |= TXTBIT_READONLY;
     if (style & ES_PASSWORD)      host->props |= TXTBIT_USEPASSWORD;
@@ -65,8 +69,7 @@ static void host_init_props( struct host *host )
     if (style & ES_VERTICAL)      host->props |= TXTBIT_VERTICAL;
     if (style & ES_NOOLEDRAGDROP) host->props |= TXTBIT_DISABLEDRAG;
 
-    ITextHost_TxGetScrollBars( &host->ITextHost_iface, &scrollbar );
-    if (!(scrollbar & ES_AUTOHSCROLL)) host->props |= TXTBIT_WORDWRAP;
+    if (!(host->scrollbars & ES_AUTOHSCROLL)) host->props |= TXTBIT_WORDWRAP;
 }
 
 struct host *host_create( HWND hwnd, CREATESTRUCTW *cs, BOOL emulate_10 )
@@ -335,27 +338,11 @@ DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetMaxLength( ITextHost *ifac
 }
 
 DEFINE_THISCALL_WRAPPER(ITextHostImpl_TxGetScrollBars,8)
-DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars( ITextHost *iface, DWORD *scrollbar )
+DECLSPEC_HIDDEN HRESULT __thiscall ITextHostImpl_TxGetScrollBars( ITextHost *iface, DWORD *scrollbars )
 {
     struct host *host = impl_from_ITextHost( iface );
-    const DWORD mask = WS_VSCROLL|
-                       WS_HSCROLL|
-                       ES_AUTOVSCROLL|
-                       ES_AUTOHSCROLL|
-                       ES_DISABLENOSCROLL;
-    if (host->editor)
-    {
-        *scrollbar = host->editor->styleFlags & mask;
-    }
-    else
-    {
-        DWORD style = GetWindowLongW( host->window, GWL_STYLE );
-        if (style & WS_VSCROLL)
-            style |= ES_AUTOVSCROLL;
-        if (!host->emulate_10 && (style & WS_HSCROLL))
-            style |= ES_AUTOHSCROLL;
-        *scrollbar = style & mask;
-    }
+
+    *scrollbars = host->scrollbars;
     return S_OK;
 }
 
@@ -780,7 +767,7 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r
     DWORD style, old_options, new_options, change, props_mask = 0;
     const DWORD mask = ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
         ECO_SELECTIONBAR | ECO_VERTICAL;
-    const DWORD host_mask = ECO_READONLY;
+    const DWORD host_mask = ECO_AUTOVSCROLL | ECO_AUTOHSCROLL | ECO_READONLY;
     HRESULT hr = S_OK;
 
     new_options = old_options = SendMessageW( host->window, EM_GETOPTIONS, 0, 0 );
@@ -803,6 +790,16 @@ static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *r
 
     change = (new_options ^ old_options);
 
+    if (change & ECO_AUTOVSCROLL)
+    {
+        host->scrollbars ^= WS_VSCROLL;
+        props_mask |= TXTBIT_SCROLLBARCHANGE;
+    }
+    if (change & ECO_AUTOHSCROLL)
+    {
+        host->scrollbars ^= WS_HSCROLL;
+        props_mask |= TXTBIT_SCROLLBARCHANGE;
+    }
     if (change & ECO_READONLY)
     {
         host->props ^= TXTBIT_READONLY;
@@ -929,6 +926,8 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
     case EM_GETOPTIONS:
         hr = ITextServices_TxSendMessage( host->text_srv, EM_GETOPTIONS, 0, 0, &res );
         if (host->props & TXTBIT_READONLY) res |= ECO_READONLY;
+        if (host->scrollbars & ES_AUTOHSCROLL) res |= ECO_AUTOHSCROLL;
+        if (host->scrollbars & ES_AUTOVSCROLL) res |= ECO_AUTOVSCROLL;
         break;
 
     case WM_GETTEXT:
@@ -1040,6 +1039,28 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
         if (text != (WCHAR *)lparam) ME_EndToUnicode( CP_ACP, text );
         break;
     }
+    case EM_SHOWSCROLLBAR:
+    {
+        DWORD mask = 0, new;
+
+        if (wparam == SB_HORZ) mask = WS_HSCROLL;
+        else if (wparam == SB_VERT) mask = WS_VSCROLL;
+        else if (wparam == SB_BOTH) mask = WS_HSCROLL | WS_VSCROLL;
+
+        if (mask)
+        {
+            new = lparam ? mask : 0;
+            if ((host->scrollbars & mask) != new)
+            {
+                host->scrollbars &= ~mask;
+                host->scrollbars |= new;
+                ITextServices_OnTxPropertyBitsChange( host->text_srv, TXTBIT_SCROLLBARCHANGE, 0 );
+            }
+        }
+
+        res = 0;
+        break;
+    }
     default:
         res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr );
     }
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index ecb5cec91c2..c017f5bae16 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -165,7 +165,7 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetHScroll( ITextServices *iface,
     if (max_pos) *max_pos = services->editor->horz_si.nMax;
     if (pos) *pos = services->editor->horz_si.nPos;
     if (page) *page = services->editor->horz_si.nPage;
-    if (enabled) *enabled = (services->editor->styleFlags & WS_HSCROLL) != 0;
+    if (enabled) *enabled = (services->editor->scrollbars & WS_HSCROLL) != 0;
     return S_OK;
 }
 
@@ -179,7 +179,7 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetVScroll( ITextServices *iface,
     if (max_pos) *max_pos = services->editor->vert_si.nMax;
     if (pos) *pos = services->editor->vert_si.nPos;
     if (page) *page = services->editor->vert_si.nPage;
-    if (enabled) *enabled = (services->editor->styleFlags & WS_VSCROLL) != 0;
+    if (enabled) *enabled = (services->editor->scrollbars & WS_VSCROLL) != 0;
     return S_OK;
 }
 
@@ -325,11 +325,28 @@ DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange,12)
 DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServices *iface, DWORD mask, DWORD bits )
 {
     struct text_services *services = impl_from_ITextServices( iface );
+    DWORD scrollbars;
+    HRESULT hr;
 
     TRACE( "%p, mask %08x, bits %08x\n", services, mask, bits );
 
     services->editor->props = (services->editor->props & ~mask) | (bits & mask);
 
+    if (mask & TXTBIT_SCROLLBARCHANGE)
+    {
+        hr = ITextHost_TxGetScrollBars( services->host, &scrollbars );
+        if (SUCCEEDED( hr ))
+        {
+            if ((services->editor->scrollbars ^ scrollbars) & WS_HSCROLL)
+                ITextHost_TxShowScrollBar( services->host, SB_HORZ, (scrollbars & WS_HSCROLL) &&
+                                           services->editor->nTotalWidth > services->editor->sizeWindow.cx );
+            if ((services->editor->scrollbars ^ scrollbars) & WS_VSCROLL)
+                ITextHost_TxShowScrollBar( services->host, SB_VERT, (scrollbars & WS_VSCROLL) &&
+                                           services->editor->nTotalLength > services->editor->sizeWindow.cy );
+            services->editor->scrollbars = scrollbars;
+        }
+    }
+
     return S_OK;
 }
 
-- 
2.23.0




More information about the wine-devel mailing list