Fabian Maurer : comctl32/listview: Avoid duplicate LVN_ENDLABELEDIT notifications on focus change.

Alexandre Julliard julliard at winehq.org
Mon Aug 27 16:18:14 CDT 2018


Module: wine
Branch: master
Commit: f6bd24fda69929b257bfad88c88165ade29327b3
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f6bd24fda69929b257bfad88c88165ade29327b3

Author: Fabian Maurer <dark.shadow4 at web.de>
Date:   Sun Aug 26 23:27:26 2018 +0300

comctl32/listview: Avoid duplicate LVN_ENDLABELEDIT notifications on focus change.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/comctl32/listview.c       | 10 ++++--
 dlls/comctl32/tests/listview.c | 78 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index d463607..777b40f 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -214,6 +214,7 @@ typedef struct tagDELAYED_ITEM_EDIT
 enum notification_mask
 {
   NOTIFY_MASK_ITEM_CHANGE = 0x1,
+  NOTIFY_MASK_END_LABEL_EDIT = 0x2,
   NOTIFY_MASK_UNMASK_ALL = 0xffffffff
 };
 
@@ -5922,9 +5923,13 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
     dispInfo.item.pszText = same ? NULL : pszText;
     dispInfo.item.cchTextMax = textlenT(dispInfo.item.pszText, isW);
 
+    infoPtr->notify_mask &= ~NOTIFY_MASK_END_LABEL_EDIT;
+
     /* Do we need to update the Item Text */
     res = notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW);
 
+    infoPtr->notify_mask |= NOTIFY_MASK_END_LABEL_EDIT;
+
     infoPtr->nEditLabelItem = -1;
     infoPtr->hwndEdit = 0;
 
@@ -11914,8 +11919,9 @@ static LRESULT LISTVIEW_Command(LISTVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lP
 	}
 	case EN_KILLFOCUS:
 	{
-	    LISTVIEW_CancelEditLabel(infoPtr);
-	    break;
+            if (infoPtr->notify_mask & NOTIFY_MASK_END_LABEL_EDIT)
+                LISTVIEW_CancelEditLabel(infoPtr);
+            break;
 	}
 
 	default:
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index c118f02..6a7842b 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -75,6 +75,8 @@ static BOOL g_disp_A_to_W;
 static NMLVDISPINFOA g_editbox_disp_info;
 /* when this is set focus will be tested on LVN_DELETEITEM */
 static BOOL g_focus_test_LVN_DELETEITEM;
+/* Whether to send WM_KILLFOCUS to the edit control during LVN_ENDLABELEDIT */
+static BOOL g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT;
 
 static HWND subclass_editbox(HWND hwndListview);
 
@@ -445,6 +447,25 @@ static const struct message parent_list_cd_seq[] = {
     { 0 }
 };
 
+static const struct message listview_end_label_edit[] = {
+    { WM_NOTIFY,  sent|id, 0, 0, LVN_ENDLABELEDITA },
+    { WM_NOTIFY,  sent|id, 0, 0, LVN_ITEMCHANGING},
+    { WM_NOTIFY,  sent|id, 0, 0, LVN_ITEMCHANGED },
+    { WM_NOTIFY,  sent|id|optional, 0, 0, NM_CUSTOMDRAW }, /* XP */
+    { WM_NOTIFY,  sent|id, 0, 0, NM_SETFOCUS },
+    { 0 }
+};
+
+static const struct message listview_end_label_edit_kill_focus[] = {
+    { WM_NOTIFY,  sent|id, 0, 0, LVN_ENDLABELEDITA },
+    { WM_COMMAND, sent|id|optional, 0, 0, EN_KILLFOCUS }, /* todo: not sent by wine yet */
+    { WM_NOTIFY,  sent|id, 0, 0, LVN_ITEMCHANGING },
+    { WM_NOTIFY,  sent|id, 0, 0, LVN_ITEMCHANGED },
+    { WM_NOTIFY,  sent|id|optional, 0, 0, NM_CUSTOMDRAW }, /* XP */
+    { WM_NOTIFY,  sent|id, 0, 0, NM_SETFOCUS },
+    { 0 }
+};
+
 static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
     static LONG defwndproc_counter = 0;
@@ -457,6 +478,7 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP
     msg.wParam = wParam;
     msg.lParam = lParam;
     if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code;
+    if (message == WM_COMMAND) msg.id = HIWORD(wParam);
 
     /* log system messages, except for painting */
     if (message < WM_USER &&
@@ -510,6 +532,9 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP
               ok(IsWindow(edit), "expected valid edit control handle\n");
               ok((GetWindowLongA(edit, GWL_STYLE) & ES_MULTILINE) == 0, "edit is multiline\n");
 
+              if (g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT)
+                  SendMessageA(edit, WM_KILLFOCUS, 0, 0);
+
               return TRUE;
               }
           case LVN_BEGINSCROLL:
@@ -6322,6 +6347,57 @@ static void test_LVSCW_AUTOSIZE(void)
     DestroyWindow(hwnd);
 }
 
+static void test_LVN_ENDLABELEDIT(void)
+{
+    WCHAR text[] = {'l','a','l','a',0};
+    HWND hwnd, hwndedit;
+    LVITEMW item = {0};
+    DWORD ret;
+
+    hwnd = create_listview_control(LVS_REPORT | LVS_EDITLABELS);
+
+    insert_column(hwnd, 0);
+
+    item.mask = LVIF_TEXT;
+    item.pszText = text;
+    SendMessageW(hwnd, LVM_INSERTITEMW, 0, (LPARAM)&item);
+
+    /* Test normal editing */
+    SetFocus(hwnd);
+    hwndedit = (HWND)SendMessageW(hwnd, LVM_EDITLABELW, 0, 0);
+    ok(hwndedit != NULL, "Failed to get edit control.\n");
+
+    ret = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)"test");
+    ok(ret, "Failed to set edit text.\n");
+
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
+
+    ret = SendMessageA(hwndedit, WM_KEYDOWN, VK_RETURN, 0);
+    ok_sequence(sequences, PARENT_SEQ_INDEX, listview_end_label_edit, "Label edit", FALSE);
+
+    /* Test editing with kill focus */
+    SetFocus(hwnd);
+    hwndedit = (HWND)SendMessageW(hwnd, LVM_EDITLABELW, 0, 0);
+    ok(hwndedit != NULL, "Failed to get edit control.\n");
+
+    ret = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)"test2");
+    ok(ret, "Failed to set edit text.\n");
+
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
+
+    g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT = TRUE;
+    ret = SendMessageA(hwndedit, WM_KEYDOWN, VK_RETURN, 0);
+    g_WM_KILLFOCUS_on_LVN_ENDLABELEDIT = FALSE;
+
+    ok_sequence(sequences, PARENT_SEQ_INDEX, listview_end_label_edit_kill_focus,
+            "Label edit, kill focus", FALSE);
+    ok(GetFocus() == hwnd, "Unexpected focused window.\n");
+
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
+
+    DestroyWindow(hwnd);
+}
+
 START_TEST(listview)
 {
     ULONG_PTR ctx_cookie;
@@ -6383,6 +6459,7 @@ START_TEST(listview)
     test_callback_mask();
     test_state_image();
     test_LVSCW_AUTOSIZE();
+    test_LVN_ENDLABELEDIT();
 
     if (!load_v6_module(&ctx_cookie, &hCtx))
     {
@@ -6425,6 +6502,7 @@ START_TEST(listview)
     test_oneclickactivate();
     test_state_image();
     test_LVSCW_AUTOSIZE();
+    test_LVN_ENDLABELEDIT();
 
     unload_v6_module(ctx_cookie, hCtx);
 




More information about the wine-cvs mailing list