开发者社区> redrain.> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

仿酷狗音乐播放器开发日志二十六 duilib在标题栏弹出菜单的方法

简介: 转载请说明原出处,谢谢~~        上篇日志说明了怎么让自定义控件响应右键消息。之后我给主窗体的标题栏增加右键响应,观察原酷狗后可以发现,在整个标题栏都是可以响应右键并弹出菜单的。
+关注继续查看

转载请说明原出处,谢谢~~

       上篇日志说明了怎么让自定义控件响应右键消息。之后我给主窗体的标题栏增加右键响应,观察原酷狗后可以发现,在整个标题栏都是可以响应右键并弹出菜单的。应该的效果如下:


       本以为像上一片博客那样,处理标题栏的布局的右键消息就可以了。后来发现在duilib的标题栏中无法像在客户区那样自如响应UIEVENT_CONTEXTMENU消息的。所以还得用另外的方法。

      在非客户区处理右击消息对应的是WM_NCRBUTTONUP,WM_NCRBUTTONUP是和WM_NCHITTEST相辅相成的。在WinImplBase.cpp文件中可以看到duilib处理WM_NCHITTEST的代码。在这里可以过滤指定的控件,被过滤的控件不会被duilib当作是非客户区的一部分,如果不过滤的话在标题栏的对应控件是无法响应用户的消息的,我为了适应仿酷狗程序,增加了被过滤的控件,源码如下:

LRESULT WindowImplBase::OnNcHitTest(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
	::ScreenToClient(*this, &pt);

	RECT rcClient;
	::GetClientRect(*this, &rcClient);

	if( !::IsZoomed(*this) )
	{
		RECT rcSizeBox = m_PaintManager.GetSizeBox();
		if( pt.y < rcClient.top + rcSizeBox.top )
		{
			if( pt.x < rcClient.left + rcSizeBox.left ) return HTTOPLEFT;
			if( pt.x > rcClient.right - rcSizeBox.right ) return HTTOPRIGHT;
			return HTTOP;
		}
		else if( pt.y > rcClient.bottom - rcSizeBox.bottom )
		{
			if( pt.x < rcClient.left + rcSizeBox.left ) return HTBOTTOMLEFT;
			if( pt.x > rcClient.right - rcSizeBox.right ) return HTBOTTOMRIGHT;
			return HTBOTTOM;
		}

		if( pt.x < rcClient.left + rcSizeBox.left ) return HTLEFT;
		if( pt.x > rcClient.right - rcSizeBox.right ) return HTRIGHT;
	}

	RECT rcCaption = m_PaintManager.GetCaptionRect();
	if( pt.x >= rcClient.left + rcCaption.left && pt.x < rcClient.right - rcCaption.right \
		&& pt.y >= rcCaption.top && pt.y < rcCaption.bottom ) {
			CControlUI* pControl = static_cast<CControlUI*>(m_PaintManager.FindControl(pt));
			if( pControl && _tcsicmp(pControl->GetClass(), _T("ButtonUI")) != 0 && 
				_tcsicmp(pControl->GetClass(), _T("OptionUI")) != 0 &&
				_tcsicmp(pControl->GetClass(), _T("TextUI")) != 0 &&
				_tcsicmp(pControl->GetClass(), _T("SliderUI")) != 0 &&
				_tcsicmp(pControl->GetClass(), _T("EditUI")) != 0)
				return HTCAPTION;
	}

	return HTCLIENT;
}

         如果要在主窗体的标题栏里响应右击消息,应该让主窗体类继承WindowImplBase类,然后重写HandleMessage函数或者直接修改WindowImplBase类的HandleMessage函数。在函数里处理WM_NCRBUTTONUP消息,我选择的是第一个方法。当发现用户右击了标题栏,就让标题栏布局向主窗体发出menu消息,剩下的就是正常处理menu消息。代码如下:


<pre code_snippet_id="459463" snippet_file_name="blog_20140827_2_9548473" name="code" class="cpp">LRESULT CFrameWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (uMsg == WM_NCRBUTTONUP )
	{
		POINT pt; pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);
<span>		</span>::ScreenToClient(*this, &pt);
RECT rcClient;::GetClientRect(*this, &rcClient);RECT rcCaption = m_PaintManager.GetCaptionRect();if( pt.x >= rcClient.left && pt.x < rcClient.right && pt.y >= rcClient.top && pt.y < rcCaption.bottom ) m_PaintManager.SendNotify(m_pWndTitle, DUI_MSGTYPE_MENU, 0, 0);}return __super::HandleMessage(uMsg, wParam, lParam);}


        原本我还在代码里过滤了控件,但是后来发现,在WM_NCHITTEST里面过滤了控件后就不用在WM_NCRBUTTONUP消息里另外过滤了!在WM_NCHITTEST里面过滤的控件,恰好在WM_NCRBUTTONUP消息就是不可以响应右键的,这正是我想要的。就这样可以模仿出酷狗的标题栏右键消息。


   Redrain  2014.8.27

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)
转载请说明原出处,谢谢~~        花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观。现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了。
1018 0
仿酷狗音乐播放器开发日志二十二 动态调色板控件第二版(性能大幅提升附源码)
转载请说明原出处,谢谢~~         在上次写的博客《仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源码)》发布后,我在群里和网友讨论这个控件的性能和优 缺点,发现了他很多不足,还有很多提升空间,之后我简单的修改了代码提升了控件的响应速度。
933 0
仿酷狗音乐播放器开发日志二十一 开发动态调色板控件(附源码)
转载请说明原出处,谢谢~~           上一篇仿酷狗日志结束后,整个换肤功能就只剩下调色板功能没有做了,我本以为会很简单,但是研究了酷狗的调色板功能后发现不是那么简单的事情。
1107 0
仿酷狗音乐播放器开发日志二十——换肤功能背景图片控件的制作(附源码)
转载请说明原出处,谢谢~~           《仿酷狗音乐播放器开发日志二十》里做了换肤功能的一部分,今天完成其他的部分。酷狗的换肤窗口里的背景图可以让用户选择来换图,原酷狗的背景图的小图标,有normal、hover、down等多种状态,鼠标移动上去便会发生变化。
1362 0
仿酷狗音乐播放器开发日志五——主体部分设计
   标题栏和状态栏设计完成后,开始设计主体部分,主体可以从左到右分为三部分,如图    其中每一个小部分又可以看成是一个纵向布局,所以先添加三个纵向布局,最左边的起名为Left_Tab,中间的为MusicList_Tab,右边的为Explorer_Tab,前两个布局宽度固定,第三个宽度要随着窗体的大小更改而更改。
754 0
仿酷狗音乐播放器开发日志九——播放列表的实现四
  经过今天的奋战,终于把CMusicListItemUI控件整合了起来,让一个列表元素可以拥有四种状态 并且可以动态更换,控件的整合过程比我想想的麻烦,切换的逻辑与duilib库本身有一些冲突,我只能重写好多代码,这是目前的仿照效果图。
742 0
仿酷狗音乐播放器开发日志——整体框架分析
转载请说明出处,谢谢~~ 学习duilib界面库有一段时间了,除了仓鼠软件共享以外还没用它开发过什么完整的软件项目。今天看到酷狗音乐播放器做得不错,经过几年的改革,酷狗现在的UI已经相当不错了。
1070 0
仿酷狗音乐播放器开发日志四——标题栏和状态栏的完善
 目前已经做好的效果图如下:    现在要把标题栏的最后一部分,分类按钮们加上,即      首先还是利用QQ截图的自定选定窗体大小的功能把酷狗截图粘贴到Firework里,然后对相应的控件的坐标和大小进行定位。
905 0
仿酷狗音乐播放器开发日志八——播放列表的实现三
    昨天做了hover状态下的CMusciListItemUI控件,也就是列表项元素,然后今天还是在Firework里对实际酷狗的软件元素进行定位,然后做了一个被选中状态下的CMusciListItemUI控件的元素,粗略看一下和原版的效果差...
864 0
仿酷狗音乐播放器开发日志十三——左侧功能块的完善
   发了6篇日志记录了播放列表控件的实现步骤,而这个播放列表只是左侧功能块的七分之一而已,还有其余6个功能需要做,他们分别是:本地列表、我的收藏、音乐电台、附近、临时播放、我的下载、更多。
926 0
+关注
redrain.
世上最可怕的事情就是比你优秀的人同时比你更努力!
93
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载