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

📄 xhtmltree.cpp

📁 读取XML信息
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			}
		}
		else	// not over an item
		{
			SetInsertMark(0, 0);	// remove insert mark
			m_hPreviousDropItem = 0;
			if (m_hNoDropCursor)
				SetCursor(m_hNoDropCursor);			// set to no-drop cursor
			else
				SetCursor(AfxGetApp()->LoadStandardCursor(IDC_NO));		// set to no-drop cursor
		}

		SetFocus();
	}
	else 
		
#endif // XHTMLDRAGDROP
		
	if (hItem)
	{
		// if mouse is on a different item, or has moved off state icon
		if ((m_hHotItem && (m_hHotItem != hItem)) || 
			(m_hHotItem && ((flags & TVHT_ONITEMSTATEICON) == 0)))
		{
			int nState = GetStateImage(m_hHotItem);

			// a hot item can only be UNCHECKED, CHECKED, or CHECKED_TRISTATE

			nState &= ~HDCheckboxImageList::HOT_INDEX;

			// remove hot from previous hot item
			SetItemState(m_hHotItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK);

			m_hHotItem = NULL;
		}

		if ((m_hHotItem == NULL) && (flags & TVHT_ONITEMSTATEICON))
		{
			TRACE(_T("cursor over state image\n"));
			int nState = GetStateImage(hItem);

			if ((nState & HDCheckboxImageList::DISABLED_INDEX) == 0)		// is it enabled?
			{
				// a hot item can only be UNCHECKED, CHECKED, or CHECKED_TRISTATE

				nState |= HDCheckboxImageList::HOT_INDEX;

				// remove hot from previous hot item
				SetItemState(hItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK);

				m_hHotItem = hItem;
				SetTimer(HOT_TIMER, 100, NULL);		// timer in case mouse leaves window
			}
		}

		CRect rect;
		BOOL bOverAnchor = IsOverAnchor(hItem, point, &rect);
		//TRACE(_T("bOverAnchor=%d\n"), bOverAnchor);

#ifdef XHTMLHTML
		if (bOverAnchor)
			m_Links.SetLinkCursor();
#endif // XHTMLHTML

		if ((m_hAnchorItem && (m_hAnchorItem != hItem)) || 
			(m_hAnchorItem && !bOverAnchor))
		{
			TRACE(_T("removing anchor 0x%X-----\n"), m_hAnchorItem);
			GetItemRect(m_hAnchorItem, &rect, FALSE);	// note:  must get entire
														// rect, since text might
														// be shifted left
			m_hAnchorItem = NULL;
			InvalidateRect(&rect, FALSE);
		}
		else if ((m_hAnchorItem == NULL) && bOverAnchor)
		{
			TRACE(_T("adding anchor 0x%X-----\n"), hItem);

			m_hAnchorItem = hItem;
			TRACE(_T("mouse over anchor 0x%X-----\n"), hItem);
			GetItemRect(hItem, &rect, FALSE);	// note:  must get entire
												// rect, since text might
												// be shifted left
			InvalidateRect(&rect, FALSE);
			SetTimer(HOT_TIMER, 80, NULL);		// timer in case mouse leaves window
		}
	}
	
	CTreeCtrl::OnMouseMove(nFlags, point);
}

//=============================================================================
HTREEITEM CXHtmlTree::IsOverItem(LPPOINT lpPoint /*= NULL*/)
//=============================================================================
{
	CPoint point;
	if (lpPoint)
	{
		point = *lpPoint;
	}
	else
	{
		::GetCursorPos(&point);
		ScreenToClient(&point);
	}
	UINT flags = 0;
	HTREEITEM hItem = HitTest(point, &flags);

	return hItem;
}

//=============================================================================
BOOL CXHtmlTree::IsOverAnchor(HTREEITEM hItem, CPoint point, CRect *pRect /*= NULL*/)
//=============================================================================
{
	BOOL rc = FALSE;

	CRect rect(0,0,0,0);

	XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);
	
	if (pXTCD && pXTCD->ds.bHasAnchor && pXTCD->bEnabled)
	{
		GetItemRect(hItem, &rect, TRUE);

		// set rect to anchor boundaries
		rect.left  = pXTCD->ds.rectAnchor.left;
		rect.right = pXTCD->ds.rectAnchor.right;

		if (rect.PtInRect(point))
		{
			rc = TRUE;
		}
	}

	if (pRect)
		*pRect = rect;

	return rc;
}

//=============================================================================
HCURSOR CXHtmlTree::SetCursor(HCURSOR hCursor)
//=============================================================================
{
	if (hCursor == m_hCurrentCursor)
		return m_hCurrentCursor;

	m_hCurrentCursor = hCursor;

	TRACE(_T("calling ::SetCursor %X\n"), hCursor);

	return ::SetCursor(hCursor);
}

//=============================================================================
BOOL CXHtmlTree::IsLeftButtonUp()
//=============================================================================
{
	BOOL rc = FALSE;

	SHORT state = 0;
	if (GetSystemMetrics(SM_SWAPBUTTON))		// check if buttons have been swapped
		state = GetAsyncKeyState(VK_RBUTTON);	// buttons swapped, get right button state
	else
		state = GetAsyncKeyState(VK_LBUTTON);

	// if the most significant bit is set, the button is down
	if (state >= 0)
		rc = TRUE;

	return rc;
}

//=============================================================================
// OnTimer - check if mouse has left, turn off underlining and hot state
void CXHtmlTree::OnTimer(UINT nIDEvent)
//=============================================================================
{
	CPoint point;
	::GetCursorPos(&point);
	ScreenToClient(&point);

	if (nIDEvent == HOT_TIMER)
	{
		// if mouse has left window, turn off hot and anchor highlighting

		CRect rectClient;
		GetClientRect(&rectClient);

		if (!rectClient.PtInRect(point))
		{
			KillTimer(nIDEvent);

			// mouse has left the window

			if (m_hHotItem)
			{
				int nState = GetStateImage(m_hHotItem);

				// a hot item can only be UNCHECKED, CHECKED, or CHECKED_TRISTATE

				nState &= ~HDCheckboxImageList::HOT_INDEX;

				// remove hot from previous hot item
				SetItemState(m_hHotItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK);

				m_hHotItem = NULL;
			}

			if (m_hAnchorItem)
			{
				// remove underline
				CRect rectAnchor;
				GetItemRect(m_hAnchorItem, &rectAnchor, FALSE);
				m_hAnchorItem = NULL;
				InvalidateRect(&rectAnchor, TRUE);
			}
		}
	}
	else if (nIDEvent == LBUTTONDOWN_TIMER)			// timer set by WM_LBUTTONDOWN
	{
		HTREEITEM hItem = IsOverItem(&point);

		if (IsLeftButtonUp())
		{
			TRACE(_T("mouse button is up >>>>>\n"));

			KillTimer(nIDEvent);

			HTREEITEM hItemSelected = GetSelectedItem();

#ifdef XHTMLDRAGDROP

			if (m_bDragging)				// case 1:  user is dragging
			{
				if (hItem && 
					(hItem != m_hItemButtonDown) && 
					(!IsChildNodeOf(hItem, m_hItemButtonDown)))
				{
					HTREEITEM hAfter = hItem;
					HTREEITEM hParent = GetParentItem(m_hItemButtonDown);
					HTREEITEM hNewParent = GetParentItem(hAfter);
					TRACE(_T("hParent=%X\n"), hParent);

					// check if Shift key down
					if ((m_dwDragOps & XHTMLTREE_DO_SHIFT_KEY) &&
						(GetAsyncKeyState(VK_SHIFT) < 0) &&
						!IsSeparator(hAfter))								//+++1.6
					{
						TRACE(_T("VK_SHIFT down, creating child item\n"));
						hNewParent = hAfter;
						hAfter = TVI_LAST;
					}
					else if (hParent == hAfter)
					{
						// dropping on parent
						hNewParent = hParent;
						hAfter = TVI_FIRST;
					}
					else if (ItemHasChildren(hAfter) && IsExpanded(hAfter))	//+++1.6
					{
						// dropping on node that is expanded
						hNewParent = hAfter;
						hAfter = TVI_FIRST;
					}
					else if (hNewParent == 0)								//+++1.6
					{
						// multiple roots
					}

					StartMoveBranch(m_hItemButtonDown, hNewParent, hAfter);
				}
				else
				{
					TRACE(_T("ERROR can't drop on %X\n"), hItem);
					SendRegisteredMessage(WM_XHTMLTREE_END_DRAG, 0, 0);
				}

				EndDragScroll();
			}
			else 

#endif // XHTMLDRAGDROP
				
			if (hItem && (hItem == hItemSelected)
				&& !IsSeparator(hItem))	// case 2:  user wants to edit a label
			{
				// clicking on a selected item
				CEdit *pEdit = GetEditControl();

				CRect rect;
				GetItemRect(hItem, &rect, TRUE);
				if (rect.PtInRect(point))
				{
					TRACE(_T("sending TVM_EDITLABEL\n"));
					// click on item text, begin edit
					SendMessage(TVM_EDITLABEL, 0, (LPARAM)hItem);
				}
				else if (pEdit && IsWindow(pEdit->m_hWnd))
				{
					TRACE(_T("sending WM_CLOSE to edit box\n"));
					// click outside item text, end edit
					pEdit->SendMessage(WM_CLOSE);
				}
			}
		}

#ifdef XHTMLDRAGDROP

		else		// left button is down
		{
			//TRACE(_T("mouse button is down >>>>>\n"));

			if (m_bDragging)
			{
				// check how long we've been hovering over same item

				if (hItem && (hItem == m_hPreviousDropItem))
				{
					if (GetBit(m_dwDragOps, XHTMLTREE_DO_AUTO_EXPAND))
					{
						// still over same item
						if ((GetTickCount() - m_dwDropHoverTime) > MIN_HOVER_TIME)
						{
							// min hover time has passed, expand node if it has children
							Expand(hItem, TVE_EXPAND);
						}
					}
				}

				if (m_bAutoScroll)
					AutoScroll(hItem);
			}
		}

#endif // XHTMLDRAGDROP

	}

#ifdef XHTMLDRAGDROP

	else if (nIDEvent == CTRL_UP_TIMER)
	{
		// check if Ctrl key down
		if (!IsCtrlDown())
		{
			TRACE(_T("VK_CONTROL up\n"));

			KillTimer(nIDEvent);

			if (IsOverItem() && m_bDragging)
			{
				SetDragCursor();
			}
		}
	}
	else if (nIDEvent == SHIFT_UP_TIMER)
	{
		if ((m_dwDragOps & XHTMLTREE_DO_SHIFT_KEY) &&
			(GetAsyncKeyState(VK_SHIFT) >= 0))
		{
			TRACE(_T("VK_SHIFT up\n"));
			KillTimer(nIDEvent);
			HTREEITEM hItem = IsOverItem();
			if (hItem)
				SetInsertMark(hItem, TRUE);
			SelectDropTarget(NULL);
		}
	}
	else if (nIDEvent == SELECT_TIMER)			// timer set by WM_LBUTTONDOWN
	{
		KillTimer(nIDEvent);
		HTREEITEM hItem = IsOverItem();
		if (hItem)
		{
			SelectItem(hItem);
		}
	}


#endif // XHTMLDRAGDROP

	CTreeCtrl::OnTimer(nIDEvent);
}

//=============================================================================
BOOL CXHtmlTree::OnEraseBkgnd(CDC* pDC)
//=============================================================================
{
	CRect rectClientx;
	GetClientRect(&rectClientx);
	pDC->FillSolidRect(rectClientx, m_crWindow);
	return TRUE;
}

//=============================================================================
CXHtmlTree& CXHtmlTree::SetCheck(HTREEITEM hItem, BOOL fCheck /*= TRUE*/)
//=============================================================================
{
	ASSERT(hItem);

	if (hItem && m_bCheckBoxes)
	{
		TRACE(_T("in CXHtmlTree::SetCheck: %d  <%s>\n"), fCheck, GetItemText(hItem));
		
		XHTMLTREEDATA *pXTCD = GetItemDataStruct(hItem);

		if (pXTCD && pXTCD->bEnabled && !pXTCD->bSeparator)		//+++1.6
		{
			BOOL bOldChecked = pXTCD->bChecked;
			pXTCD->bChecked = fCheck;

			UINT nState = GetStateImage(hItem);

			//TRACE(_T("nState=0x%X  nOldState=0x%X ~~~~~\n"), nState, nOldState);

			SetItemState(hItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK);

			if (m_bSmartCheck && (bOldChecked != fCheck))
			{
				HTREEITEM hParent = hItem;
				int nCount = 0;
				if (fCheck)
					nCount = pXTCD->nChildren - pXTCD->nChecked + 1;//bOldCheck ? 1 : 0;
				else
					nCount = -(pXTCD->nChecked + 1);//bOldCheck ? 1 : 0);

				SetCheckChildren(hItem, fCheck);

				// find all parents, adjust their checked counts
				TRACE(_T("starting nCount=%d\n"), nCount);
				while ((hParent = GetParentItem(hParent)) != NULL)
				{
					nCount = SetCheckParent(hParent, nCount);
				}
			}

			SendRegisteredMessage(WM_XHTMLTREE_CHECKBOX_CLICKED, hItem, fCheck);
		}
	}

	return *this;
}

//=============================================================================
void CXHtmlTree::SetHotItem(HTREEITEM hItem, UINT nFlags)
//=============================================================================
{
	if (m_hHotItem && (m_hHotItem != hItem))
	{
		int nState = GetStateImage(m_hHotItem);

		// a hot item can only be UNCHECKED, CHECKED, or CHECKED_TRISTATE

		nState &= ~HDCheckboxImageList::HOT_INDEX;

		// remove hot from previous hot item
		SetItemState(m_hHotItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK);

		m_hHotItem = NULL;
	}

	if (hItem && (m_hHotItem == NULL) && (nFlags & TVHT_ONITEMSTATEICON))
	{
		TRACE(_T("cursor over state image\n"));
		int nState = GetStateImage(hItem);

		// a hot item can only be UNCHECKED, CHECKED, or CHECKED_TRISTATE

		nState |= HDCheckboxImageList::HOT_INDEX;

		// remove hot from previous hot item
		SetItemState(hItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK);

		m_hHotItem = hItem;
	}
}

//=============================================================================
LRESULT CXHtmlTree::SendRegisteredMessage(UINT nMessage, 
									   HTREEITEM hItem, 
									   LPARAM lParam /*= 0*/)
//=============================================================================
{
	LRESULT lResult = 0;

	CWnd *pWnd = GetParent();
	if (!pWnd)
		pWnd = GetOwner();

	if (pWnd && ::IsWindow(pWnd->m_hWnd))
	{
		XHTMLTREEMSGDATA msgdata = { 0 };
		msgdata.hCtrl    = m_hWnd;
		msgdata.nCtrlId  = GetDlgCtrlID();
		msgdata.hItem    = hItem;

⌨️ 快捷键说明

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