From: Alex Henrie Subject: [PATCH] riched20: Fix link notification conditions and add tests. Message-Id: <1433399680-8631-1-git-send-email-alexhenrie24@gmail.com> Date: Thu, 4 Jun 2015 00:34:40 -0600 Fixes https://bugs.winehq.org/show_bug.cgi?id=35949 --- dlls/riched20/editor.c | 13 +++- dlls/riched20/tests/editor.c | 178 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 172 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..d2ea70c 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -6004,26 +6004,155 @@ 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, BOOL notifies) +{ + LPARAM lParam; + ENLINK junk_enlink; + + switch (msg) + { + case EM_LINESCROLL: + lParam = 1; + break; + 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; + /* fall through */ + default: + lParam = 0; + } + + 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); + 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); + } + else + { + ok(enlink.wParam == wParam, + "%s test %i: Expected wParam 0x%lx got 0x%lx\n", desc, i, wParam, enlink.wParam); + ok(enlink.lParam == lParam, + "%s test %i: Expected lParam 0x%lx got 0x%lx\n", desc, i, lParam, 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; + BOOL notifies; + } + link_notify_tests[] = + { + /* hold down the left button and try some messages */ + { WM_LBUTTONDOWN, 0, TRUE }, /* 0 */ + { EM_LINESCROLL, 0, FALSE }, + { EM_SCROLL, SB_BOTTOM, FALSE }, + { WM_LBUTTONDBLCLK, 0, TRUE }, + { WM_MOUSEHOVER, 0, FALSE }, + { WM_MOUSEMOVE, 0, FALSE }, + { WM_MOUSEWHEEL, 0, FALSE }, + { WM_RBUTTONDBLCLK, 0, TRUE }, + { WM_RBUTTONDOWN, 0, TRUE }, + { WM_RBUTTONUP, 0, TRUE }, + { WM_SETCURSOR, 0, FALSE }, + { WM_SETCURSOR, WP_PARENT, FALSE }, + { WM_SETCURSOR, WP_CHILD, TRUE }, + { WM_VSCROLL, SB_BOTTOM, FALSE }, + { WM_LBUTTONUP, 0, TRUE }, + /* hold down the right button and try some messages */ + { WM_RBUTTONDOWN, 0, TRUE }, /* 15 */ + { EM_LINESCROLL, 0, FALSE }, + { EM_SCROLL, SB_BOTTOM, FALSE }, + { WM_LBUTTONDBLCLK, 0, TRUE }, + { WM_LBUTTONDOWN, 0, TRUE }, + { WM_LBUTTONUP, 0, TRUE }, + { WM_MOUSEHOVER, 0, FALSE }, + { WM_MOUSEMOVE, 0, TRUE }, + { WM_MOUSEWHEEL, 0, FALSE }, + { WM_RBUTTONDBLCLK, 0, TRUE }, + { WM_SETCURSOR, 0, FALSE }, + { WM_SETCURSOR, WP_PARENT, FALSE }, + { WM_SETCURSOR, WP_CHILD, TRUE }, + { WM_VSCROLL, SB_BOTTOM, FALSE }, + { WM_RBUTTONUP, 0, TRUE }, + /* try the messages with both buttons released */ + { EM_LINESCROLL, 0, FALSE }, /* 30 */ + { EM_SCROLL, SB_BOTTOM, FALSE }, + { WM_LBUTTONDBLCLK, 0, TRUE }, + { WM_LBUTTONDOWN, 0, TRUE }, + { WM_LBUTTONUP, 0, TRUE }, + { WM_MOUSEHOVER, 0, FALSE }, + { WM_MOUSEMOVE, 0, TRUE }, + { WM_MOUSEWHEEL, 0, FALSE }, + { WM_RBUTTONDBLCLK, 0, TRUE }, + { WM_RBUTTONDOWN, 0, TRUE }, + { WM_RBUTTONUP, 0, TRUE }, + { WM_SETCURSOR, 0, FALSE }, + { WM_SETCURSOR, WP_CHILD, TRUE }, + { WM_SETCURSOR, WP_PARENT, FALSE }, + { WM_VSCROLL, SB_BOTTOM, FALSE } + }; /* register class to capture WM_NOTIFY */ cls.style = 0; @@ -6042,21 +6171,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].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].notifies); + } + + DestroyWindow(hwnd); DestroyWindow(parent); } -- 2.4.2