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

📄 lefttreeview.cpp

📁 本例通过ADO技术
💻 CPP
字号:
// LeftTreeView.cpp : implementation file
//

#include "stdafx.h"
#include "Chapter21.h"
#include "LeftTreeView.h"
#include "MainFrm.h"

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

/////////////////////////////////////////////////////////////////////////////
// CLeftTreeView

IMPLEMENT_DYNCREATE(CLeftTreeView, CFormView)

CLeftTreeView::CLeftTreeView()
	: CFormView(CLeftTreeView::IDD)
{
	//{{AFX_DATA_INIT(CLeftTreeView)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}

CLeftTreeView::~CLeftTreeView()
{
}

void CLeftTreeView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CLeftTreeView)
	DDX_Control(pDX, IDC_TREE, m_treeCtrl);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CLeftTreeView, CFormView)
	//{{AFX_MSG_MAP(CLeftTreeView)
	ON_WM_SIZE()
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelchangedTree)
	ON_NOTIFY(NM_KILLFOCUS, IDC_TREE, OnKillfocusTree)
	ON_WM_CONTEXTMENU()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CLeftTreeView diagnostics

#ifdef _DEBUG
void CLeftTreeView::AssertValid() const
{
	CFormView::AssertValid();
}

void CLeftTreeView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CLeftTreeView message handlers

void CLeftTreeView::OnSize(UINT nType, int cx, int cy) 
{
	CFormView::OnSize(nType, cx, cy);
	CFormView::ShowScrollBar(SB_BOTH,FALSE);
	// TODO: Add your message handler code here
	//使树控件填满整个视图
	if (GetSafeHwnd())
	{
		CRect rect;
		GetClientRect(&rect);
		if (m_treeCtrl.GetSafeHwnd())
			m_treeCtrl.MoveWindow(&rect);
	}
}

void CLeftTreeView::OnInitialUpdate() 
{
	CFormView::OnInitialUpdate();	
	// TODO: Add your specialized code here and/or call the base class
	m_ImageList.Create(IDB_TREE, 32, 1, RGB(255, 0, 255));	
	m_treeCtrl.SetImageList(&m_ImageList, LVSIL_NORMAL);
	m_hSelItem=NULL;
	//随机图标
	srand((unsigned)time(NULL));
	//首先调用一次rand(),这样才确保m_iImage起始值不同
	rand();
	m_iImage=(int)((float)rand()*8.0/(float)RAND_MAX);
	ShowTree();
}


void CLeftTreeView::OnSelchangedTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	CString strRoot, strFirstClass,strSecondClass;
	HTREEITEM hRootItem,hFirstClassItem,hSecondClassItem;
	HTREEITEM hSelItem,hParent;
	BOOL bHasChild;
	hSelItem=pNMTreeView->itemNew.hItem;
	m_hSelItem=hSelItem;
	//有无子
	bHasChild=m_treeCtrl.ItemHasChildren(hSelItem);
	//其父
	hParent=m_treeCtrl.GetParentItem(hSelItem);
	//二级类别
	if(!bHasChild)
	{
		hSecondClassItem=hSelItem;
		strSecondClass=m_treeCtrl.GetItemText(hSecondClassItem);
		hFirstClassItem=m_treeCtrl.GetParentItem(hSecondClassItem);
		strFirstClass=m_treeCtrl.GetItemText(hFirstClassItem);
		hRootItem=m_treeCtrl.GetParentItem(hFirstClassItem);
		strRoot=m_treeCtrl.GetItemText(hRootItem);
		//让辅助框架处理
		m_pRightPaneFrame->m_strFirstClass=strFirstClass;
		m_pRightPaneFrame->m_strSecondClass=strSecondClass;
		m_pRightPaneFrame->SendMessage(LIST_EVERYONE,2,0);
		
	}//所有联系人
	else if(hParent==NULL)
	{
		hRootItem=hSelItem;
		strRoot=m_treeCtrl.GetItemText(hRootItem);
		m_pRightPaneFrame->SendMessage(LIST_EVERYONE,0,0);
	}
	//一级类别
	else
	{
		hFirstClassItem=hSelItem;
		hRootItem=m_treeCtrl.GetParentItem(hFirstClassItem);
		strFirstClass=m_treeCtrl.GetItemText(hFirstClassItem);		
		strRoot=m_treeCtrl.GetItemText(hRootItem);
		m_pRightPaneFrame->m_strFirstClass=strFirstClass;
		m_pRightPaneFrame->SendMessage(LIST_EVERYONE,1,0);
	}

	*pResult = 0;
}

BOOL CLeftTreeView::OpenRecordSet(_RecordsetPtr &recPtr, CString &strSQL)
{
	CChapter21App* pApp=(CChapter21App*)AfxGetApp();
	//创建记录集对象
	m_pRecordset.CreateInstance(__uuidof(Recordset));
	//在ADO操作中建议语句中要常用try...catch()来捕获错误信息,
    //因为它有时会经常出现一些想不到的错误
	try
	{
		//从数据库中打开表
		recPtr->Open(strSQL.AllocSysString(), 
			pApp->m_pConnection.GetInterfacePtr(),
			adOpenDynamic,
			adLockOptimistic,
			adCmdText);
	}
	catch (_com_error e)
	{
		CString strError;
		strError.Format("警告:打开数据表时发生异常。 错误信息: %s",\
			e.ErrorMessage());
		AfxMessageBox(strError);
		return FALSE;
	}
	return TRUE;
}

void CLeftTreeView::ShowTree()
{
	//首先删除所有的树项
	m_treeCtrl.DeleteAllItems();
	CString strSQL;
	strSQL="select * from info";
	if(!OpenRecordSet(m_pRecordset,strSQL))
	{
		return;
	}
	//定义变量
	_variant_t varValue;	
	//从数据库中开始填充树
	HTREEITEM hRootItem,hFirstClassItem,hSecondClassItem;
	hRootItem=m_treeCtrl.InsertItem("所有联系人", 0, 1);
	int i=0;	
	m_pRecordset->MoveFirst();
	while(!m_pRecordset->adoEOF)
	{
		CString strClass;
		varValue=m_pRecordset->GetCollect("一级类别");
		strClass=VariantToCString(varValue);
		//添加二级类别
		hFirstClassItem=AddFirstClassToTree(hRootItem,strClass);
		varValue=m_pRecordset->GetCollect("二级类别");
		strClass=VariantToCString(varValue);
		hSecondClassItem=AddSecondClassToTree(hFirstClassItem,strClass);
		//展开根目录
		m_pRecordset->MoveNext();
	}
	//关闭
	m_pRecordset->Close();
	m_pRecordset=NULL;
	m_treeCtrl.Expand(hRootItem,TVE_EXPAND);
}

HTREEITEM CLeftTreeView::AddFirstClassToTree(HTREEITEM hRootItem, 
											 CString strFirstClass)
{
	//从数据库中开始填充树
	if(hRootItem==NULL)
		return NULL;
	
	if(m_treeCtrl.ItemHasChildren(hRootItem))
	{
		HTREEITEM hFirstClassItem=m_treeCtrl.GetChildItem(hRootItem);
		while(hFirstClassItem)
		{
			CString strItemText =m_treeCtrl.GetItemText(hFirstClassItem);
			if(strItemText==strFirstClass)
				return hFirstClassItem;
			hFirstClassItem=m_treeCtrl.GetNextSiblingItem(hFirstClassItem);
		}
	}
	//插入数据项数据结构
	TV_INSERTSTRUCT TCItem;
	TCItem.hParent =hRootItem;
	TCItem.hInsertAfter = TVI_LAST;
	//设屏蔽
	TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
	//序号
	TCItem.item.lParam=0;
	//正常图标
	TCItem.item.iImage=m_iImage;
	//选中时图标
	TCItem.item.iSelectedImage=m_iImage>4?m_iImage-4:m_iImage+1;	
	TCItem.item.pszText = (LPTSTR)(LPCTSTR)strFirstClass;
	HTREEITEM hFirstClassItemNew =m_treeCtrl.InsertItem(&TCItem);
	m_treeCtrl.SortChildren(hRootItem);
	return hFirstClassItemNew;
}

HTREEITEM CLeftTreeView::AddSecondClassToTree(HTREEITEM hFirstClassItem,
											  CString strSecondClass)
{
	//从数据库中开始填充树
	if(hFirstClassItem==NULL)
		return NULL;	
	if(m_treeCtrl.ItemHasChildren(hFirstClassItem))
	{
		HTREEITEM hSecondClassItem=m_treeCtrl.GetChildItem(hFirstClassItem);
		while(hSecondClassItem)
		{
			CString strItemText =m_treeCtrl.GetItemText(hSecondClassItem);
			if(strItemText==strSecondClass)
				return hSecondClassItem;
			hSecondClassItem=m_treeCtrl.GetNextSiblingItem(hSecondClassItem);
		}
	}
	//插入数据项数据结构
	TV_INSERTSTRUCT TCItem;
	TCItem.hParent =hFirstClassItem;
	TCItem.hInsertAfter = TVI_LAST;
	//设屏蔽
	TCItem.item.mask=TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
	//序号
	TCItem.item.lParam=0;
	//正常图标
	TCItem.item.iImage=m_iImage>4?m_iImage-3:m_iImage+2;
	//选中时图标
	TCItem.item.iSelectedImage=m_iImage>4?m_iImage-2:m_iImage+3;
	TCItem.item.pszText = (LPTSTR)(LPCTSTR)strSecondClass;

	HTREEITEM hSecondClassItemNew =m_treeCtrl.InsertItem(&TCItem);
	m_treeCtrl.SortChildren(hFirstClassItem);
	return hSecondClassItemNew;
}

CString CLeftTreeView::VariantToCString(const _variant_t &var)
{
	CString strValue;	
	switch (var.vt)
	{
	case VT_BSTR://字符串
	case VT_LPSTR:
	case VT_LPWSTR:
		strValue = (LPCTSTR)(_bstr_t)var;
		break;
	case VT_I1://无符号字符
	case VT_UI1:
		strValue.Format("%d", var.bVal);
		break;
	case VT_I2://短整型
		strValue.Format("%d", var.iVal);
		break;
	case VT_UI2://无符号短整型
		strValue.Format("%d", var.uiVal);
		break;
	case VT_INT://整型
		strValue.Format("%d", var.intVal);
		break;
	case VT_I4: //整型
	case VT_I8: //长整型
		 strValue.Format("%d", var.lVal);
		break;
	case VT_UINT://无符号整型
		strValue.Format("%d", var.uintVal);
		break;
	case VT_UI4: //无符号整型
	case VT_UI8: //无符号长整型
		 strValue.Format("%d", var.ulVal);
		 break;
	case VT_VOID:
		strValue.Format("%8x", var.byref);
		break;
	case VT_R4://浮点型
		strValue.Format("%.4f", var.fltVal);
		break;
	case VT_R8://双精度型
		strValue.Format("%.8f", var.dblVal);
		break;
	case VT_DECIMAL: //小数
		strValue.Format("%.8f", (double)var);
		break;
	case VT_CY:
		{
			COleCurrency cy = var.cyVal;
			strValue = cy.Format();
		}
		break;
	case VT_BLOB:
	case VT_BLOB_OBJECT:
	case 0x2011:
		strValue = "[BLOB]";
		break;
	case VT_BOOL://布尔型		
		strValue = var.boolVal ? "TRUE" : "FALSE";
		break;
	case VT_DATE: //日期型
		{
			DATE dt = var.date;
			COleDateTime da = COleDateTime(dt); 
			strValue = da.Format("%Y-%m-%d %H:%M:%S");
		}
		break;
	case VT_NULL://NULL值
	case VT_EMPTY://空
		 strValue = "";
		 break;
	case VT_UNKNOWN://未知类型
	default:
		strValue = "UN_KNOW";
		break;
	}
	return strValue;
}

void CLeftTreeView::OnKillfocusTree(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	CMainFrame* pMainFrm=(CMainFrame*)AfxGetMainWnd();
	//全部落选,以便在删除时可以判断删除情况啊	
	m_treeCtrl.SelectItem(NULL);  //TVM_GETNEXTITEM
	pMainFrm->bTreeSel=FALSE;
	*pResult = 0;
}

void CLeftTreeView::OnContextMenu(CWnd* pWnd, CPoint point) 
{
	// TODO: Add your message handler code here
	if (point != CPoint (-1, -1))
	{
		//选中点击的树项:
		CPoint ptTree = point;
		m_treeCtrl.ScreenToClient (&ptTree);		
		HTREEITEM hTreeItem =m_treeCtrl.HitTest(ptTree);
		if (hTreeItem != NULL)
		{
			//首先选中
			m_treeCtrl.SelectItem (hTreeItem);
		}
	}
	//赋予输入焦点
	m_treeCtrl.SetFocus ();
	//上下文菜单,命令由主框架处理
	CMainFrame* pMainFrm=(CMainFrame*)AfxGetMainWnd();
	CMenu menu;
    menu.LoadMenu(IDR_MAINFRAME);
    menu.GetSubMenu(1)
        ->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
        point.x, point.y,pMainFrm);
}

⌨️ 快捷键说明

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