[PATCH 1/2 v2] riched20: Implement EM_SELECTIONTYPE.

Jactry Zeng jzeng at codeweavers.com
Thu Apr 19 03:08:50 CDT 2018


Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
 dlls/riched20/editor.c       | 46 +++++++++++++++++-
 dlls/riched20/tests/editor.c | 92 ++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+), 2 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index c57d3ea9b9..eb67e11fdd 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -90,7 +90,7 @@
   + EM_REPLACESEL (proper style?) ANSI&Unicode
   + EM_SCROLL
   + EM_SCROLLCARET
-  - EM_SELECTIONTYPE
+  + EM_SELECTIONTYPE
   - EM_SETBIDIOPTIONS 3.0
   + EM_SETBKGNDCOLOR
   + EM_SETCHARFORMAT (partly done, no ANSI)
@@ -2960,6 +2960,47 @@ static void ME_SetDefaultFormatRect(ME_TextEditor *editor)
   editor->rcFormat.right -= 1;
 }
 
+static LONG ME_GetSelectionType(ME_TextEditor *editor)
+{
+    LONG sel_type = SEL_EMPTY;
+    LONG start, end;
+
+    ME_GetSelectionOfs(editor, &start, &end);
+    if (start == end)
+        sel_type = SEL_EMPTY;
+    else
+    {
+        LONG object_count = 0, character_count = 0;
+        int i;
+
+        for (i = 0; i < end - start; i++)
+        {
+            ME_Cursor cursor;
+
+            ME_CursorFromCharOfs(editor, start + i, &cursor);
+            if (cursor.pRun->member.run.reobj)
+                object_count++;
+            else
+                character_count++;
+            if (character_count >= 2 && object_count >= 2)
+                return (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT);
+        }
+        if (character_count)
+        {
+            sel_type |= SEL_TEXT;
+            if (character_count >= 2)
+                sel_type |= SEL_MULTICHAR;
+        }
+        if (object_count)
+        {
+            sel_type |= SEL_OBJECT;
+            if (object_count >= 2)
+                sel_type |= SEL_MULTIOBJECT;
+        }
+    }
+    return sel_type;
+}
+
 static BOOL ME_ShowContextMenu(ME_TextEditor *editor, int x, int y)
 {
   CHARRANGE selrange;
@@ -3498,7 +3539,6 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
   UNSUPPORTED_MSG(EM_GETTYPOGRAPHYOPTIONS)
   UNSUPPORTED_MSG(EM_GETUNDONAME)
   UNSUPPORTED_MSG(EM_GETWORDBREAKPROCEX)
-  UNSUPPORTED_MSG(EM_SELECTIONTYPE)
   UNSUPPORTED_MSG(EM_SETBIDIOPTIONS)
   UNSUPPORTED_MSG(EM_SETEDITSTYLE)
   UNSUPPORTED_MSG(EM_SETLANGOPTIONS)
@@ -3814,6 +3854,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     ME_UpdateRepaint(editor, FALSE);
     return len;
   }
+  case EM_SELECTIONTYPE:
+    return ME_GetSelectionType(editor);
   case EM_SETBKGNDCOLOR:
   {
     LRESULT lColor;
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index 9bfbf45837..2a6907bfe7 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -20,6 +20,8 @@
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
 
+#define COBJMACROS
+
 #include <stdarg.h>
 #include <stdio.h>
 #include <assert.h>
@@ -30,6 +32,7 @@
 #include <winnls.h>
 #include <ole2.h>
 #include <richedit.h>
+#include <richole.h>
 #include <commdlg.h>
 #include <time.h>
 #include <wine/test.h>
@@ -8798,6 +8801,94 @@ static void test_para_numbering(void)
     DestroyWindow( edit );
 }
 
+static void fill_reobject_struct(REOBJECT *reobj, LONG cp, LPOLEOBJECT poleobj,
+                                 LPSTORAGE pstg, LPOLECLIENTSITE polesite, LONG sizel_cx,
+                                 LONG sizel_cy, DWORD aspect, DWORD flags, DWORD user)
+{
+    reobj->cbStruct = sizeof(*reobj);
+    reobj->clsid = CLSID_NULL;
+    reobj->cp = cp;
+    reobj->poleobj = poleobj;
+    reobj->pstg = pstg;
+    reobj->polesite = polesite;
+    reobj->sizel.cx = sizel_cx;
+    reobj->sizel.cy = sizel_cy;
+    reobj->dvaspect = aspect;
+    reobj->dwFlags = flags;
+    reobj->dwUser = user;
+}
+
+static void test_EM_SELECTIONTYPE(void)
+{
+    HWND hwnd = new_richedit(NULL);
+    IRichEditOle *reole = NULL;
+    static const char text1[] = "abcdefg\n";
+    int result;
+    REOBJECT reo1, reo2;
+    IOleClientSite *clientsite;
+    HRESULT hr;
+
+    SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)text1);
+    SendMessageA(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&reole);
+
+    SendMessageA(hwnd, EM_SETSEL, 1, 1);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == SEL_EMPTY, "got wrong selection type: %x.\n", result);
+
+    SendMessageA(hwnd, EM_SETSEL, 1, 2);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == SEL_TEXT, "got wrong selection type: %x.\n", result);
+
+    SendMessageA(hwnd, EM_SETSEL, 2, 5);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == (SEL_TEXT | SEL_MULTICHAR), "got wrong selection type: %x.\n", result);
+
+    SendMessageA(hwnd, EM_SETSEL, 0, 1);
+    hr = IRichEditOle_GetClientSite(reole, &clientsite);
+    ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
+    fill_reobject_struct(&reo1, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
+                         DVASPECT_CONTENT, 0, 1);
+    hr = IRichEditOle_InsertObject(reole, &reo1);
+    ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+    IOleClientSite_Release(clientsite);
+
+    SendMessageA(hwnd, EM_SETSEL, 0, 1);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == SEL_OBJECT, "got wrong selection type: %x.\n", result);
+
+    SendMessageA(hwnd, EM_SETSEL, 0, 2);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == (SEL_TEXT | SEL_OBJECT), "got wrong selection type: %x.\n", result);
+
+    SendMessageA(hwnd, EM_SETSEL, 0, 3);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == (SEL_TEXT | SEL_MULTICHAR | SEL_OBJECT), "got wrong selection type: %x.\n", result);
+
+    SendMessageA(hwnd, EM_SETSEL, 2, 3);
+    hr = IRichEditOle_GetClientSite(reole, &clientsite);
+    ok(hr == S_OK, "IRichEditOle_GetClientSite failed: 0x%08x\n", hr);
+    fill_reobject_struct(&reo2, REO_CP_SELECTION, NULL, NULL, clientsite, 10, 10,
+                         DVASPECT_CONTENT, 0, 2);
+    hr = IRichEditOle_InsertObject(reole, &reo2);
+    ok(hr == S_OK, "IRichEditOle_InsertObject failed: 0x%08x\n", hr);
+    IOleClientSite_Release(clientsite);
+
+    SendMessageA(hwnd, EM_SETSEL, 0, 2);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == (SEL_OBJECT | SEL_TEXT), "got wrong selection type: %x.\n", result);
+
+    SendMessageA(hwnd, EM_SETSEL, 0, 3);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == (SEL_OBJECT | SEL_MULTIOBJECT | SEL_TEXT), "got wrong selection type: %x.\n", result);
+
+    SendMessageA(hwnd, EM_SETSEL, 0, 4);
+    result = SendMessageA(hwnd, EM_SELECTIONTYPE, 0, 0);
+    ok(result == (SEL_TEXT| SEL_MULTICHAR | SEL_OBJECT | SEL_MULTIOBJECT), "got wrong selection type: %x.\n", result);
+
+    IRichEditOle_Release(reole);
+    DestroyWindow(hwnd);
+}
+
 START_TEST( editor )
 {
   BOOL ret;
@@ -8872,6 +8963,7 @@ START_TEST( editor )
   test_background();
   test_eop_char_fmt();
   test_para_numbering();
+  test_EM_SELECTIONTYPE();
 
   /* Set the environment variable WINETEST_RICHED20 to keep windows
    * responsive and open for 30 seconds. This is useful for debugging.
-- 
2.17.0





More information about the wine-devel mailing list