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

📄 daotreeview.cpp

📁 Visual C++ 实践与提高--数据库篇的源代码。很好的东西。欢迎下载。
💻 CPP
字号:
// DAOTreeView.cpp : implementation of the CDAOTreeView class
//

#include "stdafx.h"
#include "DAOQry.h"
#include "DAOQryDoc.h"
#include "DAOTreeView.h"
#include "DaoListView.h"
#include "DragItem.h"
#include "DlgSQL.h"


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

/////////////////////////////////////////////////////////////////////////////

IMPLEMENT_DYNCREATE(CDaoTreeView, CTreeView)

BEGIN_MESSAGE_MAP(CDaoTreeView, CTreeView)
	//{{AFX_MSG_MAP(CDaoTreeView)
	ON_WM_CREATE()
	ON_WM_SYSCOLORCHANGE()
	ON_COMMAND(ID_EDIT_NEWQUERY, OnNewQuery)
	ON_COMMAND(ID_QUERY_EDIT, OnQueryEdit)
	//}}AFX_MSG_MAP

	//这是一个消息映射宏,可能与读者平时使用的右健菜单命令响应方式
	//不一致,但这是一种非常好的方式,推荐使用。顾名思义,RANGE表示
	//一个范围,该宏第一个参数表示值最小的一个,第二个最大的。
	ON_COMMAND_RANGE(ID_TABLE_SCHEMA,ID_QUERY_RUN, OnPopupCommand)

	ON_NOTIFY_REFLECT(TVN_KEYDOWN,OnKeyDown)
	ON_NOTIFY_REFLECT(TVN_SELCHANGED,OnNodeSelect)
	ON_NOTIFY_REFLECT(TVN_BEGINDRAG,OnBeginDrag)
	ON_NOTIFY_REFLECT(NM_RCLICK,OnRightClick)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDaoTreeView construction/destruction

CDaoTreeView::CDaoTreeView():CTreeView()
{
	m_nIDClipFormat = RegisterClipboardFormat(_T("DaoView"));
	m_pDB = NULL;
	m_bNoNotifications = FALSE;
}

CDaoTreeView::~CDaoTreeView()
{
}


/////////////////////////////////////////////////////////////////////////////
// CDaoTreeView diagnostics

#ifdef _DEBUG
void CDaoTreeView::AssertValid() const
{
	CTreeView::AssertValid();
}

void CDaoTreeView::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
CDAOQryDoc* CDaoTreeView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDAOQryDoc)));
	return (CDAOQryDoc*)m_pDocument;
}
#endif //_DEBUG


/////////////////////////////////////////////////////////////////////////////
// CDaoTreeView message handlers

int CDaoTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	lpCreateStruct->style |= TVS_HASLINES | TVS_HASBUTTONS;
	if (CTreeView::OnCreate(lpCreateStruct) == -1)
		return -1;

	GetDocument()->m_pTreeView = this;

	//创建位图链
	m_ctlImage.Create(IDB_IMAGELIST,16,0,RGB(255,0,255));
	m_ctlImage.SetBkColor(GetSysColor(COLOR_WINDOW));

	//把位图关联到树上
	CTreeCtrlEx& ctlTree = (CTreeCtrlEx&) GetTreeCtrl();
	ctlTree.SetImageList(&m_ctlImage);

	//把该窗口注册为有效的拖放目标
	m_dropTarget.Register(this);

	return 0;
}

/////////////////////////////////////////////////////////////////////////////
// CDaoTreeView implementation functions
//函数功能:刷新树
void CDaoTreeView::PopulateTree()
{
	CTreeCtrlEx& ctlTree = (CTreeCtrlEx&) GetTreeCtrl();
	m_bNoNotifications = TRUE;
	//删除所有树视结点
	ctlTree.DeleteAllItems();
	UpdateWindow();

	ASSERT(m_pDB);
	ASSERT(m_pDB->IsOpen());

	//插入树视根结点
	tDatabase = ctlTree.GetRootItem().AddTail(m_pDB->GetName(),IID_DATABASE);

	//插入Tables(表)、Relations(关系)和QueryDefs(查询)
	tTables = tDatabase.AddTail(_T("Tables"),IID_TABLES);
	tRelations = tDatabase.AddTail(_T("Relations"),IID_RELATIONS);
	tQueryDefs = tDatabase.AddTail(_T("QueryDefs"),IID_QUERYDEFS);

	BOOL bShowSystemObjects = ((CDAOQryApp *)AfxGetApp())->m_bShowSystemObjects;

	CDaoTableDefInfo tabInfo;//表定义
	CDaoFieldInfo fieldInfo; //字段(域)
	CDaoIndexInfo indexInfo; //索引

	//获得数据库模式中所有表并插入树
	try
	{
		//表的数目
		int nTableDefCount = m_pDB->GetTableDefCount();
		for (int i = 0; i < nTableDefCount; i++)
		{
			//获得表的信息
			m_pDB->GetTableDefInfo(i,tabInfo);
			if (!bShowSystemObjects)
				if (tabInfo.m_lAttributes & dbSystemObject)
					continue;
			//插入结点
			AddItem(IID_TABLE,tabInfo.m_strName);
		}
	}
	//捕捉异常
	catch (CDaoException* e)
	{
		e->Delete();
	}

	//获得数据库模式中所有查询并插入树
	try
	{
		CDaoQueryDefInfo queryInfo;
		int nQueryDefCount= m_pDB->GetQueryDefCount();
		for (int i = 0; i < nQueryDefCount; i++)
		{
			m_pDB->GetQueryDefInfo(i,queryInfo);
			if (!bShowSystemObjects)
				if (queryInfo.m_nType == 5)
					continue;
			tQueryDefs.AddTail(queryInfo.m_strName,IID_QUERYDEF);
		}
	}
	catch (CDaoException* e)
	{
		e->Delete();
	}

	//获得数据库模式中所有关系并插入树
	try
	{
		CDaoRelationInfo relInfo;
		int nRelationCount = m_pDB->GetRelationCount();
		for (int i = 0;i < nRelationCount;i++)
		{
			m_pDB->GetRelationInfo(i,relInfo);
			if (!bShowSystemObjects)
				if (relInfo.m_lAttributes & dbSystemObject)
					continue;
			tRelations.AddTail(relInfo.m_strName,IID_RELATION);
		}
	}
	catch (CDaoException* e)
	{
		e->Delete();
	}

	//展开结点
	tDatabase.Expand();
	m_bNoNotifications = FALSE;
	UpdateWindow();
}
//函数功能:在树上插入一个结点
//参数说明:nItemType----结点类型;lpszName----结点名称
//其他说明:这里只处理两种情况:表和查询定义
void CDaoTreeView::AddItem(WORD nItemType, LPCTSTR lpszName)
{
	switch (nItemType)
	{
		case IID_TABLE:
		{
			//插入表名
			tTable = tTables.AddTail(lpszName,IID_TABLE);
			//在表名结点下分别插入字段(Fields)和索引(Indexes)
			tFields = tTable.AddTail(_T("Fields"),IID_FIELDS);
			tIndexes = tTable.AddTail(_T("Indexes"),IID_INDEXES);
			CDaoTableDef td(m_pDB);
			try
			{
				//初始化表定义
				td.Open(lpszName);
				CDaoFieldInfo fieldInfo;
				//获得属性列数目
				int nFieldCount = td.GetFieldCount();
				for (int j=0; j < nFieldCount; j++)
				{
					//得到指定字段信息并插入到树上
					td.GetFieldInfo(j,fieldInfo);
					tFields.AddTail(fieldInfo.m_strName,IID_FIELD);
				}
				CDaoIndexInfo indexInfo;
				//得到索引数目
				int nIndexCount = td.GetIndexCount();
				for(j=0;j < nIndexCount;j++)
				{
					//得到指定索引信息并插入到树上
					td.GetIndexInfo(j,indexInfo);
					tIndexes.AddTail(indexInfo.m_strName,IID_INDEX);
				}
			}
			catch(CDaoException* e)
			{				
				e->Delete();
			}
			//删除表定义对象
			td.Close();
			break;
		}
		case IID_QUERYDEF:
		{
			//插入查询定义
			tQueryDefs.AddTail(lpszName,nItemType);
			break;
		}
	}
}
//函数功能:在树上删除一个指定结点
//参数说明:itemDelete----待删除结点书签
//其他说明:这里只处理两种情况:表和查询定义
void CDaoTreeView::DeleteItem(CTreeCursor& itemDelete)
{
	switch (itemDelete.GetImageID())
	{
		case IID_TABLE:
		{
			try
			{
				//删除指定表定义
				m_pDB->DeleteTableDef(itemDelete.GetText());
				itemDelete.Delete();
			}
			catch (CDaoException* e)
			{
				MessageBox(
					_T("DaoView - Warning"),
					e->m_pErrorInfo->m_strDescription);
				e->Delete();
			}
			break;
		}
		case IID_QUERYDEF:
		{
			try
			{
				//删除指定查询定义
				m_pDB->DeleteQueryDef(itemDelete.GetText());
				itemDelete.Delete();
			}
			catch (CDaoException* e)
			{
				MessageBox(
					_T("DaoView - Warning"),
					e->m_pErrorInfo->m_strDescription);
				e->Delete();
			}
			break;
		}
	}
}
//函数功能:当鼠标点击树视不同结点时,列表视显示相应内容
void CDaoTreeView::OnNodeSelect(NMHDR *pNotifyStruct,LRESULT *result)
{
	*result = 0;

	if (m_bNoNotifications)
		return;

	CTreeCtrlEx& ctlTree = (CTreeCtrlEx&) GetTreeCtrl();
	//得到当前结点书签
	m_ItemSel = ctlTree.GetSelectedItem();
	//得到当前结点ID
	UINT nImageID = m_ItemSel.GetImageID();
	GetDocument()->m_pListView->SetRedraw(FALSE);
	switch (nImageID)
	{
		case IID_DATABASE://数据库
			GetDocument()->m_pListView->ShowDatabase();
			break;
		case IID_TABLES://表定义模式
			GetDocument()->m_pListView->ShowTableSchema();
			break;
		case IID_TABLE:
			GetDocument()->m_pListView->ShowTableSchema(m_ItemSel.GetText());
			break;
		case IID_FIELDS://字段信息
			GetDocument()->m_pListView->ShowFields(m_ItemSel.GetParent().GetText());
			break;
		case IID_FIELD:
			GetDocument()->m_pListView->ShowFields(m_ItemSel.GetParent().GetParent().GetText(),
													m_ItemSel.GetText());
			break;
		case IID_QUERYDEFS://显示查询定义模式
			GetDocument()->m_pListView->ShowQuerySchema();
			break;
		case IID_QUERYDEF:
			GetDocument()->m_pListView->ShowQuerySchema(m_ItemSel.GetText());
			break;
		case IID_RELATIONS://显示关系
			GetDocument()->m_pListView->ShowRelations();
			break;
		case IID_RELATION:
			GetDocument()->m_pListView->ShowRelations(m_ItemSel.GetText());
			break;
		case IID_INDEXES://显示索引
			GetDocument()->m_pListView->ShowIndexes(m_ItemSel.GetParent().GetText());
			break;
		case IID_INDEX:
			GetDocument()->m_pListView->ShowIndexes(m_ItemSel.GetParent().GetParent().GetText(),
													m_ItemSel.GetText());
			break;
	}
	GetDocument()->m_pListView->SetRedraw(TRUE);
}
//函数功能:响应右键菜单命令
void CDaoTreeView::OnRightClick(NMHDR *pNotifyStruct,LRESULT *result)
{
	CTreeCtrlEx& ctlTree = (CTreeCtrlEx&) GetTreeCtrl();

	//得到当前结点书签
	UINT nFlags;
	CPoint curPoint;
	GetCursorPos(&curPoint);
	ScreenToClient(&curPoint);
	m_ItemSel = ctlTree.HitTest(curPoint, &nFlags);
	//得到当前结点ID
	UINT nImageID = m_ItemSel.GetImageID();
	switch (nImageID)
	{
		case IID_TABLE:
			//弹出表定义菜单
			DoPopupMenu(IDR_POPUP_TABLE);
			break;
		case IID_QUERYDEF:
			//弹出查询定义菜单
			DoPopupMenu(IDR_POPUP_QUERY);
			break;
	}
	*result = 0;
}
//函数功能:弹出表定义菜单
void CDaoTreeView::DoPopupMenu(UINT nMenuID)
{
	CMenu popMenu;
	popMenu.LoadMenu(nMenuID);
	CPoint posMouse;
	GetCursorPos(&posMouse);
	popMenu.GetSubMenu(0)->TrackPopupMenu( 0,
										   posMouse.x,posMouse.y,this);
}
//函数功能:弹出查询定义菜单单
void CDaoTreeView::OnPopupCommand(UINT nMenuID)
{
	CWaitCursor w;
	GetDocument()->m_pListView->SetRedraw(FALSE);
	//响应菜单命令
	switch (nMenuID)
	{
		case ID_TABLE_SCHEMA:
			GetDocument()->m_pListView->ShowTableSchema(m_ItemSel.GetText());
			break;
		case ID_TABLE_DATA:
			GetDocument()->m_pListView->ShowTableData(m_ItemSel.GetText());
			break;
		case ID_QUERY_DEFINITION:
			GetDocument()->m_pListView->ShowQuerySchema(m_ItemSel.GetText());
			break;
		case ID_QUERY_RUN:
			GetDocument()->m_pListView->RunQueryDef(m_ItemSel.GetText());
			break;
	}
	GetDocument()->m_pListView->SetRedraw(TRUE);
}

//当拖拽动作开始时,框架调用此函数
void CDaoTreeView::OnBeginDrag(NMHDR *pNotifyStruct,LRESULT *result)
{
	int nImageID = m_ItemSel.GetImageID();

	switch (nImageID)
	{
		case IID_TABLE:
		case IID_QUERYDEF:
			CSharedFile globFile;
			CArchive ar(&globFile,CArchive::store);
			CDragItem dragItem( nImageID,m_pDB->GetName(),
								m_pDB->GetConnect(),m_ItemSel.GetText());
			dragItem.Serialize(ar);
			ar.Close();

			COleDataSource srcItem;

			srcItem.CacheGlobalData(m_nIDClipFormat,globFile.Detach());
			srcItem.DoDragDrop();
	}
}

//在拖拽操作过程中,当鼠标试图进入目标窗口时,该函数被调用
DROPEFFECT CDaoTreeView::OnDragEnter( COleDataObject* pDataObject, 
									  DWORD dwKeyState, CPoint point)
{
	if (m_pDB)
		if (pDataObject->IsDataAvailable(m_nIDClipFormat))
			return DROPEFFECT_COPY;

	return CTreeView::OnDragEnter(pDataObject, dwKeyState, point);
}
//在拖拽操作过程中,当鼠标跨过窗口边框时,该函数被调用
DROPEFFECT CDaoTreeView::OnDragOver( COleDataObject* pDataObject, 
									 DWORD dwKeyState, CPoint point)
{
	if (m_pDB)
		if (pDataObject->IsDataAvailable(m_nIDClipFormat))
			return DROPEFFECT_COPY;

	return CTreeView::OnDragOver(pDataObject, dwKeyState, point);
}
//在拖拽操作过程中,当拖拽目标内置于目的地时,该函数被调用
BOOL CDaoTreeView::OnDrop( COleDataObject* pDataObject, 
						   DROPEFFECT dropEffect, CPoint point)
{
	if (!(m_pDB && pDataObject->IsDataAvailable(m_nIDClipFormat)))
		return CTreeView::OnDrop(pDataObject, dropEffect, point);

	HGLOBAL hGlob = pDataObject->GetGlobalData(m_nIDClipFormat);
	if (hGlob != NULL){
		CSharedFile globFile;
		globFile.SetHandle(hGlob,FALSE);
		CArchive ar(&globFile,CArchive::load);
		CDragItem dragItem;
		dragItem.Serialize(ar);
		ar.Close();
		dragItem.Transfer(this,m_pDB);
		return TRUE;
	}

	return FALSE;
}


void CDaoTreeView::OnSysColorChange()
{
	CWnd::OnSysColorChange();

	//Reset the background color of our image list when notified
	m_ctlImage.SetBkColor(GetSysColor(COLOR_WINDOW));
}
//函数功能:响应键盘操作
void CDaoTreeView::OnKeyDown(NMHDR *pNotifyStruct,LRESULT *result)
{
	TV_KEYDOWN* pKeyDown = (TV_KEYDOWN *) pNotifyStruct;

	if (pKeyDown->wVKey == VK_DELETE)
	{
		BOOL bShowWarnings = ((CDAOQryApp *)AfxGetApp())->m_bShowWarnings;
		int retCode = IDYES;
		if (bShowWarnings)
		{
			retCode = MessageBox(
				_T("Are you sure you want to delete this item ?"),
				_T("DaoView - Warning"),MB_YESNO);
		}
		if (retCode == IDYES)
			DeleteItem(m_ItemSel);
	}
	*result = 0;
}

//函数功能:创建一个新查询
void CDaoTreeView::OnNewQuery()
{
	ASSERT(m_pDB);
	ASSERT(m_pDB->IsOpen());

	CDlgSQL dlgSQL;

	if (dlgSQL.DoModal() != IDOK)
		return;

	try
	{
		CDaoQueryDef qdTarget(m_pDB);

		qdTarget.Create(dlgSQL.m_strName,dlgSQL.m_strSQL);
		qdTarget.Append();
	}
	catch (CDaoException* e)
	{
		DisplayDaoException(e);
		e->Delete();
		return;
	}
	AddItem(IID_QUERYDEF,dlgSQL.m_strName);
}

//函数功能:修改已存在查询
void CDaoTreeView::OnQueryEdit()
{
	try
	{
		CDlgSQL dlgSQL;

		dlgSQL.m_bEditMode = TRUE;

		CDaoQueryDef qdEdit(m_pDB);
		qdEdit.Open(m_ItemSel.GetText());

		dlgSQL.m_strName = m_ItemSel.GetText();
		dlgSQL.m_strSQL = qdEdit.GetSQL();

		if (dlgSQL.DoModal() == IDOK)
			qdEdit.SetSQL(dlgSQL.m_strSQL);

		qdEdit.Close();
	}
	catch (CDaoException* e)
	{
		DisplayDaoException(e);
		e->Delete();
		return;
	}
}

⌨️ 快捷键说明

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