📄 channellisttree.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 + -