首先,我們要?jiǎng)?chuàng)建一個(gè)基本對(duì)話框的MFC工程MFC_TreeCRTL(名字隨便給一個(gè))。然后在資源視圖中插入兩個(gè)Dialog,ID分別為IDD_DIALOG11和IDD_DIALOG211,都更改Style屬性為Child,Border屬性為None,為它們建立兩個(gè)類,分別命名為Cdialog11和Cdialog211,并在MFC_TreeCRTLDlg.CPP文件中包含dialog11.h和dialog211.h兩個(gè)頭文件。再導(dǎo)入幾個(gè)資源圖標(biāo)作為樹(shù)形控件節(jié)點(diǎn)的圖標(biāo)及裝飾面板。最后在主面板上添加一個(gè)CTreeCtrl控件,ID為默認(rèn),并在ClassWizard中添加它的一個(gè)變量,命名為m_mytree。
始初化完成后,我們要添加CTreeCtrl的消息響應(yīng)事件,這樣才能讓它按我們的要求起作用。我們打開(kāi)Class Wizard點(diǎn)選IDC_TREE1添加TVN_SELCHANGED消息,并在消息響應(yīng)函數(shù)中寫(xiě)入代碼。
在創(chuàng)建treeview
control之后,用SetWindowLong函數(shù)設(shè)置TVS_CHECKBOXES 即可。
TVS_DISABLEDRAGDROP
防止tree-view control發(fā)送TVN_BEGINDRAG消息。
TVS_EDITLABELS
允許用戶修改item標(biāo)簽
TVS_FULLROWSELECT
允許選定整行。已選定的整行將高亮顯示,點(diǎn)擊這個(gè)item所在行的任意地方都將導(dǎo)致它被選中。這種風(fēng)格不能與TVS_HASLINES并存。
TVS_HASBUTTONS
在父節(jié)點(diǎn)處顯示(+)或(-)。用戶可以點(diǎn)擊這些按鈕展開(kāi)或者合并它的子節(jié)點(diǎn)。為了在tree-view的root處顯示出按鈕來(lái),必須要用TVS_LINESATROOT.
TVS_HASLINES
用直線顯示item之間的層次關(guān)系。
TVS_INFOTIP
通過(guò)發(fā)送TVN_GETINFOTIP得到功能提示信息。
TVS_LINESATROOT
用直線連接root處的item.如果沒(méi)有TVS_HASLINES風(fēng)格,這種風(fēng)格將被忽略。
TVS_NOHSCROLL
不顯示垂直滾動(dòng)條。
TVS_NONEVENHEIGHT
讓items之間的距離是不等的,否則就是等間距的.可用TVM_SETITEMHEIGHT設(shè)置高度。
TVS_NOSCROLL
無(wú)滾動(dòng)條。.
TVS_NOTOOLTIPS
無(wú)提示
TVS_RTLREADING
按照從右到左的順序顯示文本。
TVS_SHOWSELALWAYS
當(dāng)tree-view control失去焦點(diǎn)時(shí),被選中的item仍然保留被選中狀態(tài)。
TVS_SINGLEEXPAND
4.71版任何時(shí)刻只有一個(gè)item的child item被展開(kāi)。如果用單擊選中item并且這個(gè)item還沒(méi)有展開(kāi)的話,那么單擊后它將被展開(kāi)。如果選擇item的時(shí)候用戶按下了CTRL鍵,未被選中的item將不會(huì)自動(dòng)收起。
5.80版將使被選中的item展開(kāi),未被選中的收起。如果按下了CTRL,未被選中的不會(huì)收起。
TVS_TRACKSELECT
允許跟蹤
關(guān)于增加/刪除
在樹(shù)形控件中每一個(gè)結(jié)點(diǎn)都有一個(gè)句柄(HTREEITEM),同時(shí)添加結(jié)點(diǎn)時(shí)必須提供的參數(shù)是該結(jié)點(diǎn)的父結(jié)點(diǎn)句柄,(其中根Root結(jié)點(diǎn)只有一個(gè),既不可以添加也不可以刪除)利用InsertItem可以添加一個(gè)結(jié)點(diǎn):
HTREEITEM InsertItem( LPCTSTR lpszItem, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST );
pszItem為顯示的字符
hParent代表父結(jié)點(diǎn)的句柄,當(dāng)前添加的結(jié)點(diǎn)會(huì)排在hInsertAfter表示的結(jié)點(diǎn)的后面,返回值為當(dāng)前創(chuàng)建的結(jié)點(diǎn)的句柄。
下面的代碼會(huì)建立一個(gè)如下形式的樹(shù)形結(jié)構(gòu):
+--- Parent1
+--- Child1_1
+--- Child1_2
+--- Child1_3
+--- Parent2
+--- Parent3
HTREEITEM hItem,hSubItem;
//在根結(jié)點(diǎn)上添加Parent1
hItem = m_tree.InsertItem( "Parent1 ",TVI_ROOT);
//在Parent1上添加一個(gè)子結(jié)點(diǎn)
hSubItem = m_tree.InsertItem( "Child1_1 ",hItem);
//在Parent1上添加一個(gè)子結(jié)點(diǎn),排在Child1_1后面
hSubItem = m_tree.InsertItem( "Child1_2 ",hItem,hSubItem);
hSubItem = m_tree.InsertItem( "Child1_3 ",hItem,hSubItem);
hItem = m_tree.InsertItem( "Parent2 ",TVI_ROOT,hItem);
hItem = m_tree.InsertItem( "Parent3 ",TVI_ROOT,hItem);
關(guān)于添加圖標(biāo)
如果你希望在每個(gè)結(jié)點(diǎn)前添加一個(gè)小圖標(biāo),就必需先調(diào)用
CImageList* SetImageList( CImageList * pImageList, int nImageListType );
指明當(dāng)前所使用的ImageList,nImageListType為T(mén)VSIL_NORMAL。在調(diào)用完成后控件中使用圖片以設(shè)置的ImageList中圖片為準(zhǔn)。然后調(diào)用InsertItem添加結(jié)點(diǎn):
HTREEITEM InsertItem( LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST);
nImage為結(jié)點(diǎn)沒(méi)被選中時(shí)所使用圖片序號(hào),nSelectedImage為結(jié)點(diǎn)被選中時(shí)所使用圖片序號(hào)。下面的代碼演示了ImageList的設(shè)置。
m_list.Create(IDB_TREE,16,4,RGB(0,0,0));
m_tree.SetImageList(&m_list,TVSIL_NORMAL);
m_tree.InsertItem( "Parent1 ",0,1);//添加,選中時(shí)顯示圖標(biāo)1,未選中時(shí)顯示圖標(biāo)0
關(guān)于插入標(biāo)記
這是拖曳時(shí)經(jīng)常用到的函數(shù)。
BOOL SetInsertMark( HTREEITEM hItem, BOOL fAfter = TRUE );
TRUE表示在hItem下面顯示橫杠,而FALSE則表示在上面。
同類函數(shù)還有:
SetInsertMarkColor,GetInsertMarkColor
關(guān)于得到/修改控件狀態(tài)
此外CTreeCtrl還提供了一些函數(shù)用于得到/修改控件的狀態(tài)。
HTREEITEM GetSelectedItem( );將返回當(dāng)前選中的結(jié)點(diǎn)的句柄。
BOOL SelectItem( HTREEITEM hItem );將選中指明結(jié)點(diǎn)。
BOOL GetItemImage( HTREEITEM hItem, int& nImage, int& nSelectedImage )用于得到某結(jié)點(diǎn)所使用圖標(biāo)索引。
BOOL SetItemImage( HTREEITEM hItem, int nImage, int nSelectedImage )用于修改某結(jié)點(diǎn)所使用圖標(biāo)索引。
CString GetItemText( HTREEITEM hItem )用于得到某一結(jié)點(diǎn)的顯示字符。
BOOL SetItemText( HTREEITEM hItem, LPCTSTR lpszItem );用于修改某一結(jié)點(diǎn)的顯示字符。
BOOL DeleteItem( HTREEITEM hItem );用于刪除某一結(jié)點(diǎn)
BOOL DeleteAllItems( );將刪除所有結(jié)點(diǎn)。
-
如何展開(kāi)/收縮一個(gè)父節(jié)點(diǎn)?
- CTreeCtrl::Expand
BOOL Expand( HTREEETEM hItem, UINT nColor );
返回值:如果成功則返回非零值;否則返回0。
參數(shù):
|
hItem |
要被擴(kuò)展的tree項(xiàng)的句柄。 |
|
nCode |
用來(lái)指示要被進(jìn)行的動(dòng)作的標(biāo)志。這個(gè)標(biāo)志可以是下列值之一:
|
· |
TVE_COLLAPSE |
收縮列表。 |
|
· |
TVE_COLLAPSERESET |
收縮列表并刪除子項(xiàng)。 |
|
· |
TVE_EXPAND |
展開(kāi)列表。 |
|
· |
TVE_TOGGLE |
如果列表當(dāng)前是展開(kāi)的則收縮列表;反之則展開(kāi)列表。 |
|
說(shuō)明:
此成員函數(shù)用來(lái)展開(kāi)或收縮給定父項(xiàng)的子項(xiàng)列表(如果有)。
關(guān)于遍歷:
此外如果想遍歷樹(shù)可以使用下面的函數(shù):
HTREEITEM GetRootItem( );得到根結(jié)點(diǎn)。
HTREEITEM GetChildItem( HTREEITEM hItem );得到子結(jié)點(diǎn)。
HTREEITEM GetPrevSiblingItem/GetNextSiblingItem( HTREEITEM hItem );得到指明結(jié)點(diǎn)的上/下一個(gè)兄弟結(jié)點(diǎn)。
HTREEITEM GetParentItem( HTREEITEM hItem );得到父結(jié)點(diǎn)。
<后面有兩個(gè)遍歷例程>
關(guān)于消息映射:
樹(shù)形控件的消息映射使用ON_NOTIFY宏,形式如同:
ON_NOTIFY( wNotifyCode, id, memberFxn )
wNotifyCode為通知代碼,id為產(chǎn)生該消息的窗口ID
memberFxn為處理函數(shù),函數(shù)的原型如同void OnXXXTree(NMHDR* pNMHDR, LRESULT* pResult),其中pNMHDR為一數(shù)據(jù)結(jié)構(gòu),在具體使用時(shí)需要轉(zhuǎn)換成其他類型的結(jié)構(gòu)。對(duì)于樹(shù)形控件可能取值和對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)為:
TVN_SELCHANGED 在所選中的結(jié)點(diǎn)發(fā)生改變后發(fā)送,所用結(jié)構(gòu):NMTREEVIEW
TVN_ITEMEXPANDED 在某結(jié)點(diǎn)被展開(kāi)后發(fā)送,所用結(jié)構(gòu):NMTREEVIEW
TVN_BEGINLABELEDIT 在開(kāi)始編輯結(jié)點(diǎn)字符時(shí)發(fā)送,所用結(jié)構(gòu):NMTVDISPINFO
TVN_ENDLABELEDIT 在結(jié)束編輯結(jié)點(diǎn)字符時(shí)發(fā)送,所用結(jié)構(gòu):NMTVDISPINFO
TVN_GETDISPINFO 在需要得到某結(jié)點(diǎn)信息時(shí)發(fā)送,(如得到結(jié)點(diǎn)的顯示字符)所用結(jié)構(gòu):NMTVDISPINFO
關(guān)于ON_NOTIFY有很多內(nèi)容,將在以后的內(nèi)容中進(jìn)行詳細(xì)講解。
消息處理例程:
如何獲得右擊項(xiàng)句柄?
響應(yīng)NM_RCLICK消息
void CLayerDialog::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
{
//
TODO: Add your control notification handler code here
NM_TREEVIEW*
pNMTreeView = (NM_TREEVIEW*)pNMHDR;
//右擊獲取所選項(xiàng)
CPoint point,p;
TVHITTESTINFO HitTestInfo;
GetCursorPos(&point);
m_treectrl.ScreenToClient(&point);
HitTestInfo.pt = point;
HTREEITEM
h = m_treectrl.HitTest(&HitTestInfo);
if(h!=NULL)
{
。。。。。//需要代碼
}
}
如何響應(yīng)checkbox被單擊?
響應(yīng)NM_CLICK消息(checkbox就是分支前面的復(fù)選框,可從資源中修改屬性添加)
void CLayerDialog::OnLclick(NMHDR *pNMHDR,LRESULT *pResult)
{
NM_TREEVIEW*
pNMTreeView = (NM_TREEVIEW*)pNMHDR;
//
TODO: Add your control notification handler code here
CPoint
p;
GetCursorPos(&p);
m_treectrl.ScreenToClient(&p);
UINT
nFlag;
HTREEITEM
h=m_treectrl.HitTest(p,&nFlag);
if((h != NULL)&&(TVHT_ONITEMSTATEICON & nFlag))
{
。。。。。//需要代碼
}
}
設(shè)置和獲取checkbox的狀態(tài)函數(shù)
GetCheck(
)
SetCheck(
)
如何知道某個(gè)點(diǎn)在CTreeCtrl上的位置
CTreeCtrl::HitTest
HTREEITEM HitTest( CPoint pt, UINT* pFlags );
HTREEITEM HitTest( TVHITTESTINFO* pHitTestInfo );
返回值:
返回位于指定點(diǎn)的tree view項(xiàng)的句柄,如果沒(méi)有項(xiàng)位于該點(diǎn),則返回NULL。
參數(shù):
|
pt |
in 要測(cè)試的點(diǎn)的客戶坐標(biāo)。 |
|
pFlags |
out 指向一個(gè)用來(lái)接收有關(guān)點(diǎn)擊測(cè)試的信息的整數(shù)的指針。它可以是說(shuō)明部分中列出的flags成員值中的一個(gè)或多個(gè)。
其中flags測(cè)試結(jié)果可以是如下值:
TVHT_ABOVE 在客戶區(qū)域上面
TVHT_BELOW 在客戶區(qū)域下面
TVHT_NOWHERE 在客戶區(qū)域中并在最后一項(xiàng)下面
TVHT_ONITEM 在與樹(shù)項(xiàng)關(guān)聯(lián)的位圖或標(biāo)簽內(nèi)
TVHT_ONITEMBUTTON 在與樹(shù)項(xiàng)關(guān)聯(lián)的按鈕上
TVHT_ONITEMICON 在與樹(shù)項(xiàng)關(guān)聯(lián)的位圖上
TVHT_ONITEMINDENT 在與樹(shù)項(xiàng)關(guān)聯(lián)的聯(lián)線上
TVHT_ONITEMLABEL 在與樹(shù)項(xiàng)關(guān)聯(lián)的標(biāo)簽上
TVHT_ONITEMRIGHT 在樹(shù)項(xiàng)的右側(cè)區(qū)域中
TVHT_ONITEMSTATEICON 在用戶定義的狀態(tài)圖標(biāo)上
TVHT_TOLEFT 在客戶區(qū)域的左側(cè)
TVHT_TORIGHT 在客戶區(qū)域的右側(cè)
|
|
pHitTestInfo |
in/out 一個(gè)包含點(diǎn)擊測(cè)試的位置并接收測(cè)試結(jié)果的信息的TVHITTESTINFO結(jié)構(gòu)的地址。
typedef struct _TVHITTESTINFO {
POINT pt;
UINT flags;
HTREEITEM hItem;
} TVHITTESTINFO, FAR* LPTVHITTESTINFO;
|
說(shuō)明:
此成員函數(shù)用來(lái)確定相對(duì)于一個(gè)tree view控件的客戶區(qū)的指定點(diǎn)的定位。
當(dāng)調(diào)用這個(gè)函數(shù)時(shí),pt參數(shù)指定要測(cè)試的點(diǎn)的坐標(biāo)。此函數(shù)返回位于指定點(diǎn)的項(xiàng)的句柄,或者如果沒(méi)有項(xiàng)位于該點(diǎn)則返回NULL。另外,pFlags參數(shù)包含了指明指定點(diǎn)的定位的值。
關(guān)于動(dòng)態(tài)提供結(jié)點(diǎn)所顯示的字符
首先你在添加結(jié)點(diǎn)時(shí)需要指明lpszItem參數(shù)為:LPSTR_TEXTCALLBACK。在控件顯示該結(jié)點(diǎn)時(shí)會(huì)通過(guò)發(fā)送TVN_GETDISPINFO來(lái)取得所需要的字符,在處理該消息時(shí)先將參數(shù)pNMHDR轉(zhuǎn)換為L(zhǎng)PNMTVDISPINFO,然后填充其中item.pszText。但是我們通過(guò)什么來(lái)知道該結(jié)點(diǎn)所對(duì)應(yīng)的信息呢,我的做法是在添加結(jié)點(diǎn)后設(shè)置其lParam參數(shù),然后在提供信息時(shí)利用該參數(shù)來(lái)查找所對(duì)應(yīng)的信息。下面的代碼說(shuō)明了這種方法:
char szOut[8][3]={ "No.1 ", "No.2 ", "No.3 "};
//添加結(jié)點(diǎn)
HTREEITEM hItem = m_tree.InsertItem(LPSTR_TEXTCALLBACK,...)
m_tree.SetItemData(hItem, 0 );
hItem = m_tree.InsertItem(LPSTR_TEXTCALLBACK,...)
m_tree.SetItemData(hItem, 1 );
//處理消息
void CParentWnd::OnGetDispInfoTree(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDI = (TV_DISPINFO*)pNMHDR;
pTVDI-> item.pszText=szOut[pTVDI-> item.lParam];//通過(guò)lParam得到需要顯示的字符在數(shù)組中的位置
*pResult = 0;
}
關(guān)于編輯結(jié)點(diǎn)的顯示字符
首先需要設(shè)置樹(shù)形控件的TVS_EDITLABELS風(fēng)格,在開(kāi)始編輯時(shí)該控件將會(huì)發(fā)送TVN_BEGINLABELEDIT,你可以通過(guò)在處理函數(shù)中返回TRUE來(lái)取消接下來(lái)的編輯,在編輯完成后會(huì)發(fā)送TVN_ENDLABELEDIT,在處理該消息時(shí)需要將參數(shù)pNMHDR轉(zhuǎn)換為L(zhǎng)PNMTVDISPINFO,然后通過(guò)其中的item.pszText得到編輯后的字符,并重置顯示字符。如果編輯在中途中取消該變量為NULL。下面的代碼說(shuō)明如何處理這些消息:
//處理消息 TVN_BEGINLABELEDIT
void CParentWnd::OnBeginEditTree(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDI = (TV_DISPINFO*)pNMHDR;
if(pTVDI-> item.lParam==0);//判斷是否取消該操作
*pResult = 1;
else
*pResult = 0;
}
//處理消息 TVN_BEGINLABELEDIT
void CParentWnd::OnBeginEditTree(NMHDR* pNMHDR, LRESULT* pResult)
{
TV_DISPINFO* pTVDI = (TV_DISPINFO*)pNMHDR;
if(pTVDI-> item.pszText==NULL);//判斷是否已經(jīng)取消取消編輯
m_tree.SetItemText(pTVDI-> item.hItem,pTVDI-> pszText);//重置顯示字符
*pResult = 0;
}
上面講述的方法所進(jìn)行的消息映射必須在父窗口中進(jìn)行(同樣WM_NOTIFY的所有消息都需要在父窗口中處理)。
關(guān)于修改樹(shù)控件的背景位圖
![[轉(zhuǎn)載]轉(zhuǎn) <wbr>樹(shù)形控件TreeCtrl [轉(zhuǎn)載]轉(zhuǎn) <wbr>樹(shù)形控件TreeCtrl](http://image86.360doc.com/DownloadImg/2015/06/1500/54972915_1)
對(duì)于Visual C++ MFC提供的標(biāo)準(zhǔn)樹(shù)型控件CTreeCtrl來(lái)說(shuō),并不支持背景位圖,所以如果需要實(shí)現(xiàn)背景位圖就需要先讓其在內(nèi)存CDC對(duì)象上對(duì)TREEVIEW缺省繪圖,然后在選擇背景位圖,與缺省位圖合成,即采用貼圖的方式,把標(biāo)準(zhǔn)的TREEVIEW窗口貼在底圖上。這個(gè)操作在內(nèi)存中完成。同時(shí)為了避免閃爍,必須重載OnItemexpanding()和OnItemexpanded()這兩個(gè)函數(shù)。SetRedraw函數(shù)主要保證其不要在子節(jié)點(diǎn)彈出時(shí)重畫(huà),而是在子節(jié)點(diǎn)已經(jīng)擴(kuò)展后重畫(huà)。為此,例程中定義了一個(gè)CTreeCtrl類的子類CmyTreeCtrl,并重載了以下幾個(gè)成員函數(shù):
BOOL
CMyTreeCtrl::SetBKImage(LPCTSTR LpszResource)
void CMyTreeCtrl::OnPaint()
void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
void CMyTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC)
我的實(shí)踐代碼:
MFC:
關(guān)于變量:
在資源文件的主對(duì)話框上添加一個(gè)CTreeCtrl控件,選中此控件點(diǎn)擊右鍵->CalassWizard->Member Variables 在這項(xiàng)中雙擊CTreeCtrl控件的ID,關(guān)聯(lián)這個(gè)控件與一個(gè)CTreeCtrl變量(eg m_TreeCtrl)
關(guān)于屬性設(shè)置:
增加 TreeCtrl 的 TVS_HASBUTTONS,TVS_HASLINES、TVS_LINESATROOT Style,代碼如下:
DWORD dwStyle = GetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE);
dwStyle |= TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT;
SetWindowLong(m_TreeCtrl.m_hWnd,GWL_STYLE,dwStyle);
如何插入一個(gè)節(jié)點(diǎn):
HTREEITEM hRoot,hItem,hItem1,hItem2,hSubItem,hSubItem1;
hRoot = m_TreeCtrl.InsertItem("我的電腦");//并不是不是真正意義上的根節(jié)點(diǎn),只是在視覺(jué)效果上看起來(lái)是
hItem = m_TreeCtrl.InsertItem( "Parent1 ",hRoot);
hSubItem = m_TreeCtrl.InsertItem("child1",hItem);
hSubItem1 = m_TreeCtrl.InsertItem("child2",hItem,hSubItem);
hItem1 = m_TreeCtrl.InsertItem( "Parent2 ",hRoot,hItem);
hItem2 = m_TreeCtrl.InsertItem( "Parent3 ",hRoot,hItem1);
效果圖:
![[轉(zhuǎn)載]轉(zhuǎn) <wbr>樹(shù)形控件TreeCtrl [轉(zhuǎn)載]轉(zhuǎn) <wbr>樹(shù)形控件TreeCtrl](http://image86.360doc.com/DownloadImg/2015/06/1500/54972915_2)
現(xiàn)在我想往child1和child2前加上圖標(biāo):
首先,構(gòu)造出來(lái)ImageList :
CImageList* imageList=new CImageList();
imageList->Create(19, 19, ILC_COLOR24|ILC_MASK, 20, 1);
//參數(shù)意義:參看:http://blog.sina.com.cn/s/blog_4b3c1f950100b0eh.html
HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,"D:\Project\TEMP\1.bmp",IMAGE_BITMAP,
19,19,LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
CBitmap* m_bitmap = new CBitmap();
m_bitmap->Attach(hBitmap);
imageList->Add(m_bitmap,RGB(0, 0, 0));//參數(shù)意義,下面有解釋
然后,把ImageList和TreeCtrl關(guān)聯(lián)起來(lái):
m_TreeCtrl.SetImageList(imageList,TVSIL_NORMAL);
注:這個(gè)關(guān)聯(lián)必須在m_TreeCtrl插入節(jié)點(diǎn)之前。
然后,在插入子節(jié)點(diǎn)時(shí)這樣:
hSubItem = m_TreeCtrl.InsertItem("child1",0,1,hItem);
//添加節(jié)點(diǎn) "child1",未選中時(shí)圖標(biāo)為imageList的第0個(gè),選中后圖標(biāo)為imageList的第1個(gè).
效果圖:
![[轉(zhuǎn)載]轉(zhuǎn) <wbr>樹(shù)形控件TreeCtrl [轉(zhuǎn)載]轉(zhuǎn) <wbr>樹(shù)形控件TreeCtrl](http://image86.360doc.com/DownloadImg/2015/06/1500/54972915_3)
?????怎么會(huì)是這樣????怎么全部都加上了圖標(biāo)??
待解答.....
?????有什么方法能在子節(jié)點(diǎn)的位置上不是只是一個(gè)字符串,而是插入一個(gè)其他的控件呢????
待解答.....
GetWindowLong
函數(shù)功能:該函數(shù)獲得有關(guān)指定窗口的信息,函數(shù)也獲得在額外窗口內(nèi)存中指定偏移位地址的32位度整型值?!?/div>
函數(shù)原型:LONG GetWindowLong(HWND hWnd,int nlndex);
參數(shù):
hWnd:窗口句柄及間接給出的窗口所屬的窗口類?! ?/div>
nlndex:指定要檢索的基于0的偏移量。有效值的范圍從0到窗口額外內(nèi)存空間的字節(jié)數(shù),減去4。例如,若指定了12位或多于12位的窗體類的額外存儲(chǔ)空間,則應(yīng)設(shè)為第三個(gè)32位整數(shù)的索引位8(12- 4=8)。要獲得任意其他值,
指定下列值之一:
GWL_EXSTYLE= (-20) 擴(kuò)展窗口樣式 GWL_STYLE=(-16) 窗口樣式
GWL_WNDPROC= (-4) 該窗口的窗口函數(shù)的地址 GWL_HINSTANCE= (-6) 擁有窗口的實(shí)例的句柄
GWL_HWNDPARENT= (-8) 該窗口之父的句柄。不要用SetWindowWord來(lái)改變這個(gè)值
GWL_ID= (-12) 對(duì)話框中一個(gè)子窗口的標(biāo)識(shí)符 GWL_USERDATA = (-21) 含義由應(yīng)用程序規(guī)定 DWL_DLGPROC = 4 這個(gè)窗口的對(duì)話框函數(shù)地址
DWL_MSGRESULT = 0 在對(duì)話框函數(shù)中處理的一條消息返回的值 DWL_USER = 8 含義由應(yīng)用程序規(guī)定
返回值:
如果函數(shù)成功,返回值是所需的32位值;如果函數(shù)失敗,返回值是0。若想獲得更多錯(cuò)誤信息請(qǐng)調(diào)用 GetLastError函數(shù)。
SetWindowLong
函數(shù)功能:SetWindowLong該函數(shù)改變指定窗口的屬性.函數(shù)也將指定的一個(gè)32位值設(shè)置在窗口的額外存儲(chǔ)空間的指定偏移位置。
函數(shù)原型:LONG SetWindowLong(HWND hWnd,int nlndex,LONG dwNewLong);
參數(shù):
nlndex:指定將設(shè)定的大于等于0的偏移值。有效值的范圍從0到額外類的存儲(chǔ)空間的字節(jié)數(shù)-4:例如若指定了12位或多于12位的額外類存儲(chǔ)空間,則應(yīng)設(shè)為第三個(gè)32位整數(shù)的索引位8。
要設(shè)置其他任何值,可以指定下面值之一:
GWL_EXSTYLE:設(shè)定一個(gè)新的擴(kuò)展風(fēng)格。GWL_STYLE:設(shè)定一個(gè)新的窗口風(fēng)格?! ?/div>
GWL_WNDPROC:為窗口過(guò)程設(shè)定一個(gè)新的地址。GWL_ID:設(shè)置一個(gè)新的窗口標(biāo)識(shí)符。
GWL_USERDATA:設(shè)置與窗口有關(guān)的32位值。每一個(gè)窗口均有一個(gè)由創(chuàng)建該窗口的應(yīng)用程序使用的32位值?!?nbsp;當(dāng)hWnd參數(shù)標(biāo)識(shí)了一個(gè)對(duì)話框時(shí),也可使用下列值:
DWL_DLGPROC:設(shè)置對(duì)話框過(guò)程的新地址。
DWL_MSGRESULT:設(shè)置在對(duì)話框過(guò)程中處理的消息的返回值?!?/div>
DWL_USER:設(shè)置的應(yīng)用程序私有的新的額外信息,例如一個(gè)句柄或指針。
dwNewLong:指定的替換值?! ?/div>
返回值:
如果函數(shù)成功,返回值是指定的32位整數(shù)的原來(lái)的值。如果函數(shù)失敗,返回值為0。若想獲得更多錯(cuò)誤信息,請(qǐng)調(diào)用GetLastError函數(shù)。
備注:如果由hWnd參數(shù)指定的窗口與調(diào)用線程不屬于同一進(jìn)程,將導(dǎo)致SetWindowLong函數(shù)失敗。
CImageList::Add
int Add( CBitmap* pbmImage, CBitmap* pbmMask );
int Add( CBitmap* pbmImage, COLORREF crMask );
int Add( HICON hIcon );
返回值:
如果成功,則為第一個(gè)新圖象的基于零的索引,否則為-1。
參數(shù):
|
pbmImage |
指向包含一個(gè)或多個(gè)圖象的位圖的指針。圖象數(shù)由位圖寬推斷。 |
|
pbmMask |
指向包含掩碼的位圖的指針。如果無(wú)掩碼與圖象列表一起使用,則此參數(shù)被忽略。 |
|
crMask |
生成掩碼的顏色。指定位圖中的此顏色的每個(gè)像素被改為黑色,掩碼中的相應(yīng)位數(shù)被設(shè)置為1。 |
|
hIcon |
包含新圖象的位圖和掩碼的圖標(biāo)的句柄。 |
說(shuō)明:
調(diào)用此函數(shù)來(lái)添加一個(gè)或多個(gè)圖象或圖標(biāo)到圖象列表中。
什么是掩碼圖??
在ImageList.Create時(shí)如果選擇ILC_MASK(既使用掩膜)。如果包含這個(gè)值,那么當(dāng)前ImageList使用2個(gè)位圖,指定一個(gè)單色位圖,將其做為掩膜,掩膜是用來(lái)實(shí)現(xiàn)透明的,就是在顯示的時(shí)候,會(huì)將這個(gè)單色位圖與圖片與PDC做一系列的“位或”“位與”等操作,最終實(shí)現(xiàn)透明。從單色位圖的設(shè)置角度來(lái)看的話,如果單色位圖“按位異或”圖片得到的像素點(diǎn)顏色值為黑色,那么這個(gè)像素點(diǎn)就按透明處理。
掩碼圖就是是指的這一幅單色位圖。
遍歷例程:
以下是采用遞歸完成的遍歷樹(shù)的函數(shù):
遍歷樹(shù)
//hitem:待遍歷樹(shù)的根節(jié)點(diǎn)
void TreeVisit(HTREEITEM hItem)
{
AfxMessageBox(GetItemText(hItem));
if(ItemHasChildren(hItem))
{
HTREEITEM hChildItem = GetChildItem(hItem);
while(hChildItem!=NULL)
{
TreeVisit(hChildItem); //遞歸遍歷孩子節(jié)點(diǎn)
hChildItem = GetNextItem(hChildItem, TVGN_NEXT);
}
}
}
如何根據(jù)名稱查找樹(shù)中的某個(gè)節(jié)點(diǎn)(必須是節(jié)點(diǎn)名稱是唯一的)
//item:待遍歷樹(shù)的根節(jié)點(diǎn),strtext:待查找節(jié)點(diǎn)名稱
HTREEITEM finditem(HTREEITEM item, CString strtext)
{
HTREEITEM hfind;
//空樹(shù),直接返回NULL
if(item == NULL)
return NULL;
//遍歷查找
while(item!=NULL)
{
//當(dāng)前節(jié)點(diǎn)即所需查找節(jié)點(diǎn)
if(GetItemText(item) == strtext)
return item;
//查找當(dāng)前節(jié)點(diǎn)的子節(jié)點(diǎn)
if(ItemHasChildren(item))
{
item = GetChildItem(item);
//遞歸調(diào)用查找子節(jié)點(diǎn)下節(jié)點(diǎn)
hfind = finditem(item,strtext);
if(hfind)
{
return hfind;
}else //子節(jié)點(diǎn)中未發(fā)現(xiàn)所需節(jié)點(diǎn),繼續(xù)查找兄弟節(jié)點(diǎn)