⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treeview.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
    while (kill != NULL)
    {
	TREEVIEW_ITEM *next = kill->nextSibling;

	TREEVIEW_RemoveItem(infoPtr, kill);

	kill = next;
    }

    assert(parentItem->cChildren <= 0); /* I_CHILDRENCALLBACK or 0 */
    assert(parentItem->firstChild == NULL);
    assert(parentItem->lastChild == NULL);
}

static void
TREEVIEW_UnlinkItem(TREEVIEW_ITEM *item)
{
    TREEVIEW_ITEM *parentItem = item->parent;

    assert(item != NULL);
    assert(item->parent != NULL); /* i.e. it must not be the root */

    if (parentItem->firstChild == item)
	parentItem->firstChild = item->nextSibling;

    if (parentItem->lastChild == item)
	parentItem->lastChild = item->prevSibling;

    if (parentItem->firstChild == NULL && parentItem->lastChild == NULL
	&& parentItem->cChildren > 0)
	parentItem->cChildren = 0;

    if (item->prevSibling)
	item->prevSibling->nextSibling = item->nextSibling;

    if (item->nextSibling)
	item->nextSibling->prevSibling = item->prevSibling;
}

static void
TREEVIEW_RemoveItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *wineItem)
{
    TRACE("%p, (%s)\n", wineItem, TREEVIEW_ItemName(wineItem));

    TREEVIEW_SendTreeviewNotify(infoPtr, TVN_DELETEITEMW, TVC_UNKNOWN,
				TVIF_HANDLE | TVIF_PARAM, wineItem, 0);

    if (wineItem->firstChild)
	TREEVIEW_RemoveAllChildren(infoPtr, wineItem);

    TREEVIEW_UnlinkItem(wineItem);

    infoPtr->uNumItems--;

    if (wineItem->pszText && wineItem->pszText != LPSTR_TEXTCALLBACKW)
	Free(wineItem->pszText);

    TREEVIEW_FreeItem(infoPtr, wineItem);
}


/* Empty out the tree. */
static void
TREEVIEW_RemoveTree(TREEVIEW_INFO *infoPtr)
{
    TREEVIEW_RemoveAllChildren(infoPtr, infoPtr->root);

    assert(infoPtr->uNumItems == 0);	/* root isn't counted in uNumItems */
}

static LRESULT
TREEVIEW_DeleteItem(TREEVIEW_INFO *infoPtr, HTREEITEM wineItem)
{
    TREEVIEW_ITEM *newSelection = NULL;
    TREEVIEW_ITEM *newFirstVisible = NULL;
    TREEVIEW_ITEM *parent, *prev = NULL;
    BOOL visible = FALSE;

    if (wineItem == TVI_ROOT)
    {
	TRACE("TVI_ROOT\n");
	parent = infoPtr->root;
	newSelection = NULL;
	visible = TRUE;
	TREEVIEW_RemoveTree(infoPtr);
    }
    else
    {
	if (!TREEVIEW_ValidItem(infoPtr, wineItem))
	    return FALSE;

	TRACE("%p (%s)\n", wineItem, TREEVIEW_ItemName(wineItem));
	parent = wineItem->parent;

        if (ISVISIBLE(wineItem))
        {
            prev = TREEVIEW_GetPrevListItem(infoPtr, wineItem);
            visible = TRUE;
        }

	if (infoPtr->selectedItem != NULL
	    && (wineItem == infoPtr->selectedItem
		|| TREEVIEW_IsChildOf(wineItem, infoPtr->selectedItem)))
	{
	    if (wineItem->nextSibling)
		newSelection = wineItem->nextSibling;
	    else if (wineItem->parent != infoPtr->root)
		newSelection = wineItem->parent;
            else
                newSelection = wineItem->prevSibling;
            TRACE("newSelection = %p\n", newSelection);
	}

	if (infoPtr->firstVisible == wineItem)
	{
	    if (wineItem->nextSibling)
	       newFirstVisible = wineItem->nextSibling;
	    else if (wineItem->prevSibling)
	       newFirstVisible = wineItem->prevSibling;
	    else if (wineItem->parent != infoPtr->root)
	       newFirstVisible = wineItem->parent;
	       TREEVIEW_SetFirstVisible(infoPtr, NULL, TRUE);
	}
	else
	    newFirstVisible = infoPtr->firstVisible;

	TREEVIEW_RemoveItem(infoPtr, wineItem);
    }

    /* Don't change if somebody else already has (infoPtr->selectedItem is cleared by FreeItem). */
    if (!infoPtr->selectedItem && newSelection)
    {
	if (TREEVIEW_ValidItem(infoPtr, newSelection))
	    TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, newSelection, TVC_UNKNOWN);
    }

    /* Validate insertMark dropItem.
     * hotItem ??? - used for comparison only.
     */
    if (!TREEVIEW_ValidItem(infoPtr, infoPtr->insertMarkItem))
	infoPtr->insertMarkItem = 0;

    if (!TREEVIEW_ValidItem(infoPtr, infoPtr->dropItem))
	infoPtr->dropItem = 0;

    if (!TREEVIEW_ValidItem(infoPtr, newFirstVisible))
        newFirstVisible = infoPtr->root->firstChild;

    TREEVIEW_VerifyTree(infoPtr);


    if (visible)
    {
       TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE);
       TREEVIEW_RecalculateVisibleOrder(infoPtr, prev);
       TREEVIEW_UpdateScrollBars(infoPtr);
       TREEVIEW_Invalidate(infoPtr, NULL);
    }
    else if (ISVISIBLE(parent) && !TREEVIEW_HasChildren(infoPtr, parent))
    {
       /* parent lost '+/-' - update it */
       TREEVIEW_Invalidate(infoPtr, parent);
    }

    return TRUE;
}


/* Get/Set Messages *********************************************************/
static LRESULT
TREEVIEW_SetRedraw(TREEVIEW_INFO* infoPtr, WPARAM wParam, LPARAM lParam)
{
  if(wParam)
    infoPtr->bRedraw = TRUE;
  else
    infoPtr->bRedraw = FALSE;

  return 0;
}

static LRESULT
TREEVIEW_GetIndent(TREEVIEW_INFO *infoPtr)
{
    TRACE("\n");
    return infoPtr->uIndent;
}

static LRESULT
TREEVIEW_SetIndent(TREEVIEW_INFO *infoPtr, UINT newIndent)
{
    TRACE("\n");

    if (newIndent < MINIMUM_INDENT)
	newIndent = MINIMUM_INDENT;

    if (infoPtr->uIndent != newIndent)
    {
	infoPtr->uIndent = newIndent;
	TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
	TREEVIEW_UpdateScrollBars(infoPtr);
	TREEVIEW_Invalidate(infoPtr, NULL);
    }

    return 0;
}


static LRESULT
TREEVIEW_GetToolTips(TREEVIEW_INFO *infoPtr)
{
    TRACE("\n");
    return (LRESULT)infoPtr->hwndToolTip;
}

static LRESULT
TREEVIEW_SetToolTips(TREEVIEW_INFO *infoPtr, HWND hwndTT)
{
    HWND prevToolTip;

    TRACE("\n");
    prevToolTip = infoPtr->hwndToolTip;
    infoPtr->hwndToolTip = hwndTT;

    return (LRESULT)prevToolTip;
}

static LRESULT
TREEVIEW_SetUnicodeFormat(TREEVIEW_INFO *infoPtr, BOOL fUnicode)
{
    BOOL rc = infoPtr->bNtfUnicode;
    infoPtr->bNtfUnicode = fUnicode;
    return rc;
}

static LRESULT
TREEVIEW_GetUnicodeFormat(TREEVIEW_INFO *infoPtr)
{
     return infoPtr->bNtfUnicode;
}

static LRESULT
TREEVIEW_GetScrollTime(TREEVIEW_INFO *infoPtr)
{
    return infoPtr->uScrollTime;
}

static LRESULT
TREEVIEW_SetScrollTime(TREEVIEW_INFO *infoPtr, UINT uScrollTime)
{
    UINT uOldScrollTime = infoPtr->uScrollTime;

    infoPtr->uScrollTime = min(uScrollTime, 100);

    return uOldScrollTime;
}


static LRESULT
TREEVIEW_GetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam)
{
    TRACE("\n");

    switch (wParam)
    {
    case (WPARAM)TVSIL_NORMAL:
	return (LRESULT)infoPtr->himlNormal;

    case (WPARAM)TVSIL_STATE:
	return (LRESULT)infoPtr->himlState;

    default:
	return 0;
    }
}

#define TVHEIGHT_MIN         16
#define TVHEIGHT_FONT_ADJUST 3 /* 2 for focus border + 1 for margin some apps assume */

/* Compute the natural height for items. */
static UINT
TREEVIEW_NaturalHeight(TREEVIEW_INFO *infoPtr)
{
    TEXTMETRICW tm;
    HDC hdc = GetDC(0);
    HFONT hOldFont = SelectObject(hdc, infoPtr->hFont);
    UINT height;

    /* Height is the maximum of:
     * 16 (a hack because our fonts are tiny), and
     * The text height + border & margin, and
     * The size of the normal image list
     */
    GetTextMetricsW(hdc, &tm);
    SelectObject(hdc, hOldFont);
    ReleaseDC(0, hdc);

    height = TVHEIGHT_MIN;
    if (height < tm.tmHeight + tm.tmExternalLeading + TVHEIGHT_FONT_ADJUST)
        height = tm.tmHeight + tm.tmExternalLeading + TVHEIGHT_FONT_ADJUST;
    if (height < infoPtr->normalImageHeight)
        height = infoPtr->normalImageHeight;
    return height;
}

static LRESULT
TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, WPARAM wParam, HIMAGELIST himlNew)
{
    HIMAGELIST himlOld = 0;
    int oldWidth  = infoPtr->normalImageWidth;
    int oldHeight = infoPtr->normalImageHeight;


    TRACE("%x,%p\n", wParam, himlNew);

    switch (wParam)
    {
    case (WPARAM)TVSIL_NORMAL:
	himlOld = infoPtr->himlNormal;
	infoPtr->himlNormal = himlNew;

	if (himlNew != NULL)
	    ImageList_GetIconSize(himlNew, &infoPtr->normalImageWidth,
				  &infoPtr->normalImageHeight);
	else
	{
	    infoPtr->normalImageWidth = 0;
	    infoPtr->normalImageHeight = 0;
	}

	break;

    case (WPARAM)TVSIL_STATE:
	himlOld = infoPtr->himlState;
	infoPtr->himlState = himlNew;

	if (himlNew != NULL)
	    ImageList_GetIconSize(himlNew, &infoPtr->stateImageWidth,
				  &infoPtr->stateImageHeight);
	else
	{
	    infoPtr->stateImageWidth = 0;
	    infoPtr->stateImageHeight = 0;
	}

	break;
    }

    if (oldWidth != infoPtr->normalImageWidth ||
        oldHeight != infoPtr->normalImageHeight)
    {
        BOOL bRecalcVisible = FALSE;

        if (oldHeight != infoPtr->normalImageHeight &&
            !infoPtr->bHeightSet)
        {
            infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
            bRecalcVisible = TRUE;
        }

        if (infoPtr->normalImageWidth > MINIMUM_INDENT &&
            infoPtr->normalImageWidth != infoPtr->uIndent)
        {
            infoPtr->uIndent = infoPtr->normalImageWidth;
            bRecalcVisible = TRUE;
        }

        if (bRecalcVisible)
            TREEVIEW_RecalculateVisibleOrder(infoPtr, NULL);

       TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
       TREEVIEW_UpdateScrollBars(infoPtr);
    }

    TREEVIEW_Invalidate(infoPtr, NULL);

    return (LRESULT)himlOld;
}

static LRESULT
TREEVIEW_SetItemHeight(TREEVIEW_INFO *infoPtr, INT newHeight)
{
    INT prevHeight = infoPtr->uItemHeight;

    TRACE("%d\n", newHeight);
    if (newHeight == -1)
    {
	infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
	infoPtr->bHeightSet = FALSE;
    }
    else
    {
	infoPtr->uItemHeight = newHeight;
	infoPtr->bHeightSet = TRUE;
    }

    /* Round down, unless we support odd ("non even") heights. */
    if (!(infoPtr->dwStyle) & TVS_NONEVENHEIGHT)
	infoPtr->uItemHeight &= ~1;

    if (infoPtr->uItemHeight != prevHeight)
    {
	TREEVIEW_RecalculateVisibleOrder(infoPtr, NULL);
	TREEVIEW_UpdateScrollBars(infoPtr);
	TREEVIEW_Invalidate(infoPtr, NULL);
    }

    return prevHeight;
}

static LRESULT
TREEVIEW_GetItemHeight(TREEVIEW_INFO *infoPtr)
{
    TRACE("\n");
    return infoPtr->uItemHeight;
}


static LRESULT
TREEVIEW_GetFont(TREEVIEW_INFO *infoPtr)
{
    TRACE("%p\n", infoPtr->hFont);
    return (LRESULT)infoPtr->hFont;
}


static INT CALLBACK
TREEVIEW_ResetTextWidth(LPVOID pItem, LPVOID unused)
{
    (void)unused;

    ((TREEVIEW_ITEM *)pItem)->textWidth = 0;

    return 1;
}

static LRESULT
TREEVIEW_SetFont(TREEVIEW_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
{
    UINT uHeight = infoPtr->uItemHeight;

    TRACE("%p %i\n", hFont, bRedraw);

    infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont;

    DeleteObject(infoPtr->hBoldFont);
    infoPtr->hBoldFont = TREEVIEW_CreateBoldFont(infoPtr->hFont);
    infoPtr->hUnderlineFont = TREEVIEW_CreateUnderlineFont(infoPtr->hFont);

    if (!infoPtr->bHeightSet)
	infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);

    if (uHeight != infoPtr->uItemHeight)
       TREEVIEW_RecalculateVisibleOrder(infoPtr, NULL);

    DPA_EnumCallback(infoPtr->items, TREEVIEW_ResetTextWidth, 0);

    TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
    TREEVIEW_UpdateScrollBars(infoPtr);

    if (bRedraw)
	TREEVIEW_Invalidate(infoPtr, NULL);

    return 0;
}


static LRESULT
TREEVIEW_GetLineColor(TREEVIEW_INFO *infoPtr)
{
    TRACE("\n");
    return (LRESULT)infoPtr->clrLine;
}

static LRESULT
TREEVIEW_SetLineColor(TREEVIEW_INFO *infoPtr, COLORREF color)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -