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

📄 collectionlisttree.cpp

📁 离线的RSS阅读器
💻 CPP
字号:
// CollectionListTree.cpp : implementation file
//

#include "stdafx.h"
#include "DiamondReader.h"
#include "CollectionListTree.h"
#include "ToolBarView.h"
#include "MainFrm.h"
#include "CppSQLite3.h"
#include "db.h"
#include "sqlite3.h"
#include "helper.h"
#include "ItemListView.h"
#include "NewCategory.h"
#include "ModifyCategoryDlg.h"
#include "ExploreView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCollectionListTree

CCollectionListTree::CCollectionListTree()
{
	m_isDrag = false;
}

CCollectionListTree::~CCollectionListTree()
{
}


BEGIN_MESSAGE_MAP(CCollectionListTree, CTreeCtrl)
	//{{AFX_MSG_MAP(CCollectionListTree)
	ON_COMMAND(IDR_COLLECTION_NEWCATEGORY, OnCollectionNewcategory)
	ON_COMMAND(IDR_COLLECTION_DELETECATEGORY, OnCollectionDeletecategory)
	ON_COMMAND(IDR_COLLECTION_MODIFYCATEGORY, OnCollectionModifycategory)
	ON_COMMAND(IDR_COLLECTION_DELETEURL,onDeleteCollection)
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
	//}}AFX_MSG_MAP

	ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_RBUTTONDOWN()
	ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteitem)
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
	ON_NOTIFY_REFLECT(NM_KILLFOCUS, OnKillfocus)
	ON_WM_CREATE()
	ON_NOTIFY_REFLECT(NM_SETFOCUS, OnSetfocus)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCollectionListTree message handlers

void CCollectionListTree::OnCreate(LPCREATESTRUCT lpCreateStruct){
	CTreeCtrl::OnCreate(lpCreateStruct);
	//创建图像列表
	m_image.Create(16,16,ILC_COLOR32,0,4);
	char *names[] = {"目录.bmp","频道.bmp","收藏.bmp"};
	//创建图像列表
	buildImageList(&m_image,names,3);
	//设置图片列表
	this->SetImageList(&m_image,TVSIL_NORMAL);

	//读取数据库,创建目录树
	MyTreeNode *result = DBBuildTree(1,db);
	makeTree(result,this);
}

//开始拖动
void CCollectionListTree::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	//设置状态为拖动状态
	m_isDrag = true;
	//保存拖动到节点
	m_dragItem = pNMTreeView->itemNew.hItem;
	this->Select(m_dragItem,TVGN_CARET);
	//设置拖动到图标
	m_dragImage = this->CreateDragImage(m_dragItem);
	m_dragImage->DragEnter(this,pNMTreeView->ptDrag);
	m_dragImage->BeginDrag(0,CPoint(0,0));
	*pResult = 0;
	
	
}

void CCollectionListTree::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	//在拖动状态时,做以下的操作
	if (m_isDrag)
	{
		m_dragImage->DragEnter(this,point);
		m_dragImage->DragMove(point);
	}
	CTreeCtrl::OnMouseMove(nFlags, point);
}

void CCollectionListTree::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	//如果处于拖动状态,鼠标左键抬起时,结束拖动
	if (m_isDrag)
	{
		//设置拖动状态
		m_isDrag = false;
		m_dragImage->EndDrag();
		delete m_dragImage;
		//获取拖动后添加节点的位置
		HTREEITEM hTar = this->HitTest(point);
		
		//如果放在一个可以放到地方
		if (hTar!=NULL)
		{
			HTREEITEM hp = hTar;
			while (hp!=NULL)
			{
				if(hp==m_dragItem){
					return;
				}
				hp = this->GetParentItem(hp);
			}

			if (hTar==GetParentItem(m_dragItem))
			{
				return;
			}
			//获取当前拖动节点的数据
			MyTreeNode * p = (MyTreeNode*)this->GetItemData(hTar);
			//拖动到节点为目录节点
			if (p->type==0)
			{
				//获取拖动节点的text
				CString str = this->GetItemText(m_dragItem);
				//新建一个节点,插入到目标节点下
				HTREEITEM newpos = this->InsertItem(str,hTar);
				//获取拖动节点的旧的父节点的数据
				MyTreeNode * temp = (MyTreeNode*)this->GetItemData(m_dragItem);
				//新创建节点的数据
				MyTreeNode * data;
				//判断拖动节点的类型
				if (temp->type==0)
				{
					//拖动到是目录
					//创建一个目录结构的数据结构
					data = new DirNode(temp->name);
					//复制拖动到节点的数据到新的阶段
					data->id = temp->id;
					data->nextSubling = temp->nextSubling;
					data->type = temp->type;
					DirNode *d = (DirNode*)data;
					DirNode *t = (DirNode*)temp;
					d->firstChild = t->firstChild;
				}
				else if (temp->type==2)
				{
					//拖动到是收藏节点
					//创建收藏节点
					CollectionNode *collTemp = (CollectionNode*)temp;
					data = new CollectionNode(temp->name,collTemp->url);
					//复制数据
					data->id = temp->id;
					data->nextSubling = temp->nextSubling;
					data->type = temp->type;
				}
				else{
					data = NULL;
				}
				//设置新节点的数据
				this->SetItemData(newpos,(DWORD)data);
				//设置图片
				this->SetItemImage(newpos,data->type,data->type);
				//断开以前的树,构建新的树
				HTREEITEM parent = this->GetParentItem(m_dragItem);
				DirNode *parentData = (DirNode*)GetItemData(parent);

				

				parentData->firstChild  = data->nextSubling;
				DirNode *tarData = (DirNode*)GetItemData(hTar);
				data->nextSubling = tarData->firstChild;
				tarData->firstChild = data;
				//更新数据库
				DBUpdateItem(parentData,temp->nextSubling,db);
				DBUpdateItem(tarData,data,db);
				this->DeleteItem(m_dragItem);
				MyTreeNode *mm = (MyTreeNode*)GetItemData(newpos);

// 				MyTreeNode *rootData = (MyTreeNode *)this->GetItemData(this->GetRootItem());
// 				this->DeleteAllItems();
// 				makeTree(rootData,this);

				_makeTree(mm,this,this->GetParentItem(newpos));
				this->Expand(this->GetParentItem(newpos),TVE_EXPAND);
				this->DeleteItem(newpos);
			}
			
		}
	}
	CTreeCtrl::OnLButtonUp(nFlags, point);
}

//右键菜单
void CCollectionListTree::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	HTREEITEM h = this->HitTest(point);
	CMenu menu;
	menu.LoadMenu(IDR_COLLECTION);
	CMenu *subMenu;
	//点在空白位置,显示相应的菜单
	if (h==NULL)
	{
		subMenu = menu.GetSubMenu(2);
	}
	else{
		DWORD d = GetItemData(h);
		//点在频道节点上面,显示相应的菜单
		if (((MyTreeNode*)d)->type)
		{
			this->SelectItem(h);
			subMenu = menu.GetSubMenu(1);
		}
		//点在目录上,显示相应的菜单
		else{
			this->SelectItem(h);
			this->Expand(h,TVE_EXPAND);
			subMenu = menu.GetSubMenu(0);
		}
		
	}
	//弹出菜单
	this->ClientToScreen(&point);
	subMenu->TrackPopupMenu(TPM_RIGHTALIGN,point.x,point.y,this);
	//CTreeCtrl::OnRButtonDown(nFlags, point);
}

void CCollectionListTree::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
}

//选择改变
void CCollectionListTree::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	//设置某些按钮的状态
	MyTreeNode *data = (MyTreeNode*)this->GetItemData(pNMTreeView->itemNew.hItem);
	CMainFrame *mf = (CMainFrame*)AfxGetMainWnd();
	CToolBarView *view = (CToolBarView*)mf->m_spli4.GetPane(0,0);
	view->disableButton(data->type);

	//选择的是频道则显示频道
	if (data->type==2)
	{
		CollectionNode *node = (CollectionNode*)data;
		CExploreView *view2 = (CExploreView*)mf->m_spli3.GetPane(1,0);
		view2->Navigate(node->url);
	}

	*pResult = 0;
}


void CCollectionListTree::OnKillfocus(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
// 	CMainFrame *mf = (CMainFrame*)AfxGetMainWnd();
// 	CToolBarView *view = (CToolBarView*)mf->m_spli4.GetPane(0,0);
// 	view->disableButton(2);
	*pResult = 0;
}


void CCollectionListTree::OnSetfocus(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
// 	MyTreeNode *data = (MyTreeNode*)this->GetItemData(this->GetSelectedItem());
// 	CMainFrame *mf = (CMainFrame*)AfxGetMainWnd();
// 	CToolBarView *view = (CToolBarView*)mf->m_spli4.GetPane(0,0);
// 	view->disableButton(data->type);
	*pResult = 0;
}

void CCollectionListTree::OnCollectionNewcategory() 
{
	// TODO: Add your command handler code here

	char c = ' ';
	char *newName = &c;
	CNewCategory cng(&newName);
	if (cng.DoModal()!=1)
	{
		return;
	}
	
	HTREEITEM h = this->GetSelectedItem();
	if (h==NULL)
	{
		h = this->GetRootItem();
	}
	MyTreeNode *m = (MyTreeNode*)this->GetItemData(h);
	if (m->type==1)
	{
		return ;
	}
	DirNode *dir = (DirNode*)m;
	MyTreeNode *child = dir->firstChild;
	while (child!=NULL)
	{
		if (!strcmp(child->name,newName)&&child->type==0)
		{
			AfxMessageBox("分类已存在");
			return ;
		}
		child = child->nextSubling;
	}
	DirNode *newdir = new DirNode(newName);
	MyTreeNode *p = dir->firstChild;
	dir->firstChild = newdir;
	newdir->nextSubling = p;
	h = this->InsertItem(newName,h);
	this->SetItemImage(h,0,0);
	this->SetItemData(h,(DWORD)newdir);
	this->Invalidate();
	DBInsertItem(dir,newdir,db);
}

void CCollectionListTree::OnCollectionDeletecategory() 
{
	// TODO: Add your command handler code here
	HTREEITEM h = this->GetSelectedItem();
	if(h==this->GetRootItem()){
		AfxMessageBox("您不能删除此目录");
		return;
	}
	MyTreeNode* data = (MyTreeNode*)this->GetItemData(h);
	//此动作不会发生
	if (data->type!=0)
	{
		return;
	}
	DirNode *node = (DirNode*)data;
	//下面有子节点
	if (node->firstChild!=NULL)
	{
		
	}
	HTREEITEM hparent = this->GetParentItem(h);
	if (hparent==NULL)
	{
		//不允许删除根节点
		return;
	}
	DirNode *parentData = (DirNode*)this->GetItemData(hparent);
	deleteCategoryData(parentData,data);
	if(data==parentData->firstChild){
		parentData->firstChild = data->nextSubling;
		delete data;
	}
	else{
		MyTreeNode *child = parentData->firstChild;
		while (child->nextSubling!=data)
		{
			child = child->nextSubling;
		}
		child->nextSubling = data->nextSubling;

		deleteTreeNode(data);
	}
	
	this->DeleteItem(h);
	this->Invalidate();
	
}

void CCollectionListTree::OnCollectionModifycategory() 
{
	// TODO: Add your command handler code here
	HTREEITEM h = this->GetSelectedItem();
	char c;
	char *pc = &c;
	//char **newName=NULL;
	CModifyCategoryDlg *cmgd = new CModifyCategoryDlg((LPTSTR)(LPCTSTR)this->GetItemText(h),&pc);
	if (!cmgd->DoModal())
	{
		DirNode *data = (DirNode*)GetItemData(h);
	
		HTREEITEM hparert = GetParentItem(h);
		if (hparert!=NULL)
		{
			MyTreeNode *sublings = (DirNode *)GetItemData(hparert);
			while (sublings)
			{
				if (!strcmp(pc,sublings->name))
				{
					AfxMessageBox("分类名已经存在");
					return;
				}
				sublings = sublings->nextSubling;
			}
		}

		delete data->name;
		data->name = pc;
		this->SetItemText(h,pc);

		char sql[255];
		sprintf(sql,"update DirList set name='%s' where id=%d",pc,data->id);
		sqlite3_exec(db,sql,NULL,NULL,NULL);
	}
	
}

void CCollectionListTree::onDeleteCollection(){
	HTREEITEM h = this->GetSelectedItem();
	HTREEITEM hParent = this->GetParentItem(h);
	CollectionNode *delItemData = (CollectionNode*)this->GetItemData(h);
	DirNode *parentData = (DirNode*)this->GetItemData(hParent);
	DBDeleteItem(parentData,delItemData,db);

	MyTreeNode *child = parentData->firstChild;
	if (child==delItemData)
	{
		parentData->firstChild = delItemData->nextSubling;
		delete delItemData;
	}
	else{
		while (child->nextSubling!=delItemData)
		{
			child = child->nextSubling;
		}
		child->nextSubling = delItemData->nextSubling;
		delete delItemData;
	}
	this->DeleteItem(h);
}

HTREEITEM CCollectionListTree::getItemByData(MyTreeNode *data,HTREEITEM h){
	MyTreeNode *nodeData = (MyTreeNode*)this->GetItemData(h);
	if (data==nodeData)
	{
		return h;
	}
	if (data->type)
	{
		return NULL;
	}
	HTREEITEM child = this->GetChildItem(h);
	while (child)
	{
		
		if (this->getItemByData(data,child))
		{
			return child;
		}
		child = this->GetNextSiblingItem(child);
	}
	return NULL;
}

⌨️ 快捷键说明

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