Redrain 通用菜单控件使用方法和说明(附源码和demo)
转载请说明原出处,谢谢~~: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、每个菜单项的高度和宽度是任意调整的
二、接着是我更新后的属性列表:
- <Menu parent="CListUI" notifies="setfocus killfocus timer menu itemselect windowinit(root)">
- <Attribute name="inset" default="0,0,0,0" type="RECT" comment="菜单的高度等于所有菜单项的高度之和,加上inset属性的top和bottom"/>
- <!-- Menu标签的属性要通过Default来定义,为了让下级菜单也能拥有同样的外观,其他属性设置见List -->
- </Menu>
- <MenuElement parent="CListContainerElementUI" notifies="click valuechanged WM_MENUCLICK">
- <Attribute name="icon" default="" type="STRING" comment="菜单项的图标图片"/>
- <Attribute name="iconsize" default="0,0" type="SIZE" comment="图片的大小,最大为26x26"/>
- <Attribute name="checkitem" default="false" type="BOOL" comment="是否有复选功能"/>
- <Attribute name="ischeck" default="false" type="BOOL" comment="是否被选中(前提是开启了复选功能,复选功能属性应该写在本属性的前面)"/>
- <Attribute name="linetype" default="false" type="BOOL" comment="是否是分割线(开启后将不会显示图标)"/>
- <Attribute name="linepadding" default="29,0,7,0" type="RECT" comment="分割线的外边据"/>
- <Attribute name="linecolor" default="0xFFBCBFC4" type="DWORD" comment="分割线的颜色"/>
- <Attribute name="expland" default="false" type="BOOL" comment="是否显示下级菜单的小三角图片(需要通过Default标签设置ExplandIcon属性图片的路径)"/>
- <Attribute name="height" default="30" type="INT" comment="菜单项高度(分割线默认高度是6)"/>
- </MenuElement>
三、下面给出动态效果图对应的布局代码:
- <?xml version="1.0" encoding="utf-8"?>
- <Window showshadow="true" shadowimage="shadow.png" shadowcorner="23,13,23,33">
- <Font name="微软雅黑" size="12" bold="false" default="true" />
- <Font name="微软雅黑" size="12" bold="true"/>
- <!-- Menu标签的属性要通过Default来定义,为了让下级菜单也能拥有同样的外观 -->
- <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"" />
- <!-- ExplandIcon属性定义了下级菜单的小图标的样子 -->
- <Default name="ExplandIcon" value="menu_expand.png" />
- <Menu>
- <MenuElement text="菜单测试0" expland="true" >
- <MenuElement text="菜单测试01" id="102"/>
- <MenuElement text="菜单测试02" />
- </MenuElement>
- <MenuElement height="120" >
- <VerticalLayout bkcolor="#FFFFFFFE">
- <Button name="Menu_btn" height="118" normalimage="error.png" hotimage="check_hover.png" pushedimage="check_pressed.png"/>
- </VerticalLayout>
- </MenuElement>
- <MenuElement name="Menu_Test1" text="菜单测试3" icon="right.png" iconsize="9,9" checkitem="true" ischeck="true" />
- <MenuElement name="Menu_Test2" text="菜单测试31" />
- <MenuElement name="Menu_Test3" text="菜单测试32" icon="right.png" iconsize="9,9" checkitem="true" ischeck="true" />
- <MenuElement linetype="true" />
- <MenuElement text="菜单测试4" icon="right.png" iconsize="9,9" expland="true" >
- <MenuElement text="菜单测试5" expland="true" icon="WebSit.png" >
- <MenuElement text="菜单测试6" icon="Virus.png" />
- <MenuElement text="菜单测试7" />
- </MenuElement>
- <MenuElement text="菜单测试8" expland="true">
- <MenuElement text="菜单测试a" />
- <MenuElement text="菜单测试b" />
- </MenuElement>
- </MenuElement>
- </Menu>
- </Window>
这里我说明一下使用菜单需要注意的一些地方:
1、需要通过Default来定义Menu的样式,这是为了可以让所有菜单(包括各个下级菜单)使用统一的样式
2、用Default标签定义ExplandIcon属性来制定下级菜单的小图标的路径
3、MenuElement如果要用单选或者复选功能,checkitem属性要写在ischeck属性前面
4、指定Menu的inset内边距属性的top和bottom属性,会自动让菜单增高(很多情况需要这样做来设置菜单的内边距)
5、MenuElement的linepadding属性可以设置分割线的外边距,默认为"29,0,7,0",这个值要根据实际的素材和需求来设置
四、使用菜单的c++代码:
菜单的创建:
- CMenuWnd* pMenu = new CMenuWnd();
- CPoint point = msg.ptMouse;
- ClientToScreen(m_hWnd, &point);
- pMenu->Init(NULL, _T("menutest.xml"), point, &m_PaintManager, &m_MenuCheckInfo);
其中菜单控件的的Init函数说明:
- /*
- * @pOwner 一级菜单不要指定这个参数,这是菜单内部使用的
- * @xml 菜单的布局文件
- * @point 菜单的左上角坐标
- * @pMainPaintManager 菜单的父窗体管理器指针
- * @xml 保存菜单的单选和复选信息结构指针
- * @dwAlignment 菜单的出现位置,默认出现在鼠标的右下侧。
- */
- void Init(CMenuElementUI* pOwner, STRINGorID xml, POINT point,
- CPaintManagerUI* pMainPaintManager, map<CDuiString,bool>* pMenuCheckInfo = NULL,
- 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消息。处理代码如下:
- LRESULT CFrameWnd::HandleCustomMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
- {
- if (uMsg == WM_MENUCLICK)
- {
- CDuiString *strMenuName = (CDuiString*)wParam;
- bool bChecked = (bool)lParam;
- if ( *strMenuName == _T("Menu_Test1"))
- {
- if (bChecked)
- {
- MessageBox(m_hWnd, L"你选中Menu_Test1", L"", 0);
- }
- else
- {
- MessageBox(m_hWnd, L"你取消Menu_Test1", L"", 0);
- }
- }
- else if ( *strMenuName == _T("Menu_Test2"))
- {
- MessageBox(m_hWnd, L"你单击了Menu_Test2", L"", 0);
- }
- else if ( *strMenuName == _T("Menu_Test3"))
- {
- if (bChecked)
- {
- MessageBox(m_hWnd, L"你选中Menu_Test3", L"", 0);
- }
- else
- {
- MessageBox(m_hWnd, L"你取消Menu_Test3", L"", 0);
- }
- }
- delete strMenuName;
- }
- bHandled = false;
- return 0;
- }
wParam参数是一个CDuiString指针,里面是被单击的菜单项的名字,通过它判断单击了哪个菜单项。使用完毕后记得销毁这个指针。lParam是菜单项的复选信息。
菜单控件源码:
菜单控件的源码相对较多,我就不直接贴出来了,需要的朋友可以直接下载我的duilib库来查看,里面已经附带了菜单使用Demo和对应源码:点击打开链接
2015.1.19 Redrain
QQ:491646717
Redrain 通用菜单控件使用方法和说明(附源码和demo)的更多相关文章
- Android Paint的使用以及方法介绍(附源码下载)
要绘图,首先得调整画笔,待画笔调整好之后,再将图像绘制到画布上,这样才可以显示在手机屏幕上.Android 中的画笔是 Paint类,Paint 中包含了很多方法对其属性进行设置,主要方法如下: se ...
- delphi附带通用控件安装方法:
附带通用控件安装方法:----------基本安装1.对于单个控件,Componet-->install component..-->PAS或DCU文件-->install;2.对于 ...
- 415 DOM 查找列表框、下拉菜单控件、对表格元素/表单控件进行增删改操作、创建元素并且复制节点与删除、 对表格操作、通用性和标准的事件监听方法(点击后弹窗效果以及去掉效果)
DOM访问列表框.下拉菜单的常用属性: form.length.options.selectedindex.type 使用options[index]返回具体选项所对应的常用属性:defa ...
- DevExpress Winform 通用控件打印方法(允许可自定义边距) z
DevExpress Winform 通用控件打印方法,包括gridcontrol,treelist,pivotGridControl,ChartControl,LayoutControl...(所有 ...
- 初识Windows窗体(包括各种控件,属性,方法)
什么是Wind ows窗体? 顾名思义,win dows窗体就是将一些所必须的信息通过窗体的形式展示给客户看.例如:我们经常玩的QQ登陆界面,微信登陆界面,等等,都是以窗体的形式将信息展示给我们看的. ...
- 【转】UIAutomator定位Android控件的方法实践和建议(Appium姊妹篇)
原文地址:http://blog.csdn.net/zhubaitian/article/details/39777951 在本人之前的一篇文章<<Appium基于安卓的各种FindEle ...
- UIAutomator定位Android控件的方法实践和建议(Appium姊妹篇)
在本人之前的一篇文章<<Appium基于安卓的各种FindElement的控件定位方法实践和建议>>第二章节谈到Appium可以通过使用UIAutomator的方法去定位And ...
- Pad控件 UIPopoverController的介绍与使用(Pad的专属菜单控件、Swift版本)
UIPopoverController 是iPad特有控件,iOS9之前,在iOS上也可以使用,在iOS9之后,只能用于Pad上. 如果非要在iOS上使用,编译不会有问题,运行后会崩溃,报错如下: T ...
- 自写JQ控件-树状菜单控件[demo下载]
一个多月没有写博客了,最近也弄一个基于JQ的树状菜单控件,在此分享给大家.另外呢,通过这个例子分享一下怎么写JQ控件的. 事实上工作中,也是经常遇到的,有些时候自己想实现一些前端效果,用网上一些插件吧 ...
随机推荐
- netty in action 笔记 二
netty的数据容器 网络数据的基本单位大多为字节,Java NIO 提供了ByteBuffer 作为它的字节容器,但使用起来过于复杂和繁琐.在Netty中, ByteBuffer 替代品是ByteB ...
- 最全的Markdown语法
目录 Markdown语法 多级标题 引用与注释 插入代码 行内代码 代码段 图片 超链接 行内超链接 参数式超链接 字体 表格 分割线 多级列表 无序列表 有序列表 多选框 LaTeX公式 行内La ...
- Elasticsearch 相同内容文档,不同score(评分)的奇怪问题
原文:http://stackoverflow.com/questions/14580752/elasticsearch-gives-different-scores-for-same-documen ...
- 使用深度学习来破解 captcha 验证码(转)
使用深度学习来破解 captcha 验证码 本项目会通过 Keras 搭建一个深度卷积神经网络来识别 captcha 验证码,建议使用显卡来运行该项目. 下面的可视化代码都是在 jupyter not ...
- 自测之Lesson3:makefile
题目:编写一个makefile文件,要求编译当前目录内的所有.c文件. 完成代码: .PHONY:clean all SRC=$(wildcard *.c) BIN=$(SRC:%.c=%) all: ...
- Fafa and the Gates(模拟)
Two neighboring kingdoms decided to build a wall between them with some gates to enable the citizens ...
- Median of Two Sorted Arrays(hard)
题目要求: 有两个排序的数组nums1和nums2分别为m和n大小. 找到两个排序数组的中位数.整体运行时间复杂度应为O(log(m + n)). 示例: 我的方法: 分别逐个读取两个数组的数,放到一 ...
- HDU 4869 Turn the pokers(思维+逆元)
考试的时候没有做出来... 想到了答案一定是一段连续的区间,一直在纠结BFS判断最后的可行1数. 原来直接模拟一遍就可以算出来最后的端点... 剩下的就是组合数取模了,用逆元就行了... # incl ...
- 新浪云部署java web程序 注意事项
在新浪云新手指南里有部署java的示例,但是对一个新手来说难免会有一些地方犯错,折腾了好长时间才把自己的java web部署到了新浪云.这里主要写一些我遇到的问题与第一次使用新浪云的朋友分享一下. 首 ...
- BZOJ4237 稻草人(分治+树状数组+单调栈)
如果要询问的某个纵坐标为inf的点左边是否有点能与其构成所要求的矩形,只要用个单调栈就可以了.可以想到用分治来制造单调性. 按横坐标排序,每次考虑跨过分治中心的矩形.考虑右边的每个点能与左边的哪些点构 ...