[PATCH (try 2)] riched20: Fix link notification conditions and add tests.

Alex Henrie alexhenrie24 at gmail.com
Mon Jun 8 15:59:20 CDT 2015


Fixes https://bugs.winehq.org/show_bug.cgi?id=35949
---
 dlls/riched20/editor.c       |  13 +++-
 dlls/riched20/tests/editor.c | 175 +++++++++++++++++++++++++++++++++++++++----
 2 files changed, 169 insertions(+), 19 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index 38861fd..33b4462 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -4121,6 +4121,10 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     return 0;
   case WM_SETCURSOR:
   {
+    POINT cursor_pos;
+    if (wParam == (WPARAM)editor->hWnd && GetCursorPos(&cursor_pos) &&
+        ScreenToClient(editor->hWnd, &cursor_pos))
+      ME_LinkNotify(editor, msg, 0, MAKELPARAM(cursor_pos.x, cursor_pos.y));
     return ME_SetCursor(editor);
   }
   case WM_LBUTTONDBLCLK:
@@ -4135,7 +4139,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
                    ME_CalculateClickCount(editor, msg, wParam, lParam));
     ITextHost_TxSetCapture(editor->texthost, TRUE);
     editor->bMouseCaptured = TRUE;
-    ME_LinkNotify(editor,msg,wParam,lParam);
+    ME_LinkNotify(editor, msg, wParam, lParam);
     if (!ME_SetCursor(editor)) goto do_default;
     break;
   }
@@ -4145,7 +4149,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
       return 0;
     if (editor->bMouseCaptured)
       ME_MouseMove(editor, (short)LOWORD(lParam), (short)HIWORD(lParam));
-    ME_LinkNotify(editor,msg,wParam,lParam);
+    else
+      ME_LinkNotify(editor, msg, wParam, lParam);
     /* Set cursor if mouse is captured, since WM_SETCURSOR won't be received. */
     if (editor->bMouseCaptured)
         ME_SetCursor(editor);
@@ -4163,15 +4168,17 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     else
     {
       ME_SetCursor(editor);
-      ME_LinkNotify(editor,msg,wParam,lParam);
+      ME_LinkNotify(editor, msg, wParam, lParam);
     }
     break;
   case WM_RBUTTONUP:
   case WM_RBUTTONDOWN:
+  case WM_RBUTTONDBLCLK:
     ME_CommitUndo(editor); /* End coalesced undos for typed characters */
     if ((editor->nEventMask & ENM_MOUSEEVENTS) &&
         !ME_FilterEvent(editor, msg, &wParam, &lParam))
       return 0;
+    ME_LinkNotify(editor, msg, wParam, lParam);
     goto do_default;
   case WM_CONTEXTMENU:
     if (!ME_ShowContextMenu(editor, (short)LOWORD(lParam), (short)HIWORD(lParam)))
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index 09437ef..14f0d06 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -6004,26 +6004,152 @@ static void test_WM_NOTIFY(void)
     DestroyWindow(parent);
 }
 
-static int cpMin_EN_LINK = -1;
-static int cpMax_EN_LINK = -1;
+static ENLINK enlink;
+#define CURSOR_CLIENT_X 5
+#define CURSOR_CLIENT_Y 5
+#define WP_PARENT 1
+#define WP_CHILD 2
 
 static LRESULT WINAPI EN_LINK_ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
-    ENLINK* enlink = (ENLINK*)lParam;
-    if(message == WM_NOTIFY && enlink->nmhdr.code == EN_LINK)
+    if(message == WM_NOTIFY && ((NMHDR*)lParam)->code == EN_LINK)
     {
-        cpMin_EN_LINK = enlink->chrg.cpMin;
-        cpMax_EN_LINK = enlink->chrg.cpMax;
+        enlink = *(ENLINK*)lParam;
     }
     return DefWindowProcA(hwnd, message, wParam, lParam);
 }
 
+static void link_notify_test(const char *desc, int i, HWND hwnd, HWND parent,
+                             UINT msg, WPARAM wParam, LPARAM lParam, BOOL notifies)
+{
+    ENLINK junk_enlink;
+
+    switch (msg)
+    {
+    case WM_LBUTTONDBLCLK:
+    case WM_LBUTTONDOWN:
+    case WM_LBUTTONUP:
+    case WM_MOUSEHOVER:
+    case WM_MOUSEMOVE:
+    case WM_MOUSEWHEEL:
+    case WM_RBUTTONDBLCLK:
+    case WM_RBUTTONDOWN:
+    case WM_RBUTTONUP:
+        lParam = MAKELPARAM(CURSOR_CLIENT_X, CURSOR_CLIENT_Y);
+        break;
+    case WM_SETCURSOR:
+        if (wParam == WP_PARENT)
+            wParam = (WPARAM)parent;
+        else if (wParam == WP_CHILD)
+            wParam = (WPARAM)hwnd;
+        break;
+    }
+
+    memset(&junk_enlink, 0x23, sizeof(junk_enlink));
+    enlink = junk_enlink;
+
+    SendMessageA(hwnd, msg, wParam, lParam);
+
+    if (notifies)
+    {
+        ok(enlink.nmhdr.hwndFrom == hwnd,
+           "%s test %i: Expected hwnd %p got %p\n", desc, i, hwnd, enlink.nmhdr.hwndFrom);
+        ok(enlink.nmhdr.idFrom == 0,
+           "%s test %i: Expected idFrom 0 got 0x%lx\n", desc, i, enlink.nmhdr.idFrom);
+        ok(enlink.msg == msg,
+           "%s test %i: Expected msg 0x%x got 0x%x\n", desc, i, msg, enlink.msg);
+        if (msg == WM_SETCURSOR)
+        {
+            ok(enlink.wParam == 0,
+               "%s test %i: Expected wParam 0 got 0x%lx\n", desc, i, enlink.wParam);
+        }
+        else
+        {
+            ok(enlink.wParam == wParam,
+               "%s test %i: Expected wParam 0x%lx got 0x%lx\n", desc, i, wParam, enlink.wParam);
+        }
+        ok(enlink.lParam == MAKELPARAM(CURSOR_CLIENT_X, CURSOR_CLIENT_Y),
+           "%s test %i: Expected lParam 0x%lx got 0x%lx\n",
+           desc, i, MAKELPARAM(CURSOR_CLIENT_X, CURSOR_CLIENT_Y), enlink.lParam);
+        ok(enlink.chrg.cpMin == 0 && enlink.chrg.cpMax == 31,
+           "%s test %i: Expected link range [0,31) got [%i,%i)\n", desc, i, enlink.chrg.cpMin, enlink.chrg.cpMax);
+    }
+    else
+    {
+        ok(memcmp(&enlink, &junk_enlink, sizeof(enlink)) == 0,
+           "%s test %i: Expected enlink to remain unmodified\n", desc, i);
+    }
+}
+
 static void test_EN_LINK(void)
 {
-    HWND parent;
+    HWND hwnd, parent;
     WNDCLASSA cls;
-    HWND hwndRichedit_EN_LINK;
     CHARFORMAT2A cf2;
+    POINT cursor_screen_pos = {CURSOR_CLIENT_X, CURSOR_CLIENT_Y};
+    int i;
+
+    static const struct
+    {
+        UINT msg;
+        WPARAM wParam;
+        LPARAM lParam;
+        BOOL notifies;
+    }
+    link_notify_tests[] =
+    {
+        /* hold down the left button and try some messages */
+        { WM_LBUTTONDOWN,    0,          0,  TRUE  }, /* 0 */
+        { EM_LINESCROLL,     0,          1,  FALSE },
+        { EM_SCROLL,         SB_BOTTOM,  0,  FALSE },
+        { WM_LBUTTONDBLCLK,  0,          0,  TRUE  },
+        { WM_MOUSEHOVER,     0,          0,  FALSE },
+        { WM_MOUSEMOVE,      0,          0,  FALSE },
+        { WM_MOUSEWHEEL,     0,          0,  FALSE },
+        { WM_RBUTTONDBLCLK,  0,          0,  TRUE  },
+        { WM_RBUTTONDOWN,    0,          0,  TRUE  },
+        { WM_RBUTTONUP,      0,          0,  TRUE  },
+        { WM_SETCURSOR,      0,          0,  FALSE },
+        { WM_SETCURSOR,      WP_PARENT,  0,  FALSE },
+        { WM_SETCURSOR,      WP_CHILD,   0,  TRUE  },
+        { WM_SETCURSOR,      WP_CHILD,   1,  TRUE  },
+        { WM_VSCROLL,        SB_BOTTOM,  0,  FALSE },
+        { WM_LBUTTONUP,      0,          0,  TRUE  },
+        /* hold down the right button and try some messages */
+        { WM_RBUTTONDOWN,    0,          0,  TRUE  }, /* 16 */
+        { EM_LINESCROLL,     0,          1,  FALSE },
+        { EM_SCROLL,         SB_BOTTOM,  0,  FALSE },
+        { WM_LBUTTONDBLCLK,  0,          0,  TRUE  },
+        { WM_LBUTTONDOWN,    0,          0,  TRUE  },
+        { WM_LBUTTONUP,      0,          0,  TRUE  },
+        { WM_MOUSEHOVER,     0,          0,  FALSE },
+        { WM_MOUSEMOVE,      0,          0,  TRUE  },
+        { WM_MOUSEWHEEL,     0,          0,  FALSE },
+        { WM_RBUTTONDBLCLK,  0,          0,  TRUE  },
+        { WM_SETCURSOR,      0,          0,  FALSE },
+        { WM_SETCURSOR,      WP_PARENT,  0,  FALSE },
+        { WM_SETCURSOR,      WP_CHILD,   0,  TRUE  },
+        { WM_SETCURSOR,      WP_CHILD,   1,  TRUE  },
+        { WM_VSCROLL,        SB_BOTTOM,  0,  FALSE },
+        { WM_RBUTTONUP,      0,          0,  TRUE  },
+        /* try the messages with both buttons released */
+        { EM_LINESCROLL,     0,          1,  FALSE }, /* 32 */
+        { EM_SCROLL,         SB_BOTTOM,  0,  FALSE },
+        { WM_LBUTTONDBLCLK,  0,          0,  TRUE  },
+        { WM_LBUTTONDOWN,    0,          0,  TRUE  },
+        { WM_LBUTTONUP,      0,          0,  TRUE  },
+        { WM_MOUSEHOVER,     0,          0,  FALSE },
+        { WM_MOUSEMOVE,      0,          0,  TRUE  },
+        { WM_MOUSEWHEEL,     0,          0,  FALSE },
+        { WM_RBUTTONDBLCLK,  0,          0,  TRUE  },
+        { WM_RBUTTONDOWN,    0,          0,  TRUE  },
+        { WM_RBUTTONUP,      0,          0,  TRUE  },
+        { WM_SETCURSOR,      0,          0,  FALSE },
+        { WM_SETCURSOR,      WP_CHILD,   0,  TRUE  },
+        { WM_SETCURSOR,      WP_CHILD,   1,  TRUE  },
+        { WM_SETCURSOR,      WP_PARENT,  0,  FALSE },
+        { WM_VSCROLL,        SB_BOTTOM,  0,  FALSE }
+    };
 
     /* register class to capture WM_NOTIFY */
     cls.style = 0;
@@ -6042,21 +6168,38 @@ static void test_EN_LINK(void)
                            0, 0, 200, 60, NULL, NULL, NULL, NULL);
     ok(parent != 0, "Failed to create parent window\n");
 
-    hwndRichedit_EN_LINK = new_richedit(parent);
-    ok(hwndRichedit_EN_LINK != 0, "Failed to create edit window\n");
+    hwnd = new_richedit(parent);
+    ok(hwnd != 0, "Failed to create edit window\n");
 
-    SendMessageA(hwndRichedit_EN_LINK, EM_SETEVENTMASK, 0, ENM_LINK);
+    SendMessageA(hwnd, EM_SETEVENTMASK, 0, ENM_LINK);
 
     cf2.cbSize = sizeof(CHARFORMAT2A);
     cf2.dwMask = CFM_LINK;
     cf2.dwEffects = CFE_LINK;
-    SendMessageA(hwndRichedit_EN_LINK, EM_SETCHARFORMAT, 0, (LPARAM)&cf2);
+    SendMessageA(hwnd, EM_SETCHARFORMAT, 0, (LPARAM)&cf2);
     /* mixing letters and numbers causes runs to be split */
-    SendMessageA(hwndRichedit_EN_LINK, WM_SETTEXT, 0, (LPARAM)"link text with at least 2 runs");
-    SendMessageA(hwndRichedit_EN_LINK, WM_LBUTTONDOWN, 0, MAKELPARAM(5, 5));
-    ok(cpMin_EN_LINK == 0 && cpMax_EN_LINK == 31, "Expected link range [0,31) got [%i,%i)\n", cpMin_EN_LINK, cpMax_EN_LINK);
+    SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"link text with at least 2 runs");
 
-    DestroyWindow(hwndRichedit_EN_LINK);
+    ok(SetCursorPos(0, 0), "SetCursorPos failed\n");
+
+    for (i = 0; i < sizeof(link_notify_tests)/sizeof(link_notify_tests[0]); i++)
+    {
+        link_notify_test("cursor position simulated", i, hwnd, parent,
+                         link_notify_tests[i].msg, link_notify_tests[i].wParam, link_notify_tests[i].lParam,
+                         link_notify_tests[i].msg == WM_SETCURSOR ? FALSE : link_notify_tests[i].notifies);
+    }
+
+    ok(ClientToScreen(hwnd, &cursor_screen_pos), "ClientToScreen failed\n");
+    ok(SetCursorPos(cursor_screen_pos.x, cursor_screen_pos.y), "SetCursorPos failed\n");
+
+    for (i = 0; i < sizeof(link_notify_tests)/sizeof(link_notify_tests[0]); i++)
+    {
+        link_notify_test("cursor position set", i, hwnd, parent,
+                         link_notify_tests[i].msg, link_notify_tests[i].wParam, link_notify_tests[i].lParam,
+                         link_notify_tests[i].notifies);
+    }
+
+    DestroyWindow(hwnd);
     DestroyWindow(parent);
 }
 
-- 
2.4.2




More information about the wine-patches mailing list