treectrlhelper.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 739 行 · 第 1/2 页
CPP
739 行
m_tree.SetItemState(hti, nCheckState, TVIS_STATEIMAGEMASK);
}
void CTreeCtrlHelper::SetItemChecked(HTREEITEM hti, BOOL bChecked)
{
SetItemChecked(hti, bChecked ? TCHC_CHECKED : TCHC_UNCHECKED);
}
TCH_CHECK CTreeCtrlHelper::GetItemCheckState(HTREEITEM hti)
{
int nCheckState = m_tree.GetItemState(hti, TVIS_STATEIMAGEMASK);
return (TCH_CHECK)((nCheckState >> 12) - 1);
}
CString CTreeCtrlHelper::GetItemPath(HTREEITEM hti, int nMaxElementLen) const
{
CString sPath;
HTREEITEM htiParent = m_tree.GetParentItem(hti);
while (htiParent)
{
CString sParent = m_tree.GetItemText(htiParent);
if (nMaxElementLen != -1 && sParent.GetLength() > nMaxElementLen)
sParent = sParent.Left(nMaxElementLen) + "...";
sParent.TrimLeft();
sParent.TrimRight();
sPath = sParent + " / "+ sPath;
htiParent = m_tree.GetParentItem(htiParent);
}
return sPath;
}
HTREEITEM CTreeCtrlHelper::GetTopLevelParentItem(HTREEITEM hti) const
{
if (!hti)
return NULL;
HTREEITEM htiParent = m_tree.GetParentItem(hti);
while (htiParent)
{
hti = htiParent; // cache this because the next parent might be the root
htiParent = m_tree.GetParentItem(hti);
}
return hti; // return the one before the root
}
HTREEITEM CTreeCtrlHelper::GetNextTopLevelItem(HTREEITEM hti, BOOL bNext) const
{
HTREEITEM htiParent = GetTopLevelParentItem(hti);
HTREEITEM htiGoto = NULL;
if (htiParent)
{
if (bNext)
htiGoto = m_tree.GetNextItem(htiParent, TVGN_NEXT);
else
{
// if the item is not htiParent then jump to it first
if (hti != htiParent)
htiGoto = htiParent;
else
htiGoto = m_tree.GetNextItem(htiParent, TVGN_PREVIOUS);
if (htiGoto == hti)
htiGoto = NULL; // nowhere to go
}
}
return htiGoto;
}
int CTreeCtrlHelper::GetDistanceToEdge(HTREEITEM htiFrom, TCH_EDGE nToEdge)
{
CRect rClient, rItem;
if (m_tree.GetItemRect(htiFrom, rItem, FALSE))
{
m_tree.GetClientRect(rClient);
int nItemHeight = m_tree.GetItemHeight();
switch (nToEdge)
{
case TCHE_TOP:
return (rItem.top - rClient.top) / nItemHeight;
case TCHE_BOTTOM:
return (rClient.bottom - rItem.bottom) / nItemHeight;
}
}
return 0;
}
void CTreeCtrlHelper::SetMinDistanceToEdge(HTREEITEM htiFrom, TCH_EDGE nToEdge, int nItems)
{
switch (nToEdge)
{
case TCHE_BOTTOM:
{
int nBorder = GetDistanceToEdge(htiFrom, TCHE_BOTTOM);
while (nBorder < nItems)
{
m_tree.SendMessage(WM_VSCROLL, SB_LINEDOWN);
nBorder++;
}
}
break;
case TCHE_TOP:
{
int nBorder = GetDistanceToEdge(htiFrom, TCHE_TOP);
while (nBorder < nItems)
{
m_tree.SendMessage(WM_VSCROLL, SB_LINEUP);
nBorder++;
}
}
break;
}
}
HTREEITEM CTreeCtrlHelper::GetNextPageVisibleItem(HTREEITEM hti) const
{
// if we're the last visible item then its just the page count
// figure out how many items to step
HTREEITEM htiNext = m_tree.GetNextVisibleItem(hti);
if (!htiNext || !IsFullyVisible(htiNext))
{
int nCount = m_tree.GetVisibleCount();
// keep going until we get NULL and then return
// the previous item
while (hti && nCount--)
{
hti = GetNextVisibleItem(hti);
if (hti)
htiNext = hti;
}
}
else // we keep going until we're the last visible item
{
// keep going until we get NULL and then return
// the previous item
while (hti)
{
hti = m_tree.GetNextVisibleItem(hti);
if (hti && IsFullyVisible(hti))
htiNext = hti;
else
hti = NULL;
}
}
return htiNext;
}
HTREEITEM CTreeCtrlHelper::GetPrevPageVisibleItem(HTREEITEM hti) const
{
// if we're the first visible item then its just the page count
// figure out how many items to step
HTREEITEM htiPrev = m_tree.GetPrevVisibleItem(hti);
if (!htiPrev || !IsFullyVisible(htiPrev))
{
int nCount = m_tree.GetVisibleCount();
// keep going until we get NULL and then return
// the previous item
while (hti && nCount--)
{
hti = GetPrevVisibleItem(hti);
if (hti)
htiPrev = hti;
}
}
else // we keep going until we're the first visible item
{
// keep going until we get NULL and then return
// the previous item
while (hti)
{
hti = m_tree.GetPrevVisibleItem(hti);
if (hti && IsFullyVisible(hti))
htiPrev = hti;
else
hti = NULL;
}
}
return htiPrev;
}
HTREEITEM CTreeCtrlHelper::GetNextVisibleItem(HTREEITEM hti, BOOL bAllowChildren) const
{
HTREEITEM htiNext = NULL;
// try our first child if we're expanded
if (bAllowChildren && m_tree.ItemHasChildren(hti) && IsItemExpanded(hti))
htiNext = m_tree.GetChildItem(hti);
else
{
// try next sibling
htiNext = m_tree.GetNextItem(hti, TVGN_NEXT);
// finally look up the parent chain as far as we can
if (!htiNext)
{
HTREEITEM htiParent = hti;
while (htiParent && !htiNext)
{
htiParent = m_tree.GetParentItem(htiParent);
if (htiParent)
htiNext = m_tree.GetNextItem(htiParent, TVGN_NEXT);
}
}
}
return htiNext == TVI_ROOT ? NULL : htiNext;
}
HTREEITEM CTreeCtrlHelper::GetPrevVisibleItem(HTREEITEM hti, BOOL bAllowChildren) const
{
// try our prior sibling
HTREEITEM htiPrev = m_tree.GetNextItem(hti, TVGN_PREVIOUS);
// if we have one then first try its last child
if (htiPrev)
{
if (bAllowChildren && m_tree.ItemHasChildren(htiPrev) && IsItemExpanded(htiPrev))
{
HTREEITEM htiChild = m_tree.GetChildItem(htiPrev);
while (htiChild)
{
htiPrev = htiChild;
htiChild = m_tree.GetNextItem(htiChild, TVGN_NEXT);
}
}
// else we settle for htiPrev as-is
}
else // get parent
htiPrev = m_tree.GetParentItem(hti);
return htiPrev == TVI_ROOT ? NULL : htiPrev;
}
BOOL CTreeCtrlHelper::IsFullyVisible(HTREEITEM hti) const
{
CRect rClient, rItem, rIntersect;
m_tree.GetClientRect(rClient);
m_tree.GetItemRect(hti, rItem, FALSE);
return (rIntersect.IntersectRect(rItem, rClient) && rIntersect == rItem);
}
int CTreeCtrlHelper::FindItem(HTREEITEM htiFind, HTREEITEM htiStart)
{
// try same first
if (htiFind == htiStart)
return 0;
// then try up
HTREEITEM htiPrev = GetPrevVisibleItem(htiStart);
while (htiPrev)
{
if (htiPrev == htiFind)
return -1;
htiPrev = GetPrevVisibleItem(htiPrev);
}
// else try down
HTREEITEM htiNext = GetNextVisibleItem(htiStart);
while (htiNext)
{
if (htiNext == htiFind)
return 1;
htiNext = GetNextVisibleItem(htiNext);
}
// else
return 0;
}
BOOL CTreeCtrlHelper::IsItemBold(HTREEITEM hti)
{
return (m_tree.GetItemState(hti, TVIS_BOLD) & TVIS_BOLD);
}
void CTreeCtrlHelper::SetItemBold(HTREEITEM hti, BOOL bBold)
{
m_tree.SetItemState(hti, bBold ? TVIS_BOLD : 0, TVIS_BOLD);
}
void CTreeCtrlHelper::SetItemStateEx(HTREEITEM hti, UINT nState, UINT nMask, BOOL bChildren)
{
if (hti)
m_tree.SetItemState(hti, nState, nMask);
if (bChildren)
{
HTREEITEM htiChild = m_tree.GetChildItem(hti);
while (htiChild)
{
SetItemStateEx(htiChild, nState, nMask, TRUE);
htiChild = m_tree.GetNextItem(htiChild, TVGN_NEXT);
}
}
}
void CTreeCtrlHelper::SetTopLevelItemsBold(BOOL bBold)
{
// clear all bold states
SetItemStateEx(NULL, 0, TVIS_BOLD, TRUE);
// set top items bold
if (bBold)
{
HTREEITEM hti = m_tree.GetChildItem(NULL);
while (hti)
{
SetItemBold(hti, TRUE);
hti = m_tree.GetNextItem(hti, TVGN_NEXT);
}
}
}
HTREEITEM CTreeCtrlHelper::FindItem(DWORD dwID, HTREEITEM htiStart) const
{
// try htiStart first
if (htiStart && m_tree.GetItemData(htiStart) == dwID)
return htiStart;
// else try htiStart's children
HTREEITEM htiFound = NULL;
HTREEITEM htiChild = m_tree.GetChildItem(htiStart);
while (htiChild && !htiFound)
{
htiFound = FindItem(dwID, htiChild);
htiChild = m_tree.GetNextItem(htiChild, TVGN_NEXT);
}
return htiFound;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?