53#define NONAMELESSUNION
64#include "wine/unicode.h"
178#define TV_HSCROLL 0x01
179#define TV_VSCROLL 0x02
181#define TV_LDRAGGING 0x08
183#define TV_RDRAGGING 0x20
187#define TV_EDIT_TIMER 2
188#define TV_EDIT_TIMER_SET 2
190#define TEXT_CALLBACK_SIZE 260
192#define TREEVIEW_LEFT_MARGIN 8
194#define MINIMUM_INDENT 19
196#define CALLBACK_MASK_ALL (TVIF_TEXT|TVIF_CHILDREN|TVIF_IMAGE|TVIF_SELECTEDIMAGE)
198#define STATEIMAGEINDEX(x) (((x) >> 12) & 0x0f)
199#define OVERLAYIMAGEINDEX(x) (((x) >> 8) & 0x0f)
200#define ISVISIBLE(x) ((x)->visibleOrder >= 0)
202#define GETLINECOLOR(x) ((x) == CLR_DEFAULT ? comctl32_color.clrGrayText : (x))
203#define GETBKCOLOR(x) ((x) == CLR_NONE ? comctl32_color.clrWindow : (x))
204#define GETTXTCOLOR(x) ((x) == CLR_NONE ? comctl32_color.clrWindowText : (x))
205#define GETINSCOLOR(x) ((x) == CLR_DEFAULT ? comctl32_color.clrBtnText : (x))
331 return infoPtr->
hFont;
338 if (
item ==
NULL)
return "<null item>";
340 if (
item->pszText ==
NULL)
return "<null>";
383 while (
item->lastChild)
579 TRACE(
"code:%d action:0x%x olditem:%p newitem:%p\n",
609 TRACE(
"code:%d dragitem:%p\n",
code, dragItem);
631 TRACE(
"drawstage:0x%x hdc:%p\n", dwDrawStage,
hdc);
633 nmcd = &nmcdhdr.
nmcd;
659 dwDrawStage =
CDDS_ITEM | uItemDrawState;
669 nmcd = &nmcdhdr->
nmcd;
678 TRACE(
"drawstage:0x%x hdc:%p item:%lx, itemstate:0x%x, lItemlParam:0x%lx\n",
692 &tvdi.
item, editItem);
708 TRACE(
"mask=0x%x, callbackmask=0x%x\n",
mask,
item->callbackMask);
711 if (
mask == 0)
return;
745 TRACE(
"returned str %s, len=%d, buflen=%d\n",
750 item->pszText = newText;
763 TRACE(
"returned wstr %s, len=%d\n",
768 item->pszText = newText;
786 TRACE(
"same buffer str %s, len=%d, buflen=%d\n",
792 item->pszText = newText;
816 item->state &= ~callback.item.stateMask;
822 item->callbackMask &= ~callback.item.mask;
846 TRACE(
"(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand);
875 item->imageOffset =
item->stateOffset
974 root->state &= ~TVIS_EXPANDED;
981 for (;
root != sibling;
989 if (
root->textWidth == 0)
1062 if (sibling !=
NULL)
1077 if (
parent->firstChild == sibling)
1078 parent->firstChild = newItem;
1081 parent->lastChild = newItem;
1094 if (sibling !=
NULL)
1109 if (
parent->lastChild == sibling)
1110 parent->lastChild = newItem;
1113 parent->firstChild = newItem;
1120 UINT callbackClear = 0;
1121 UINT callbackSet = 0;
1127 item->textWidth = 0;
1143 item->pszText = newText;
1158 TRACE(
"setting callback, item %p\n",
item);
1212 TRACE(
"prevstate 0x%x, state 0x%x, mask 0x%x\n",
item->state, tvItem->
state,
1214 item->state &= ~tvItem->stateMask;
1218 if (tvItem->
mask & TVIF_STATEEX)
1223 item->callbackMask |= callbackSet;
1224 item->callbackMask &= ~callbackClear;
1240 parentItem = infoPtr->
root;
1248 WARN(
"invalid parent %p\n", parentItem);
1265 insertAfter->
parent != parentItem)
1267 WARN(
"invalid insert after %p\n", insertAfter);
1272 TRACE(
"parent %p position %p: %s\n", parentItem, insertAfter,
1279 if (newItem ==
NULL)
1282 newItem->
parent = parentItem;
1322 bTextUpdated =
TRUE;
1326 while (aChild !=
NULL)
1337 aChild == originalFirst)
1339 bItemInserted =
TRUE;
1344 previousChild = aChild;
1361 bItemInserted =
TRUE;
1370 if ((!bItemInserted) && (aChild ==
NULL))
1378 TRACE(
"new item %p; parent %p, mask 0x%x\n", newItem,
1399 if (parentItem == infoPtr->
root ||
1417 for (
item = newItem;
1444 while (kill !=
NULL)
1466 parentItem =
item->parent;
1478 if (
item->prevSibling)
1479 item->prevSibling->nextSibling =
item->nextSibling;
1481 if (
item->nextSibling)
1482 item->nextSibling->prevSibling =
item->prevSibling;
1490 if (
item->firstChild)
1526 TRACE(
"TVI_ROOT\n");
1528 newSelection =
NULL;
1550 if (
item->nextSibling)
1551 newSelection =
item->nextSibling;
1552 else if (
item->parent != infoPtr->
root)
1553 newSelection =
item->parent;
1555 newSelection =
item->prevSibling;
1556 TRACE(
"newSelection = %p\n", newSelection);
1562 if (
item->nextSibling)
1563 newFirstVisible =
item->nextSibling;
1564 else if (
item->prevSibling)
1565 newFirstVisible =
item->prevSibling;
1566 else if (
item->parent != infoPtr->
root)
1567 newFirstVisible =
item->parent;
1649 if (infoPtr->
uIndent != newIndent)
1707 return uOldScrollTime;
1729#define TVHEIGHT_MIN 16
1730#define TVHEIGHT_FONT_ADJUST 3
1753 if (height < infoPtr->normalImageHeight)
1805 ERR(
"unknown imagelist type %u\n",
type);
1817 bRecalcVisible =
TRUE;
1824 bRecalcVisible =
TRUE;
1844 TRACE(
"new=%d, old=%d\n", newHeight, prevHeight);
1845 if (newHeight == -1)
1852 if (newHeight == 0) newHeight = 1;
1967 if (infoPtr->
clrText != prevColor)
1987 infoPtr->
clrBk = newColor;
1989 if (newColor != prevColor)
2063 if (!
item->textWidth)
2070 *lpRect =
item->rect;
2099 infoPtr =
item->infoPtr;
2100 TRACE(
"got item from different tree %p, called from %p\n",
item->infoPtr, infoPtr);
2107 if (!valid_item)
return FALSE;
2115 FIXME(
"I_CHILDRENCALLBACK not supported\n");
2152 FIXME(
" GetItem called with LPSTR_TEXTCALLBACK\n");
2164 FIXME(
" GetItem called with LPSTR_TEXTCALLBACK\n");
2174 if (tvItem->
mask & TVIF_STATEEX)
2176 FIXME(
"Extended item state not supported, returning 0.\n");
2180 TRACE(
"item <%p>, txt %p, img %d, mask 0x%x\n",
2203 originalItem = *
item;
2291 TRACE(
"flags:0x%x, returns %p\n",
which, retval);
2303 retval =
item->nextSibling;
2306 retval =
item->prevSibling;
2312 retval =
item->firstChild;
2342 static const unsigned int state_table[] = { 0, 2, 1 };
2348 item->state &= ~TVIS_STATEIMAGEMASK;
2368 LONG centerx, centery;
2375 if (!lar &&
item->iLevel == 0)
2381 centerx = (
item->linesOffset +
item->stateOffset) / 2;
2382 centery = (
item->rect.top +
item->rect.bottom) / 2;
2386 HPEN hOldPen, hNewPen;
2398 centery = (centery + 2) & ~1;
2403 if (
item->prevSibling ||
item->parent != infoPtr->
root)
2409 if (
item->nextSibling)
2419 int pcenterx = (
parent->linesOffset +
parent->stateOffset) / 2;
2442 if (
item->cChildren)
2448 glyphRect.
left =
item->linesOffset;
2460 LONG plussize = (rectsize + 1) * 3 / 4;
2465 Rectangle(
hdc, centerx - rectsize - 1, centery - rectsize - 1,
2466 centerx + rectsize + 2, centery + rectsize + 2);
2478 LineTo(
hdc, centerx + plussize, centery);
2484 LineTo(
hdc, centerx, centery + plussize);
2490 centerx + plussize, centery + 2);
2496 centerx + 2, centery + plussize);
2516 COLORREF oldTextColor, oldTextBkColor;
2560 if (!
item->textWidth)
2569 TRACE(
"prepaint:cditem-app returns 0x%x\n", cditem);
2594 centery = (
item->rect.top +
item->rect.bottom) / 2;
2622 imageIndex =
item->iSelectedImage;
2627 imageIndex =
item->iExpandedImage;
2632 imageIndex =
item->iImage;
2667 TRACE(
"drawing text %s at (%s)\n",
2693 TRACE(
"item:%d,mark:%p\n",
2699 HPEN hNewPen, hOldPen;
2736 TRACE(
"postpaint:cditem-app returns 0x%x\n", cditem);
2888 TRACE(
"%p\n", infoPtr);
2905 TRACE(
"empty window\n");
2973 hdcScreen =
GetDC(0);
2993 TRACE(
"checkbox index %d\n", nIndex);
3008 item->state &= ~TVIS_STATEIMAGEMASK;
3026 TRACE(
"(%p %p)\n", infoPtr, hdc_ref);
3110 else if(
first->pszText)
3179 ERR(
"invalid item hParent=%p\n",
parent);
3186 lpCompare = (
LPARAM)pSort;
3191 lpCompare = (
LPARAM)infoPtr;
3207 if (sortList ==
NULL)
3211 DPA_Sort(sortList, pfnCompare, lpCompare);
3220 item->nextSibling = nextItem;
3223 if (prevItem ==
NULL)
3232 item->prevSibling = prevItem;
3264 if (
item->visibleOrder == visOrder)
3332 BOOL bSetSelection, bSetFirstVisible;
3334 LONG scrollDist = 0;
3350 item->state &= ~TVIS_EXPANDED;
3352 if (wasExpanded && bUser)
3364 if (tmpItem->nextSibling)
3369 tmpItem = tmpItem->
parent;
3373 scrollDist = nextItem->
rect.
top;
3375 if (bRemoveChildren)
3377 INT old_cChildren =
item->cChildren;
3378 TRACE(
"TVE_COLLAPSERESET\n");
3379 item->state &= ~TVIS_EXPANDEDONCE;
3381 item->cChildren = old_cChildren;
3386 if (
item->firstChild)
3392 for (
i =
item->firstChild;
i != sibling;
3395 i->visibleOrder = -1;
3402 scrollDist = -(scrollDist - nextItem->
rect.
top);
3415 scrollRect.
left = 0;
3427 scrollRect.
top =
item->rect.top;
3443 LONG orgNextTop = 0;
3446 BOOL sendsNotifications;
3448 TRACE(
"(%p, %p, partial=%d, %d)\n", infoPtr,
item, partial,
user);
3461 tmpItem = tmpItem->
parent;
3465 orgNextTop = nextItem->
rect.
top;
3469 sendsNotifications =
user || ((
item->cChildren != 0) &&
3471 if (sendsNotifications)
3475 TRACE(
" TVN_ITEMEXPANDING returned TRUE, exiting...\n");
3479 if (!
item->firstChild)
3485 FIXME(
"TVE_EXPANDPARTIAL not implemented\n");
3493 scrollRect.
left = 0;
3498 scrollDist = nextItem->
rect.
top - orgNextTop;
3499 scrollRect.
top = orgNextTop;
3505 scrollRect.
top =
item->rect.top;
3514 int nChildren =
item->lastChild->visibleOrder
3515 -
item->firstChild->visibleOrder + 1;
3517 int visible_pos =
item->visibleOrder
3522 if (visible_pos > 0 && nChildren > rows_below)
3524 int scroll = nChildren - rows_below;
3526 if (scroll > visible_pos)
3527 scroll = visible_pos;
3542 if (sendsNotifications) {
3621 TRACE(
"For (%s) item:%d, flags 0x%x, state:%d\n",
3660 && row < item->visibleOrder +
item->iIntegral)
3685 else if (
x >
rect.right)
3694 else if (
y >
rect.bottom)
3712 if (!
item->textWidth)
3715 if (
x >=
item->textOffset +
item->textWidth)
3719 else if (
x >=
item->textOffset)
3723 else if (
x >=
item->imageOffset)
3727 else if (
x >=
item->stateOffset)
3764 TRACE(
"WM_PAINT start\n");
3767 TRACE(
"WM_PAINT done\n");
3922 if (infoPtr->
hFont != 0)
3941 if (infoPtr->
hFont != 0)
4000 WCHAR tmpText[1024] = {
'\0' };
4001 WCHAR *newText = tmpText;
4018 if (iLength >= 1023)
4020 ERR(
"Insufficient space to retrieve new item label\n");
4035 if (!bCancel && bCommit)
4050 ERR(
"OutOfMemory, cannot allocate space for label\n");
4051 if (newText != tmpText)
heap_free(newText);
4065 if (newText != tmpText)
heap_free(newText);
4080 ERR(
"got unknown timer\n");
4085 infoPtr->
Timer &= ~TV_EDIT_TIMER_SET;
4107 r.top =
pt.y - cyDrag;
4108 r.left =
pt.x - cxDrag;
4109 r.bottom =
pt.y + cyDrag;
4110 r.right =
pt.x + cxDrag;