[PATCH] comctl32/listview: Don't send LVN_ENDLABELEDIT twice under some circumstances

Fabian Maurer dark.shadow4 at web.de
Fri Aug 24 15:41:38 CDT 2018


Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/comctl32/listview.c       | 10 +++++++++
 dlls/comctl32/tests/listview.c | 41 ++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 200bf93be55..0193c038ebb 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -326,6 +326,7 @@ typedef struct tagLISTVIEW_INFO
 
   /* misc */
   DWORD iVersion;          /* CCM_[G,S]ETVERSION */
+  BOOL inEndEditLabel;    /* To prevent sending LVN_ENDLABELEDIT during LVN_ENDLABELEDIT */
 } LISTVIEW_INFO;
 
 /*
@@ -5869,6 +5870,9 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
     WCHAR *pszText = NULL;
     BOOL res;
 
+    if (infoPtr->inEndEditLabel)
+        return FALSE;
+
     if (storeText)
     {
         DWORD len = isW ? GetWindowTextLengthW(infoPtr->hwndEdit) : GetWindowTextLengthA(infoPtr->hwndEdit);
@@ -5914,9 +5918,14 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
     dispInfo.item.pszText = same ? NULL : pszText;
     dispInfo.item.cchTextMax = textlenT(dispInfo.item.pszText, isW);
 
+    /* Sending LVN_ENDLABELEDITW might trigger EN_KILLFOCUS which would call this function again */
+    infoPtr->inEndEditLabel = TRUE;
+
     /* Do we need to update the Item Text */
     res = notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW);
 
+    infoPtr->inEndEditLabel = FALSE;
+
     infoPtr->nEditLabelItem = -1;
     infoPtr->hwndEdit = 0;
 
@@ -9497,6 +9506,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, WPARAM wParam, const CREATESTRUCTW *
   infoPtr->itemEdit.fEnabled = FALSE;
   infoPtr->iVersion = COMCTL32_VERSION;
   infoPtr->colRectsDirty = FALSE;
+  infoPtr->inEndEditLabel = FALSE;
 
   /* get default font (icon title) */
   SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index e9b715ee412..3e9e9697a4f 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -75,6 +75,10 @@ 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 do_LVN_ENDLABELEDIT_killfocus = FALSE;
+/* Number of LVN_ENDLABELEDIT notifications received */
+static BOOL LVN_ENDLABELEDITA_count = 0;
 
 static HWND subclass_editbox(HWND hwndListview);
 
@@ -510,6 +514,11 @@ 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");
 
+              LVN_ENDLABELEDITA_count++;
+
+              if (do_LVN_ENDLABELEDIT_killfocus)
+                  SendMessageA(edit, WM_KILLFOCUS, 0, 0);
+
               return TRUE;
               }
           case LVN_BEGINSCROLL:
@@ -6322,6 +6331,37 @@ static void test_LVSCW_AUTOSIZE(void)
     DestroyWindow(hwnd);
 }
 
+static void test_LVN_ENDLABELEDITW(void)
+{
+    HWND hwnd, hwndedit;
+    LVITEMW item = {0};
+    WCHAR text[] = {'l','a','l','a',0};
+    DWORD ret;
+
+    hwnd = create_listview_control(LVS_REPORT | LVS_EDITLABELS);
+
+    insert_column(hwnd, 0);
+
+    item.mask = LVIF_TEXT;
+    item.pszText = text;
+    ListView_InsertItemW(hwnd, &item);
+
+    SetFocus(hwnd);
+    hwndedit = (HWND)SendMessageW(hwnd, LVM_EDITLABELW, 0, 0);
+
+    ret = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)"test");
+    expect(TRUE, ret);
+
+    LVN_ENDLABELEDITA_count = 0;
+    do_LVN_ENDLABELEDIT_killfocus = TRUE;
+    ret = SendMessageA(hwndedit, WM_KEYDOWN, VK_RETURN, 0);
+    do_LVN_ENDLABELEDIT_killfocus = FALSE;
+    ok(LVN_ENDLABELEDITA_count == 1,
+            "messagebox during LVN_ENDLABELEDIT gave wrong number of LVN_ENDLABELEDITA: %d\n", LVN_ENDLABELEDITA_count);
+
+    DestroyWindow(hwnd);
+}
+
 START_TEST(listview)
 {
     ULONG_PTR ctx_cookie;
@@ -6425,6 +6465,7 @@ START_TEST(listview)
     test_oneclickactivate();
     test_state_image();
     test_LVSCW_AUTOSIZE();
+    test_LVN_ENDLABELEDITW();
 
     unload_v6_module(ctx_cookie, hCtx);
 
-- 
2.18.0




More information about the wine-devel mailing list