转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/42889709

大概半年前我写过博客说明怎么改造duilib的原代MenuDemo来支持消息发送(地址为:http://blog.csdn.net/zhuhongshu/article/details/38253297),而后在仿酷狗项目里也用到了菜单类,并且菜单类岁仿酷狗一起开源了。但是仿酷狗里面的菜单是专门针对仿酷狗的需求而修改的,所以通用性还不够。考虑到菜单也比较常用。所以今天就把菜单控件重整,修改为通用的控件,并且把它集成了到我的duilib库里,可以直接使用。

在此我把通用菜单控件的使用方法说明一下,源码和Demo可以在我的duilib库中下载到。

     一、首先看看这个菜单的功能:

1、可以展现多级菜单

2、可内嵌自定义控件,并且控件可以向主窗体发送消息,如图的红色叹号就是个按钮控件,可以制作酷狗音乐的托盘菜单的播放暂停按钮和进度控制进度条。

3、菜单拥有阴影效果(使用我库里的阴影类完成)

4、菜单可以自定义前方显示小图标,并且可以控制图标的大小和是否显示

5、菜单可以根据是否拥有子菜单决定是否显示小箭头

6、菜单可以添加分割线(控制分割线的样式和位置)

7、每个菜单项都可以实现复选或者单选功能

8、优化菜单的xml描述文件,编写方便容易

9、可以通过键盘的按钮控制菜单的选项

10、每个菜单项的高度和宽度是任意调整的

   二、接着是我更新后的属性列表:

  1. <Menu parent="CListUI" notifies="setfocus killfocus timer menu itemselect windowinit(root)">
  2. <Attribute name="inset" default="0,0,0,0" type="RECT" comment="菜单的高度等于所有菜单项的高度之和,加上inset属性的top和bottom"/>
  3. <!-- Menu标签的属性要通过Default来定义,为了让下级菜单也能拥有同样的外观,其他属性设置见List -->
  4. </Menu>
  5. <MenuElement parent="CListContainerElementUI" notifies="click valuechanged WM_MENUCLICK">
  6. <Attribute name="icon" default="" type="STRING" comment="菜单项的图标图片"/>
  7. <Attribute name="iconsize" default="0,0" type="SIZE" comment="图片的大小,最大为26x26"/>
  8. <Attribute name="checkitem" default="false" type="BOOL" comment="是否有复选功能"/>
  9. <Attribute name="ischeck" default="false" type="BOOL" comment="是否被选中(前提是开启了复选功能,复选功能属性应该写在本属性的前面)"/>
  10. <Attribute name="linetype" default="false" type="BOOL" comment="是否是分割线(开启后将不会显示图标)"/>
  11. <Attribute name="linepadding" default="29,0,7,0" type="RECT" comment="分割线的外边据"/>
  12. <Attribute name="linecolor" default="0xFFBCBFC4" type="DWORD" comment="分割线的颜色"/>
  13. <Attribute name="expland" default="false" type="BOOL" comment="是否显示下级菜单的小三角图片(需要通过Default标签设置ExplandIcon属性图片的路径)"/>
  14. <Attribute name="height" default="30" type="INT" comment="菜单项高度(分割线默认高度是6)"/>
  15. </MenuElement>

       三、下面给出动态效果图对应的布局代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <Window showshadow="true" shadowimage="shadow.png" shadowcorner="23,13,23,33">
  3. <Font name="微软雅黑" size="12" bold="false" default="true" />
  4. <Font name="微软雅黑" size="12" bold="true"/>
  5.  
  6. <!-- Menu标签的属性要通过Default来定义,为了让下级菜单也能拥有同样的外观 -->
  7. <Default name="Menu" value="bordersize="1" borderround="2,2" bordercolor="0x303132" inset="2,2,2,2" itemtextpadding="30,0,0,0" bkimage="file='menu_bk.png' corner='26,2,2,2' source='6,6,44,24'" itemselectedbkcolor="0xFF338ACA"" />
  8. <!-- ExplandIcon属性定义了下级菜单的小图标的样子 -->
  9. <Default name="ExplandIcon" value="menu_expand.png" />
  10.  
  11. <Menu>
  12. <MenuElement text="菜单测试0" expland="true" >
  13. <MenuElement text="菜单测试01" id="102"/>
  14. <MenuElement text="菜单测试02" />
  15. </MenuElement>
  16.  
  17. <MenuElement height="120" >
  18. <VerticalLayout bkcolor="#FFFFFFFE">
  19. <Button name="Menu_btn" height="118" normalimage="error.png" hotimage="check_hover.png" pushedimage="check_pressed.png"/>
  20. </VerticalLayout>
  21. </MenuElement>
  22.  
  23. <MenuElement name="Menu_Test1" text="菜单测试3" icon="right.png" iconsize="9,9" checkitem="true" ischeck="true" />
  24. <MenuElement name="Menu_Test2" text="菜单测试31" />
  25. <MenuElement name="Menu_Test3" text="菜单测试32" icon="right.png" iconsize="9,9" checkitem="true" ischeck="true" />
  26.  
  27. <MenuElement linetype="true" />
  28.  
  29. <MenuElement text="菜单测试4" icon="right.png" iconsize="9,9" expland="true" >
  30. <MenuElement text="菜单测试5" expland="true" icon="WebSit.png" >
  31. <MenuElement text="菜单测试6" icon="Virus.png" />
  32. <MenuElement text="菜单测试7" />
  33. </MenuElement>
  34. <MenuElement text="菜单测试8" expland="true">
  35. <MenuElement text="菜单测试a" />
  36. <MenuElement text="菜单测试b" />
  37. </MenuElement>
  38. </MenuElement>
  39. </Menu>
  40. </Window>

这里我说明一下使用菜单需要注意的一些地方:

1、需要通过Default来定义Menu的样式,这是为了可以让所有菜单(包括各个下级菜单)使用统一的样式

2、用Default标签定义ExplandIcon属性来制定下级菜单的小图标的路径

3、MenuElement如果要用单选或者复选功能,checkitem属性要写在ischeck属性前面

4、指定Menu的inset内边距属性的top和bottom属性,会自动让菜单增高(很多情况需要这样做来设置菜单的内边距)

5、MenuElement的linepadding属性可以设置分割线的外边距,默认为"29,0,7,0",这个值要根据实际的素材和需求来设置

       四、使用菜单的c++代码:



       菜单的创建:



  1. CMenuWnd* pMenu = new CMenuWnd();
  2. CPoint point = msg.ptMouse;
  3. ClientToScreen(m_hWnd, &point);
  4. pMenu->Init(NULL, _T("menutest.xml"), point, &m_PaintManager, &m_MenuCheckInfo);

其中菜单控件的的Init函数说明:

  1. /*
  2. * @pOwner 一级菜单不要指定这个参数,这是菜单内部使用的
  3. * @xml 菜单的布局文件
  4. * @point 菜单的左上角坐标
  5. * @pMainPaintManager 菜单的父窗体管理器指针
  6. * @xml 保存菜单的单选和复选信息结构指针
  7. * @dwAlignment 菜单的出现位置,默认出现在鼠标的右下侧。
  8. */
  9. void Init(CMenuElementUI* pOwner, STRINGorID xml, POINT point,
  10. CPaintManagerUI* pMainPaintManager, map<CDuiString,bool>* pMenuCheckInfo = NULL,
  11. DWORD dwAlignment = eMenuAlignment_Left | eMenuAlignment_Top);

使用new在堆上创建菜单控件(菜单会自己销毁内存)。自己主动创建菜单时第一参数直接填写NULL就可以;如果需要用到单选和复选功能就需要给控件指定一个map,来保存复选数据;如果需要控制菜单出现的位置,可以修改dwAlignment参数,参数可以设置eMenuAlignment_Left ,
eMenuAlignment_Top ,eMenuAlignment_Right ,eMenuAlignment_Bottom 四种值,具体用法参见demo。

      菜单的消息响应:

这个菜单类支持响应菜单内嵌的控件(比如按钮或者滑动条控件,这个常用在做播放器的菜单上),内嵌控件的消息响应和普通的消息响应完全一样,目前支持click消息和valuechanged消息(可以根据需求再增加),但是注意不可以在这些消息相应代码弹出像是MessageBox这样的模态对话框,原因见我之前写的博客。

单击每个菜单项的消息响应方法是,接收WM_MENUCLICK消息,这是我自定义的消息,处理这个消息时可以任意弹出模态对话框。通常消息响应的方法是重写WindowImplBase类的HandleCustomMessage函数来处理自定义消息(如果没有继承WindowImplBase类就自己写类似的函数功能),然后处理WM_MENUCLICK消息。处理代码如下:

  1. LRESULT CFrameWnd::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2. {
  3. if (uMsg == WM_MENUCLICK)
  4. {
  5. CDuiString *strMenuName = (CDuiString*)wParam;
  6. bool bChecked = (bool)lParam;
  7.  
  8. if ( *strMenuName == _T("Menu_Test1"))
  9. {
  10. if (bChecked)
  11. {
  12. MessageBox(m_hWnd, L"你选中Menu_Test1", L"", 0);
  13. }
  14. else
  15. {
  16. MessageBox(m_hWnd, L"你取消Menu_Test1", L"", 0);
  17. }
  18. }
  19. else if ( *strMenuName == _T("Menu_Test2"))
  20. {
  21. MessageBox(m_hWnd, L"你单击了Menu_Test2", L"", 0);
  22. }
  23. else if ( *strMenuName == _T("Menu_Test3"))
  24. {
  25. if (bChecked)
  26. {
  27. MessageBox(m_hWnd, L"你选中Menu_Test3", L"", 0);
  28. }
  29. else
  30. {
  31. MessageBox(m_hWnd, L"你取消Menu_Test3", L"", 0);
  32. }
  33. }
  34.  
  35. delete strMenuName;
  36. }
  37. bHandled = false;
  38. return 0;
  39. }

wParam参数是一个CDuiString指针,里面是被单击的菜单项的名字,通过它判断单击了哪个菜单项。使用完毕后记得销毁这个指针。lParam是菜单项的复选信息。

菜单控件源码:



菜单控件的源码相对较多,我就不直接贴出来了,需要的朋友可以直接下载我的duilib库来查看,里面已经附带了菜单使用Demo和对应源码:点击打开链接

2015.1.19   Redrain

QQ:491646717

Redrain 通用菜单控件使用方法和说明(附源码和demo)的更多相关文章

  1. Android Paint的使用以及方法介绍(附源码下载)

    要绘图,首先得调整画笔,待画笔调整好之后,再将图像绘制到画布上,这样才可以显示在手机屏幕上.Android 中的画笔是 Paint类,Paint 中包含了很多方法对其属性进行设置,主要方法如下: se ...

  2. delphi附带通用控件安装方法:

    附带通用控件安装方法:----------基本安装1.对于单个控件,Componet-->install component..-->PAS或DCU文件-->install;2.对于 ...

  3. 415 DOM 查找列表框、下拉菜单控件、对表格元素/表单控件进行增删改操作、创建元素并且复制节点与删除、 对表格操作、通用性和标准的事件监听方法(点击后弹窗效果以及去掉效果)

    DOM访问列表框.下拉菜单的常用属性: form.length.options.selectedindex.type       使用options[index]返回具体选项所对应的常用属性:defa ...

  4. DevExpress Winform 通用控件打印方法(允许可自定义边距) z

    DevExpress Winform 通用控件打印方法,包括gridcontrol,treelist,pivotGridControl,ChartControl,LayoutControl...(所有 ...

  5. 初识Windows窗体(包括各种控件,属性,方法)

    什么是Wind ows窗体? 顾名思义,win dows窗体就是将一些所必须的信息通过窗体的形式展示给客户看.例如:我们经常玩的QQ登陆界面,微信登陆界面,等等,都是以窗体的形式将信息展示给我们看的. ...

  6. 【转】UIAutomator定位Android控件的方法实践和建议(Appium姊妹篇)

    原文地址:http://blog.csdn.net/zhubaitian/article/details/39777951 在本人之前的一篇文章<<Appium基于安卓的各种FindEle ...

  7. UIAutomator定位Android控件的方法实践和建议(Appium姊妹篇)

    在本人之前的一篇文章<<Appium基于安卓的各种FindElement的控件定位方法实践和建议>>第二章节谈到Appium可以通过使用UIAutomator的方法去定位And ...

  8. Pad控件 UIPopoverController的介绍与使用(Pad的专属菜单控件、Swift版本)

    UIPopoverController 是iPad特有控件,iOS9之前,在iOS上也可以使用,在iOS9之后,只能用于Pad上. 如果非要在iOS上使用,编译不会有问题,运行后会崩溃,报错如下: T ...

  9. 自写JQ控件-树状菜单控件[demo下载]

    一个多月没有写博客了,最近也弄一个基于JQ的树状菜单控件,在此分享给大家.另外呢,通过这个例子分享一下怎么写JQ控件的. 事实上工作中,也是经常遇到的,有些时候自己想实现一些前端效果,用网上一些插件吧 ...

随机推荐

  1. netty in action 笔记 二

    netty的数据容器 网络数据的基本单位大多为字节,Java NIO 提供了ByteBuffer 作为它的字节容器,但使用起来过于复杂和繁琐.在Netty中, ByteBuffer 替代品是ByteB ...

  2. 最全的Markdown语法

    目录 Markdown语法 多级标题 引用与注释 插入代码 行内代码 代码段 图片 超链接 行内超链接 参数式超链接 字体 表格 分割线 多级列表 无序列表 有序列表 多选框 LaTeX公式 行内La ...

  3. Elasticsearch 相同内容文档,不同score(评分)的奇怪问题

    原文:http://stackoverflow.com/questions/14580752/elasticsearch-gives-different-scores-for-same-documen ...

  4. 使用深度学习来破解 captcha 验证码(转)

    使用深度学习来破解 captcha 验证码 本项目会通过 Keras 搭建一个深度卷积神经网络来识别 captcha 验证码,建议使用显卡来运行该项目. 下面的可视化代码都是在 jupyter not ...

  5. 自测之Lesson3:makefile

    题目:编写一个makefile文件,要求编译当前目录内的所有.c文件. 完成代码: .PHONY:clean all SRC=$(wildcard *.c) BIN=$(SRC:%.c=%) all: ...

  6. Fafa and the Gates(模拟)

    Two neighboring kingdoms decided to build a wall between them with some gates to enable the citizens ...

  7. Median of Two Sorted Arrays(hard)

    题目要求: 有两个排序的数组nums1和nums2分别为m和n大小. 找到两个排序数组的中位数.整体运行时间复杂度应为O(log(m + n)). 示例: 我的方法: 分别逐个读取两个数组的数,放到一 ...

  8. HDU 4869 Turn the pokers(思维+逆元)

    考试的时候没有做出来... 想到了答案一定是一段连续的区间,一直在纠结BFS判断最后的可行1数. 原来直接模拟一遍就可以算出来最后的端点... 剩下的就是组合数取模了,用逆元就行了... # incl ...

  9. 新浪云部署java web程序 注意事项

    在新浪云新手指南里有部署java的示例,但是对一个新手来说难免会有一些地方犯错,折腾了好长时间才把自己的java web部署到了新浪云.这里主要写一些我遇到的问题与第一次使用新浪云的朋友分享一下. 首 ...

  10. BZOJ4237 稻草人(分治+树状数组+单调栈)

    如果要询问的某个纵坐标为inf的点左边是否有点能与其构成所要求的矩形,只要用个单调栈就可以了.可以想到用分治来制造单调性. 按横坐标排序,每次考虑跨过分治中心的矩形.考虑右边的每个点能与左边的哪些点构 ...