diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c index 252949ff8bb..7c86450a902 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,21 +863,49 @@ 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 84a8c304792..44bb84192ef 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;