duilib進階教程 -- 各種控件的響應 (10)


  到上一個教程為止,界面顯示的代碼就都介紹完啦,現在開始介紹控件的響應,其實在《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~






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM