From: Alex Henrie Subject: [PATCH] riched20: Consider adjacent runs when computing EN_LINK range. Message-Id: <20140615231543.b89cfaa54a6532d524c33d53@gmail.com> Date: Sun, 15 Jun 2014 23:15:43 -0600 Fixes bug 35948. --- dlls/riched20/editor.c | 21 +++++++++++++++- dlls/riched20/tests/editor.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index 0127616..2af2582 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -3093,6 +3093,8 @@ static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM if (cursor.pRun->member.run.style->fmt.dwMask & CFM_LINK && cursor.pRun->member.run.style->fmt.dwEffects & CFE_LINK) { /* The clicked run has CFE_LINK set */ + ME_DisplayItem *di; + info.nmhdr.hwndFrom = NULL; info.nmhdr.idFrom = 0; info.nmhdr.code = EN_LINK; @@ -3100,8 +3102,25 @@ static void ME_LinkNotify(ME_TextEditor *editor, UINT msg, WPARAM wParam, LPARAM info.wParam = wParam; info.lParam = lParam; cursor.nOffset = 0; + + /* find the first contiguous run with CFE_LINK set */ info.chrg.cpMin = ME_GetCursorOfs(&cursor); - info.chrg.cpMax = info.chrg.cpMin + cursor.pRun->member.run.len; + for (di = cursor.pRun->prev; + di && di->type == diRun && (di->member.run.style->fmt.dwMask & CFM_LINK) && (di->member.run.style->fmt.dwEffects & CFE_LINK); + di = di->prev) + { + info.chrg.cpMin -= di->member.run.len; + } + + /* find the last contiguous run with CFE_LINK set */ + info.chrg.cpMax = ME_GetCursorOfs(&cursor) + cursor.pRun->member.run.len; + for (di = cursor.pRun->next; + di && di->type == diRun && (di->member.run.style->fmt.dwMask & CFM_LINK) && (di->member.run.style->fmt.dwEffects & CFE_LINK); + di = di->next) + { + info.chrg.cpMax += di->member.run.len; + } + ITextHost_TxNotify(editor->texthost, info.nmhdr.code, &info); } } diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c index 2a85357..5421614 100644 --- a/dlls/riched20/tests/editor.c +++ b/dlls/riched20/tests/editor.c @@ -5937,6 +5937,62 @@ static void test_WM_NOTIFY(void) DestroyWindow(parent); } +static int cpMin_EN_LINK = -1; +static int cpMax_EN_LINK = -1; + +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) + { + cpMin_EN_LINK = enlink->chrg.cpMin; + cpMax_EN_LINK = enlink->chrg.cpMax; + } + return DefWindowProcA(hwnd, message, wParam, lParam); +} + +static void test_EN_LINK(void) +{ + HWND parent; + WNDCLASSA cls; + HWND hwndRichedit_EN_LINK; + CHARFORMAT2A cf2; + + /* register class to capture WM_NOTIFY */ + cls.style = 0; + cls.lpfnWndProc = EN_LINK_ParentMsgCheckProcA; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleA(0); + cls.hIcon = 0; + cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = "EN_LINK_ParentClass"; + if(!RegisterClassA(&cls)) assert(0); + + parent = CreateWindowA(cls.lpszClassName, NULL, WS_POPUP|WS_VISIBLE, + 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"); + + SendMessageA(hwndRichedit_EN_LINK, 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); + /* 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); + + DestroyWindow(hwndRichedit_EN_LINK); + DestroyWindow(parent); +} + static void test_undo_coalescing(void) { HWND hwnd; @@ -7565,6 +7621,7 @@ START_TEST( editor ) test_EM_REPLACESEL(1); test_EM_REPLACESEL(0); test_WM_NOTIFY(); + test_EN_LINK(); test_EM_AUTOURLDETECT(); test_eventMask(); test_undo_coalescing(); -- 1.9.1