到上一個教程為止,界面顯示的代碼就都介紹完啦,現在開始介紹控件的響應,其實在《2013 duilib入門簡明教程 -- 事件處理和消息響應 (17)》里已經列出了duilib自己定義的所有消息,並且前面也介紹了Button和Tab的響應,還是有小伙伴們不知道怎么響應其他控件,因此這里介紹一下其他控件的響應。
需要注意的是,如果要響應控件,則必須給控件指定一個唯一的ID,在windows編程里,每個控件的ID都是一個數字,如IDC_BUTTON_ 等等,可以用GetDlgItem()來獲取控件的指針;而duilib的ID卻不是數字,而是一個字符串,如name="button1",獲取控件的指針是通過FindControl函數。duilib沒有像MFC那樣的DDX機制來綁定ID和控件變量,所以只能通過FindControl函數。
Button和Option控件已經在入門教程里介紹過了,而其他控件在duilib自帶的Demo里面都有介紹,Alberl搞不清楚為什么有些小伙伴還是不知道怎么響應的,那么這里就說說其他控件的響應吧,入門教程里已經說了,duilib的控件響應都可以在Notify函數里搞定,也可以用DUI_ON_MSGTYPE宏搞定,比如DUI_ON_MSGTYPE(DUI_MSGTYPE_CLICK,OnClick)。
一、菜單控件:
由於Demo里的菜單控件既不通用,代碼量也大,看起來還比較復雜,所以Alberl提煉出了一個精簡的菜單控件,用法很簡單:
1、在想要顯示菜單的地方加上:
CMenuWnd *pMenu = new CMenuWnd(_T("menu.xml")); POINT pt = {msg.ptMouse.x, msg.ptMouse.y}; pMenu->Init(&m_PaintManager, pt); pMenu->ShowWindow(TRUE);
2、在menu.xml里加上要顯示的菜單項,如:
<ListContainerElement name="menuSingleCircle" height="22" inset="15,0,25,0" > <Label text="單曲循環" textcolor="#FFC8C6CB" align="center"/> </ListContainerElement>
3、在Notify里響應itemclick消息,如:
if(msg.sType == _T("itemclick")) { if (msg.pSender->GetName() == _T("menuSingleCircle")) { m_emPlayMode = EM_PLAY_MODE_SINGLE_CIRCLE; } }
二、treeview控件:
List的響應都是在"itemactivate"里,所以在Notify里用 if( msg.sType == _T("itemactivate") ) 就可以了,需要說明的是List控件比較特殊,雖然也可以像button一樣指定一個name屬性,然后判斷name就知道點擊了哪個控件,但還是建議用List自帶的函數GetItemIndex(msg.pSender)來獲取點擊了哪一列,List控件比較簡單,請自行看Demo,TreeView由於沒有Demo可以看,這里介紹一下:
因為TreeView繼承於List,所以很多特性都是一樣的,比如在_T("itemactivate")里響應點擊消息,用GetItemIndex獲取點擊了哪一列。
if( msg.sType == _T("itemactivate")) { CTreeViewUI* pTree = static_cast<CTreeViewUI*>(m_PaintManager.FindControl(_T("treePlaylist"))); if(pTree && -1 != pTree->GetItemIndex(msg.pSender) && U_TAG_PLAYLIST == msg.pSender->GetTag()) { int iListIndex = pTree->GetItemIndex(msg.pSender); } }
不過獲取到了iListIndex,好像也沒啥用,它是哪個節點的?是我想要的節點嗎?
所以這里就需要給我們想要的節點加上特殊的屬性,比如name、tag、userdata等等,這里Alberl用的是Tag來標記的,所以只要GetTag獲取一下tag就知道是不是點擊了播放列表。
而Tag的設置是在添加TreeNode節點時調用pNodeTmp->SetTag(U_TAG_PLAYLIST); 這樣就設置了一個值為U_TAG_PLAYLIST 的Tag。
知道了用戶點擊了咱們想要的控件,那么直接GetItemText就可以獲取到文件路徑了,這個時候就可以播放啦~O(∩_∩)O~
但是問題又來了,如果想要實現順序播放的功能,那么就必須獲取下一個節點的指針,不過List並沒有提供GetNextItem這樣的功能,所以得繞一下,就是先用GetItemIndex獲取本節點的Index,再用GetItemAt(Index + 1)即可獲取下一個節點的指針。
如果播放到最后一首,想跳到第一首,怎么辦?
嗯,這個時候只有找出播放列表第一個文件的下標了,可以看到本播放器的文件路徑是從【播放列表】的第五個子節點才開始的,我們直接用【播放列表】的下標加5就OK了?目前是OK,但是如果在前面再加上2個節點呢,那不就要改成7了? 所以這里用了一個通用的函數GetPlaylistInfo來獲取文件的數量,以及第一個文件的Tree下標。
是不是繞暈了? 嗯,因為Demo里並沒有Tree控件的響應,Alberl只是為了給大家示范Tree控件的用法,實際使用中,建議嵌入一個ListBox進去,這樣就無需繞來繞去了,直接GetItemIndex就是相應的下標,GetItemIndex(0)就是第一個文件~O(∩_∩)O~
嗯,最復雜的控件響應都介紹完了,剩下的就去看Demo吧~O(∩_∩)O~