📄 xhtmltree.cpp
字号:
pFont->GetLogFont(&lf);
lf.lfWeight = pXTCD->ds.bBold ? FW_BOLD : FW_NORMAL;
lf.lfUnderline = (BYTE) pXTCD->ds.bUnderline;
lf.lfItalic = (BYTE) pXTCD->ds.bItalic;
lf.lfStrikeOut = (BYTE) pXTCD->ds.bStrikeThrough;
font.CreateFontIndirect(&lf);
pOldFont = pDC->SelectObject(&font);
}
pDC->SetTextColor(crText);
if (crTextBackground == COLOR_NONE)
pDC->SetBkColor(crBackground);
else
pDC->SetBkColor(crTextBackground);
CRect rectOut(rectText);
pDC->DrawText(str, &rectOut, uFormat | DT_CALCRECT);
pDC->DrawText(str, &rectOut, uFormat);
rectOut.InflateRect(m_nPadding, 0);
nWidth = rectOut.right;
pXTCD->ds.nRightX = rectOut.right;
if (pOldFont)
pDC->SelectObject(pOldFont);
}
return nWidth;
}
#ifdef XHTMLHTML
//=============================================================================
int CXHtmlTree::DrawItemTextHtml(CDC *pDC,
HTREEITEM hItem,
LPCTSTR lpszText,
COLORREF crText,
COLORREF crTextBackground,
COLORREF crBackground,
COLORREF crAnchorText,
CRect& rect)
//=============================================================================
{
ASSERT(pDC);
ASSERT(hItem);
if (!pDC || !hItem)
{
TRACE(_T("ERROR bad parameters\n"));
return 0;
}
if (IsBadRect(rect))
{
return 0;
}
XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
if (!pXTCD)
{
TRACE(_T("ERROR no XHTMLTREEDATA\n"));
return 0;
}
COLORREF crTextOld, crTextBackgroundOld, crBackgroundOld, crAnchorTextOld;
crTextOld = pXTCD->ds.crText;
crTextBackgroundOld = pXTCD->ds.crTextBackground;
crBackgroundOld = pXTCD->ds.crBackground;
crAnchorTextOld = pXTCD->ds.crAnchorText;
pXTCD->ds.crText = crText;
pXTCD->ds.crTextBackground = crTextBackground;
pXTCD->ds.crBackground = crBackground;
pXTCD->ds.crAnchorText = crAnchorText;
pXTCD->ds.rect = rect;
pXTCD->ds.bUseEllipsis = FALSE;
if (m_bLogFont)
{
pXTCD->ds.bLogFont = TRUE;
memcpy(&pXTCD->ds.lf, &m_lf, sizeof(LOGFONT));
}
CString strText = lpszText;//GetItemText(hItem);
TRACE(_T("in CXHtmlTree::DrawItemTextHtml: <%s> crText=%06X crBk=%06X\n"), strText, crText, crBackground);
CXHtmlDraw htmldraw;
int nWidth = htmldraw.Draw(pDC->m_hDC, strText, &pXTCD->ds, hItem == m_hAnchorItem);
pXTCD->ds.crText = crTextOld;
pXTCD->ds.crTextBackground = crTextBackgroundOld;
pXTCD->ds.crBackground = crBackgroundOld;
pXTCD->ds.crAnchorText = crAnchorTextOld;
return nWidth;
}
#endif // XHTMLHTML
//=============================================================================
int CXHtmlTree::DrawSeparator(CDC *pDC, //+++1.6
HTREEITEM hItem,
COLORREF crText,
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 rectSep(rect);
pDC->FillSolidRect(&rectSep, crBackground);
//TRACE(_T("CXHtmlTree::DrawItemText: crText=%08X crBkgnd=%08X <%s> ++++++\n"), crText, crBackground, str);
XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
if (pXTCD)
{
CPen pen(PS_SOLID, 1, crText);
CPen * pOldPen = pDC->SelectObject(&pen);
TRACE(_T("drawing separator\n"));
rectSep.right -= 1;
rectSep.left -= 2;
rectSep.top += rectSep.Height()/2;
pDC->MoveTo(rectSep.left, rectSep.top);
pDC->LineTo(rectSep.right, rectSep.top);
pDC->SelectObject(pOldPen);
nWidth = rectSep.right;
pXTCD->ds.nRightX = rectSep.right;
}
return nWidth;
}
//=============================================================================
void CXHtmlTree::OnDestroy()
//=============================================================================
{
TRACE(_T("in CXHtmlTree::OnDestroy\n"));
DeleteMap();
CTreeCtrl::OnDestroy();
}
//=============================================================================
void CXHtmlTree::DeleteMap()
//=============================================================================
{
BOOL bOldDestroyingTree = m_bDestroyingTree;
m_bDestroyingTree = TRUE;
int n = (int)m_DataMap.GetCount();
POSITION pos = m_DataMap.GetStartPosition();
HTREEITEM hItem = 0;
XHTMLTREEDATA *pXTCD = NULL;
if (n > 0)
{
do
{
m_DataMap.GetNextAssoc(pos, hItem, pXTCD);
if (hItem && pXTCD)
delete pXTCD;
n--;
} while (pos != NULL);
}
ASSERT(n == 0);
m_DataMap.RemoveAll();
m_bDestroyingTree = bOldDestroyingTree;
}
//=============================================================================
// GetNextItem - Get next item in sequence (as if tree was completely expanded)
// see http://www.codeguru.com/Cpp/controls/treeview/treetraversal/article.php/c645
// hItem - The reference item
// Returns - The item immediately below the reference item
HTREEITEM CXHtmlTree::GetNextItem(HTREEITEM hItem)
//=============================================================================
{
HTREEITEM hItemNext = NULL;
ASSERT(hItem);
if (hItem)
{
if (ItemHasChildren(hItem))
{
hItemNext = GetChildItem(hItem); // first child
}
if (hItemNext == NULL)
{
// return next sibling item - go up the tree to find
// a parent's sibling if needed.
while ((hItemNext = GetNextSiblingItem(hItem)) == NULL)
{
if ((hItem = GetParentItem(hItem)) == NULL)
return NULL;
}
}
}
return hItemNext;
}
//=============================================================================
// GetNextItem - Get previous item as if outline was completely expanded
// Returns - The item immediately above the reference item
// hItem - The reference item
HTREEITEM CXHtmlTree::GetPrevItem(HTREEITEM hItem)
//=============================================================================
{
HTREEITEM hItemPrev;
hItemPrev = GetPrevSiblingItem(hItem);
if (hItemPrev == NULL)
hItemPrev = GetParentItem(hItem);
else
hItemPrev = GetLastItem(hItemPrev);
return hItemPrev;
}
//=============================================================================
// GetLastItem - Gets last item in the branch
// Returns - Last item
// hItem - Node identifying the branch. NULL will
// return the last item in outine
HTREEITEM CXHtmlTree::GetLastItem(HTREEITEM hItem)
//=============================================================================
{
// Last child of the last child of the last child ...
HTREEITEM hItemNext;
if (hItem == NULL)
{
// Get the last item at the top level
hItemNext = GetRootItem();
while (hItemNext)
{
hItem = hItemNext;
hItemNext = GetNextSiblingItem(hItemNext);
}
}
while (ItemHasChildren(hItem))
{
hItemNext = GetChildItem(hItem);
while (hItemNext)
{
hItem = hItemNext;
hItemNext = GetNextSiblingItem(hItemNext);
}
}
return hItem;
}
//=============================================================================
// FindItem - Finds an item that contains the search string
//
// http://www.codeguru.com/cpp/controls/treeview/treetraversal/article.php/c673/
//
// Returns - Handle to the item or NULL
//
// str - String to search for
// bCaseSensitive - Should the search be case sensitive
// bDownDir - Search direction - TRUE for down
// bWholeWord - True if search should match whole words
// hItem - Item to start searching from. NULL for
// currently selected item
HTREEITEM CXHtmlTree::FindItem(CString &str,
BOOL bCaseSensitive /*= FALSE*/,
BOOL bDownDir /*= TRUE*/,
BOOL bWholeWord /*= FALSE*/,
BOOL bWrap /* = TRUE */,
HTREEITEM hItem /*= NULL*/)
//=============================================================================
{
int lenSearchStr = str.GetLength();
if (lenSearchStr == 0)
return NULL;
HTREEITEM hItemSel = hItem ? hItem : GetSelectedItem();
HTREEITEM hItemCur = bDownDir ? GetNextItem(hItemSel) : GetPrevItem(hItemSel);
CString sSearch = str;
if (hItemCur == NULL)
{
if (bDownDir)
hItemCur = GetRootItem();
else
hItemCur = GetLastItem(NULL);
}
if (!bCaseSensitive)
sSearch.MakeLower();
while (hItemCur && (hItemCur != hItemSel))
{
CString sItemText = GetItemText(hItemCur);
#ifdef XHTMLHTML
TCHAR s[200];
// remove html tags
CXHtmlDraw hd;
hd.GetPlainText(sItemText, s, sizeof(s)/sizeof(TCHAR)-1);
sItemText = s;
#endif // XHTMLHTML
if (!bCaseSensitive)
sItemText.MakeLower();
int n = 0;
while ((n = sItemText.Find(sSearch)) != -1)
{
// search string found
if (bWholeWord)
{
// check preceding char
if (n != 0)
{
if (isalpha(sItemText[n-1]) ||
sItemText[n-1] == '_')
{
// Not whole word
sItemText = sItemText.Right(sItemText.GetLength() -
n - lenSearchStr);
continue;
}
}
// check succeeding char
if (sItemText.GetLength() > (n + lenSearchStr) &&
(isalpha(sItemText[n+lenSearchStr]) ||
sItemText[n+lenSearchStr] == '_' ))
{
// Not whole word
sItemText = sItemText.Right(sItemText.GetLength()
- n - sSearch.GetLength());
continue;
}
}
if (IsFindValid( hItemCur))
return hItemCur;
else
break;
}
hItemCur = bDownDir ? GetNextItem(hItemCur) : GetPrevItem(hItemCur);
if ((hItemCur == NULL) && !bWrap)
break;
if ((hItemCur == NULL) && (hItemSel != NULL)) // wrap only if there
// is a selected item
{
if (bDownDir)
hItemCur = GetRootItem();
else
hItemCur = GetLastItem(NULL);
}
}
return NULL;
}
//=============================================================================
// IsFindValid - Virtual function used by FindItem to allow this
// function to filter the result of FindItem
// Returns - True if item matches the criteria
// Arg - Handle of the item
BOOL CXHtmlTree::IsFindValid(HTREEITEM)
//=============================================================================
{
return TRUE;
}
//=============================================================================
void CXHtmlTree::RedrawItem(HTREEITEM hItem)
//=============================================================================
{
if (hItem)
{
CRect rect;
GetItemRect(hItem, &rect, FALSE);
InvalidateRect(&rect, FALSE);
UpdateWindow();
}
}
//=============================================================================
// OnMouseMove - handle link underlining and checkbox hot state
void CXHtmlTree::OnMouseMove(UINT nFlags, CPoint point)
//=============================================================================
{
// hItem will be non-zero if the cursor is anywhere over a valid item
UINT flags = 0;
HTREEITEM hItem = HitTest(point, &flags);
#ifdef XHTMLDRAGDROP
if (!m_bDragging && !IsLeftButtonUp() && IsSeparator(hItem))
{
// we must send TVN_BEGINDRAG to ourself, since separator has no text
NMTREEVIEW nmtv = { 0 };
nmtv.hdr.hwndFrom = m_hWnd;
nmtv.hdr.idFrom = GetDlgCtrlID();
nmtv.hdr.code = TVN_BEGINDRAG;
nmtv.itemNew.hItem = hItem;
SendMessage(WM_NOTIFY, 0, (LPARAM)&nmtv);
}
else if (m_bDragging)
{
CPoint cursor_point(point);
ClientToScreen(&cursor_point);
LRESULT lResult = 0; // allow drop if lResult is 0
BOOL bCopyDrag = IsDragCopy();
if (hItem)
{
// allow parent to decide whether to permit drag
XHTMLTREEDRAGMSGDATA dragdata = { 0 };
dragdata.hItem = m_hItemButtonDown;
dragdata.hAfter = hItem;
dragdata.bCopyDrag = bCopyDrag;
lResult = SendRegisteredMessage(WM_XHTMLTREE_DROP_HOVER,
m_hItemButtonDown, (LPARAM)&dragdata);
}
// Check to see if the drag is over an item in the tree
if (hItem && !lResult)
{
if (m_hPreviousDropItem != hItem)
{
SetDragCursor();
SetInsertMark(0, 0); // remove previous insert mark
TRACE(_T("Drag target item 0x%X\n"), hItem);
m_hPreviousDropItem = hItem;
m_dwDropHoverTime = GetTickCount();
// check if Shift key down
if (GetBit(m_dwDragOps, XHTMLTREE_DO_SHIFT_KEY) &&
(GetAsyncKeyState(VK_SHIFT) < 0))
{
TRACE(_T("VK_SHIFT down\n"));
if (IsSeparator(hItem)) //+++1.6
{
SelectDropTarget(NULL);
SetInsertMark(hItem, TRUE);
}
else
{
SelectDropTarget(hItem);
}
}
else
{
SetInsertMark(hItem, TRUE);
SelectDropTarget(NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -