• 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~





  • 相关阅读:
    NGINX location 在配置中的优先级
    CentOS 系统启动流程
    微软输入法正则bug
    uniapp改变页面背景色
    路由Router
    vue-cli3替换默认的title和图标(区别脚手架vue-cli2版本)
    浏览器报错 Refused to apply style from 'http://******' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
    禁止浏览器后退
    前端构建工具(webpack-gulp-grunt-rollup...)
    鼠标经过小箭头(状态伪类需求)
  • 原文地址:https://www.cnblogs.com/Alberl/p/3403755.html
Copyright © 2020-2023  润新知