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