📄 control.htm#1
字号:
</p></td></tr><tr><td><font color="0000FF"><a name="12">TreeList control中使用check box<Br>闻怡洋译</a></font></td></tr><tr><td><p></Br></Br>方法很简单,一句话总结:定义用户定义状态,并对不同的状态(state)使用不同的图片。<Br></Br>在下面的sample中,我们使用CTreeListCtrl作为父类。由于TreeList control支持一些现有state 所以用户定义的state必需使用INDEXTOSTATEIMAGEMASK(i)进行变换。<Br></Br>如果对本文所讲的方法有不明的地方,可以先熟悉一下TreeList Control的使用,然后再看本文。<Br></Br></Br>Step 1: 创建state list image<Br>创建的图片有三种状态。<Br></Br>state ImageList只是用于和state改变有关的显示图片,TreeList Control中还应包含其他image List,如:焦点选择改变的imageList,用于在选中和未选中是改变显示图片。<Br></Br>Step 2: 初始化<Br>CImageList m_imageState; 成员变量<Br>m_imageState.Create( IDB_STATE, 13, 1, RGB(255,255,255) );//创建ImageList<Br>m_tree.SetImageList( &(m_tree.m_imageState), TVSIL_STATE );//在TreeList中加入表示状态的ImageList。<Br>Step 3: 增加结点时设置标记<Br>重新定义一个InsertItem函数。使用TV_INSERTSTRUCT来插入结点。<Br></Br>即使用函数HTREEITEM InsertItem( LPTV_INSERTSTRUCT lpInsertStruct );<Br></Br>lpInsertStruct->item.mask |= TVIF_STATE ;//保证state 和stateMask是有效的。<Br></Br>你必须在TV_ITEM中标明state和stateMask。(INDEXTOSTATEIMAGEMASK宏可以得到state image的下标)<Br></Br>state 设置为INDEXTOSTATEIMAGEMASK(1)表示用户定义的第一种状态<Br></Br>stateMask设置为TVIS_STATEIMAGEMASK.表示用户定义的状态。<Br></Br>当然也可以调用SetItemState设置state.<Br></Br>SetItemState( hItem, INDEXTOSTATEIMAGEMASK(1), TVIS_STATEIMAGEMASK );<Br></Br>Step 4: 增加mouse button down消息映射<Br>通过使用HitTest来得知是否按在State图片上。并需要得到当前state。<Br></Br>void CTreeCtrlX::OnLButtonDown(UINT nFlags, CPoint point)<Br>{<Br> UINT uFlags=0;<Br> HTREEITEM hti = HitTest(point,&uFlags);<Br></Br> if( uFlags & TVHT_ONITEMSTATEICON )<Br> {<Br> int iImage = GetItemState( hti, TVIS_STATEIMAGEMASK )>>12;<Br> //GetItemState( hti, TVIS_STATEIMAGEMASK )>>12 对用户定义state反变换<Br> SetItemState( hti, INDEXTOSTATEIMAGEMASK(iImage == 1 ? 2 : 1),<Br> TVIS_STATEIMAGEMASK );<Br> return;<Br> }<Br>}<Br></Br>Step 5:处理 OnKeyDown<Br>void CTreeCtrlX::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)<Br>{<Br> if( nChar == VK_SPACE )<Br> {<Br> HTREEITEM hti = GetSelectedItem();<Br> int iImage = GetItemState( hti, TVIS_STATEIMAGEMASK )>>12;<Br> SetItemState( hti, INDEXTOSTATEIMAGEMASK(iImage == 1 ? 2 : 1),<Br> TVIS_STATEIMAGEMASK );<Br> return;<Br> }<Br>}<Br></Br></Br></Br></Br>Step 6: 增加其他的功能函数<Br>BOOL CTreeCtrlX::IsItemChecked(HTREEITEM hItem)<Br>{<Br> return GetItemState( hItem, TVIS_STATEIMAGEMASK )>>12 == 2;<Br>}<Br></Br>HTREEITEM CTreeCtrlX::GetFirstCheckedItem()<Br>{<Br> for ( HTREEITEM hItem = GetRootItem(); hItem!=NULL; hItem = GetNextItem( hItem ) )<Br> if ( IsItemChecked(hItem) )<Br> return hItem;<Br></Br> return NULL;<Br>}<Br></Br>HTREEITEM CTreeCtrlX::GetNextCheckedItem( HTREEITEM hItem )<Br>{<Br> for ( hItem = GetNextItem( hItem ); hItem!=NULL; hItem = GetNextItem( hItem ) )<Br> if ( IsItemChecked(hItem) )<Br> return hItem;<Br></Br> return NULL;<Br>}<Br></Br>HTREEITEM CTreeCtrlX::GetPrevCheckedItem( HTREEITEM hItem )<Br>{<Br> for ( hItem = GetPrevItem( hItem ); hItem!=NULL; hItem = GetPrevItem( hItem ) )<Br> if ( IsItemChecked(hItem) )<Br> return hItem;<Br></Br> return NULL;<Br>}<Br></Br></p></td></tr><tr><td><font color="0000FF"><a name="13">可以使用Drag&Drop的CTreeView<Br>闻怡洋译</a></font></td></tr><tr><td><p></Br></Br>CTreeViewExt是MFC使用者可重用的类,该类由CTreeView派生,可以用在文档-视结构的应用程序中,并且支持Drag&Drop。<Br></Br>使用者所需要做的仅仅是将文件加到AppWizard产生的工程中,(CTreeView为基类)并且将CTreeView替换为CTreeViewExt。并重载三个Virtual Function。<Br></Br>(WenYY:这很简单吧,下面是源代码,我会在必要的地方加上注释,但由于原作者并未加,所以如果有出入请原谅,作者定义了三处虚拟函数,其作用是让使用者重载后,加入自己的判断条件和结果处理的功能,很巧妙的思想:<Br></Br> CopyItemProperties<Br> IsItemCanBeDroppedOn(HTREEITEM hSource, HTREEITEM hTarget);<Br> BOOL ItemCanBeDragged(HTREEITEM hItem);//检查是否可以对该ITEM实施Drag&Drop<Br>)<Br></Br>Header file<Br></Br>#if !defined(AFX_TREEVIEWEXT_H__99D8F6F8_79F0_11D1_8DC6_0000E8125FE5__INCLUDED_)<Br>#define AFX_TREEVIEWEXT_H__99D8F6F8_79F0_11D1_8DC6_0000E8125FE5__INCLUDED_<Br></Br>#if _MSC_VER >= 1000<Br>#pragma once<Br>#endif // _MSC_VER >= 1000<Br>// TreeViewExt.h : header file<Br>//<Br></Br>/////////////////////////////////////////<Br>// CTreeViewExt view<Br></Br>class CTreeViewExt : public CTreeView<Br>{<Br>protected:<Br> CTreeViewExt(); // protected constructor used by dynamic creation<Br> DECLARE_DYNCREATE(CTreeViewExt)<Br></Br>// Attributes<Br>public:<Br></Br>// Operations<Br>public:<Br></Br>// Overrides<Br> // ClassWizard generated virtual function overrides<Br> //{{AFX_VIRTUAL(CTreeViewExt)<Br> protected:<Br> virtual void OnDraw(CDC* pDC); // overridden to draw this view<Br> //}}AFX_VIRTUAL<Br></Br>// Implementation<Br>protected:<Br> HTREEITEM m_hDraggedItem;<Br> BOOL m_bDraggingNow; //标记<Br> CImageList *m_pDragImageList;<Br> virtual ~CTreeViewExt();<Br>#ifdef _DEBUG<Br> virtual void AssertValid() const;<Br> virtual void Dump(CDumpContext& dc) const;<Br>#endif<Br></Br> // Generated message map functions<Br>protected:<Br> virtual void CopyItemProperties(HTREEITEM hNewItem, HTREEITEM hDraggedItem);<Br> virtual BOOL IsItemCanBeDroppedOn(HTREEITEM hSource, HTREEITEM hTarget);<Br> virtual BOOL ItemCanBeDragged(HTREEITEM hItem);//检查是否可以对该ITEM实施Drag&Drop<Br> //{{AFX_MSG(CTreeViewExt)<Br> afx_msg void OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult);//必须重载的函数<Br> afx_msg void OnMouseMove(UINT nFlags, CPoint point);<Br> afx_msg void OnLButtonUp(UINT nFlags, CPoint point);<Br> //}}AFX_MSG<Br> DECLARE_MESSAGE_MAP()<Br>};<Br></Br>/////////////////////////////////////////<Br></Br>//{{AFX_INSERT_LOCATION}}<Br>// Microsoft Developer Studio will insert additional declarations immediately before the previous line.<Br></Br>#endif // !defined(AFX_TREEVIEWEXT_H__99D8F6F8_79F0_11D1_8DC6_0000E8125FE5__INCLUDED_)<Br></Br>Implementation file<Br></Br>// TreeViewExt.cpp : implementation file<Br>//<Br></Br>#include "stdafx.h"<Br>#include "TreeViewExt.h"<Br></Br>#ifdef _DEBUG<Br>#define new DEBUG_NEW<Br>#undef THIS_FILE<Br>static char THIS_FILE[] = __FILE__;<Br>#endif<Br></Br>/////////////////////////////////////////<Br>// CTreeViewExt<Br></Br>IMPLEMENT_DYNCREATE(CTreeViewExt, CTreeView)<Br></Br>CTreeViewExt::CTreeViewExt()<Br>{<Br> m_bDraggingNow = FALSE;<Br> m_hDraggedItem = NULL;<Br> m_pDragImageList = NULL;<Br>}<Br></Br>CTreeViewExt::~CTreeViewExt()<Br>{<Br>}<Br></Br></Br>BEGIN_MESSAGE_MAP(CTreeViewExt, CTreeView)<Br> //{{AFX_MSG_MAP(CTreeViewExt)<Br> ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)<Br> ON_WM_MOUSEMOVE()<Br> ON_WM_LBUTTONUP()<Br> //}}AFX_MSG_MAP<Br>END_MESSAGE_MAP()<Br></Br>/////////////////////////////////////////<Br>// CTreeViewExt drawing<Br></Br>void CTreeViewExt::OnDraw(CDC* pDC)<Br>{<Br> CDocument* pDoc = GetDocument();<Br> // TODO: add draw code here<Br>}<Br></Br>/////////////////////////////////////////<Br>// CTreeViewExt diagnostics<Br></Br>#ifdef _DEBUG<Br>void CTreeViewExt::AssertValid() const<Br>{<Br> CTreeView::AssertValid();<Br>}<Br></Br>void CTreeViewExt::Dump(CDumpContext& dc) const<Br>{<Br> CTreeView::Dump(dc);<Br>}<Br>#endif //_DEBUG<Br></Br>/////////////////////////////////////////<Br>// CTreeViewExt message handlers<Br></Br>void CTreeViewExt::OnBegindrag(NMHDR* pNMHDR, LRESULT* pResult)<Br>{<Br> NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;<Br></Br> if (!m_bDraggingNow)<Br> {//先检查是否正在过程中<Br> if (ItemCanBeDragged(pNMTreeView->itemNew.hItem))<Br> {//查询条件,是否允许Drag&Drop<Br> CTreeCtrl& tree = GetTreeCtrl();<Br> tree.SetCapture();<Br> m_bDraggingNow = TRUE;<Br> m_hDraggedItem = pNMTreeView->itemNew.hItem;//保存变量<Br> tree.Select(m_hDraggedItem, TVGN_CARET);<Br> m_pDragImageList = tree.CreateDragImage(m_hDraggedItem);<Br> m_pDragImageList->DragEnter(&tree, pNMTreeView->ptDrag);<Br> m_pDragImageList->BeginDrag(0, CPoint(0, 0));<Br> }<Br> }<Br></Br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -