[1/2] comctl32/treeview: Use separate pointer for currently edited item

Nikolay Sivov bunglehead at gmail.com
Thu Aug 6 15:22:59 CDT 2009


>From a2e75df6ec014287d9dee94cbe8c502bcabda02b Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <bunglehead at gmail.com>
Date: Fri, 7 Aug 2009 00:10:30 +0400
Subject: Use separate pointer for currently edited item

---
 dlls/comctl32/tests/treeview.c |   31 ++++++++++++++++-
 dlls/comctl32/treeview.c       |   72 ++++++++++++++++++++++++---------------
 2 files changed, 74 insertions(+), 29 deletions(-)

diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c
index 252949f..7c86450 100644
--- a/dlls/comctl32/tests/treeview.c
+++ b/dlls/comctl32/tests/treeview.c
@@ -769,6 +769,7 @@ static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
                 }
                 return 0;
               }
+            case TVN_ENDLABELEDIT: return TRUE;
             }
         }
         return 0;
@@ -862,20 +863,48 @@ static void test_itemedit(void)
 {
     DWORD r;
     HWND edit;
+    TVITEMA item;
+    CHAR buff[2];
 
     hTree = create_treeview_control();
     fill_tree(hTree);
 
+    /* try with null item */
+    edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)NULL);
+    ok(!IsWindow(edit), "Expected valid handle\n");
+
     /* trigger edit */
     edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot);
     ok(IsWindow(edit), "Expected valid handle\n");
     /* item shouldn't be selected automatically after TVM_EDITLABEL */
     r = SendMessage(hTree, TVM_GETITEMSTATE, (WPARAM)hRoot, TVIS_SELECTED);
-    todo_wine expect(0, r);
+    expect(0, r);
+    r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit);
+    expect(0, r);
+    ok(!IsWindow(edit), "Expected edit control to be destroyed\n");
 
+    /* remove selection after starting edit */
+    r = TreeView_SelectItem(hTree, hRoot);
+    expect(TRUE, r);
+    edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot);
+    ok(IsWindow(edit), "Expected valid handle\n");
+    r = TreeView_SelectItem(hTree, NULL);
+    expect(TRUE, r);
+    /* alter text */
+    strncpy(buff, "x", sizeof(buff)/sizeof(CHAR));
+    r = SendMessage(edit, WM_SETTEXT, 0, (LPARAM)buff);
+    expect(TRUE, r);
     r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit);
     expect(0, r);
     ok(!IsWindow(edit), "Expected edit control to be destroyed\n");
+    /* check that text is saved */
+    item.mask = TVIF_TEXT;
+    item.hItem = hRoot;
+    item.pszText = buff;
+    item.cchTextMax = sizeof(buff)/sizeof(CHAR);
+    r = SendMessage(hTree, TVM_GETITEM, 0, (LPARAM)&item);
+    expect(TRUE, r);
+    ok(!strcmp("x", buff), "Expected item text to change\n");
 
     DestroyWindow(hTree);
 }
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index 84a8c30..44bb841 100644
--- a/dlls/comctl32/treeview.c
+++ b/dlls/comctl32/treeview.c
@@ -119,6 +119,7 @@ typedef struct tagTREEVIEW_INFO
   HTREEITEM     selectedItem;   /* handle to selected item or 0 if none */
   HTREEITEM     hotItem;        /* handle currently under cursor, 0 if none */
   HTREEITEM	focusedItem;    /* item that was under the cursor when WM_LBUTTONDOWN was received */
+  HTREEITEM     editItem;       /* item being edited with builtin edit box */
 
   HTREEITEM     firstVisible;   /* handle to first visible item */
   LONG          maxVisibleOrder;
@@ -3546,6 +3547,14 @@ TREEVIEW_Edit_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 	    return TRUE;
 	break;
 
+    case WM_DESTROY:
+    {
+	WNDPROC editProc = infoPtr->wpEditOrig;
+	infoPtr->wpEditOrig = 0;
+	SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (DWORD_PTR)editProc);
+	return CallWindowProcW(editProc, hwnd, uMsg, wParam, lParam);
+    }
+
     case WM_GETDLGCODE:
 	return DLGC_WANTARROWS | DLGC_WANTALLKEYS;
 
@@ -3581,7 +3590,7 @@ TREEVIEW_Edit_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 static LRESULT
 TREEVIEW_Command(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
-    TRACE("%lx %ld\n", wParam, lParam);
+    TRACE("code=%x, id=%x, handle=%lx\n", HIWORD(wParam), LOWORD(wParam), lParam);
 
     switch (HIWORD(wParam))
     {
@@ -3591,11 +3600,15 @@ TREEVIEW_Command(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 	     * Adjust the edit window size
 	     */
 	    WCHAR buffer[1024];
-	    TREEVIEW_ITEM *editItem = infoPtr->selectedItem;
+	    TREEVIEW_ITEM *editItem = infoPtr->editItem;
 	    HDC hdc = GetDC(infoPtr->hwndEdit);
 	    SIZE sz;
 	    HFONT hFont, hOldFont = 0;
 
+	    TRACE("edit=%p\n", infoPtr->hwndEdit);
+
+	    if (!IsWindow(infoPtr->hwndEdit) || !hdc) return FALSE;
+
 	    infoPtr->bLabelChanged = TRUE;
 
 	    GetWindowTextW(infoPtr->hwndEdit, buffer, sizeof(buffer)/sizeof(buffer[0]));
@@ -3654,7 +3667,6 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     HWND hwnd = infoPtr->hwnd;
     HWND hwndEdit;
     SIZE sz;
-    TREEVIEW_ITEM *editItem = hItem;
     HINSTANCE hinst = (HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE);
     HDC hdc;
     HFONT hOldFont=0;
@@ -3662,7 +3674,7 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     static const WCHAR EditW[] = {'E','d','i','t',0};
 
     TRACE("%p %p\n", hwnd, hItem);
-    if (!TREEVIEW_ValidItem(infoPtr, editItem))
+    if (!TREEVIEW_ValidItem(infoPtr, hItem))
 	return NULL;
 
     if (infoPtr->hwndEdit)
@@ -3670,11 +3682,10 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
 
     infoPtr->bLabelChanged = FALSE;
 
-    /* Make sure that edit item is selected */
-    TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, hItem, TVC_UNKNOWN);
+    /* make edit item visible */
     TREEVIEW_EnsureVisible(infoPtr, hItem, TRUE);
 
-    TREEVIEW_UpdateDispInfo(infoPtr, editItem, TVIF_TEXT);
+    TREEVIEW_UpdateDispInfo(infoPtr, hItem, TVIF_TEXT);
 
     hdc = GetDC(hwnd);
     /* Select the font to get appropriate metric dimensions */
@@ -3684,8 +3695,8 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     }
 
     /* Get string length in pixels */
-    if (editItem->pszText)
-        GetTextExtentPoint32W(hdc, editItem->pszText, strlenW(editItem->pszText),
+    if (hItem->pszText)
+        GetTextExtentPoint32W(hdc, hItem->pszText, strlenW(hItem->pszText),
                         &sz);
     else
         GetTextExtentPoint32A(hdc, "", 0, &sz);
@@ -3695,7 +3706,7 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     sz.cx += (textMetric.tmMaxCharWidth * 2);
 
     sz.cx = max(sz.cx, textMetric.tmMaxCharWidth * 3);
-    sz.cx = min(sz.cx, infoPtr->clientWidth - editItem->textOffset + 2);
+    sz.cx = min(sz.cx, infoPtr->clientWidth - hItem->textOffset + 2);
 
     if (infoPtr->hFont != 0)
     {
@@ -3703,15 +3714,18 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     }
 
     ReleaseDC(hwnd, hdc);
+
+    infoPtr->editItem = hItem;
+
     hwndEdit = CreateWindowExW(WS_EX_LEFT,
 			       EditW,
 			       0,
 			       WS_CHILD | WS_BORDER | ES_AUTOHSCROLL |
 			       WS_CLIPSIBLINGS | ES_WANTRETURN |
-			       ES_LEFT, editItem->textOffset - 2,
-			       editItem->rect.top - 1, sz.cx + 3,
-			       editItem->rect.bottom -
-			       editItem->rect.top + 3, hwnd, 0, hinst, 0);
+			       ES_LEFT, hItem->textOffset - 2,
+			       hItem->rect.top - 1, sz.cx + 3,
+			       hItem->rect.bottom -
+			       hItem->rect.top + 3, hwnd, 0, hinst, 0);
 /* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0); */
 
     infoPtr->hwndEdit = hwndEdit;
@@ -3723,23 +3737,22 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
 		   GetWindowLongW(hwndEdit, GWL_STYLE) | WS_BORDER);
 
     SendMessageW(hwndEdit, WM_SETFONT,
-		 (WPARAM)TREEVIEW_FontForItem(infoPtr, editItem), FALSE);
+		 (WPARAM)TREEVIEW_FontForItem(infoPtr, hItem), FALSE);
 
     infoPtr->wpEditOrig = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC,
 						  (DWORD_PTR)
 						  TREEVIEW_Edit_SubclassProc);
 
-    if (TREEVIEW_BeginLabelEditNotify(infoPtr, editItem))
+    if (TREEVIEW_BeginLabelEditNotify(infoPtr, hItem))
     {
 	DestroyWindow(hwndEdit);
 	infoPtr->hwndEdit = 0;
+	infoPtr->editItem = NULL;
 	return NULL;
     }
 
-    infoPtr->selectedItem = hItem;
-
-    if (editItem->pszText)
-        SetWindowTextW(hwndEdit, editItem->pszText);
+    if (hItem->pszText)
+        SetWindowTextW(hwndEdit, hItem->pszText);
 
     SetFocus(hwndEdit);
     SendMessageW(hwndEdit, EM_SETSEL, 0, -1);
@@ -3753,7 +3766,7 @@ static LRESULT
 TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
 {
     HWND hwnd = infoPtr->hwnd;
-    TREEVIEW_ITEM *editedItem = infoPtr->selectedItem;
+    TREEVIEW_ITEM *editedItem = infoPtr->editItem;
     NMTVDISPINFOW tvdi;
     BOOL bCommit;
     WCHAR tmpText[1024] = { '\0' };
@@ -3813,6 +3826,7 @@ TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
                 if(newText != tmpText) Free(newText);
                 DestroyWindow(infoPtr->hwndEdit);
                 infoPtr->hwndEdit = 0;
+                infoPtr->editItem = NULL;
                 return FALSE;
             }
             else
@@ -3829,6 +3843,7 @@ TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
     ShowWindow(infoPtr->hwndEdit, SW_HIDE);
     DestroyWindow(infoPtr->hwndEdit);
     infoPtr->hwndEdit = 0;
+    infoPtr->editItem = NULL;
     return TRUE;
 }
 
@@ -4942,13 +4957,14 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
     infoPtr->treeHeight = 0;
 
     infoPtr->uIndent = MINIMUM_INDENT;
-    infoPtr->selectedItem = 0;
-    infoPtr->focusedItem = 0;
-    infoPtr->hotItem = 0;
-    infoPtr->firstVisible = 0;
+    infoPtr->selectedItem = NULL;
+    infoPtr->focusedItem = NULL;
+    infoPtr->hotItem = NULL;
+    infoPtr->editItem = NULL;
+    infoPtr->firstVisible = NULL;
     infoPtr->maxVisibleOrder = 0;
-    infoPtr->dropItem = 0;
-    infoPtr->insertMarkItem = 0;
+    infoPtr->dropItem = NULL;
+    infoPtr->insertMarkItem = NULL;
     infoPtr->insertBeforeorAfter = 0;
     /* dragList */
 
@@ -4961,7 +4977,7 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
 
     /* hwndToolTip */
 
-    infoPtr->hwndEdit = 0;
+    infoPtr->hwndEdit = NULL;
     infoPtr->wpEditOrig = NULL;
     infoPtr->bIgnoreEditKillFocus = FALSE;
     infoPtr->bLabelChanged = FALSE;
-- 
1.5.6.5







More information about the wine-patches mailing list