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