[PATCH 1/5] riched20: Handle the read-only property setting in the host.

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


Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/riched20/editor.c  | 49 +++++++++++++-----------------
 dlls/riched20/editstr.h |  1 +
 dlls/riched20/txthost.c | 67 +++++++++++++++++++++++++++++++++--------
 dlls/riched20/txtsrv.c  |  9 ++++--
 4 files changed, 83 insertions(+), 43 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 4988f6e0746..3d1eb458419 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -2279,10 +2279,9 @@ static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BO
     IDataObject *data;
 
     /* Protect read-only edit control from modification */
-    if (editor->styleFlags & ES_READONLY)
+    if (editor->props & TXTBIT_READONLY)
     {
-        if (!check_only)
-            MessageBeep(MB_ICONERROR);
+        if (!check_only) MessageBeep(MB_ICONERROR);
         return FALSE;
     }
 
@@ -2354,7 +2353,7 @@ HRESULT editor_copy_or_cut( ME_TextEditor *editor, BOOL cut, ME_Cursor *start, i
 {
     HRESULT hr;
 
-    if (cut && (editor->styleFlags & ES_READONLY))
+    if (cut && (editor->props & TXTBIT_READONLY))
     {
         return E_ACCESSDENIED;
     }
@@ -2469,7 +2468,7 @@ static BOOL handle_enter(ME_TextEditor *editor)
         int from, to;
         ME_Style *style, *eop_style;
 
-        if (editor->styleFlags & ES_READONLY)
+        if (editor->props & TXTBIT_READONLY)
         {
             MessageBeep(MB_ICONERROR);
             return TRUE;
@@ -2631,7 +2630,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
     case VK_DELETE:
       editor->nUDArrowX = -1;
       /* FIXME backspace and delete aren't the same, they act different wrt paragraph style of the merged paragraph */
-      if (editor->styleFlags & ES_READONLY)
+      if (editor->props & TXTBIT_READONLY)
         return FALSE;
       if (ME_IsSelection(editor))
       {
@@ -2738,7 +2737,7 @@ static LRESULT handle_wm_char( ME_TextEditor *editor, WCHAR wstr, LPARAM flags )
   if (editor->bMouseCaptured)
     return 0;
 
-  if (editor->styleFlags & ES_READONLY)
+  if (editor->props & TXTBIT_READONLY)
   {
     MessageBeep(MB_ICONERROR);
     return 0; /* FIXME really 0 ? */
@@ -3035,7 +3034,6 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
 {
   ME_TextEditor *ed = heap_alloc(sizeof(*ed));
   int i;
-  DWORD props;
   LONG selbarwidth;
 
   ed->hWnd = NULL;
@@ -3047,13 +3045,10 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
   ed->styleFlags = 0;
   ed->exStyleFlags = 0;
   ed->total_rows = 0;
-  ITextHost_TxGetPropertyBits(texthost,
-                              (TXTBIT_RICHTEXT|TXTBIT_MULTILINE|
-                               TXTBIT_READONLY|TXTBIT_USEPASSWORD|
-                               TXTBIT_HIDESELECTION|TXTBIT_SAVESELECTION|
-                               TXTBIT_AUTOWORDSEL|TXTBIT_VERTICAL|
-                               TXTBIT_WORDWRAP|TXTBIT_DISABLEDRAG),
-                              &props);
+  ITextHost_TxGetPropertyBits( texthost, TXTBIT_RICHTEXT | TXTBIT_MULTILINE | TXTBIT_READONLY |
+                               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);
@@ -3094,7 +3089,7 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
   ed->pfnWordBreak = NULL;
   ed->lpOleCallback = NULL;
   ed->mode = TM_MULTILEVELUNDO | TM_MULTICODEPAGE;
-  ed->mode |= (props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT;
+  ed->mode |= (ed->props & TXTBIT_RICHTEXT) ? TM_RICHTEXT : TM_PLAINTEXT;
   ed->AutoURLDetect_bEnable = FALSE;
   ed->bHaveFocus = FALSE;
   ed->bDialogMode = FALSE;
@@ -3122,26 +3117,24 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10)
   ed->nSelectionType = stPosition;
 
   ed->cPasswordMask = 0;
-  if (props & TXTBIT_USEPASSWORD)
+  if (ed->props & TXTBIT_USEPASSWORD)
     ITextHost_TxGetPasswordChar(texthost, &ed->cPasswordMask);
 
-  if (props & TXTBIT_AUTOWORDSEL)
+  if (ed->props & TXTBIT_AUTOWORDSEL)
     ed->styleFlags |= ECO_AUTOWORDSELECTION;
-  if (props & TXTBIT_MULTILINE) {
+  if (ed->props & TXTBIT_MULTILINE) {
     ed->styleFlags |= ES_MULTILINE;
-    ed->bWordWrap = (props & TXTBIT_WORDWRAP) != 0;
+    ed->bWordWrap = (ed->props & TXTBIT_WORDWRAP) != 0;
   } else {
     ed->bWordWrap = FALSE;
   }
-  if (props & TXTBIT_READONLY)
-    ed->styleFlags |= ES_READONLY;
-  if (!(props & TXTBIT_HIDESELECTION))
+  if (!(ed->props & TXTBIT_HIDESELECTION))
     ed->styleFlags |= ES_NOHIDESEL;
-  if (props & TXTBIT_SAVESELECTION)
+  if (ed->props & TXTBIT_SAVESELECTION)
     ed->styleFlags |= ES_SAVESEL;
-  if (props & TXTBIT_VERTICAL)
+  if (ed->props & TXTBIT_VERTICAL)
     ed->styleFlags |= ES_VERTICAL;
-  if (props & TXTBIT_DISABLEDRAG)
+  if (ed->props & TXTBIT_DISABLEDRAG)
     ed->styleFlags |= ES_NOOLEDRAGDROP;
 
   ed->notified_cr.cpMin = ed->notified_cr.cpMax = 0;
@@ -3502,7 +3495,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
   {
     /* these flags are equivalent to the ES_* counterparts */
     DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
-                 ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN | ECO_SELECTIONBAR;
+                 ECO_NOHIDESEL | ECO_WANTRETURN | ECO_SELECTIONBAR;
     DWORD settings = editor->styleFlags & mask;
 
     return settings;
@@ -3554,7 +3547,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
      * 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 |
-                       ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
+                       ECO_NOHIDESEL | ECO_WANTRETURN |
                        ECO_SELECTIONBAR | ECO_AUTOWORDSELECTION;
     DWORD settings = mask & editor->styleFlags;
     DWORD oldSettings = settings;
diff --git a/dlls/riched20/editstr.h b/dlls/riched20/editstr.h
index 57dd45136af..7b78e5dccbe 100644
--- a/dlls/riched20/editstr.h
+++ b/dlls/riched20/editstr.h
@@ -385,6 +385,7 @@ typedef struct tagME_TextEditor
   ME_Cursor *pCursors;
   DWORD styleFlags;
   DWORD exStyleFlags;
+  DWORD props;
   int nCursors;
   SIZE sizeWindow;
   int nTotalLength, nLastTotalLength;
diff --git a/dlls/riched20/txthost.c b/dlls/riched20/txthost.c
index c810589b4a6..79cc79daa9a 100644
--- a/dlls/riched20/txthost.c
+++ b/dlls/riched20/txthost.c
@@ -775,12 +775,59 @@ static HRESULT get_text_rangeA( struct host *host, TEXTRANGEA *rangeA, LRESULT *
     return hr;
 }
 
+static HRESULT set_options( struct host *host, DWORD op, DWORD value, LRESULT *res )
+{
+    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;
+    HRESULT hr = S_OK;
+
+    new_options = old_options = SendMessageW( host->window, EM_GETOPTIONS, 0, 0 );
+
+    switch (op)
+    {
+    case ECOOP_SET:
+        new_options = value;
+        break;
+    case ECOOP_OR:
+        new_options |= value;
+        break;
+    case ECOOP_AND:
+        new_options &= value;
+        break;
+    case ECOOP_XOR:
+        new_options ^= value;
+    }
+    new_options &= mask;
+
+    change = (new_options ^ old_options);
+
+    if (change & ECO_READONLY)
+    {
+        host->props ^= TXTBIT_READONLY;
+        props_mask |= TXTBIT_READONLY;
+    }
+
+    if (props_mask)
+        ITextServices_OnTxPropertyBitsChange( host->text_srv, props_mask, host->props & props_mask );
+
+    /* Handle the rest in the editor for now */
+    hr = ITextServices_TxSendMessage( host->text_srv, EM_SETOPTIONS, op, value, res );
+    *res = (*res & ~host_mask) | (new_options & host_mask);
+
+    style = GetWindowLongW( host->window, GWL_STYLE );
+    style = (style & ~mask) | (*res & mask);
+    SetWindowLongW( host->window, GWL_STYLE, style );
+    return hr;
+}
+
 static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
                                        LPARAM lparam, BOOL unicode )
 {
     struct host *host;
     ME_TextEditor *editor;
-    HRESULT hr;
+    HRESULT hr = S_OK;
     LRESULT res = 0;
 
     TRACE( "enter hwnd %p msg %04x (%s) %lx %lx, unicode %d\n",
@@ -879,6 +926,11 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
         }
         break;
     }
+    case EM_GETOPTIONS:
+        hr = ITextServices_TxSendMessage( host->text_srv, EM_GETOPTIONS, 0, 0, &res );
+        if (host->props & TXTBIT_READONLY) res |= ECO_READONLY;
+        break;
+
     case WM_GETTEXT:
     {
         GETTEXTEX params;
@@ -965,18 +1017,9 @@ static LRESULT RichEditWndProc_common( HWND hwnd, UINT msg, WPARAM wparam,
         break;
     }
     case EM_SETOPTIONS:
-    {
-        DWORD style;
-        const DWORD mask = ECO_VERTICAL | ECO_AUTOHSCROLL | ECO_AUTOVSCROLL |
-            ECO_NOHIDESEL | ECO_READONLY | ECO_WANTRETURN |
-            ECO_SELECTIONBAR;
+        hr = set_options( host, wparam, lparam, &res );
+        break;
 
-        res = ME_HandleMessage( editor, msg, wparam, lparam, unicode, &hr );
-        style = GetWindowLongW( hwnd, GWL_STYLE );
-        style = (style & ~mask) | (res & mask);
-        SetWindowLongW( hwnd, GWL_STYLE, style );
-        return res;
-    }
     case EM_SETREADONLY:
     {
         DWORD op = wparam ? ECOOP_OR : ECOOP_AND;
diff --git a/dlls/riched20/txtsrv.c b/dlls/riched20/txtsrv.c
index 7893888af57..ecb5cec91c2 100644
--- a/dlls/riched20/txtsrv.c
+++ b/dlls/riched20/txtsrv.c
@@ -322,12 +322,15 @@ DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_TxGetDropTarget(ITextServices *ifac
 }
 
 DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxPropertyBitsChange,12)
-DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange(ITextServices *iface, DWORD dwMask, DWORD dwBits)
+DECLSPEC_HIDDEN HRESULT __thiscall fnTextSrv_OnTxPropertyBitsChange( ITextServices *iface, DWORD mask, DWORD bits )
 {
     struct text_services *services = impl_from_ITextServices( iface );
 
-    FIXME( "%p: STUB\n", services );
-    return E_NOTIMPL;
+    TRACE( "%p, mask %08x, bits %08x\n", services, mask, bits );
+
+    services->editor->props = (services->editor->props & ~mask) | (bits & mask);
+
+    return S_OK;
 }
 
 DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCachedSize,12)
-- 
2.23.0




More information about the wine-devel mailing list