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

📄 lefttreeview.cpp

📁 vc++的技巧查找方式源代码。
💻 CPP
📖 第 1 页 / 共 2 页
字号:

	if(bWriteDB)
	{
		m_ADO.Update();
	}
}

int CLeftTreeView::GetIndentLevel(HTREEITEM hItem)
{
	int nIndent = 0;
	
	while((hItem = m_pTreeSkill->GetParentItem(hItem)) != NULL)
	{
		nIndent++;
	}

	return nIndent;
}

HTREEITEM CLeftTreeView::GetNextItem(HTREEITEM hItem)
{
	HTREEITEM hTemp;
	
	if(m_pTreeSkill->ItemHasChildren(hItem) )
	{//return first child
		return m_pTreeSkill->GetChildItem(hItem);		
	}
	else
	{
		// return next sibling item
		// go up the tree to find a parent's sibling if needed.
		while((hTemp = m_pTreeSkill->GetNextSiblingItem(hItem)) == NULL)
		{
			if((hItem = m_pTreeSkill->GetParentItem(hItem)) == NULL)
			{
				return NULL;
			}
		}
	}

	return hTemp;
}

int CLeftTreeView::GetItemTypeByTag(const int nTag)
{
	int nType=-1;
	POSITION pos=NULL;

	if(m_TreeInfoList.GetCount() < 1)
	{
		return -1;
	}

	for(pos=m_TreeInfoList.GetHeadPosition(); NULL!=pos;)
	{
		if(m_TreeInfoList.GetAt(pos).nTag == nTag)
		{
			nType = m_TreeInfoList.GetAt(pos).nType;
			break;
		}

		m_TreeInfoList.GetNext(pos);
	}

	return nType;
}

void CLeftTreeView::OnUpdateMenuAddchildarticle(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bEnableAddItem);
}

void CLeftTreeView::OnUpdateMenuAddchildnode(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	pCmdUI->Enable(m_bEnableAddItem);
}

POSITION CLeftTreeView::GetFreeItemTag(int &nTag)
{
	int i,j;
	int nCount;
	int nMaxTag=0;
	POSITION pos=NULL;
	BOOL bFindFreeTag=FALSE;
	BOOL bFind=FALSE;
	BOOL bAddMaxTag=TRUE;

	nCount = m_TreeInfoList.GetCount();

	if(nCount < 1)
	{
		nTag = 1;
		return NULL;
	}

	for(pos=m_TreeInfoList.GetHeadPosition(); NULL!=pos;)
	{
		if(m_TreeInfoList.GetAt(pos).nTag > nMaxTag)
		{
			nMaxTag = m_TreeInfoList.GetAt(pos).nTag;
		}
		
		m_TreeInfoList.GetNext(pos);
	}

	for(pos=m_TreeInfoList.GetHeadPosition(); NULL!=pos;)
	{
		if(m_TreeInfoList.GetAt(pos).nDeleted == 1)
		{
			nTag = m_TreeInfoList.GetAt(pos).nTag;
			bFindFreeTag = TRUE;

			break;
		}
		
		m_TreeInfoList.GetNext(pos);
	}

	if(!bFindFreeTag)
	{
		for(i=1; i<nMaxTag; i++)
		{
			j=0;
			bFind = FALSE;
			for(pos=m_TreeInfoList.GetHeadPosition(); NULL!=pos;)
			{
				j++;

				if(m_TreeInfoList.GetAt(pos).nTag == i)
				{
					bFind = TRUE;
					break;
				}
				
				m_TreeInfoList.GetNext(pos);
			}

			if((j == nCount) && !bFind)
			{
				nTag = i;
				bAddMaxTag = FALSE;
				break;
			}
		}

		if(bAddMaxTag)
		{
			nTag = nMaxTag + 1;
		}

		pos = NULL;
	}

	return pos;
}

void CLeftTreeView::SetDeletedItemTagFlag()
{
	POSITION pos1=NULL;
	POSITION pos2=NULL;
	CString szSQL("");
	CString szTemp(""),szIn("");
	
	if((m_TreeInfoList.GetCount() < 1) 
		|| (m_SelectedItemTagList.GetCount() < 1))
	{
		return;
	}

	for(pos1=m_SelectedItemTagList.GetHeadPosition(); NULL!=pos1;)
	{
		for(pos2=m_TreeInfoList.GetHeadPosition(); NULL!=pos2;) 
		{
			int nTag=m_SelectedItemTagList.GetAt(pos1);
			if(nTag == m_TreeInfoList.GetAt(pos2).nTag)
			{
				szTemp.Format(_T("'%d'"), nTag);
				szIn += szTemp + ",";
				m_TreeInfoList.GetAt(pos2).nDeleted = 1;
				break;
			}

			m_TreeInfoList.GetNext(pos2);
		}

		m_SelectedItemTagList.GetNext(pos1);
	}

	if(!szIn.IsEmpty())
	{
		szTemp = szIn.Left(szIn.GetLength() - 1);
		szSQL.Format(_T("DELETE * FROM Article WHERE Tag IN (%s)"), szTemp);
		m_ADO.ExeSQL(szSQL, TRUE);
		szSQL.Format(_T("DELETE * FROM TreeNode WHERE Tag IN (%s)"), szTemp);
		m_ADO.ExeSQL(szSQL, TRUE);
	}
	
}

BOOL CLeftTreeView::ShowArticleByTreeItemTag(const int nTag)
{
	CString szSQL("");
	CString szValue("");
	
	
	szSQL.Format(_T("SELECT * FROM Article WHERE Tag='%d'"), nTag);
	m_ADO.ExeSQL(szSQL);
	
	if(m_ADO.GetRecordCount() > 0)
	{
		m_ADO.MoveFirst();
		m_ADO.GetFieldValue("Article", szValue);
	}

	CMainFrame *pMainFrame = (CMainFrame*)GetParent()->GetParent(); 
	CSkillBookView *pView = (CSkillBookView *)pMainFrame->m_wndSplitter.GetPane(0,1); 

	pView->GetRichEditCtrl().SetWindowText(szValue);

	return TRUE;
}

BOOL CLeftTreeView::SaveArticleByTreeItemTag(const int nTag)
{
	if(nTag == -1)
	{
		return FALSE;
	}

	CString szSQL("");
	CString szValue("");
	
	szSQL.Format(_T("SELECT * FROM Article WHERE Tag='%d'"), nTag);
	m_ADO.ExeSQL(szSQL);
	
	if(m_ADO.GetRecordCount() > 0)
	{
		m_ADO.MoveFirst();
	}
	else
	{
		m_ADO.AddNew();
	}

	CMainFrame *pMainFrame = (CMainFrame*)GetParent()->GetParent(); 
	CSkillBookView *pView = (CSkillBookView *)pMainFrame->m_wndSplitter.GetPane(0,1); 

	szValue.Format(_T("%d"), nTag);
	m_ADO.SetFieldValue("Tag", szValue);

	pView->GetRichEditCtrl().GetWindowText(szValue);
	m_ADO.SetFieldValue("Article", szValue);

	m_ADO.Update();

	return TRUE;
}

void CLeftTreeView::OnMenuAddrootnode() 
{
	// TODO: Add your command handler code here
	AddRootNode();
}

void CLeftTreeView::AddRootNode()
{
	int nTag=0;
	char szText[255];
	POSITION pos=NULL;
	TV_INSERTSTRUCT TCItem;//定义插入项数据结构
	HTREEITEM hParent=TVI_ROOT;

	sprintf(szText, "%s", "新增目录");

	//设置父项句柄
	TCItem.hParent = hParent;
	//在最后增加
	TCItem.hInsertAfter = TVI_LAST;
	TCItem.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
	TCItem.item.pszText = szText;
	//索引号增加
	pos = GetFreeItemTag(nTag);
	TCItem.item.lParam = nTag;
	//正常图标
	TCItem.item.iImage = 0;
	//选中时图标
	TCItem.item.iSelectedImage = 1;
	//增加
	HTREEITEM hInsert = m_pTreeSkill->InsertItem(&TCItem);
	
	m_pTreeSkill->Expand(hParent, TVE_EXPAND);
	//修改增加的数据
	m_bCanEditLabel = TRUE;
	m_pTreeSkill->EditLabel(hInsert);

	TREEINFO treeinfo;

	treeinfo.nType = 0;
	treeinfo.nTag = int(TCItem.item.lParam);
	treeinfo.nDeleted = 0;

	if(NULL == pos)
	{
		m_TreeInfoList.AddTail(treeinfo);
	}
	else
	{
		m_TreeInfoList.SetAt(pos, treeinfo);
	}
}

void CLeftTreeView::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	*pResult = 0;
	//如果是无意拖曳,则放弃操作
	if((GetTickCount() - m_dwDragStart) < DRAG_DELAY)
	{
		return;
	}

	m_hItemDragS = pNMTreeView->itemNew.hItem;
	m_hItemDragD = NULL;

	//得到用于拖动时显示的图象列表
	m_pDragImage = m_pTreeSkill->CreateDragImage(m_hItemDragS);
	if(NULL == m_pDragImage)
	{
		return;
	}

	m_bDragging = TRUE;
	m_pDragImage->BeginDrag (0,CPoint(8,8));
	CPoint  pt = pNMTreeView->ptDrag;
	ClientToScreen(&pt);
	m_pDragImage->DragEnter(this, pt);  //"this"将拖曳动作限制在该窗口
	SetCapture();

	m_nScrollTimerID = SetTimer(2, 40, NULL);
}

void CLeftTreeView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	HTREEITEM  hItem;
	UINT       flags;

	//检测鼠标敏感定时器是否存在,如果存在则删除,删除后再定时
	if(m_nHoverTimerID)
	{
		KillTimer( m_nHoverTimerID );
		m_nHoverTimerID = 0;
	}

	m_nHoverTimerID = SetTimer(1, 800, NULL);  //定时为 0.8 秒则自动展开
	m_HoverPoint = point;

	if(m_bDragging)
	{
		CPoint  pt = point;
		CImageList::DragMove(pt);

		//鼠标经过时高亮显示
		CImageList::DragShowNolock(FALSE);  //避免鼠标经过时留下难看的痕迹
		if((hItem = m_pTreeSkill->HitTest(point,&flags)) != NULL)
		{
			m_pTreeSkill->SelectDropTarget(hItem);
			m_hItemDragD = hItem;
		}
		CImageList::DragShowNolock(TRUE);

		//当条目被拖曳到左边缘时,将条目放在根下
		CRect  rect;

		GetClientRect( &rect );
		if( point.x < rect.left + 20 )
		{
			m_hItemDragD = NULL;
		}
	}

	CTreeView::OnMouseMove(nFlags, point);
}

void CLeftTreeView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CTreeView::OnLButtonUp(nFlags, point);

	if(m_bDragging)
	{
		m_bDragging = FALSE;
		CImageList::DragLeave(this);
		CImageList::EndDrag();
		ReleaseCapture();
		delete m_pDragImage;

		m_pTreeSkill->SelectDropTarget(NULL);
		
		if(m_hItemDragS == m_hItemDragD)
		{
			KillTimer(m_nScrollTimerID);
			return;
		}
		else
		{
			if(m_hItemDragD != NULL)
			{
				int nTag = m_pTreeSkill->GetItemData(m_hItemDragD);
				
				if(GetItemTypeByTag(nTag) == 1)
				{//拖放目标是文章
					KillTimer(m_nScrollTimerID);
					return;
				}
			}
		}

		m_pTreeSkill->Expand(m_hItemDragD,TVE_EXPAND);

		HTREEITEM  htiParent = m_hItemDragD;
		while((htiParent = m_pTreeSkill->GetParentItem(htiParent)) != NULL)
		{
			if(htiParent == m_hItemDragS)
			{
				HTREEITEM  htiNewTemp = CopyBranch(m_hItemDragS,NULL,TVI_LAST);
				HTREEITEM  htiNew = CopyBranch(htiNewTemp,m_hItemDragD,TVI_LAST);
				m_pTreeSkill->DeleteItem(htiNewTemp);
				m_pTreeSkill->SelectItem(htiNew);
				KillTimer(m_nScrollTimerID);
				return;
			}
		}

		HTREEITEM  htiNew = CopyBranch(m_hItemDragS, m_hItemDragD, TVI_LAST);
		m_pTreeSkill->DeleteItem(m_hItemDragS);
		m_pTreeSkill->SelectItem(htiNew);
		KillTimer(m_nScrollTimerID);
	}
}

//拷贝条目
HTREEITEM CLeftTreeView::CopyItem(HTREEITEM hItem, HTREEITEM htiNewParent, HTREEITEM htiAfter)
{
	TV_INSERTSTRUCT  tvstruct;
	HTREEITEM        hNewItem;
	CString          sText;

	//得到源条目的信息
	tvstruct.item.hItem = hItem;
	tvstruct.item.mask  = TVIF_CHILDREN|TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
	m_pTreeSkill->GetItem(&tvstruct.item);
	sText = m_pTreeSkill->GetItemText(hItem);
	tvstruct.item.cchTextMax = sText.GetLength();
	tvstruct.item.pszText    = sText.LockBuffer();

	//将条目插入到合适的位置
	tvstruct.hParent         = htiNewParent;
	tvstruct.hInsertAfter    = htiAfter;
	tvstruct.item.mask       = TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
	hNewItem = m_pTreeSkill->InsertItem(&tvstruct);
	sText.ReleaseBuffer();

	//限制拷贝条目数据和条目状态
	m_pTreeSkill->SetItemData(hNewItem, m_pTreeSkill->GetItemData(hItem));
	m_pTreeSkill->SetItemState(hNewItem, m_pTreeSkill->GetItemState(hItem, TVIS_STATEIMAGEMASK), TVIS_STATEIMAGEMASK);

	return hNewItem;
}

//拷贝分支
HTREEITEM CLeftTreeView::CopyBranch(HTREEITEM htiBranch, HTREEITEM htiNewParent, HTREEITEM htiAfter)
{
	HTREEITEM  hChild;
	HTREEITEM  hNewItem = CopyItem(htiBranch,htiNewParent,htiAfter);
	hChild = m_pTreeSkill->GetChildItem(htiBranch);

	while(hChild != NULL)
	{
		CopyBranch(hChild,hNewItem,htiAfter);
		hChild = m_pTreeSkill->GetNextSiblingItem(hChild);
	}

	return  hNewItem;
}

void CLeftTreeView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	//鼠标敏感节点
	if(nIDEvent == m_nHoverTimerID)
	{
		KillTimer(m_nHoverTimerID);
		m_nHoverTimerID = 0;
		HTREEITEM  trItem = 0;
		UINT  uFlag = 0;
		trItem = m_pTreeSkill->HitTest(m_HoverPoint, &uFlag);

		if(trItem && m_bDragging)
		{
			m_pTreeSkill->SelectItem(trItem);
			m_pTreeSkill->Expand(trItem, TVE_EXPAND);
		}
	}
	//处理拖曳过程中的滚动问题
	else if(nIDEvent == m_nScrollTimerID)
	{
		CPoint  pt;
		CRect  rect;

		m_TimerTicks++;
		GetCursorPos(&pt);
		GetClientRect(&rect);
		ClientToScreen(&rect);

		HTREEITEM  hItem = m_pTreeSkill->GetFirstVisibleItem();
		
		if( pt.y < rect.top +10 )
		{
			//向上滚动
			int  slowscroll = 6 - (rect.top + 10 - pt.y )/20;
			if(0 == (m_TimerTicks % ((slowscroll > 0) ? slowscroll : 1)))
			{
				CImageList::DragShowNolock(FALSE);
				SendMessage(WM_VSCROLL,SB_LINEUP);
				m_pTreeSkill->SelectDropTarget(hItem);
				m_hItemDragD = hItem;
				CImageList::DragShowNolock(TRUE);
			}
		}
		else if(pt.y > rect.bottom - 10)
		{
			//向下滚动
			int  slowscroll = 6 - (pt.y - rect.bottom + 10)/20;
			if(0 == (m_TimerTicks % ((slowscroll > 0) ? slowscroll : 1)))
			{
				CImageList::DragShowNolock(FALSE);
				SendMessage( WM_VSCROLL,SB_LINEDOWN );
				int  nCount = m_pTreeSkill->GetVisibleCount();
				for(int i=0; i<nCount-1; i++)
				{
					hItem = m_pTreeSkill->GetNextVisibleItem(hItem);
				}

				if(NULL != hItem)
				{
					m_pTreeSkill->SelectDropTarget(hItem);
				}

				m_hItemDragD = hItem;
				CImageList::DragShowNolock(TRUE);
			}
		}
	}
	else
	{
		CTreeView::OnTimer(nIDEvent);
	}
}

void CLeftTreeView::SaveCurrentArticle()
{
	SaveArticleByTreeItemTag(m_nCurrentSelTag);
}

void CLeftTreeView::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult) 
{
	TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
	// TODO: Add your control notification handler code here
	if(m_bCanEditLabel)
	{
		*pResult = 0;
	}
	else
	{
		*pResult = 1;
	}
}

void CLeftTreeView::OnMenuRename() 
{
	// TODO: Add your command handler code here
	HTREEITEM hItem=m_pTreeSkill->GetSelectedItem();

	m_bCanEditLabel = TRUE;
	m_pTreeSkill->EditLabel(hItem);
}

void CLeftTreeView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	CRect rcclient;
	GetClientRect(&rcclient);

	// create a compatible memory dc 
	CDC memdc;
	memdc.CreateCompatibleDC(&dc);	
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
	memdc.SelectObject( &bitmap );

	CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);

	CDC maskdc;
	maskdc.CreateCompatibleDC(&dc);
	CBitmap maskbitmap;
	maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
	maskdc.SelectObject( &maskbitmap );
	maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc, 
		rcclient.left, rcclient.top, SRCCOPY);

	CBrush brush;
	brush.CreatePatternBrush(&m_bitmap);
	dc.FillRect(rcclient, &brush);	
	
	memdc.SetBkColor(RGB(0,0,0));          
	memdc.SetTextColor(RGB(255,255,255));  
	memdc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);	

	dc.SetBkColor(RGB(255,255,255));
	dc.SetTextColor(RGB(0,0,0));
	dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);
	
	dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &memdc, 
					rcclient.left, rcclient.top,SRCPAINT);
	brush.DeleteObject();
	// Do not call CTreeView::OnPaint() for painting messages
}

BOOL CLeftTreeView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	return TRUE;
//	return CTreeView::OnEraseBkgnd(pDC);
}

void CLeftTreeView::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	Invalidate();
//	m_pTreeSkill->SetRedraw(TRUE);
	SetRedraw(TRUE);
	
	*pResult = 0;
}

void CLeftTreeView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	SetRedraw(FALSE);
//	m_pTreeSkill->SetRedraw(FALSE);
	
	*pResult = 0;
}

LRESULT CLeftTreeView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	return CTreeView::WindowProc(message, wParam, lParam);
}

⌨️ 快捷键说明

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