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

📄 channellisttree.cpp

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

//频道树
#include "stdafx.h"
#include "DiamondReader.h"
#include "ChannelListTree.h"
#include "ToolBarView.h"
#include "MainFrm.h"
#include "CppSQLite3.h"
#include "db.h"
#include "sqlite3.h"
#include "helper.h"
#include "ItemListView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CChannelListTree

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

CChannelListTree::~CChannelListTree()
{
}

IMPLEMENT_DYNCREATE(CChannelListTree, CTreeCtrl)
BEGIN_MESSAGE_MAP(CChannelListTree, CTreeCtrl)
	//{{AFX_MSG_MAP(CChannelListTree)
	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)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChannelListTree message handlers

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
    int i;
    for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

void CChannelListTree::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);

	const char* gszFile = "C:\\diamondReader.db";

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

//开始拖动
void CChannelListTree::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 CChannelListTree::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 CChannelListTree::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 (m_dragItem==GetRootItem())
		{
			return;
		}
		//如果放在一个可以放到地方
		if (hTar!=NULL)
		{
			HTREEITEM hp = hTar;
			while (hp!=NULL)
			{
				if(hp==m_dragItem){
					return;
				}
				hp = this->GetParentItem(hp);
			}
			hp = this->GetParentItem(m_dragItem);
			if (hp==NULL)
			{
				//拖动根节点
				MyTreeNode *data = (MyTreeNode*)this->GetItemData(m_dragItem);
				MyTreeNode *rootData = (MyTreeNode*)this->GetItemData(this->GetRootItem());
				while (rootData->nextSubling!=data)
				{
					rootData = rootData->nextSubling;
				}
				rootData->nextSubling = data->nextSubling;
				this->DeleteItem(m_dragItem);
				int nextSublingID = -1;
				if (data->nextSubling)
				{
					nextSublingID = data->nextSubling->id;
				}
				char sql[255];
				sprintf(sql,"update Dirlist set nextsublingID=%d where id = %d",nextSublingID,rootData->id);
				sqlite3_exec(db,sql,NULL,NULL,NULL);
				
				DirNode *parentData = (DirNode*)this->GetItemData(hTar);
				data->nextSubling = parentData->firstChild;
				parentData->firstChild = data;
				HTREEITEM hnew = this->InsertItem(data->name,hTar);
				this->SetItemData(hnew,(DWORD)data);
				this->SetItemImage(hnew,0,0);
				
				sprintf(sql,"update DirList set firstChildID=%d where id = %d",data->id,parentData->id);
				sqlite3_exec(db,sql,NULL,NULL,NULL);
				nextSublingID = -1;
				if (data->nextSubling)
				{
					nextSublingID = data->nextSubling->id;
				}
				sprintf(sql,"update DirList set nextSublingID=%d where id=%d",nextSublingID,data->id);
				sqlite3_exec(db,sql,NULL,NULL,NULL);
				
				_makeTree(data,this,hTar);

				this->DeleteItem(hnew);
				return;

			}

			//获取当前拖动节点的数据
			MyTreeNode * p = (MyTreeNode*)this->GetItemData(hTar);
			//拖动到节点为目录节点
			if (p->type==0)
			{
				if (hTar==GetParentItem(m_dragItem))
				{
					return;
				}
				//获取拖动节点的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==1)
				{
					//拖动到是节点
					//创建频道节点
					data = new ChannelNode(temp->name);
					//复制数据
					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->DeleteItem(newpos);
			}
			
		}
		else{
			HTREEITEM hparent = this->GetParentItem(m_dragItem);
			if (hparent==NULL)
			{
				return;
			}
			DirNode *parentData = (DirNode*)this->GetItemData(hparent);
			MyTreeNode *data = (MyTreeNode*)this->GetItemData(m_dragItem);
			if (data->type)
			{
				return;
			}
			if(data == parentData->firstChild){
				parentData->firstChild = data->nextSubling;
				int firstChildID = -1;
				if (data->nextSubling)
				{
					firstChildID = data->nextSubling->id;
					
				}
				char sql[255];
					sprintf(sql,"update dirlist set firstChildID=%d where id =%d",firstChildID,parentData->id);
					sqlite3_exec(db,sql,NULL,NULL,NULL);
			}
			else{
				MyTreeNode *child = parentData->firstChild;
				while (child->nextSubling!=data)
				{
					child = child->nextSubling;
				}
				child->nextSubling = data->nextSubling;
				int nextSublingID = -1;
				if(data->nextSubling){
					nextSublingID = data->nextSubling->id;
				}
				char sql[255];
				if (child->type)
				{
					sprintf(sql,"update channelList set nextSublingID=%d where id =%d",nextSublingID,parentData->id);
					sqlite3_exec(db,sql,NULL,NULL,NULL);
				}
				else{
					
					sprintf(sql,"update dirlist set nextSublingID=%d where id =%d",nextSublingID,parentData->id);
					sqlite3_exec(db,sql,NULL,NULL,NULL);
				}
			}
			
			
			this->DeleteItem(m_dragItem);
			MyTreeNode *roots = (MyTreeNode*)this->GetItemData(this->GetRootItem());
			while (roots->nextSubling)
			{
				roots = roots->nextSubling;
			}
			roots->nextSubling = data;
			data->nextSubling = NULL;
			char sql[255];
			sprintf(sql,"update dirlist set nextSublingID=%d where id =%d",data->id,roots->id);
			sqlite3_exec(db,sql,NULL,NULL,NULL);
			sprintf(sql,"update dirlist set nextSublingID=-1 where id =%d",data->id);
			sqlite3_exec(db,sql,NULL,NULL,NULL);

			//HTREEITEM newpos = this->InsertItem(data->name,TVI_ROOT,TVI_LAST);
			_makeTree(data,this,TVI_ROOT);
		}
	}
	CTreeCtrl::OnLButtonUp(nFlags, point);
}

//右键菜单
void CChannelListTree::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_CHANNELLIST);
	CMenu *subMenu;
	//点在空白位置,显示相应的菜单
	if (h==NULL)
	{
		subMenu = menu.GetSubMenu(0);
	}
	else{
		DWORD d = GetItemData(h);
		//点在频道节点上面,显示相应的菜单
		if (((MyTreeNode*)d)->type)
		{
			this->SelectItem(h);
			subMenu = menu.GetSubMenu(2);
		}
		//点在目录上,显示相应的菜单
		else{
			this->SelectItem(h);
			this->Expand(h,TVE_EXPAND);
			subMenu = menu.GetSubMenu(1);
		}
		
	}
	//弹出菜单
	this->ClientToScreen(&point);
	subMenu->TrackPopupMenu(TPM_RIGHTALIGN,point.x,point.y,AfxGetMainWnd());
	//CTreeCtrl::OnRButtonDown(nFlags, point);
}

void CChannelListTree::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
// 	HTREEITEM h = pNMTreeView->itemOld.hItem;
// 	HTREEITEM parent = this->GetParentItem(h);
// 	DirNode *parentData = (DirNode *)GetItemData(parent);
// 	MyTreeNode *data = (MyTreeNode *)GetItemData(h);
// 	MyTreeNode *preSublingData = parentData->firstChild;	
// 	if (data == preSublingData)
// 	{
// 		parentData->firstChild = data->nextSubling;
// 		delete data;
// 		*pResult = 0;
// 		return;
// 	}
// 	while(data!=preSublingData->nextSubling){
// 		preSublingData = preSublingData->nextSubling;
// 	}
// 	preSublingData->nextSubling = data->nextSubling;
// 	delete data;
// 	*pResult = 0;
}

//选择改变
void CChannelListTree::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==1)
	{
		CItemListView *view2 = (CItemListView*)mf->m_spli2.GetPane(0,0);
		//获取频道的id,并从数据库中获取他的所有项
		ItemList *items = DBGetItemById(data->id,db);
		//显示频道
		view2->showChannel(items);
	}

	*pResult = 0;
}


void CChannelListTree::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 CChannelListTree::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;
}

⌨️ 快捷键说明

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