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

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

本以为像上一片博客那样,处理标题栏的布局的右键消息就可以了。后来发现在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消息。代码如下:

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); 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

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

  1. 仿酷狗音乐播放器开发日志二十五 duilib右键事件的不足的bug修复

    转载请说明原出处,谢谢~~ 虽然仿酷狗的各个菜单早就写好了,但是一直没有附加到程序里.今天把菜单和播放列表控件关联时发现了问题. 和播放列表相关的菜单有三个,分别是每个音乐项目控件相关的菜单.分组的菜 ...

  2. 仿酷狗音乐播放器开发日志二十四 选项设置窗体的实现(附328行xml布局源码)

    转载请说明原出处,谢谢~~ 花了两天时间把仿酷狗的选项设置窗体做出来了,当然了只是做了外观.现在开学了,写代码的时间减少,所以整个仿酷狗的工程开发速度减慢了.今天把仿酷狗的选项设置窗体的布局代码分享出 ...

  3. 仿酷狗音乐播放器开发日志二十七 用ole为窗体增加文件拖动功能(附源码)

    转载请说明原出处,谢谢~~ 中秋到了,出去玩了几天.今天把仿酷狗程序做了收尾,已经开发完成了,下一篇博客把完结的情况说一下.在这篇博客里说一下使用OLE为窗体增加文件拖拽的功能.使用播放器,我更喜欢直 ...

  4. 仿酷狗音乐播放器开发日志二十三 修复Option控件显示状态不全的bug(附源码)

    转载请说明原出处,谢谢~~ 整个仿酷狗工程的开发将近尾声,现在还差选项设置窗体的部分,显然在设置窗体里用的最多的就是OptionUI控件,我在写好大致的布局后去测试效果,发现Option控件的显示效果 ...

  5. 仿酷狗音乐播放器开发日志十九——CTreeNodeUI的bug修复二(附源码)

    转载请说明原出处,谢谢 今天本来打算把仿酷狗播放列表的子控件拖动插入功能做一下,但是仔细使用播放列表控件时发现了几个逻辑错误,由于我的播放 列表控件是基于CTreeViewUI和CTreeNodeUI ...

  6. 仿酷狗音乐播放器开发日志十一——CTreeNodeUI的bug修复

    由于做播放列表控件,我的CMusicLength控件继承了CTreeVieWUI控件,在向分组控件中添加播放项目时,发现代码无法正常工作,调用CTreeNodeUI控件的Add方法后无反应,导致我的播 ...

  7. 仿酷狗音乐播放器开发日志三——修复CEditUI的bug2

    无意中发现了CEditUI控件的另一个bug,当我给播放器的搜索栏获取焦点时,这时再改变窗体大小,原本搜索栏应该对应着也改变大小,却发现CEditUI内嵌的edit控件没有跟着改变(如下图),跟着调试 ...

  8. Redrain仿酷狗音乐播放器开发完毕,发布测试程序

    转载请说明原出处,谢谢~~ 从暑假到现在中秋刚过,我用duilib开发仿酷狗播放器大概经历了50天.做仿酷狗的意图只是看原酷狗的界面比较漂亮,想做个完整一些的工程来练习一下duilib.今天把写好的程 ...

  9. 项目源码--Android类似酷狗音乐播放器

    下载源码 知识技能概要: 1.音乐文件的扫描与管理 2.音频流的解码 3. UI控件的综合使用 4.播放列表方式管理 5.随机播放方式 6.源码带详细的中文注释 ...... 详细介绍 1. 音乐文件 ...

随机推荐

  1. 淘宝(taobao)HSF框架

    一.背景 随着网站访问量增加,仅仅靠增加机器已不能满足系统的要求,于是需要对应用系统进行垂直拆分和水平拆分.在拆分之后,各个被拆分的模块如何通信?如何保证 性能?如何保证各个应用都以同样的方式交互?这 ...

  2. 【nginx网站性能优化篇(1)】gzip压缩与expire浏览器缓存

    gzip压缩 概述 网页在服务器端经过了gzip或者其他格式的压缩后的输出明显减少了content-length字节,当访问过百万时,这些减少的字节就会变为客观的流量给节约下来;从而减轻服务器的压力以 ...

  3. 【Linux高频命令专题(20)】du

    概述 显示每个文件和目录的磁盘使用空间. 命令格式 du [选项][文件] 文件缺省就代表当前目录大小 参数 -a或-all 显示目录中个别文件的大小. -b或-bytes 显示目录或文件大小时,以b ...

  4. App应用与思考

    我为什么没有加入苹果的iOS APP移动大军?http://blog.csdn.net/Code_GodFather/article/details/7956858 ----------------- ...

  5. 在PowerDesigner中设计物理模型3——视图、存储过程和函数

    原文:在PowerDesigner中设计物理模型3--视图.存储过程和函数 视图 在SQL Server中视图定义了一个SQL查询,一个查询中可以查询一个表也可以查询多个表,在PD中定义视图与在SQL ...

  6. C# 时间函数

    DateTime dt = DateTime.Now; string str = dt.ToString("yyyy-MM-dd");//2013-09-07 str = dt.T ...

  7. SQLserver临时表

    IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME='#temp') DROP TABLE #tempGOSELECT ID,XM,ADDDW INTO #t ...

  8. svn is already under version control问题解决

    svn ci 时出现 xx is already under version control,然后无法提交,出现这个问题的原因是你所提交的文件或目录是其他SVN的东西,即下面有.svn的目录,需要先把 ...

  9. 类handler

    /** The handler class is the interface for dynamically loadable storage engines. Do not add ifdefs a ...

  10. char型变量中能存贮一个中文汉字

    char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦.不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么 ...