4.实现上下文菜单 在WM_RBUTTONDOWN消息处理函数上实现上下文菜单 5.展开和收起树视图结点: HTREEITEM hItem=GetRootItem(); //获取根结点,可能会有多个根结点 ItemHasChildren(hParent) //判断结点是否有孩子结点 hItem=GetChildItem(hParent); //获取第一个子结点 hItem=GetNextSiblingItem(hItem)); //获取下一个兄弟结点结点 Expand(hItem,bExpand?TVE_EXPAND:TVE_COLLAPSE);//展开/叠起结点 Select(hItem,TVGN_FIRSTVISIBLE); //设置选中结点 CString str=GetItemText(hChild); //获取结点字符串信息 HTREEITEM hCurrSel = GetSelectedItem(); //获取当前选中结点 SelectItem(hNewSel); HTREEITEM hNewSel = HitTest(pt, &nFlags); //判断坐标是否在当前结点范围内 HTREEITEM hItem=InsertItem(dlg.m_strItemText,hItemParent); //插入结点 #pragma once //定义文件MyTreeCtrl.h // CMyTreeCtrl class CMyTreeCtrl : public CTreeCtrl { DECLARE_DYNAMIC(CMyTreeCtrl) public: CMyTreeCtrl(); virtual ~CMyTreeCtrl(); protected: DECLARE_MESSAGE_MAP() void ExpandBranch(HTREEITEM hItem,BOOL bExpand =TRUE); public: void ExpandAllBranches(BOOL bExpand =TRUE); BOOL DoesItemExist(HTREEITEM hItemParent, CString const& strItem); afx_msg void OnRButtonDown(UINT nFlags, CPoint point); afx_msg void OnAddItem(); virtual BOOL PreTranslateMessage(MSG* pMsg); afx_msg void OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg BOOL OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult); }; // MyTreeCtrl.cpp : 实现文件 #include "stdafx.h" #include "TreeCtrl.h" #include "MyTreeCtrl.h" #include ".mytreectrl.h" #include "AddItemDlg.h" // CMyTreeCtrl IMPLEMENT_DYNAMIC(CMyTreeCtrl, CTreeCtrl) CMyTreeCtrl::CMyTreeCtrl() { } CMyTreeCtrl::~CMyTreeCtrl() { } BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl) ON_WM_RBUTTONDOWN() ON_COMMAND(IDR_ADD_ITEM, OnAddItem) ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnTvnEndlabeledit) ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnTvnBeginlabeledit) ON_NOTIFY_REFLECT_EX(TVN_SELCHANGED, OnTvnSelchanged) END_MESSAGE_MAP() // CMyTreeCtrl 消息处理程序 void CMyTreeCtrl::ExpandBranch(HTREEITEM hItem,BOOL bExpand ) //展开 { if (ItemHasChildren(hItem)) //判断是否有孩子结点 { Expand(hItem,bExpand?TVE_EXPAND:TVE_COLLAPSE); //展开/叠起结点 hItem=GetChildItem(hItem);//获取第一个子结点 do{ ExpandBranch(hItem); } while(hItem=GetNextSiblingItem(hItem));//获取兄弟结点 } } void CMyTreeCtrl::ExpandAllBranches(BOOL bExpand ) { HTREEITEM hItem=GetRootItem();//获取根结点,可能会有多个根结点 do{ ExpandBranch(hItem,bExpand); } while(hItem=GetNextSiblingItem(hItem)); Select(hItem,TVGN_FIRSTVISIBLE);//设置选中结点 } BOOL CMyTreeCtrl::DoesItemExist(HTREEITEM hItemParent, CString const& strItem) { BOOL bDoesItemExist=FALSE; ASSERT(strItem.GetLength()); HTREEITEM hChild=GetChildItem(hItemParent?hItemParent:TVI_ROOT); while (NULL!=hChild&&!bDoesItemExist) { CString str=GetItemText(hChild);//获取结点字符串信息 if (0==str.CompareNoCase(strItem)) { bDoesItemExist=TRUE; } else { hChild=GetNextSiblingItem(hChild); } } return bDoesItemExist; } void CMyTreeCtrl::OnRButtonDown(UINT nFlags, CPoint point) { // TODO: 在此添加消息处理程序代码和/或调用默认值 // set focus to the tree control SetFocus(); // map the point that is passed to the // function from client coordinates // to screen coordinates ClientToScreen(&point); // Get the currently selected item HTREEITEM hCurrSel = GetSelectedItem();//获取当前选中结点 // Figure out which item was right clicked CPoint pt(0, 0); ::GetCursorPos(&pt); ScreenToClient (&pt); HTREEITEM hNewSel = HitTest(pt, &nFlags); // Set the selection to the item that the // mouse was over when the user right // clicked if (NULL == hNewSel) { SelectItem(NULL); } else if (hCurrSel != hNewSel) { SelectItem(hNewSel); SetFocus(); } // Load the context menu CMenu Menu; if (Menu.LoadMenu(IDM_CONTEXT_MENU)) { CMenu* pSubMenu = Menu.GetSubMenu(0); if (pSubMenu!=NULL) { // Display the context menu pSubMenu->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this); } } } void CMyTreeCtrl::OnAddItem() //添加上下文菜单 { // TODO: 在此添加命令处理程序代码 HTREEITEM hItemParent=GetSelectedItem(); //获取当前选中结点 CAddItemDlg dlg; if (dlg.DoModal()==IDOK) { if (!DoesItemExist(hItemParent,dlg.m_strItemText)) { HTREEITEM hItem=InsertItem(dlg.m_strItemText,hItemParent); //插入结点 SelectItem(hItem); } else { AfxMessageBox("已存在相同结点"); } }
} BOOL CMyTreeCtrl::PreTranslateMessage(MSG* pMsg) { // TODO: 在此添加专用代码和/或调用基类 BOOL bHandledMsg = FALSE; switch (pMsg->message) { case WM_KEYDOWN: { switch (pMsg->wParam) { case VK_ESCAPE: case VK_RETURN: if (::GetKeyState(VK_CONTROL) & 0x8000) { break; } if (GetEditControl()) { ::TranslateMessage(pMsg); ::DispatchMessage(pMsg); bHandledMsg = TRUE; } break; default: break; } // switch (pMsg->wParam) } // WM_KEYDOWN break; default: break; } // switch (pMsg->message) // continue normal translation and dispatching return (bHandledMsg ?TRUE : CTreeCtrl::PreTranslateMessage(pMsg)); } void CMyTreeCtrl::OnTvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult) { LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 *pResult=1; CEdit*pEdit=GetEditControl(); ASSERT(pEdit); if (pEdit) { pEdit->LimitText(15); *pResult=0; } } void CMyTreeCtrl::OnTvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult) { LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 BOOL bValidItem=FALSE; CString strItem=pTVDispInfo->item.pszText; if (0<strItem.GetLength()) { HTREEITEM hParent=GetParentItem(pTVDispInfo->item.hItem); bValidItem=!DoesItemExist(hParent,strItem); } *pResult = bValidItem; } BOOL CMyTreeCtrl::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult) { LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); // TODO: 在此添加控件通知处理程序代码 TRACE(GetItemText(pNMTreeView->itemNew.hItem)); TRACE(" "); *pResult = 0; return FALSE; //返回FALSE可以让父窗口进行进一步的处理 } |
vc树形控件TreeCtrl经验总结(二)
最新推荐文章于 2015-01-08 11:17:51 发布