?? lefttreeview.cpp
字號:
if(bWriteDB)
{
m_ADO.Update();
}
}
int CLeftTreeView::GetIndentLevel(HTREEITEM hItem)
{
int nIndent = 0;
while((hItem = m_pTreeSkill->GetParentItem(hItem)) != NULL)
{
nIndent++;
}
return nIndent;
}
HTREEITEM CLeftTreeView::GetNextItem(HTREEITEM hItem)
{
HTREEITEM hTemp;
if(m_pTreeSkill->ItemHasChildren(hItem) )
{//return first child
return m_pTreeSkill->GetChildItem(hItem);
}
else
{
// return next sibling item
// go up the tree to find a parent's sibling if needed.
while((hTemp = m_pTreeSkill->GetNextSiblingItem(hItem)) == NULL)
{
if((hItem = m_pTreeSkill->GetParentItem(hItem)) == NULL)
{
return NULL;
}
}
}
return hTemp;
}
int CLeftTreeView::GetItemTypeByTag(const int nTag)
{
int nType=-1;
POSITION pos=NULL;
if(m_TreeInfoList.GetCount() < 1)
{
return -1;
}
for(pos=m_TreeInfoList.GetHeadPosition(); NULL!=pos;)
{
if(m_TreeInfoList.GetAt(pos).nTag == nTag)
{
nType = m_TreeInfoList.GetAt(pos).nType;
break;
}
m_TreeInfoList.GetNext(pos);
}
return nType;
}
void CLeftTreeView::OnUpdateMenuAddchildarticle(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_bEnableAddItem);
}
void CLeftTreeView::OnUpdateMenuAddchildnode(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->Enable(m_bEnableAddItem);
}
POSITION CLeftTreeView::GetFreeItemTag(int &nTag)
{
int i,j;
int nCount;
int nMaxTag=0;
POSITION pos=NULL;
BOOL bFindFreeTag=FALSE;
BOOL bFind=FALSE;
BOOL bAddMaxTag=TRUE;
nCount = m_TreeInfoList.GetCount();
if(nCount < 1)
{
nTag = 1;
return NULL;
}
for(pos=m_TreeInfoList.GetHeadPosition(); NULL!=pos;)
{
if(m_TreeInfoList.GetAt(pos).nTag > nMaxTag)
{
nMaxTag = m_TreeInfoList.GetAt(pos).nTag;
}
m_TreeInfoList.GetNext(pos);
}
for(pos=m_TreeInfoList.GetHeadPosition(); NULL!=pos;)
{
if(m_TreeInfoList.GetAt(pos).nDeleted == 1)
{
nTag = m_TreeInfoList.GetAt(pos).nTag;
bFindFreeTag = TRUE;
break;
}
m_TreeInfoList.GetNext(pos);
}
if(!bFindFreeTag)
{
for(i=1; i<nMaxTag; i++)
{
j=0;
bFind = FALSE;
for(pos=m_TreeInfoList.GetHeadPosition(); NULL!=pos;)
{
j++;
if(m_TreeInfoList.GetAt(pos).nTag == i)
{
bFind = TRUE;
break;
}
m_TreeInfoList.GetNext(pos);
}
if((j == nCount) && !bFind)
{
nTag = i;
bAddMaxTag = FALSE;
break;
}
}
if(bAddMaxTag)
{
nTag = nMaxTag + 1;
}
pos = NULL;
}
return pos;
}
void CLeftTreeView::SetDeletedItemTagFlag()
{
POSITION pos1=NULL;
POSITION pos2=NULL;
CString szSQL("");
CString szTemp(""),szIn("");
if((m_TreeInfoList.GetCount() < 1)
|| (m_SelectedItemTagList.GetCount() < 1))
{
return;
}
for(pos1=m_SelectedItemTagList.GetHeadPosition(); NULL!=pos1;)
{
for(pos2=m_TreeInfoList.GetHeadPosition(); NULL!=pos2;)
{
int nTag=m_SelectedItemTagList.GetAt(pos1);
if(nTag == m_TreeInfoList.GetAt(pos2).nTag)
{
szTemp.Format(_T("'%d'"), nTag);
szIn += szTemp + ",";
m_TreeInfoList.GetAt(pos2).nDeleted = 1;
break;
}
m_TreeInfoList.GetNext(pos2);
}
m_SelectedItemTagList.GetNext(pos1);
}
if(!szIn.IsEmpty())
{
szTemp = szIn.Left(szIn.GetLength() - 1);
szSQL.Format(_T("DELETE * FROM Article WHERE Tag IN (%s)"), szTemp);
m_ADO.ExeSQL(szSQL, TRUE);
szSQL.Format(_T("DELETE * FROM TreeNode WHERE Tag IN (%s)"), szTemp);
m_ADO.ExeSQL(szSQL, TRUE);
}
}
BOOL CLeftTreeView::ShowArticleByTreeItemTag(const int nTag)
{
CString szSQL("");
CString szValue("");
szSQL.Format(_T("SELECT * FROM Article WHERE Tag='%d'"), nTag);
m_ADO.ExeSQL(szSQL);
if(m_ADO.GetRecordCount() > 0)
{
m_ADO.MoveFirst();
m_ADO.GetFieldValue("Article", szValue);
}
CMainFrame *pMainFrame = (CMainFrame*)GetParent()->GetParent();
CSkillBookView *pView = (CSkillBookView *)pMainFrame->m_wndSplitter.GetPane(0,1);
pView->GetRichEditCtrl().SetWindowText(szValue);
return TRUE;
}
BOOL CLeftTreeView::SaveArticleByTreeItemTag(const int nTag)
{
if(nTag == -1)
{
return FALSE;
}
CString szSQL("");
CString szValue("");
szSQL.Format(_T("SELECT * FROM Article WHERE Tag='%d'"), nTag);
m_ADO.ExeSQL(szSQL);
if(m_ADO.GetRecordCount() > 0)
{
m_ADO.MoveFirst();
}
else
{
m_ADO.AddNew();
}
CMainFrame *pMainFrame = (CMainFrame*)GetParent()->GetParent();
CSkillBookView *pView = (CSkillBookView *)pMainFrame->m_wndSplitter.GetPane(0,1);
szValue.Format(_T("%d"), nTag);
m_ADO.SetFieldValue("Tag", szValue);
pView->GetRichEditCtrl().GetWindowText(szValue);
m_ADO.SetFieldValue("Article", szValue);
m_ADO.Update();
return TRUE;
}
void CLeftTreeView::OnMenuAddrootnode()
{
// TODO: Add your command handler code here
AddRootNode();
}
void CLeftTreeView::AddRootNode()
{
int nTag=0;
char szText[255];
POSITION pos=NULL;
TV_INSERTSTRUCT TCItem;//定義插入項數據結構
HTREEITEM hParent=TVI_ROOT;
sprintf(szText, "%s", "新增目錄");
//設置父項句柄
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 = 0;
//選中時圖標
TCItem.item.iSelectedImage = 1;
//增加
HTREEITEM hInsert = m_pTreeSkill->InsertItem(&TCItem);
m_pTreeSkill->Expand(hParent, TVE_EXPAND);
//修改增加的數據
m_bCanEditLabel = TRUE;
m_pTreeSkill->EditLabel(hInsert);
TREEINFO treeinfo;
treeinfo.nType = 0;
treeinfo.nTag = int(TCItem.item.lParam);
treeinfo.nDeleted = 0;
if(NULL == pos)
{
m_TreeInfoList.AddTail(treeinfo);
}
else
{
m_TreeInfoList.SetAt(pos, treeinfo);
}
}
void CLeftTreeView::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
*pResult = 0;
//如果是無意拖曳,則放棄操作
if((GetTickCount() - m_dwDragStart) < DRAG_DELAY)
{
return;
}
m_hItemDragS = pNMTreeView->itemNew.hItem;
m_hItemDragD = NULL;
//得到用于拖動時顯示的圖象列表
m_pDragImage = m_pTreeSkill->CreateDragImage(m_hItemDragS);
if(NULL == m_pDragImage)
{
return;
}
m_bDragging = TRUE;
m_pDragImage->BeginDrag (0,CPoint(8,8));
CPoint pt = pNMTreeView->ptDrag;
ClientToScreen(&pt);
m_pDragImage->DragEnter(this, pt); //"this"將拖曳動作限制在該窗口
SetCapture();
m_nScrollTimerID = SetTimer(2, 40, NULL);
}
void CLeftTreeView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
HTREEITEM hItem;
UINT flags;
//檢測鼠標敏感定時器是否存在,如果存在則刪除,刪除后再定時
if(m_nHoverTimerID)
{
KillTimer( m_nHoverTimerID );
m_nHoverTimerID = 0;
}
m_nHoverTimerID = SetTimer(1, 800, NULL); //定時為 0.8 秒則自動展開
m_HoverPoint = point;
if(m_bDragging)
{
CPoint pt = point;
CImageList::DragMove(pt);
//鼠標經過時高亮顯示
CImageList::DragShowNolock(FALSE); //避免鼠標經過時留下難看的痕跡
if((hItem = m_pTreeSkill->HitTest(point,&flags)) != NULL)
{
m_pTreeSkill->SelectDropTarget(hItem);
m_hItemDragD = hItem;
}
CImageList::DragShowNolock(TRUE);
//當條目被拖曳到左邊緣時,將條目放在根下
CRect rect;
GetClientRect( &rect );
if( point.x < rect.left + 20 )
{
m_hItemDragD = NULL;
}
}
CTreeView::OnMouseMove(nFlags, point);
}
void CLeftTreeView::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CTreeView::OnLButtonUp(nFlags, point);
if(m_bDragging)
{
m_bDragging = FALSE;
CImageList::DragLeave(this);
CImageList::EndDrag();
ReleaseCapture();
delete m_pDragImage;
m_pTreeSkill->SelectDropTarget(NULL);
if(m_hItemDragS == m_hItemDragD)
{
KillTimer(m_nScrollTimerID);
return;
}
else
{
if(m_hItemDragD != NULL)
{
int nTag = m_pTreeSkill->GetItemData(m_hItemDragD);
if(GetItemTypeByTag(nTag) == 1)
{//拖放目標是文章
KillTimer(m_nScrollTimerID);
return;
}
}
}
m_pTreeSkill->Expand(m_hItemDragD,TVE_EXPAND);
HTREEITEM htiParent = m_hItemDragD;
while((htiParent = m_pTreeSkill->GetParentItem(htiParent)) != NULL)
{
if(htiParent == m_hItemDragS)
{
HTREEITEM htiNewTemp = CopyBranch(m_hItemDragS,NULL,TVI_LAST);
HTREEITEM htiNew = CopyBranch(htiNewTemp,m_hItemDragD,TVI_LAST);
m_pTreeSkill->DeleteItem(htiNewTemp);
m_pTreeSkill->SelectItem(htiNew);
KillTimer(m_nScrollTimerID);
return;
}
}
HTREEITEM htiNew = CopyBranch(m_hItemDragS, m_hItemDragD, TVI_LAST);
m_pTreeSkill->DeleteItem(m_hItemDragS);
m_pTreeSkill->SelectItem(htiNew);
KillTimer(m_nScrollTimerID);
}
}
//拷貝條目
HTREEITEM CLeftTreeView::CopyItem(HTREEITEM hItem, HTREEITEM htiNewParent, HTREEITEM htiAfter)
{
TV_INSERTSTRUCT tvstruct;
HTREEITEM hNewItem;
CString sText;
//得到源條目的信息
tvstruct.item.hItem = hItem;
tvstruct.item.mask = TVIF_CHILDREN|TVIF_HANDLE|TVIF_IMAGE|TVIF_SELECTEDIMAGE;
m_pTreeSkill->GetItem(&tvstruct.item);
sText = m_pTreeSkill->GetItemText(hItem);
tvstruct.item.cchTextMax = sText.GetLength();
tvstruct.item.pszText = sText.LockBuffer();
//將條目插入到合適的位置
tvstruct.hParent = htiNewParent;
tvstruct.hInsertAfter = htiAfter;
tvstruct.item.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT;
hNewItem = m_pTreeSkill->InsertItem(&tvstruct);
sText.ReleaseBuffer();
//限制拷貝條目數據和條目狀態
m_pTreeSkill->SetItemData(hNewItem, m_pTreeSkill->GetItemData(hItem));
m_pTreeSkill->SetItemState(hNewItem, m_pTreeSkill->GetItemState(hItem, TVIS_STATEIMAGEMASK), TVIS_STATEIMAGEMASK);
return hNewItem;
}
//拷貝分支
HTREEITEM CLeftTreeView::CopyBranch(HTREEITEM htiBranch, HTREEITEM htiNewParent, HTREEITEM htiAfter)
{
HTREEITEM hChild;
HTREEITEM hNewItem = CopyItem(htiBranch,htiNewParent,htiAfter);
hChild = m_pTreeSkill->GetChildItem(htiBranch);
while(hChild != NULL)
{
CopyBranch(hChild,hNewItem,htiAfter);
hChild = m_pTreeSkill->GetNextSiblingItem(hChild);
}
return hNewItem;
}
void CLeftTreeView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//鼠標敏感節點
if(nIDEvent == m_nHoverTimerID)
{
KillTimer(m_nHoverTimerID);
m_nHoverTimerID = 0;
HTREEITEM trItem = 0;
UINT uFlag = 0;
trItem = m_pTreeSkill->HitTest(m_HoverPoint, &uFlag);
if(trItem && m_bDragging)
{
m_pTreeSkill->SelectItem(trItem);
m_pTreeSkill->Expand(trItem, TVE_EXPAND);
}
}
//處理拖曳過程中的滾動問題
else if(nIDEvent == m_nScrollTimerID)
{
CPoint pt;
CRect rect;
m_TimerTicks++;
GetCursorPos(&pt);
GetClientRect(&rect);
ClientToScreen(&rect);
HTREEITEM hItem = m_pTreeSkill->GetFirstVisibleItem();
if( pt.y < rect.top +10 )
{
//向上滾動
int slowscroll = 6 - (rect.top + 10 - pt.y )/20;
if(0 == (m_TimerTicks % ((slowscroll > 0) ? slowscroll : 1)))
{
CImageList::DragShowNolock(FALSE);
SendMessage(WM_VSCROLL,SB_LINEUP);
m_pTreeSkill->SelectDropTarget(hItem);
m_hItemDragD = hItem;
CImageList::DragShowNolock(TRUE);
}
}
else if(pt.y > rect.bottom - 10)
{
//向下滾動
int slowscroll = 6 - (pt.y - rect.bottom + 10)/20;
if(0 == (m_TimerTicks % ((slowscroll > 0) ? slowscroll : 1)))
{
CImageList::DragShowNolock(FALSE);
SendMessage( WM_VSCROLL,SB_LINEDOWN );
int nCount = m_pTreeSkill->GetVisibleCount();
for(int i=0; i<nCount-1; i++)
{
hItem = m_pTreeSkill->GetNextVisibleItem(hItem);
}
if(NULL != hItem)
{
m_pTreeSkill->SelectDropTarget(hItem);
}
m_hItemDragD = hItem;
CImageList::DragShowNolock(TRUE);
}
}
}
else
{
CTreeView::OnTimer(nIDEvent);
}
}
void CLeftTreeView::SaveCurrentArticle()
{
SaveArticleByTreeItemTag(m_nCurrentSelTag);
}
void CLeftTreeView::OnBeginlabeledit(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
// TODO: Add your control notification handler code here
if(m_bCanEditLabel)
{
*pResult = 0;
}
else
{
*pResult = 1;
}
}
void CLeftTreeView::OnMenuRename()
{
// TODO: Add your command handler code here
HTREEITEM hItem=m_pTreeSkill->GetSelectedItem();
m_bCanEditLabel = TRUE;
m_pTreeSkill->EditLabel(hItem);
}
void CLeftTreeView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CRect rcclient;
GetClientRect(&rcclient);
// create a compatible memory dc
CDC memdc;
memdc.CreateCompatibleDC(&dc);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
memdc.SelectObject( &bitmap );
CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);
CDC maskdc;
maskdc.CreateCompatibleDC(&dc);
CBitmap maskbitmap;
maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
maskdc.SelectObject( &maskbitmap );
maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc,
rcclient.left, rcclient.top, SRCCOPY);
CBrush brush;
brush.CreatePatternBrush(&m_bitmap);
dc.FillRect(rcclient, &brush);
memdc.SetBkColor(RGB(0,0,0));
memdc.SetTextColor(RGB(255,255,255));
memdc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);
dc.SetBkColor(RGB(255,255,255));
dc.SetTextColor(RGB(0,0,0));
dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &maskdc, rcclient.left, rcclient.top, SRCAND);
dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), &memdc,
rcclient.left, rcclient.top,SRCPAINT);
brush.DeleteObject();
// Do not call CTreeView::OnPaint() for painting messages
}
BOOL CLeftTreeView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
// return CTreeView::OnEraseBkgnd(pDC);
}
void CLeftTreeView::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
Invalidate();
// m_pTreeSkill->SetRedraw(TRUE);
SetRedraw(TRUE);
*pResult = 0;
}
void CLeftTreeView::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
SetRedraw(FALSE);
// m_pTreeSkill->SetRedraw(FALSE);
*pResult = 0;
}
LRESULT CLeftTreeView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
return CTreeView::WindowProc(message, wParam, lParam);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -