小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

【材料整理】VC 樹(shù)形控件 例子及相關(guān)知識(shí)

 牛人的尾巴 2015-06-15
分類: windows編程 2013-05-09 10:21 1153人閱讀 評(píng)論(0) 收藏 舉報(bào)

目錄(?)[+]

轉(zhuǎn)自:http://www./index.php/wv/1352

首先,我們要?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。

接著,我們進(jìn)行具體代碼編寫(xiě)。

我們必須在CMFC_TreeCRTLDlg類中加入這些變量和函數(shù)

  1. CDialog * m_treePages[2];  
  2. CString node_name;  
  3. BOOL InitMytree();  

我們還要在CMFC_TreeCRTLDlg類的構(gòu)造函數(shù)中為m_treePages[2]分配空間,

  1. m_treePages[0]=new Cdialog11;  
  2. m_treePages[1]=new Cdialog211;  
InitMytree()函數(shù)為m_mytree的初始化過(guò)程。(原文遺漏,若沒(méi)有這句,不顯示)在OnInitDialog里面加上 InitMytree();  //關(guān)鍵

  1. BOOL CMFC_TreeCRTLDlg::InitMytree()  
  2. {  
  3.     //節(jié)點(diǎn)的圖標(biāo)    
  4.     int i=0;  
  5.     int i_count=2;  
  6.     //載入圖標(biāo)  
  7.     HICON icon[4];  
  8.     icon[0]=AfxGetApp()->LoadIcon (IDI_ICON6);   
  9.     icon[1]=AfxGetApp()->LoadIcon (IDI_ICON7);  
  10.   
  11.     //創(chuàng)建圖像列表控件  
  12.     CImageList* m_imagelist=new CImageList;   
  13.     m_imagelist->Create(16,16,0,7,7);   
  14.     m_imagelist->SetBkColor (RGB(255,255,255));  
  15.     for(int n=0; n < i_count; n++)  
  16.         m_imagelist->Add(icon[n]);//把圖標(biāo)載入圖像列表控件  
  17.     m_mytree.SetImageList(m_imagelist,TVSIL_NORMAL);  //為m_mytree設(shè)置一個(gè)圖像列表,使CtreeCtrl的節(jié)點(diǎn)顯示不同的圖標(biāo)   
  18.     m_mytree.SetBkColor(RGB(0,250,255));//設(shè)置m_mytree的背景色  
  19.   
  20.     //創(chuàng)建節(jié)點(diǎn)  
  21.     //父節(jié)點(diǎn)  
  22.     HTREEITEM root0=m_mytree.InsertItem(L"Dialog1",0,1,TVI_ROOT,TVI_LAST);  
  23.     HTREEITEM root1=m_mytree.InsertItem(L"Dialog2",0,1,TVI_ROOT,TVI_LAST);  
  24.     //一層子節(jié)點(diǎn)  
  25.     HTREEITEM sub_son0=m_mytree.InsertItem(L"Dialog 1-1",0,1,root0,TVI_LAST);  
  26.     HTREEITEM sub_son1=m_mytree.InsertItem(L"Dialog 2-1",0,1,root1,TVI_LAST);  
  27.     //二層孫子節(jié)點(diǎn)  
  28.     HTREEITEM sub_m_son0=m_mytree.InsertItem(L"Dialog 2-1-1",0,1,sub_son1,TVI_LAST);  
  29.   
  30.     //建立節(jié)點(diǎn)對(duì)應(yīng)的Dialog  
  31.     m_treePages[0]->Create(IDD_DIALOG11,this);  
  32.     m_treePages[1]->Create(IDD_DIALOG211,this);  
  33.     m_treePages[0]->ShowWindow(SW_SHOW);  
  34.     m_treePages[1]->ShowWindow(SW_HIDE);  
  35.   
  36.     //把Dialog移到合適位置  
  37.     CRect m_rect;  
  38.     GetClientRect(m_rect);  
  39.     m_rect.left=200;  
  40.     m_treePages[0]->MoveWindow(m_rect);  
  41.     m_treePages[1]->MoveWindow(m_rect);  
  42.   
  43.     return true;  
  44. }  

始初化完成后,我們要添加CTreeCtrl的消息響應(yīng)事件,這樣才能讓它按我們的要求起作用。我們打開(kāi)Class Wizard點(diǎn)選IDC_TREE1添加TVN_SELCHANGED消息,并在消息響應(yīng)函數(shù)中寫(xiě)入代碼。

  1. void CMFC_TreeCRTLDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)  
  2. {  
  3.     //LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);  
  4.     NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;  
  5.     UpdateData(true);  
  6.     CString node_name=m_mytree.GetItemText(pNMTreeView->itemNew.hItem);  
  7.     //在標(biāo)題欄顯示節(jié)點(diǎn)信息  
  8.     SetWindowText(node_name);  
  9.     //切換面板  
  10.     if(node_name=="Dialog 1-1"){  
  11.         m_treePages[0]->ShowWindow(SW_SHOW);  
  12.         m_treePages[1]->ShowWindow(SW_HIDE);  
  13.     }  
  14.     else if(node_name=="Dialog 2-1-1"){  
  15.         m_treePages[0]->ShowWindow(SW_HIDE);  
  16.         m_treePages[1]->ShowWindow(SW_SHOW);  
  17.     }  
  18.     UpdateData(false);  
  19.   
  20.     *pResult = 0;  
  21. }  


以下轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_6a817a6c0100v2sx.html

樹(shù)形控件TreeCtrl和下節(jié)要講的列表控件 ListCtrl在系統(tǒng)中大量被使用,例如Windows資源管理器就是一個(gè)典型的例子。

關(guān)于創(chuàng)建及風(fēng)格:

樹(shù)形控件可以用于樹(shù)形的結(jié)構(gòu),其中有一個(gè)根接點(diǎn)(Root)然后下面有許多子結(jié)點(diǎn),而每個(gè)子結(jié)點(diǎn)上有允許有一個(gè)或多個(gè)或沒(méi)有子結(jié)點(diǎn)。MFC中使用CTreeCtrl類來(lái)封裝樹(shù)形控件的各種操作。通過(guò)調(diào)用Create創(chuàng)建一個(gè)窗口:

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

dwStyle中可以使用以下一些樹(shù)形控件的專用風(fēng)格:

TVS_CHECKBOXES 

    4.70版:在每個(gè)item前面顯示出復(fù)選框。必須為item關(guān)聯(lián)了Image之后,復(fù)選框才能顯示出來(lái)。設(shè)置這種風(fēng)格的時(shí)候,要用DrawFrameControl創(chuàng)建并且設(shè)置兩種狀態(tài)的圖片,一種是選中狀態(tài)的圖片,另一種是未選中時(shí)的圖片。更多信息請(qǐng)查看Working with state image indexes.

在5.80版中,即使沒(méi)有圖片,也會(huì)顯示復(fù)選框。

這種風(fēng)格一旦創(chuàng)建,將不能移除。只能destroy后再create一個(gè)新的。

  在創(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, );
hItem m_tree.InsertItem(LPSTR_TEXTCALLBACK,...)
m_tree.SetItemData(hItem, );
//處理消息
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

     對(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

現(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

?????怎么會(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ù):
   hWnd:窗口句柄及間接給出的窗口所屬的類。   
   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_HINSTANCE:設(shè)置一個(gè)新的應(yīng)用程序實(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)
                 item = GetNextSiblingItem(GetParentItem(item));   
       }   
       else{ //若無(wú)子節(jié)點(diǎn),繼續(xù)查找兄弟節(jié)點(diǎn)
           item = GetNextSiblingItem(item);   
      }   
  }   
  return item;  
}


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多