zoukankan      html  css  js  c++  java
  • MFC TreeControl简单应用


    对于TreeControl常用操作,做如下介绍。

    1. TreeControl添加节点

    1. 在界面种选择TreeControl控件,点击右键,在弹出的菜单种选择【添加变量】,在弹出的界面中输入变量名 "m_list”

    2. 点击界面右键,在弹出的菜单中选择【类向导】,选中“虚函数”选项卡,选择其中的“OnInitDialog”函数,然后点击【添加函数按钮】,然后点击确定。

    3. 将TreeControl控件中的属性“Has Buttons”、”Line at root“和“Has Line”后改为 “True”,如果相实现双击更改其值的功能,则将”Edit Labels“改为”True“

    4. 如果想要在树节点前添加图标,则需要导入*.icon的图标文件。具体方法为:
      选择资源视图,在资源视图中点击右键,在弹出的菜单中选择【添加资源】,在弹出的界面中点击【导入】按钮,然后选择.icon的文件。此图标导入后的名称为”IDI_ICON1“

    5. 在初始化函数中添加节点代码

    //在.h文件中添加如下代码
    CImageList m_imageList1;
    
    //修改初始化函数
    BOOL TreeTest::OnInitDialog()
    {
    	CDialogEx::OnInitDialog();
    
    	m_list.SetBkColor(RGB(230,230,230));//设置树的颜色
    
    	m_imageList1.Create(16,16,ILC_COLOR8|ILC_MASK,0,4);//第五个参数为图标的总数
    	m_imageList1.Add(AfxGetApp()->LoadIconW(IDI_ICON1));//将图标添加到imageList中
    
    	m_list.SetImageList(&m_imageList1,TVSIL_NORMAL);//将图标进行加载
    
    	
    	HTREEITEM root = m_list.InsertItem(_T("root"));//插入根节点
    	HTREEITEM hChild1 = m_list.InsertItem(_T("child1"),root);//在根节点下插入子节点
        HTREEITEM hChild2 = m_list.InsertItem(_T("child2"),root);//在根节点下插入子节点
        HTREEITEM hChild3 = m_list.InsertItem(_T("child3"),root);//在根节点下插入子节点
    
    	m_list.SetItemImage(root,0,0);//设置根节点图标
    	m_list.SetItemImage(hChild1,0,0);
        m_list.SetItemImage(hChild2,0,0);
        m_list.SetItemImage(hChild3,0,0);//设置子节点图标,注意:第一个参数为要设置的节点、第二个参数为默认状态下的图标、第三个值为选中后的图标。
    
    
    	return TRUE;  // return TRUE unless you set the focus to a control
    
    }
    

    2. TreeControl菜单

    1. 新建一个菜单,内容为”增加“、”删除“、”重命名“
    2. 选中Tree控件,点击右键,在弹出的菜单中选择”类向导“;在弹出的界面中选择【命令】、对象下选择”IDC_TREE1“,在消息中选择右键消息”NM_RCLICK“,然后点击【添加处理程序】按钮。
    3. 选中节点后才可以加载菜单,具体代码如下:
    void TreeTest::OnRclickTree1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	CPoint ScreenPt;
    	GetCursorPos(&ScreenPt);
    
    	CPoint pt =GetCurrentMessage()->pt;//获取当前鼠标点击消息的坐标点
    	m_list.ScreenToClient(&pt);//将鼠标的屏幕坐标,转换成树控件的客户区域坐标
    	UINT uFlags = 0;
    	HTREEITEM hItem = m_list.HitTest(pt,&uFlags);//然后做点击测试
    
    	/**判断右键是否在节点上**/
    	if ((hItem != NULL)&&(TVHT_ONITEM & uFlags))//如果点击位置在界面位置上面
    	{
    		
    		CMenu menu;
    		menu.LoadMenuW(IDR_MENU1);//装载第一个子菜单,即我们菜单的第一列
    		CMenu* pPopup = menu.GetSubMenu(0);
    		pPopup->TrackPopupMenu(TPM_LEFTALIGN, ScreenPt.x, ScreenPt.y, this);//弹出菜单 2
    	
    	}
    	*pResult = 0;
    }
    

    3. TreeControl修改节点

    参考链接
    实现双击修改节点名称,双击时速度需要慢一些,快速双击为展开和折叠节点

    1. 属性设置:将”Edit Labels“改为”True“
    2. 选中Tree控件,在弹出的菜单中选择【类向导】,添加消息函数”TVN_BEGINLABELEDIT“ 和 ”TVN_ENDLABELEDIT“
    3. 添加全局变量CString g_sSelectStr
    4. 修改两个消息函数,,如下:
    void TreeTest::OnBeginlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
    
    	g_sSelectStr = m_list.GetItemText(m_list.GetSelectedItem());//得到修改前的数据
    	*pResult = 0;
    }
    
    
    void TreeTest::OnEndlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR);
    	
    	CString strName; //修改后的数据
    	CString rootstr;
    	m_list.GetEditControl()->GetWindowText(strName);
    	if (strName.IsEmpty())
    	{
    		AfxMessageBox(_T("数据项不能为空,请重新输入"));
    		return;
    	}
    	if (strName.Compare(g_sSelectStr) == 0)//名字未做修改
    	{
    		return;
    	}
    	//判断是否由重复的名字
    	HTREEITEM hRoot = m_list.GetRootItem();
    	HTREEITEM hFind = FindItem(hRoot,strName);
    	if (hFind == NULL)//如果没有重名,则修改
    	{
    		CString strText;
    		m_list.GetEditControl()->GetWindowText(strText);
    		m_list.SetItemText(m_list.GetSelectedItem(),strText);
    	}
    	*pResult = 0;
    }
    
    

    4. TreeControl查找节点

    //根据名称来查找节点
    HTREEITEM TreeTest::FindItem(HTREEITEM item,CString strText)
    {
    	HTREEITEM hFind;
    	if (item == NULL)//修改数据与根数据不同,遍历时使用
    	{
    		return NULL;
    	}
    	while(item != NULL)
    	{
    		if (strText.Compare(m_list.GetItemText(item))  == 0)//名字相同
    		{
    			return item;
    		}
    		if (m_list.ItemHasChildren(item))//如果有子节点,则继续判断
    		{
    			item = m_list.GetChildItem(item);
    			hFind = FindItem(item,strText);
    			if (hFind)
    			{
    				return hFind;
    			}
    			else
    			{
    				item = m_list.GetNextSiblingItem(m_list.GetParentItem(item));
    			}
    		}
    		else
    		{
    			item = m_list.GetNextSiblingItem(item);
    			return FindItem(item,strText);
    		}
    	}
    	return item;
    }
    

    5. TreeControl折叠展开节点

    //折叠所有的树节点
    void TreeTest::mFoldTree(HTREEITEM hTreeItem)
    {
    	if(!m_list.ItemHasChildren(hTreeItem))    
    	{    
    		return;    
    	}    
    	HTREEITEM hNextItem = m_list.GetChildItem(hTreeItem);
    	while (hNextItem != NULL)    
    	{   
    		ExpandTree(hNextItem);    
    		hNextItem = m_list.GetNextItem(hNextItem, TVGN_NEXT);    
    	}    
    	m_list.Expand(hTreeItem,TVE_COLLAPSE); 
    }
    
    //展开所有的树节点
    void TreeTest::ExpandTree(HTREEITEM hTreeItem)
    {
    	if(!m_list.ItemHasChildren(hTreeItem))    
    	{    
    		return;    
    	}  
    	HTREEITEM hNextItem = m_list.GetChildItem(hTreeItem);
    	while (hNextItem != NULL)    
    	{   
    		ExpandTree(hNextItem); 
    		hNextItem = m_list.GetNextItem(hNextItem, TVGN_NEXT);    
    	} 
    	HTREEITEM hchild = m_list.GetChildItem(hTreeItem);
    	CString NodeData,NodeName;
    	NodeName = m_list.GetItemText(hchild);
    	if (NodeData.Compare(_T("2")) == 0 )
    	{
    		return;
    	}
    	m_list.Expand(hTreeItem,TVE_EXPAND); 
    }
    
    //展开单独的树节点
    void TreeTest::ExpandTree2(HTREEITEM hTreeItem)
    {
    	if(!m_list.ItemHasChildren(hTreeItem))    
    	{    
    		return;    
    	}  
    	HTREEITEM hNextItem = m_list.GetChildItem(hTreeItem);
    	while (hNextItem != NULL)    
    	{   
    		ExpandTree(hNextItem); 
    		hNextItem = m_list.GetNextItem(hNextItem, TVGN_NEXT);    
    	} 
    	m_list.Expand(hTreeItem,TVE_EXPAND); 
    }
    
    
    void TreeTest::OnClickTree1(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	hTreeItem = m_list.GetSelectedItem();
    	*pResult = 0;
    }
    
    //折叠树按钮
    void TreeTest::OnBnClickedButton1()
    {
    	HTREEITEM hItem = m_list.GetSelectedItem();
    	if (hItem == NULL)
    	{
    		HTREEITEM hroot = m_list.GetRootItem();
    		mFoldTree(hroot);	  
    	}
    	else
    	{
    		mFoldTree(hItem);
    	}
    }
    
    //展开树按钮
    void TreeTest::OnBnClickedButton7()
    {
    	HTREEITEM hItem = m_list.GetSelectedItem();
    	if (hItem == NULL)
    	{
    		HTREEITEM hroot = m_list.GetRootItem();
    		ExpandTree(hroot);
    	}
    	else
    	{
    		ExpandTree2(hItem);
    	}
    }
    

    6. TreeControl拖动树

    参考网址1
    参考网址2
    参考网址3
    参考网址4

    创建树的时候,使用继承类TreeControl进行创建。例如:
    注意:此方法目前具有一定的局限性,即节点下必须有子节点,才可以完成拖动。后期进行优化

    CXtreeCtrl m_list;
    HTREEITEM root =	m_list.InsertItem(_T("root"));
    HTREEITEM parent1 = m_list.InsertItem(_T("1"),root);
    m_list.InsertItem(_T("11"),parent1);
    
    HTREEITEM parent2 = m_list.InsertItem(_T("2"),root);
    m_list.InsertItem(_T("21"),parent2);
    	
    HTREEITEM parent3 = m_list.InsertItem(_T("3"),root);
    m_list.InsertItem(_T("31"),parent3);
    
    HTREEITEM parent4 = m_list.InsertItem(_T("4"),root);
    m_list.InsertItem(_T("41"),parent4);
    

    7. 继承类TreeControl

    XTreeCtrl.cpp

    // XtreeCtrl.cpp : implementation file
    //
    
    #include "stdafx.h"
    #include "Drag.h"
    #include "XtreeCtrl.h"
    #define DRAG_DELAY 60
    
    // CXtreeCtrl
    
    IMPLEMENT_DYNAMIC(CXtreeCtrl, CTreeCtrl)
    
    CXtreeCtrl::CXtreeCtrl()
    {
    	m_bDragging = FALSE;
    	//m_hSelectItem = NULL;
    	m_hItemDragS = NULL;
    	m_nHoverTimerID = 0;
    	m_nScrollTimerID = 0;
    	m_bInsertAbove = FALSE;
    	m_hItemDragD = NULL;
    
    }
    
    CXtreeCtrl::~CXtreeCtrl()
    {
    }
    
    
    BEGIN_MESSAGE_MAP(CXtreeCtrl, CTreeCtrl)
    	ON_NOTIFY_REFLECT(TVN_BEGINDRAG, &CXtreeCtrl::OnTvnBegindrag)
    	ON_WM_LBUTTONUP()
    	ON_WM_MOUSEMOVE()
    	ON_WM_TIMER()
    	ON_WM_LBUTTONDOWN()
    END_MESSAGE_MAP()
    
    
    
    // CXtreeCtrl message handlers
    
    
    
    void CXtreeCtrl::OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult)
    {
    	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
    	// TODO: Add your control notification handler code here
    	
    	*pResult = 0;
    	if( (GetTickCount() - m_dwDragStart) < DRAG_DELAY )
    		return;
    	
    	m_hItemDragS = pNMTreeView->itemNew.hItem;
    	if (!ItemHasChildren(m_hItemDragS))				//子节点不能被拖拽,注释后可以随意拖拽
    	{
    		return;
    	}
    	m_hItemDragD = NULL;
    	m_bDragging = true;
    	m_nScrollTimerID = SetTimer( 2,40,NULL );
    }
    HTREEITEM CXtreeCtrl::GetDragTarget(HTREEITEM hItem, POINT point, BOOL& bInsertAbove)
    {
    	ASSERT(hItem != NULL);
    	HTREEITEM hDragTarget;
    	CRect rectItem;
    	GetItemRect(hItem, &rectItem, FALSE);
    	if (point.y < rectItem.CenterPoint().y)
    	{
    		hDragTarget = hItem;
    		bInsertAbove = TRUE;
    	}
    	else
    	{
    		if (ItemHasChildren(hItem) && (GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED))
    		{
    			hDragTarget = GetChildItem(hItem);    
    			bInsertAbove = TRUE;
    		}
    		else
    		{
    			hDragTarget = hItem;
    			bInsertAbove = FALSE;
    		}
    	}
    	ASSERT(hDragTarget != NULL);
    	return hDragTarget;
    }
    
    void CXtreeCtrl::OnMouseMove(UINT nFlags, CPoint point)
    {
    	// TODO: Add your message handler code here and/or call default
    
    	HTREEITEM hItem;
    	UINT      flags;
    	if (m_nHoverTimerID > 0)
    	{
    		KillTimer(m_nHoverTimerID);
    		m_nHoverTimerID = 0;
    	}	
    	if( m_bDragging )
    	{
    		m_nHoverTimerID = SetTimer(1, 800, NULL);
    		m_HoverPoint = point;
    		//鼠标经过时高亮显示
    		CImageList::DragShowNolock( false ); //避免鼠标经过时留下难看的痕迹
    		HTREEITEM m_hNextDragTarget;	
    		BOOL m_bNextInsertAbove;		
    		if( (hItem = HitTest(point,&flags)) != NULL )
    		{
    			m_hNextDragTarget = GetDragTarget(hItem, point, m_bNextInsertAbove);
    			if ((m_hNextDragTarget != m_hItemDragD) || (m_bInsertAbove != m_bNextInsertAbove))
    			{
    				SelectDropTarget(m_hNextDragTarget);
    				m_hItemDragD = m_hNextDragTarget;
    				m_bInsertAbove = m_bNextInsertAbove;
    				EnsureVisible(m_hItemDragD);
    				RedrawWindow();
    			}
    		}
    		if ((GetScrollPos(SB_HORZ) > 0) && (GetScrollLimit(SB_VERT) > 0))
    		{
    			Invalidate();
    		}
    	}
    	CTreeCtrl::OnMouseMove(nFlags, point);
    }
    HTREEITEM CXtreeCtrl::CopyItem(HTREEITEM hItem1, HTREEITEM htiNewParent, HTREEITEM htiAfter) //拷贝条目
    {
    	TV_ITEM tvSrc;
    	tvSrc.mask  = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE;
    	tvSrc.hItem = hItem1;
    	if (!GetItem(&tvSrc)) 
    		return	htiNewParent;
    
    	tvSrc.hItem = htiNewParent;
    	SetItem(&tvSrc);
    	SetItemText(htiNewParent,GetItemText(hItem1));
    	SetCheck(htiNewParent,GetCheck   (hItem1));
    
    	if (tvSrc.state & TVIS_EXPANDED) 
    		Expand(htiNewParent,TVE_EXPAND);
    }
    HTREEITEM CXtreeCtrl::CopyBranch(HTREEITEM htiBranch, HTREEITEM htiNewParent, HTREEITEM htiAfter) //拷贝分支
    {
    	ASSERT((htiNewParent != NULL) && (htiBranch != NULL));
    	HTREEITEM hChild;
    	hChild = GetChildItem( htiBranch );
    	while ( hChild != NULL )
    	{
    		HTREEITEM hChildDest = InsertItem(_T("dest child"), htiNewParent);
    		CopyBranch( hChild,hChildDest,htiAfter );
    		CopyItem(hChild,hChildDest,htiAfter);
    		hChild = GetNextSiblingItem( hChild );
    	}
    	return htiNewParent;
    }
    
    HTREEITEM CXtreeCtrl::InsertItemAndSubtree(HTREEITEM hParent)
    {
    	if ((m_hItemDragD == NULL) || (m_hItemDragS == NULL)) 
    	{
    		ASSERT(FALSE);
    		return NULL;
    	}
    	HTREEITEM hRoot = GetRootItem();
    	if (!ItemHasChildren(m_hItemDragD))		//如果注释可以随意拖拽父节点到子节点(自己看效果)
    	{
    		return	NULL;
    	}
    	
    	else if (hRoot == m_hItemDragD)			//如果注释可以随意拖拽父节点至根节点(自己看效果)
    	{
    		return	NULL;
    	}
    	if (hParent == NULL)
    		hParent = GetParentItem(m_hItemDragD);
    	if (hParent == NULL)
    		hParent = TVI_ROOT;
    
    	HTREEITEM hInsertAfter;
    
    	if (m_bInsertAbove)
    		hInsertAfter = GetPrevSiblingItem(m_hItemDragD);
    	else
    		hInsertAfter = m_hItemDragD;
    
    	if ((hInsertAfter == hParent) || (hInsertAfter == NULL))
    		hInsertAfter = TVI_FIRST;
    
    	HTREEITEM hNew = InsertItem(_T("dummy"), hParent, hInsertAfter);
    	if (hNew == NULL)
    		return NULL;
    
    	CopyBranch(m_hItemDragS,hNew,m_hItemDragD);
    	CopyItem(m_hItemDragS,hNew,m_hItemDragD);
    
    	return hNew;
    }
    
    void CXtreeCtrl::OnLButtonUp(UINT nFlags, CPoint point)
    {
    	// TODO: Add your message handler code here and/or call default
    	CTreeCtrl::OnLButtonUp(nFlags, point);
    	if(m_bDragging)
    	{
    		m_bLeftBtnUp = TRUE;
    		KillTimer(m_nScrollTimerID);
    		m_nScrollTimerID = 0;
    		KillTimer(m_nHoverTimerID);
    		m_nHoverTimerID = 0;
    		ReleaseCapture();
    		ShowCursor(true);
    		m_bDragging = false;
    		SelectDropTarget(NULL);
    		if (m_bLeftBtnUp)
    		{
    			if (m_hItemDragD != NULL)
    				m_bGoingOK = TRUE;
    			HTREEITEM m_hParentNew = m_hItemDragD;
    			while (m_hParentNew != NULL)
    			{
    
    				if(m_hParentNew == m_hItemDragS)
    				{
    					//AfxMessageBox(_T("禁止此操作!"), MB_ICONEXCLAMATION);
    					m_bGoingOK = FALSE;
    					break;
    				}
    				m_hParentNew = GetParentItem(m_hParentNew);
    			}
    			HTREEITEM m_hParent;
    			if (m_bGoingOK)
    			{
    				SetRedraw(FALSE);            
    				m_hParent = GetParentItem(m_hItemDragD);
    				if (m_hParent == NULL)
    					m_hParent = TVI_ROOT;		
    				if (m_bGoingOK)
    				{
    					// We're finally ready to insert the actual item.
    					HTREEITEM hNew = InsertItemAndSubtree(m_hParent);
    					if (hNew != NULL) 
    					{
    						SelectItem(hNew);
    						DeleteItem(m_hItemDragS);
    					}
    				}
    			}
    			// Regardless of what happens, we need to reset the tree.
    			SetRedraw(TRUE);            
    			Invalidate();
    		}
    		else
    		{
    			// The User chose to abort the drag
    			EnsureVisible(m_hItemDragS);
    			// Refresh the screen to get rid of any remnants of the drag drawing
    			Invalidate();
    		}
    
    	}
    	CTreeCtrl::OnLButtonUp(nFlags, point);
    }
    
    void CXtreeCtrl::OnTimer(UINT_PTR 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 = HitTest(m_HoverPoint,&uFlag);
    		if( trItem && m_bDragging)
    		{
    			SelectItem(trItem);
    			//Expand( trItem,TVE_EXPAND );
    		}
    	}
    	else if(nIDEvent == m_nScrollTimerID)
    	{
    		m_TimerTicks++;
    		CPoint pt;
    		GetCursorPos(&pt);
    		CRect rect;
    		GetClientRect(&rect);
    		ClientToScreen(&rect);
    		HTREEITEM hItem = 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);
    				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 = GetVisibleCount();
    				for( int i=0 ; i<nCount-1 ; i++ )
    					hItem = GetNextVisibleItem( hItem);
    				if( hItem)
    					SelectDropTarget(hItem);
    
    				m_hItemDragD = hItem;
    				CImageList::DragShowNolock (true);
    			}
    		}
    	}
    	else
    	CTreeCtrl::OnTimer(nIDEvent);
    }
    
    void CXtreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
    {
    	// TODO: Add your message handler code here and/or call default
    	//m_dwDragStart = GetTickCount();	
    	//m_hSelectItem = GetSelectedItem();
    	//UINT nHitFlags = 0;
    	//HTREEITEM hClickedItem = HitTest( point, &nHitFlags );
    	CTreeCtrl::OnLButtonDown(nFlags, point);
    }
    
    

    XTreeCtrl.h

    #pragma once
    
    
    // CXtreeCtrl
    
    class CXtreeCtrl : public CTreeCtrl
    {
    	DECLARE_DYNAMIC(CXtreeCtrl)
    
    public:
    	CXtreeCtrl();
    	virtual ~CXtreeCtrl();
    
    protected:
    	DECLARE_MESSAGE_MAP()
    
    
    public:
    	afx_msg void OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult);
    	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    	afx_msg void OnTimer(UINT_PTR nIDEvent);
    	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    protected:
    	DWORD		m_dwDragStart;
    	UINT        m_nScrollTimerID;
    	UINT        m_nHoverTimerID;
    	UINT		m_TimerTicks;
    	POINT       m_HoverPoint;
    	BOOL        m_bDragging;
    	BOOL        m_bInsertAbove;
    	BOOL		m_bLeftBtnUp;
    	BOOL		m_bGoingOK;
    	CImageList* m_pDragImage;
    	HTREEITEM   m_hItemDragS;
    	HTREEITEM   m_hItemDragD;
    	HTREEITEM	m_hSelectItem;
    	HTREEITEM CopyBranch(HTREEITEM htiBranch,HTREEITEM htiNewParent,HTREEITEM htiAfter);
    	HTREEITEM CopyItem(HTREEITEM hItem,HTREEITEM htiNewParent,HTREEITEM htiAfter);
    	HTREEITEM GetDragTarget(HTREEITEM hItem, POINT point, BOOL& bInsertAbove);
    	HTREEITEM InsertItemAndSubtree(HTREEITEM hParent = NULL);
    };
    
    
  • 相关阅读:
    Windows系统架构
    UVa10006-Carmichael Numbers
    Android打开系统设置
    C语言与汇编“硬在哪里”——什么是面向硬件?
    javaSocket与C通信
    小智慧25
    sqlplus中显示sql执行计划和统计信息
    记一次修复被篡改的IE首页
    UIView的生命周期
    [置顶] 关于UBUNTU 12.04, 在THINKPAD E430C上WIFI连接不上的问题
  • 原文地址:https://www.cnblogs.com/gaozihan/p/10835764.html
Copyright © 2011-2022 走看看