comctl32/treeview: Use separate pointer for currently edited item.

This commit is contained in:
Nikolay Sivov 2009-08-07 00:10:30 +04:00 committed by Alexandre Julliard
parent 99ec95e474
commit 83c9cdb797
2 changed files with 75 additions and 30 deletions

View File

@ -769,6 +769,7 @@ static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
} }
return 0; return 0;
} }
case TVN_ENDLABELEDIT: return TRUE;
} }
} }
return 0; return 0;
@ -862,21 +863,49 @@ static void test_itemedit(void)
{ {
DWORD r; DWORD r;
HWND edit; HWND edit;
TVITEMA item;
CHAR buff[2];
hTree = create_treeview_control(); hTree = create_treeview_control();
fill_tree(hTree); 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 */ /* trigger edit */
edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot); edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot);
ok(IsWindow(edit), "Expected valid handle\n"); ok(IsWindow(edit), "Expected valid handle\n");
/* item shouldn't be selected automatically after TVM_EDITLABEL */ /* item shouldn't be selected automatically after TVM_EDITLABEL */
r = SendMessage(hTree, TVM_GETITEMSTATE, (WPARAM)hRoot, TVIS_SELECTED); 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); r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit);
expect(0, r); expect(0, r);
ok(!IsWindow(edit), "Expected edit control to be destroyed\n"); 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); DestroyWindow(hTree);
} }

View File

@ -119,6 +119,7 @@ typedef struct tagTREEVIEW_INFO
HTREEITEM selectedItem; /* handle to selected item or 0 if none */ HTREEITEM selectedItem; /* handle to selected item or 0 if none */
HTREEITEM hotItem; /* handle currently under cursor, 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 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 */ HTREEITEM firstVisible; /* handle to first visible item */
LONG maxVisibleOrder; LONG maxVisibleOrder;
@ -3546,6 +3547,14 @@ TREEVIEW_Edit_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return TRUE; return TRUE;
break; 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: case WM_GETDLGCODE:
return DLGC_WANTARROWS | DLGC_WANTALLKEYS; return DLGC_WANTARROWS | DLGC_WANTALLKEYS;
@ -3581,7 +3590,7 @@ TREEVIEW_Edit_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
static LRESULT static LRESULT
TREEVIEW_Command(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam) 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)) switch (HIWORD(wParam))
{ {
@ -3591,11 +3600,15 @@ TREEVIEW_Command(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
* Adjust the edit window size * Adjust the edit window size
*/ */
WCHAR buffer[1024]; WCHAR buffer[1024];
TREEVIEW_ITEM *editItem = infoPtr->selectedItem; TREEVIEW_ITEM *editItem = infoPtr->editItem;
HDC hdc = GetDC(infoPtr->hwndEdit); HDC hdc = GetDC(infoPtr->hwndEdit);
SIZE sz; SIZE sz;
HFONT hFont, hOldFont = 0; HFONT hFont, hOldFont = 0;
TRACE("edit=%p\n", infoPtr->hwndEdit);
if (!IsWindow(infoPtr->hwndEdit) || !hdc) return FALSE;
infoPtr->bLabelChanged = TRUE; infoPtr->bLabelChanged = TRUE;
GetWindowTextW(infoPtr->hwndEdit, buffer, sizeof(buffer)/sizeof(buffer[0])); 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 hwnd = infoPtr->hwnd;
HWND hwndEdit; HWND hwndEdit;
SIZE sz; SIZE sz;
TREEVIEW_ITEM *editItem = hItem;
HINSTANCE hinst = (HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE); HINSTANCE hinst = (HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE);
HDC hdc; HDC hdc;
HFONT hOldFont=0; HFONT hOldFont=0;
@ -3662,7 +3674,7 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
static const WCHAR EditW[] = {'E','d','i','t',0}; static const WCHAR EditW[] = {'E','d','i','t',0};
TRACE("%p %p\n", hwnd, hItem); TRACE("%p %p\n", hwnd, hItem);
if (!TREEVIEW_ValidItem(infoPtr, editItem)) if (!TREEVIEW_ValidItem(infoPtr, hItem))
return NULL; return NULL;
if (infoPtr->hwndEdit) if (infoPtr->hwndEdit)
@ -3670,11 +3682,10 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
infoPtr->bLabelChanged = FALSE; infoPtr->bLabelChanged = FALSE;
/* Make sure that edit item is selected */ /* make edit item visible */
TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, hItem, TVC_UNKNOWN);
TREEVIEW_EnsureVisible(infoPtr, hItem, TRUE); TREEVIEW_EnsureVisible(infoPtr, hItem, TRUE);
TREEVIEW_UpdateDispInfo(infoPtr, editItem, TVIF_TEXT); TREEVIEW_UpdateDispInfo(infoPtr, hItem, TVIF_TEXT);
hdc = GetDC(hwnd); hdc = GetDC(hwnd);
/* Select the font to get appropriate metric dimensions */ /* Select the font to get appropriate metric dimensions */
@ -3684,8 +3695,8 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
} }
/* Get string length in pixels */ /* Get string length in pixels */
if (editItem->pszText) if (hItem->pszText)
GetTextExtentPoint32W(hdc, editItem->pszText, strlenW(editItem->pszText), GetTextExtentPoint32W(hdc, hItem->pszText, strlenW(hItem->pszText),
&sz); &sz);
else else
GetTextExtentPoint32A(hdc, "", 0, &sz); GetTextExtentPoint32A(hdc, "", 0, &sz);
@ -3695,7 +3706,7 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
sz.cx += (textMetric.tmMaxCharWidth * 2); sz.cx += (textMetric.tmMaxCharWidth * 2);
sz.cx = max(sz.cx, textMetric.tmMaxCharWidth * 3); 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) if (infoPtr->hFont != 0)
{ {
@ -3703,15 +3714,18 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
} }
ReleaseDC(hwnd, hdc); ReleaseDC(hwnd, hdc);
infoPtr->editItem = hItem;
hwndEdit = CreateWindowExW(WS_EX_LEFT, hwndEdit = CreateWindowExW(WS_EX_LEFT,
EditW, EditW,
0, 0,
WS_CHILD | WS_BORDER | ES_AUTOHSCROLL | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL |
WS_CLIPSIBLINGS | ES_WANTRETURN | WS_CLIPSIBLINGS | ES_WANTRETURN |
ES_LEFT, editItem->textOffset - 2, ES_LEFT, hItem->textOffset - 2,
editItem->rect.top - 1, sz.cx + 3, hItem->rect.top - 1, sz.cx + 3,
editItem->rect.bottom - hItem->rect.bottom -
editItem->rect.top + 3, hwnd, 0, hinst, 0); hItem->rect.top + 3, hwnd, 0, hinst, 0);
/* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0); */ /* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0); */
infoPtr->hwndEdit = hwndEdit; infoPtr->hwndEdit = hwndEdit;
@ -3723,23 +3737,22 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
GetWindowLongW(hwndEdit, GWL_STYLE) | WS_BORDER); GetWindowLongW(hwndEdit, GWL_STYLE) | WS_BORDER);
SendMessageW(hwndEdit, WM_SETFONT, SendMessageW(hwndEdit, WM_SETFONT,
(WPARAM)TREEVIEW_FontForItem(infoPtr, editItem), FALSE); (WPARAM)TREEVIEW_FontForItem(infoPtr, hItem), FALSE);
infoPtr->wpEditOrig = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC, infoPtr->wpEditOrig = (WNDPROC)SetWindowLongPtrW(hwndEdit, GWLP_WNDPROC,
(DWORD_PTR) (DWORD_PTR)
TREEVIEW_Edit_SubclassProc); TREEVIEW_Edit_SubclassProc);
if (TREEVIEW_BeginLabelEditNotify(infoPtr, editItem)) if (TREEVIEW_BeginLabelEditNotify(infoPtr, hItem))
{ {
DestroyWindow(hwndEdit); DestroyWindow(hwndEdit);
infoPtr->hwndEdit = 0; infoPtr->hwndEdit = 0;
infoPtr->editItem = NULL;
return NULL; return NULL;
} }
infoPtr->selectedItem = hItem; if (hItem->pszText)
SetWindowTextW(hwndEdit, hItem->pszText);
if (editItem->pszText)
SetWindowTextW(hwndEdit, editItem->pszText);
SetFocus(hwndEdit); SetFocus(hwndEdit);
SendMessageW(hwndEdit, EM_SETSEL, 0, -1); SendMessageW(hwndEdit, EM_SETSEL, 0, -1);
@ -3753,7 +3766,7 @@ static LRESULT
TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel) TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
{ {
HWND hwnd = infoPtr->hwnd; HWND hwnd = infoPtr->hwnd;
TREEVIEW_ITEM *editedItem = infoPtr->selectedItem; TREEVIEW_ITEM *editedItem = infoPtr->editItem;
NMTVDISPINFOW tvdi; NMTVDISPINFOW tvdi;
BOOL bCommit; BOOL bCommit;
WCHAR tmpText[1024] = { '\0' }; WCHAR tmpText[1024] = { '\0' };
@ -3813,6 +3826,7 @@ TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
if(newText != tmpText) Free(newText); if(newText != tmpText) Free(newText);
DestroyWindow(infoPtr->hwndEdit); DestroyWindow(infoPtr->hwndEdit);
infoPtr->hwndEdit = 0; infoPtr->hwndEdit = 0;
infoPtr->editItem = NULL;
return FALSE; return FALSE;
} }
else else
@ -3829,6 +3843,7 @@ TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
ShowWindow(infoPtr->hwndEdit, SW_HIDE); ShowWindow(infoPtr->hwndEdit, SW_HIDE);
DestroyWindow(infoPtr->hwndEdit); DestroyWindow(infoPtr->hwndEdit);
infoPtr->hwndEdit = 0; infoPtr->hwndEdit = 0;
infoPtr->editItem = NULL;
return TRUE; return TRUE;
} }
@ -4942,13 +4957,14 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
infoPtr->treeHeight = 0; infoPtr->treeHeight = 0;
infoPtr->uIndent = MINIMUM_INDENT; infoPtr->uIndent = MINIMUM_INDENT;
infoPtr->selectedItem = 0; infoPtr->selectedItem = NULL;
infoPtr->focusedItem = 0; infoPtr->focusedItem = NULL;
infoPtr->hotItem = 0; infoPtr->hotItem = NULL;
infoPtr->firstVisible = 0; infoPtr->editItem = NULL;
infoPtr->firstVisible = NULL;
infoPtr->maxVisibleOrder = 0; infoPtr->maxVisibleOrder = 0;
infoPtr->dropItem = 0; infoPtr->dropItem = NULL;
infoPtr->insertMarkItem = 0; infoPtr->insertMarkItem = NULL;
infoPtr->insertBeforeorAfter = 0; infoPtr->insertBeforeorAfter = 0;
/* dragList */ /* dragList */
@ -4961,7 +4977,7 @@ TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
/* hwndToolTip */ /* hwndToolTip */
infoPtr->hwndEdit = 0; infoPtr->hwndEdit = NULL;
infoPtr->wpEditOrig = NULL; infoPtr->wpEditOrig = NULL;
infoPtr->bIgnoreEditKillFocus = FALSE; infoPtr->bIgnoreEditKillFocus = FALSE;
infoPtr->bLabelChanged = FALSE; infoPtr->bLabelChanged = FALSE;