📄 xhtmltree.cpp
字号:
{
Expand(hItem, nCode);
return TRUE; // skip default processing
}
}
}
return CTreeCtrl::PreTranslateMessage(pMsg);
}
//=============================================================================
void CXHtmlTree::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
//=============================================================================
{
NMTVCUSTOMDRAW* pCD = reinterpret_cast<NMTVCUSTOMDRAW*>(pNMHDR);
CDC* pDC = CDC::FromHandle(pCD->nmcd.hdc);
HTREEITEM hItem = reinterpret_cast<HTREEITEM> (pCD->nmcd.dwItemSpec);
// Take the default processing unless we set this to something else below.
*pResult = CDRF_DODEFAULT;
// First thing - check the draw stage. If it's the control's prepaint
// stage, then tell Windows we want messages for every item.
//=========================================================================
if (pCD->nmcd.dwDrawStage == CDDS_PREPAINT) // before the painting cycle begins
//=========================================================================
{
*pResult = CDRF_NOTIFYITEMDRAW /*| CDRF_NOTIFYPOSTPAINT*/;
}
//=========================================================================
else if (pCD->nmcd.dwDrawStage == CDDS_ITEMPREPAINT) // before an item is drawn
//=========================================================================
{
pCD->clrText = pCD->clrTextBk; // don't want default drawing -
// set text color = background color
if (hItem)
{
CRect rectItem1;
GetItemRect(hItem, &rectItem1, FALSE); // get rect for item
if (!IsBadRect(rectItem1))
{
CBrush brush(m_crWindow);
pDC->FillRect(&rectItem1, &brush); // erase entire background
}
}
*pResult = CDRF_NOTIFYPOSTPAINT | CDRF_NEWFONT;
}
//=========================================================================
else if (pCD->nmcd.dwDrawStage == CDDS_ITEMPOSTPAINT) // after an item has been drawn
//=========================================================================
{
// by doing the drawing at this stage we avoid having to draw lines, etc.
if (m_bFirstTime)
{
if (m_bToolTip)
CreateToolTipsForTree();
CImageList *pImageList = GetImageList(TVSIL_NORMAL);
if (!pImageList) //+++1.5
{
TRACE(_T("WARNING no image list, setting m_bImages to FALSE\n"));
m_bImages = FALSE;
}
}
m_bFirstTime = FALSE;
CRect rectItem;
GetItemRect(hItem, &rectItem, FALSE); // get rect for entire item
CRect rectText;
GetItemRect(hItem, &rectText, TRUE); // get rect for text
rectText.right = rectItem.right;
XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
// set up colors
COLORREF crText = m_crWindowText;
COLORREF crAnchorText = m_crAnchorText;
COLORREF crBackground = m_crWindow;
COLORREF crTextBackground = m_crWindow;
BOOL bEnabled = TRUE;
HTREEITEM hSelected = GetSelectedItem();
if (pXTCD)
{
// try to use colors specified for this item
pXTCD->ds.bIgnoreColorTag = FALSE;
crText = pXTCD->ds.crText;
crTextBackground = pXTCD->ds.crTextBackground;
crBackground = pXTCD->ds.crBackground;
//TRACE(_T("crText=%08X crBkgnd=%08X ~~~~~\n"), crText, crBackground);
bEnabled = pXTCD->bEnabled;
if ((hItem == hSelected) ||
(GetItemState(hItem, TVIF_STATE) & TVIS_DROPHILITED))
{
crTextBackground = m_crHighlight;
}
else
{
//crTextBackground = COLOR_NONE;
}
if (!bEnabled)
{
crText = crAnchorText = m_crGrayText;
pXTCD->ds.bIgnoreColorTag = TRUE;
}
else if ((hItem == hSelected) ||
(GetItemState(hItem, TVIF_STATE) & TVIS_DROPHILITED))
{
crText = crAnchorText = m_crHighlightText;
pXTCD->ds.bIgnoreColorTag = TRUE;
}
else
{
}
}
if (crBackground == COLOR_NONE)
crBackground = m_crWindow;
if (pXTCD && pXTCD->bSeparator) //+++1.6
{
if (crText == COLOR_NONE)
crText = m_crSeparator;
if (hItem == hSelected)
crBackground = m_crHighlight;
DrawSeparator(pDC, hItem, crText, crBackground, rectText);
}
else
{
if (crText == COLOR_NONE)
crText = m_crWindowText;
CString strText = GetItemText(hItem);
BOOL bContainsHtml = FALSE;
// check for html tag and char entity
if (strText.FindOneOf(_T("<&")) >= 0)
bContainsHtml = TRUE;
if (m_bStripHtml && bContainsHtml)
strText = GetItemText(hItem, TRUE);
#ifdef XHTMLHTML
if (m_bHtml && bContainsHtml)
DrawItemTextHtml(pDC, hItem, strText, crText, crTextBackground,
crBackground, crAnchorText, rectText);
else
#endif // XHTMLHTML
DrawItemText(pDC, hItem, strText, crText, crTextBackground, crBackground, rectText);
}
//*pResult = CDRF_SKIPDEFAULT; // We've painted everything.
}
}
//=============================================================================
BOOL CXHtmlTree::SelectItem(HTREEITEM hItem)
//=============================================================================
{
HTREEITEM hPrevItemSel = GetSelectedItem();
if (hItem == hPrevItemSel)
return TRUE;
XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
if (pXTCD && pXTCD->bEnabled)
{
NMTREEVIEW nmtv = { 0 };
nmtv.hdr.hwndFrom = m_hWnd;
nmtv.hdr.idFrom = GetDlgCtrlID();
nmtv.hdr.code = TVN_SELCHANGED;
nmtv.itemNew.hItem = hItem;
CWnd *pWnd = GetParent();
if (!pWnd)
pWnd = GetOwner();
if (pWnd && ::IsWindow(pWnd->m_hWnd))
{
pWnd->SendMessage(WM_NOTIFY, GetDlgCtrlID(), (LPARAM)&nmtv);
}
}
else
{
if (hPrevItemSel)
hItem = hPrevItemSel;
else
return TRUE;
}
return CTreeCtrl::SelectItem(hItem);
}
//=============================================================================
BOOL CXHtmlTree::IsSelected(HTREEITEM hItem)
//=============================================================================
{
BOOL rc = FALSE;
if (hItem == GetSelectedItem())
rc = TRUE;
return rc;
}
//=============================================================================
BOOL CXHtmlTree::IsEnabled(HTREEITEM hItem)
//=============================================================================
{
BOOL rc = FALSE;
XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
if (pXTCD)
{
rc = pXTCD->bEnabled;
}
return rc;
}
//=============================================================================
BOOL CXHtmlTree::IsExpanded(HTREEITEM hItem)
//=============================================================================
{
BOOL rc = FALSE;
XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
if (pXTCD)
{
rc = pXTCD->bExpanded && ItemHasChildren(hItem);
}
return rc;
}
//=============================================================================
BOOL CXHtmlTree::IsSeparator(HTREEITEM hItem) //+++1.6
//=============================================================================
{
BOOL rc = FALSE;
XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
if (pXTCD)
{
rc = pXTCD->bSeparator;
}
return rc;
}
//=============================================================================
BOOL CXHtmlTree::GetItemPath(HTREEITEM hItem, CStringArray& sa, CPtrArray& items)
//=============================================================================
{
BOOL rc = FALSE;
sa.RemoveAll();
items.RemoveAll();
if (hItem == NULL)
hItem = GetRootItem();
if (hItem)
{
CStringArray path;
CPtrArray htreeitems;
// get the path in reverse order
while (hItem)
{
CString strText = GetItemText(hItem);
#ifdef XHTMLHTML
// remove html tags
CXHtmlDraw hd;
TCHAR s[200];
hd.GetPlainText(strText, s, sizeof(s)/sizeof(TCHAR)-1);
strText = s;
#endif // XHTMLHTML
path.Add(strText);
htreeitems.Add(hItem);
hItem = GetParentItem(hItem);
}
int n = (int) path.GetSize();
if (n)
{
// return path in correct order
for (int i = n-1; i >= 0 ; i--)
{
sa.Add(path[i]);
items.Add(htreeitems[i]);
}
rc = TRUE;
}
}
return rc;
}
//=============================================================================
int CXHtmlTree::GetDefaultTipWidth()
//=============================================================================
{
int nWidth = 200;
if (m_nDefaultTipWidth == 0)
{
// no default width specified, use a heuristic
CWnd *pWnd = GetParent();
if (!pWnd)
pWnd = GetOwner();
if (pWnd && ::IsWindow(pWnd->m_hWnd))
{
CRect rectParent;
pWnd->GetWindowRect(&rectParent);
CRect rectTree;
GetWindowRect(&rectTree);
int nWidthTree = (3 * rectTree.Width()) / 4;
int nWidthParent = rectParent.Width() / 2;
nWidth = (nWidthTree < 200) ? nWidthParent : nWidthTree;
}
}
else
{
nWidth = m_nDefaultTipWidth;
}
return nWidth;
}
//=============================================================================
void CXHtmlTree::CreateToolTipsForTree()
//=============================================================================
{
if ((m_pToolTip == 0) || (!IsWindow(m_pToolTip->m_hWnd)))
return;
#ifdef XHTMLTOOLTIPS
m_pToolTip->SetNotify(TRUE);
#endif // XHTMLTOOLTIPS
m_pToolTip->SetMaxTipWidth(GetDefaultTipWidth());
// first delete all existing tools
int nCount = m_nToolCount; //m_pToolTip->GetToolCount();
for (int j = 0; j < nCount; j++)
m_pToolTip->DelTool(this, TOOLTIP_BASE_ID+j);
m_nToolCount = 0;
CRect rect;
GetClientRect(rect);
CRect rectItem;
GetItemRect(GetFirstVisibleItem(), &rectItem, FALSE);
ASSERT(!IsBadRect(rectItem));
rect.top = 0;
rect.bottom = rect.top + rectItem.Height()-1;
UINT n = GetVisibleCount();
// loop to add a tool for each visible item
UINT i = 0;
for (i = 0; i < n; i++)
{
#ifdef XHTMLTOOLTIPS
PPTOOLTIP_INFO ti;
ti.nBehaviour = PPTOOLTIP_MULTIPLE_SHOW;
ti.nIDTool = 123;
ti.rectBounds = rect;
ti.sTooltip = "";
ti.nMask = PPTOOLTIP_MASK_BEHAVIOUR;
m_pToolTip->AddTool(this, ti);
#else
m_pToolTip->AddTool(this, LPSTR_TEXTCALLBACK, rect, TOOLTIP_BASE_ID+i);
#endif // XHTMLTOOLTIPS
rect.top = rect.bottom+1;
rect.bottom = rect.top + rectItem.Height()-1;
}
m_nToolCount = i;
if (m_pToolTip)
{
// allow parent to perform custom initializatio of tooltip
SendRegisteredMessage(WM_XHTMLTREE_INIT_TOOLTIP, 0, (LPARAM)m_pToolTip);
}
}
//=============================================================================
// GetNormalImageWidth
// returns: width - if image is specified
// -width - TV_NOIMAGE is specified for this item
// 0 - no image list
int CXHtmlTree::GetNormalImageWidth(HTREEITEM hItem)
//=============================================================================
{
int nWidth = 0;
CImageList *pImageList = GetImageList(TVSIL_NORMAL);
if (pImageList && hItem)
{
// there is an image list
int nImage = TV_NOIMAGE;
int nSelectedImage = TV_NOIMAGE;
GetItemImage(hItem, nImage, nSelectedImage);
IMAGEINFO ii = { 0 };
if (pImageList->GetImageInfo(0, &ii)) // use first image width
{
nWidth = ii.rcImage.right - ii.rcImage.left;
}
if (nImage == TV_NOIMAGE)
nWidth = -nWidth;
}
return nWidth;
}
//=============================================================================
BOOL CXHtmlTree::CreateCheckboxImages()
//=============================================================================
{
CDC *pDC = GetDC();
ASSERT(pDC);
BOOL rc = HDCheckboxImageList::CreateCheckboxImageList(pDC, m_StateImage,
m_nImageHeight, m_crWindow);
ReleaseDC(pDC);
SetImageList(&m_StateImage, TVSIL_STATE);
return rc;
}
//=============================================================================
int CXHtmlTree::DrawItemText(CDC *pDC,
HTREEITEM hItem,
LPCTSTR lpszText,
COLORREF crText,
COLORREF crTextBackground,
COLORREF crBackground,
CRect& rect)
//=============================================================================
{
ASSERT(pDC);
ASSERT(hItem);
if (!pDC || !hItem)
{
TRACE(_T("ERROR bad parameters\n"));
return 0;
}
if (IsBadRect(rect))
{
return 0;
}
int nWidth = 0;
CRect rectText(rect);
pDC->FillSolidRect(&rectText, crBackground);
CString str = lpszText;
//TRACE(_T("CXHtmlTree::DrawItemText: crText=%08X crBkgnd=%08X <%s> ++++++\n"), crText, crBackground, str);
XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
if (pXTCD && !str.IsEmpty())
{
UINT uFormat = DT_VCENTER | DT_SINGLELINE | DT_LEFT | DT_NOPREFIX;
CFont *pOldFont = NULL;
CFont font;
CFont *pFont = pDC->GetCurrentFont();
if (pFont)
{
LOGFONT lf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -