1. 程式人生 > >MFC製作一個可自由新增刪除節點的樹(CTreeCtrl)類

MFC製作一個可自由新增刪除節點的樹(CTreeCtrl)類


微軟的MFC提供了強大的介面設計功能,但因為其很多函式過於繁瑣,對初學者來說不好上手,而我自己在學習過程中也碰到了很多問題,查了很多文章,在此要特地感謝雞琢米以及各位在CSDN上些小教程的各位前輩大佬。因此我打算分享一下我的學習經驗。

1.第一步在Visual Studio 2017中建立一個對話方塊工程,並刪除原有的3個控制元件

2.建立完對話方塊工程後,放置一個Tree Ctrl控制元件,將Has Button設為TRUE,這樣有+-小按鈕,再將Has Line勾上,這樣就有連線線了,最好在將Line At Root勾上,這樣根節點也會有連線線,此時一個最基本的樹便完成了。這是別忘了為樹關聯一個成員變數m_webTree用於之後的程式編寫。

3.再放入一個靜態文字框,一個按鈕,一個Edit Control,靜態文字框寫上:當前選中的節點。Edit Control用於顯示選中的節點和編輯名字,按鈕用於確認更改名字(當然也可以不用按鈕來確認)。總體效果如下圖

4.在完成了上述步驟後,我們就可以開始插入自己的樹啦,首先,為了美觀,我們需要準備幾個小圖示,記得用icon轉換器轉換格式,之後放入res資料夾內,之後,在資源試圖,右擊XXX.rc項,選擇新增資源,之後選擇Icon,然後匯入,將剛剛儲存的小圖片匯入進來,之後為其設定ID。同時在對話方塊的.h檔案中申明CImageList m_imageList,用於圖示的控制。

之後找到系統生成的BOOL CMFC_Study_TreeDlg::OnInitDialog()函式,新增初始化樹程式碼,使得在程式執行的時候可以顯示出剛剛設定的樹。

在使用圖示之前,需要將匯入的圖示依次加入圖示序列,程式碼如下:

//TODO:在此新增額外的初始化程式碼
HICON hMyIcon[3];      // 圖示控制代碼陣列   

						 // 載入圖示
	hMyIcon[0] = theApp.LoadIcon(ID_ICON_0);
	hMyIcon[1] = theApp.LoadIcon(ID_ICON_1);
	hMyIcon[2] = theApp.LoadIcon(ID_ICON_2);

	// 建立影象序列CImageList物件   
	m_imageList.Create(32, 32, ILC_COLOR32, 3, 3);
	// 將三個圖示新增到影象序列   
	for (int i = 0; i<3; i++)
	{
		m_imageList.Add(hMyIcon[i]);
	}

	// 為樹形控制元件設定影象序列   
	m_webTree.SetImageList(&m_imageList, TVSIL_NORMAL);
這樣一來,便將圖示和樹關聯了起來,之後可以使用
CTreeCtrl::InsertItem函式的一個過載插入樹了,該函式申明如下

HTREEITEM InsertItem(LPCTSTR lpszItem,int nImage,int nSelectedImage,HTREEITEM hParent = TVI_ROOT,HTREEITEM hInsertAfter = TVI_LAST);

其中lpszItem為標題,nimage為未選中時的圖示序號,nSelectedImage為選中時的圖示序號,此序號與之前新增影象序列的順序有關,hParent 表示插入的新樹將作為hParent的子樹,hParent是一個控制代碼,hInsertAfter 表示插入在誰之後,也是一個控制代碼。

CTreeCtrl::InsertItem()插入程式碼如下

	HTREEITEM hRoot;     // 樹的根節點的控制代碼   
	HTREEITEM hSecondLeaf; // 第二層  
	HTREEITEM hThirdLeaf;  // 第三層

hRoot = m_webTree.InsertItem(_T("爺爺"), 0, 0);
	// 在根節點下插入子節點   
hSecondLeaf= m_webTree.InsertItem(_T("爸爸1號"), 1, 1, hRoot, TVI_LAST);//插入第二層節點
	hThirdLead= m_webTree.InsertItem(_T("爸爸1號的兒子1"), 2, 2, hSecondLeaf, TVI_LAST);//插入第三層節點
	hThirdLeaf= m_webTree.InsertItem(_T("爸爸1號的兒子2"), 2, 2, hSecondLeaf, TVI_LAST);
之後執行,得到如下效果

5.有了自己的樹後,便可以將選中的樹的名字顯示到文字框中。我們可以為樹形控制元件IDC_WEB_TREE的通知訊息TVN_SELCHANGED新增訊息處理函式,這樣一來在我們滑鼠切換節點的時候就可以進入這個訊息處理函式

/*******************************************將樹的標題顯示到對話方塊中************************************/

void CMFC_Study_TreeDlg::OnTvnSelchangedWebtree(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	// TODO: 在此新增控制元件通知處理程式程式碼
	*pResult = 0;
	CString strText; // 樹節點的標籤文字字串   
	 // 獲取當前選中節點的控制代碼   
	HTREEITEM hItem = m_webTree.GetSelectedItem();
	// 獲取選中節點的標籤文字字串   
	strText = m_webTree.GetItemText(hItem);
	// 將字串顯示到編輯框中   
	SetDlgItemText(IDC_ITEM_SEL_EDIT, strText);

}

CTreeCtrl::GetSelectedItem()十分常用,用於得到選中節點的控制代碼,GetrItemText函式用於得到樹的標籤的字元,與此對應的是SetItemText,用於將字串設定為樹的標題,之後會用到。

到現在樹的基本功能便實現了,接下來,我們需要為樹設定右鍵選單。

6.我設計的是一個3層數,根節點不能刪除,第三層樹不能新增子樹,我使用了3個不同的選單(當然也有更好的方法)

設定選單在資源試圖裡,右鍵XXX.rc,選擇新增資源,選擇Menu,新建,之後為自己的選單設定好ID,然後就可以呼叫啦。

在樹的右擊事件中編寫如下程式碼,用於顯示選單

/***************************************新增右鍵選單*****************************************************/
void CMFC_Study_TreeDlg::OnNMRClickWebtree(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	*pResult = 0;
	CPoint point;
	GetCursorPos(&point);         //得到當前位置
	CPoint pointInTree = point;  
	m_webTree.ScreenToClient(&pointInTree);       //該函式把螢幕上指定點的螢幕座標轉換成使用者座標
	HTREEITEM item;
	UINT flag = TVHT_ONITEM;
	item = m_webTree.HitTest(pointInTree, &flag);        //函式能夠得到與當前滑鼠位置相關的項
	CMenu menu;
	m_webTree.SelectItem(item);        //選中當前右鍵樹
	HTREEITEM curPosition = m_webTree.GetSelectedItem();

	if ((item != NULL) && (GetLevel(curPosition)==2))   //第二層樹
	{
		menu.LoadMenu(IDR_MY_MENU2);
		menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN |
			TPM_RIGHTBUTTON, point.x, point.y, this, NULL);
	}
	else if ((GetLevel(curPosition) == 3))
	{
		menu.LoadMenu(IDR_MENU_NOSONTREE);    //第三層樹選單
		menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN |
			TPM_RIGHTBUTTON, point.x, point.y, this, NULL);
	}
	else   //根節點
	{
		menu.LoadMenu(IDR_MENU_ROOT);
		menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN |
		TPM_RIGHTBUTTON, point.x, point.y, this, NULL);
	}
}
由於我也是初學並且有點智障,找了半天沒找到哪個函式用於獲取樹的層次,於是索性自己寫了一個,通過找Parent的方法判斷是第幾層樹。
int CMFC_Study_TreeDlg::GetLevel(HTREEITEM inputTree)
{
	HTREEITEM temp;
	temp = inputTree;
	int level = 0;
	while (temp != NULL)
	{
		temp = m_webTree.GetParentItem(temp);
		++level;
	}
	return level;
}
這樣我就可以通過層數來設定不同的選單了。

7.設定好選單後,可以為每一個選單編輯事件啦。新增一顆樹的程式碼如下

void CMFC_Study_TreeDlg::OnMenu_MENU_ROOT_ADDNEWNODE()
{
	// TODO: 在此新增命令處理程式程式碼
	HTREEITEM curPosition;
	curPosition = m_webTree.GetSelectedItem();        //將返回當前選中的結點的控制代碼
	int imageNum = GetLevel(curPosition);//得到設定的是第幾層樹,由此確定不同的圖示
	m_webTree.InsertItem(_T("我是新生的結點!"), imageNum, imageNum, curPosition, TVI_LAST);
}

刪除一顆樹的程式碼如下:
void CMFC_Study_TreeDlg::OnMenuDelteThissontree() //沒有子樹的節點的右鍵刪除命令
{
	// TODO: 在此新增命令處理程式程式碼
	HTREEITEM curPosition;
	curPosition = m_webTree.GetSelectedItem();        //將返回當前選中的結點的控制代碼
	m_webTree.DeleteItem(curPosition);
}

8.最後,我們來設定給樹重新命名

為之前的Edit Control關聯一個變數TreeName,然後,為更改名字按鈕設定事件,就可以在那個編輯框更改名字啦,不過千萬不要忘記UpdaData,之前忘了可是糾結了好久呢

void CMFC_Study_TreeDlg::OnBnClickedButton1()
{
	// TODO: 在此新增控制元件通知處理程式程式碼
	UpdateData();
	HTREEITEM hItem = m_webTree.GetSelectedItem();
	m_webTree.SetItemText(hItem, TreeName);

}
9.到此,一個簡單的可自由增刪節點的樹便設計好啦



相關推薦

MFC製作一個自由新增刪除節點CTreeCtrl

微軟的MFC提供了強大的介面設計功能,但因為其很多函式過於繁瑣,對初學者來說不好上手,而我自己在學習過程中也碰到了很多問題,查了很多文章,在此要特地感謝雞琢米以及各位在CSDN上些小教程的各位前輩大佬。因此我打算分享一下我的學習經驗。 1.第一步在Visual Studi

HTML下拉選擇 簡單例項 新增刪除節點到另一個節點

 下拉選擇 簡單例項   <html> <head> <title>HTML</title> <style type="text/css"> </style> </h

HTML下拉選擇 簡單例項 新增刪除節點到另一個節點

 下拉選擇 簡單例項 <html> <head> <title>HTML</title> <style type="text/css"> </style> </head>

Solr叢集新增/刪除節點

叢集環境搭建好之後,確保叢集已經啟動成功。 ps:本篇文章的操作都是通過http請求來對進行的,錯誤和不足之處還望補充指正,謝謝! 新增一個節點:得先有存活的solr例項,還沒被新增到當前collection中 例: http://192.168.217.129:

C 製作Windows service服務系列一 製作一個安裝 啟動 停止 解除安裝的Windows service

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Mongodb 3.6 副本集測試及新增刪除節點等操作

下載tar包並安裝curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.6.8.tgz [[email protected] soft]# tar -zxvf mongodb-linux-x86_64-rhel

【redis】叢集伸縮新增刪除節點

注:本文知識點全部來自於《redis開發與運維》這本書在加上博主本人對於redis的理解構成 一、叢集伸縮原理         Redis叢集提供了靈活的節點擴容和收縮方案。在不影響叢集對外服務的情況下,可以為叢集新增節點進行擴容也可以下線部分節點進行縮容:

Rainbond:如何製作一個分享的雲市應用?

應用是Rainbond可管理的最小服務單元,使用者可以將多個應用組成一個複雜的業務系統,這套業務系統可以對外提供服務,也可以分享給其他組織獨立部署。本文將會通過Solo+Pinpoint(Pinpoint-java效能分析最佳實踐)這個例子,演示“如何製作一個可分享的雲市應用”, 分享後

redis linux-叢集新增刪除節點流程

一。新增主節點 開啟/usr/local/redis-3.2.7/cluster         mkdir 6385     #複製redis.conf配置檔案並把埠改成6385 啟動新增節點:./redis-server /usr/local/redis-3.2.7/c

MFC製作一個倒計時小程式

void CCdTimerDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default UpdateData(TRUE); BOOL bIsDecreased = FALSE;

sql建立一個表並新增刪除欄位

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using S

hadoop2.X動態新增刪除節點及相關問題總結

hadoop2.X動態新增節點教程及相關問題總結 設定hadoop執行的系統環境 修改系統hostname(通過hostname和/etc/sysconfig/network進行修改) 修改hosts

自由新增到指定位置的分頁標控制元件支付寶淘寶效果

LGFFreePT 可自由新增到指定位置的分頁標控制元件 製作目的 想要把分頁標放在檢視任意位置 把分頁用的子控制器 Page

配置語法分析器開發紀事——構造一個真正能用的狀態機

上一篇部落格寫到了如何給一個非終結符的文法規則構造出一個壓縮過的下推狀態機,那麼今天說的就是如何把所有的文法都連線起來。其實主要的idea在(三)和他的勘誤(三點五)裡面已經說得差不多了。但是今天我們要處理的是帶資訊的transition,所以還有一些地方要注意一下。 所以在這裡我們先把幾條文法

配置語法分析器開發紀事——構造一個真正能用的狀態機

上一篇文章對大部分文法都構造出了一個使用的狀態機了,這次主要來講右遞迴的情況。右遞迴不像左遞迴那麼麻煩,因為大部分右遞迴寫成迴圈也不會過分的讓語法樹變得難以操作,不過仍然有少數情況是我們仍然希望保留遞迴的語法樹形狀,譬如C++的連等操作,因此這裡就來講一下這個問題。 右遞迴是怎麼形成的呢?在這裡我

linux下export命令新增刪除環境變數轉載

export命令 功能說明:設定或顯示環境變數。 語  法:export [-fnp][變數名稱]=[變數設定值] 補充說明:在shell中執行程式時,shell會提供一組環境變數。 export可新增,修改或刪除環境變數,供後續執行的程式使用。 export的效力僅及於該此登陸操作。 參  數:    

Hadoop中正常啟動了datanode但管理介面卻卻顯示0個datanode節點或者只有本機的一個datanade,DFS Used顯示0100%

 以下會列出引起該問題的常見原因,及其解決辦法 1、在hadoop已經啟動的前提下,使用命令netstat  -an |grep 9001  (改命令用來監聽namenode主節點通訊情況,9001為

JS實現新增刪除TR行

經過在網上的查詢,終於弄好了JS新增和刪除TR的效果。 JS程式碼如下: 新增tr的JS程式碼 function addRemark(){ //table_name 是table的id var tr = document.getElementById("table