?? lefttreeview.cpp
字號:
// LeftTreeView.cpp : implementation file
//
#include "stdafx.h"
#include "SkillBook.h"
#include "LeftTreeView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define DRAG_DELAY 60
/////////////////////////////////////////////////////////////////////////////
// CLeftTreeView
IMPLEMENT_DYNCREATE(CLeftTreeView, CTreeView)
CLeftTreeView::CLeftTreeView()
{
m_bDragging = FALSE;
m_bCanEditLabel = FALSE;
m_pTreeSkill = NULL;
m_pTreeSkill = new CTreeCtrl();
InitDatabaseConnection();
}
CLeftTreeView::~CLeftTreeView()
{
CloseDatabaseConnection();
}
BEGIN_MESSAGE_MAP(CLeftTreeView, CTreeView)
//{{AFX_MSG_MAP(CLeftTreeView)
ON_WM_DESTROY()
ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
ON_WM_CONTEXTMENU()
ON_WM_LBUTTONDOWN()
ON_WM_RBUTTONDOWN()
ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeydown)
ON_COMMAND(ID_MENU_DELETE, OnMenuDelete)
ON_COMMAND(ID_MENU_ADDNODE, OnMenuAddnode)
ON_COMMAND(ID_MENU_ADDCHILDNODE, OnMenuAddchildnode)
ON_COMMAND(ID_MENU_ADDARTICLE, OnMenuAddarticle)
ON_COMMAND(ID_MENU_ADDCHILDARTICLE, OnMenuAddchildarticle)
ON_UPDATE_COMMAND_UI(ID_MENU_ADDCHILDARTICLE, OnUpdateMenuAddchildarticle)
ON_UPDATE_COMMAND_UI(ID_MENU_ADDCHILDNODE, OnUpdateMenuAddchildnode)
ON_COMMAND(ID_MENU_ADDROOTNODE, OnMenuAddrootnode)
ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_TIMER()
ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnBeginlabeledit)
ON_COMMAND(ID_MENU_RENAME, OnMenuRename)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLeftTreeView drawing
void CLeftTreeView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here
}
/////////////////////////////////////////////////////////////////////////////
// CLeftTreeView diagnostics
#ifdef _DEBUG
void CLeftTreeView::AssertValid() const
{
CTreeView::AssertValid();
}
void CLeftTreeView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CLeftTreeView message handlers
void CLeftTreeView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
// TODO: Add your specialized code here and/or call the base class
m_imglstTree.Create(IDB_TREE, 16, 4, RGB(192, 192, 192));
m_pTreeSkill = &GetTreeCtrl();
DWORD dwStyle = m_pTreeSkill->GetStyle();
m_pTreeSkill->ModifyStyle(dwStyle, dwStyle | TVS_HASLINES | TVS_LINESATROOT | TVS_EDITLABELS | TVS_HASBUTTONS);
m_pTreeSkill->SetImageList(&m_imglstTree, TVSIL_NORMAL);
LoadTreeFromDB();
m_bitmap.LoadBitmap(IDB_TREEBK);
}
void CLeftTreeView::OnDestroy()
{
SaveTreeToDB();
CTreeView::OnDestroy();
// TODO: Add your message handler code here
if(NULL != m_pTreeSkill)
{
delete m_pTreeSkill;
m_pTreeSkill = NULL;
}
}
void CLeftTreeView::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
if(pTVDispInfo->item.pszText != NULL)//判斷是否已經(jīng)取消取消編輯
{
m_pTreeSkill->SetItemText(pTVDispInfo->item.hItem, pTVDispInfo->item.pszText);//重置顯示字符
}
*pResult = 0;
}
void CLeftTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
// TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
//取得選項句柄
HTREEITEM hSel = m_pTreeSkill->GetSelectedItem();
if(hSel == NULL)
{//無任何選項則返回
m_nCurrentSelTag = -1;
}
else
{
//取得數(shù)據(jù)項序號
m_nCurrentSelTag = m_pTreeSkill->GetItemData(hSel);
m_SelectedItemTagList.RemoveAll();
*pResult = 0;
}
if(GetItemTypeByTag(m_nCurrentSelTag) == 1)
{
m_bEnableAddItem = FALSE;
}
else
{
m_bEnableAddItem = TRUE;
}
HTREEITEM hItem,hNext,hStop;
hItem = hSel;
hStop = m_pTreeSkill->GetNextItem(hSel, TVGN_NEXT);
//XTRACE("\n選擇信息: %d", m_nCurrentSelTag);
if(hStop)
{
//XTRACE("\n停止信息: %d", m_pTreeSkill->GetItemData(hStop));
}
else
{
//XTRACE("\n停止信息: %d", 0);
}
m_SelectedItemTagList.AddTail(m_nCurrentSelTag);
while(m_pTreeSkill->ItemHasChildren(hItem))
{
hNext = m_pTreeSkill->GetChildItem(hItem);
while(hNext)
{
hItem = hNext;
int nTag = m_pTreeSkill->GetItemData(hItem);
//XTRACE("\n%d", nTag);
m_SelectedItemTagList.AddTail(nTag);
hNext = GetNextItem(hNext);
if(hNext == hStop)
{
break;
}
}
}
ShowArticleByTreeItemTag(m_nCurrentSelTag);
}
void CLeftTreeView::OnContextMenu(CWnd* pWnd, CPoint point)
{
// TODO: Add your message handler code here
UINT uFlags;
CTreeCtrl &treectrl = GetTreeCtrl();
CPoint ptTree = point;
treectrl.ScreenToClient(&ptTree);
HTREEITEM htitem = treectrl.HitTest(ptTree, &uFlags);
if((htitem != NULL) && (uFlags & TVHT_ONITEM))
{
ShowPopupMenu(point);
treectrl.SetItemState(htitem, 0, TVIS_DROPHILITED);
}
else
{
CTreeView::OnContextMenu(pWnd, point);
}
}
void CLeftTreeView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
HTREEITEM htitem = m_pTreeSkill->GetSelectedItem();
if(htitem != NULL)
{
m_pTreeSkill->SelectItem(htitem);
}
m_bCanEditLabel = FALSE;
//處理無意拖曳
m_dwDragStart = GetTickCount();
CTreeView::OnLButtonDown(nFlags, point);
}
void CLeftTreeView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
HTREEITEM htitem = m_pTreeSkill->GetSelectedItem();
if(htitem != NULL)
{
m_pTreeSkill->SelectItem(htitem);
}
// CTreeView::OnRButtonDown(nFlags, point);
}
void CLeftTreeView::ShowPopupMenu(CPoint &point)
{
if(point.x == -1 && point.y == -1)
{
//keystroke invocation
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
point = rect.TopLeft();
point.Offset(5, 5);
}
CMenu menu;
VERIFY(menu.LoadMenu(IDR_MAINFRAME));
CMenu* pPopup = menu.GetSubMenu(2);
ASSERT(pPopup != NULL);
CWnd* pWndPopupOwner = this;
while(pWndPopupOwner->GetStyle() & WS_CHILD)
{
pWndPopupOwner = pWndPopupOwner->GetParent();
}
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, pWndPopupOwner);
}
void CLeftTreeView::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
// TODO: Add your control notification handler code here
static BOOL bshift = FALSE;
if(bshift && pTVKeyDown->wVKey == 121)
{
HTREEITEM hitem = GetTreeCtrl().GetSelectedItem();
CRect rect;
GetTreeCtrl().GetItemRect(hitem, &rect, TRUE);
ClientToScreen(rect);
OnContextMenu( this, CPoint(rect.right, rect.top));
}
else if(pTVKeyDown->wVKey == VK_DELETE)
{
OnMenuDelete();
}
bshift = pTVKeyDown->wVKey == 16;
*pResult = 0;
}
void CLeftTreeView::OnMenuDelete()
{
// TODO: Add your command handler code here
//取得選項句柄
HTREEITEM hSel=m_pTreeSkill->GetSelectedItem();
if(hSel == NULL)
{//無任何選項則返回
return;
}
//判斷是否有子項
if(m_pTreeSkill->ItemHasChildren(hSel))
{
if(MessageBox("該目錄及其下屬目錄將會被刪除,是否刪除(Y/N)?", "警告", MB_YESNO + MB_ICONWARNING) == IDNO)
{
return;
}
SetDeletedItemTagFlag();
m_pTreeSkill->DeleteItem(hSel);
}
else
{
SetDeletedItemTagFlag();
m_pTreeSkill->DeleteItem(hSel);
}
}
void CLeftTreeView::OnMenuAddnode()
{
// TODO: Add your command handler code here
AddNode();
}
void CLeftTreeView::OnMenuAddchildnode()
{
// TODO: Add your command handler code here
AddChildNode();
}
void CLeftTreeView::OnMenuAddarticle()
{
// TODO: Add your command handler code here
AddNode(1);
}
void CLeftTreeView::OnMenuAddchildarticle()
{
// TODO: Add your command handler code here
AddChildNode(1);
}
void CLeftTreeView::AddNode(const int nType)
{
HTREEITEM hSel=m_pTreeSkill->GetSelectedItem();//取得選擇項句柄
if(hSel == NULL)
{//無任何選項則返回
return;
}
int nTag=0;
int nImage=0;
int nSelectedImage=1;
char szText[255];
POSITION pos=NULL;
HTREEITEM hParent=m_pTreeSkill->GetParentItem(hSel);
sprintf(szText, "%s", "新增目錄");
if(nType != 0)
{
nImage = 2;
nSelectedImage = 3;
sprintf(szText, "%s", "新增文章");
}
TV_INSERTSTRUCT TCItem;//定義插入項數(shù)據(jù)結構
//設置父項句柄
TCItem.hParent = hParent;
//在最后增加
TCItem.hInsertAfter = TVI_LAST;
TCItem.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
TCItem.item.pszText = szText;
//索引號增加
pos = GetFreeItemTag(nTag);
TCItem.item.lParam = nTag;
//正常圖標
TCItem.item.iImage = nImage;
//選中時圖標
TCItem.item.iSelectedImage = nSelectedImage;
//增加
HTREEITEM hInsert = m_pTreeSkill->InsertItem(&TCItem);
m_pTreeSkill->Expand(hParent, TVE_EXPAND);
//修改增加的數(shù)據(jù)
m_bCanEditLabel = TRUE;
m_pTreeSkill->EditLabel(hInsert);
TREEINFO treeinfo;
treeinfo.nType = nType;
treeinfo.nTag = int(TCItem.item.lParam);
treeinfo.nDeleted = 0;
if(NULL == pos)
{
m_TreeInfoList.AddTail(treeinfo);
}
else
{
m_TreeInfoList.SetAt(pos, treeinfo);
}
}
void CLeftTreeView::InitPara()
{
m_nCurrentSelTag = -1;
m_bEnableAddItem = FALSE;
}
void CLeftTreeView::AddChildNode(const int nType)
{
//增加子項功能函數(shù)
HTREEITEM hSel=m_pTreeSkill->GetSelectedItem();//取得選擇項句柄
if(hSel == NULL)
{
return;//無任何選項則返回
}
int nTag=0;
int nImage=0;
int nSelectedImage=1;
char szText[255];
POSITION pos=NULL;
sprintf(szText, "%s", "新增子目錄");
if(nType != 0)
{
nImage = 2;
nSelectedImage = 3;
sprintf(szText, "%s", "新增文章");
}
TV_INSERTSTRUCT TCItem;//定義插入項數(shù)據(jù)結構
//設置父項句柄
TCItem.hParent = hSel;
//在最后增加
TCItem.hInsertAfter = TVI_LAST;
TCItem.item.mask = TVIF_TEXT|TVIF_PARAM|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
TCItem.item.pszText = szText;
//索引號增加
pos = GetFreeItemTag(nTag);
TCItem.item.lParam = nTag;
//正常圖標
TCItem.item.iImage = nImage;
//選中時圖標
TCItem.item.iSelectedImage = nSelectedImage;
//增加
HTREEITEM hInsert = m_pTreeSkill->InsertItem(&TCItem);
m_pTreeSkill->Expand(hSel,TVE_EXPAND);
//修改增加的數(shù)據(jù)
m_bCanEditLabel = TRUE;
m_pTreeSkill->EditLabel(hInsert);
TREEINFO treeinfo;
treeinfo.nType = nType;
treeinfo.nTag = int(TCItem.item.lParam);
treeinfo.nDeleted = 0;
if(NULL == pos)
{
m_TreeInfoList.AddTail(treeinfo);
}
else
{
m_TreeInfoList.SetAt(pos, treeinfo);
}
}
BOOL CLeftTreeView::InitDatabaseConnection()
{
::CoInitialize(NULL);
CString szUdlFileName("");
szUdlFileName = ".\\SkillBook.udl";
m_ADO.SetUdlFileName(szUdlFileName);
return m_ADO.InitDatabaseConnection();
}
BOOL CLeftTreeView::CloseDatabaseConnection()
{
::CoUninitialize();
return TRUE;
}
void CLeftTreeView::LoadTreeFromDB()
{
//裝載
CString szLine("");
CString szSQL("");
CString szValue("");
char szItemText[255];
TREEINFO treeinfo;
int nTag=0;
int nImage=0;
int nSelectedImage=1;
m_TreeInfoList.RemoveAll();
szSQL.Format(_T("SELECT * FROM TreeNode"));
m_ADO.ExeSQL(szSQL);
if(m_ADO.GetRecordCount() < 1)
{
return;
}
HTREEITEM hTemp = NULL;
int nIndent, nBaseIndent = 0;
// XTRACE("\nnBaseIndent = %d", nBaseIndent);
m_ADO.MoveFirst();
do{
m_ADO.GetFieldValue("Node", szLine);
if(szLine.GetLength() == 0)
{
continue;
}
m_ADO.GetFieldValue("Tag", szValue);
nTag = ::atoi(szValue);
treeinfo.nTag = nTag;
m_ADO.GetFieldValue("Type", szValue);
treeinfo.nType = ::atoi(szValue);
treeinfo.nDeleted = 0;
m_TreeInfoList.AddTail(treeinfo);
for(nIndent = 0; szLine[nIndent]=='`'; nIndent++)
{//we don't need a body
NULL;
}
if(treeinfo.nType != 0)
{
nImage = 2;
nSelectedImage = 3;
}
else
{
nImage = 0;
nSelectedImage = 1;
}
szLine = szLine.Right(szLine.GetLength() - nIndent);
nIndent -= nBaseIndent;
HTREEITEM hParent;
int nPreIndent = GetIndentLevel(hTemp);
if(nIndent == nPreIndent)
{
hParent = m_pTreeSkill->GetParentItem(hTemp);
}
else if(nIndent > nPreIndent)
{
hParent = hTemp;
}
else
{
int nLevelsUp = nPreIndent - nIndent;
hParent = m_pTreeSkill->GetParentItem(hTemp);
while(nLevelsUp--)
{
hParent = m_pTreeSkill->GetParentItem(hParent);
}
}
if(NULL == hParent)
{
hParent = TVI_ROOT;
}
TVINSERTSTRUCT tvInsert;
sprintf(szItemText, "%s", szLine);
tvInsert.hParent = hParent;
tvInsert.hInsertAfter = TVI_LAST;
tvInsert.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
tvInsert.item.pszText = szItemText;
tvInsert.item.lParam = nTag;
tvInsert.item.iImage = nImage;
tvInsert.item.iSelectedImage = nSelectedImage;
hTemp = m_pTreeSkill->InsertItem(&tvInsert);
m_ADO.MoveNext();
}while(!m_ADO.AdoEof());
}
void CLeftTreeView::SaveTreeToDB()
{
int nRootNum=-1;
int nTag=0;
CString szSQL("");
CString szValue("");
CString szSymbol("");
BOOL bWriteDB=FALSE;
szSQL.Format(_T("DELETE FROM TreeNode"));
m_ADO.ExeSQL(szSQL, TRUE);
//保存
szSQL.Format(_T("SELECT * FROM TreeNode"));
m_ADO.ExeSQL(szSQL);
HTREEITEM hTemp = m_pTreeSkill->GetRootItem();
while(hTemp)
{
int nIndent = GetIndentLevel(hTemp);
if(nIndent == 0)
{
nRootNum++;
}
//XTRACE("\n%d, %d", nRootNum, nIndent);
szSymbol = "";
while(nIndent--)
{
szSymbol += "`";
}
szValue = szSymbol + m_pTreeSkill->GetItemText(hTemp);
//XTRACE("-->%s", m_pTreeSkill->GetItemText(hTemp));
if(m_ADO.AddNew())
{
m_ADO.SetFieldValue("Node", szValue);
nTag = m_pTreeSkill->GetItemData(hTemp);
szValue.Format(_T("%d"), nTag);
m_ADO.SetFieldValue("Tag", szValue);
szValue.Format(_T("%d"), GetItemTypeByTag(nTag));
m_ADO.SetFieldValue("Type", szValue);
bWriteDB = TRUE;
}
hTemp = GetNextItem(hTemp);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -