Redrain 通用菜单控件使用方法和说明(附源码和demo)

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


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


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


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


Redrain 通用菜单控件使用方法和说明(附源码和demo)_第1张图片


        1、可以展现多级菜单

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

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

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

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

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

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

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

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

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


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


	
		
		
	
	
		
		
		
		
		
		
		
		
		
	

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












    
     	 
     	 
    

    
    	
            

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

       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* 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

转载于:https://www.cnblogs.com/redrainblog/p/4275826.html

你可能感兴趣的:(Redrain 通用菜单控件使用方法和说明(附源码和demo))